diff --git a/.gitignore b/.gitignore index 285f01c..7233f82 100644 --- a/.gitignore +++ b/.gitignore @@ -232,4 +232,4 @@ $RECYCLE.BIN/ # Windows shortcuts *.lnk -# End of https://www.toptal.com/developers/gitignore/api/windows,linux,python,visualstudiocode,jupyternotebooks \ No newline at end of file +# End of https://www.toptal.com/developers/gitignore/api/windows,linux,python,visualstudiocode,jupyternotebooks diff --git a/.vscode/settings.json b/.vscode/settings.json index 0eb9829..182245d 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -5,4 +5,4 @@ ], "python.testing.pytestEnabled": true, "python.testing.unittestEnabled": false -} \ No newline at end of file +} diff --git a/README.md b/README.md index 3000532..c712b30 100644 --- a/README.md +++ b/README.md @@ -37,4 +37,3 @@ CORNETO is developed at the [Institute for Computational Biomedicine](https://sa PerMedCoE project ([permedcoe.eu](https://permedcoe.eu/)) agreement no. 951773. Saez lab logo PerMedCoE logo UKHD logo - diff --git a/corneto/__init__.py b/corneto/__init__.py index d3e628e..d7a4477 100644 --- a/corneto/__init__.py +++ b/corneto/__init__.py @@ -1,12 +1,9 @@ import sys -from corneto._constants import * - from corneto import _plotting as pl -from corneto._graph import Graph, Attr, Attributes, EdgeType +from corneto._constants import * +from corneto._graph import Attr, Attributes, EdgeType, Graph from corneto._util import info -from corneto.utils import Attr, Attributes - from corneto.backend import DEFAULT_BACKEND, DEFAULT_SOLVER, available_backends from corneto.backend import DEFAULT_BACKEND as K from corneto.backend import DEFAULT_BACKEND as ops @@ -20,6 +17,7 @@ signaling, signflow_constraints, ) +from corneto.utils import Attr, Attributes __all__ = [ "Attr", @@ -30,7 +28,7 @@ "DEFAULT_BACKEND", "available_backends", "K", - "ops" + "ops", ] diff --git a/corneto/_core.py b/corneto/_core.py index 842505c..2ee4530 100644 --- a/corneto/_core.py +++ b/corneto/_core.py @@ -1,13 +1,14 @@ import abc +from collections import OrderedDict from copy import deepcopy +from itertools import chain +from numbers import Number +from typing import Any, Dict, Iterable, List, Optional, Set, Tuple + import numpy as np -from typing import Any, Optional, Iterable, Set, Tuple, Union, Dict, List -from corneto._settings import sparsify + from corneto._constants import * -from corneto._decorators import jit -from numbers import Number -from collections import OrderedDict -from itertools import chain +from corneto._settings import sparsify def _set(e): @@ -312,7 +313,7 @@ def to_graphviz( s, t = e s = list(s) if len(s) == 0: - s = f"*_{str(t)}" + s = f"*_{t!s}" g.node(s, shape="point") elif len(s) == 1: s = str(s[0]) @@ -322,7 +323,7 @@ def to_graphviz( raise NotImplementedError("Represent- hyperedges as composite edges") t = list(t) if len(t) == 0: - t = f"{str(s)}_*" + t = f"{s!s}_*" g.node(t, shape="point") elif len(t) == 1: t = str(t[0]) diff --git a/corneto/_decorators.py b/corneto/_decorators.py index 26f002a..f032ae7 100644 --- a/corneto/_decorators.py +++ b/corneto/_decorators.py @@ -1,5 +1,6 @@ from functools import wraps from typing import Callable + from corneto._settings import LOGGER, USE_NUMBA @@ -27,8 +28,7 @@ def _wrapped_func(*args, **kwargs): def _delegate(func): - """ - A decorator that wraps a function to provide extended functionality + """A decorator that wraps a function to provide extended functionality when applied within a class. This decorator modifies the behavior of the function `func` to handle expression objects and delegate calls to their underlying representations, while maintaining a set of @@ -74,6 +74,7 @@ def __add__(self, other): pass ``` """ + @wraps(func) def _wrapper_func(self, *args, **kwargs): symbols = set() @@ -97,9 +98,7 @@ def _wrapper_func(self, *args, **kwargs): # if available. E.g., if function is __add__, checks if the backend # expression has that function and uses it instead, this returns a # new backend expression which is wrapped back to CORNETO expr. - return self._create( - f(*args, **kwargs), symbols - ) + return self._create(f(*args, **kwargs), symbols) return self._create(func(self, *args, **kwargs), symbols) return _wrapper_func diff --git a/corneto/_graph.py b/corneto/_graph.py index 14480eb..63e98a1 100644 --- a/corneto/_graph.py +++ b/corneto/_graph.py @@ -20,9 +20,10 @@ ) import numpy as np -from corneto._types import Edge, CobraModel, NxDiGraph, NxGraph -from corneto._util import unique_iter + from corneto._io import import_cobra_model +from corneto._types import CobraModel, Edge, NxDiGraph, NxGraph +from corneto._util import unique_iter from corneto.utils import Attr, Attributes T = TypeVar("T") @@ -57,7 +58,8 @@ def _tpl(elements: Union[Any, Iterable[Any]]) -> Tuple[Any, ...]: class BaseGraph(abc.ABC): """BaseGraph class for graphs or hypergraphs with directed/undirected/mixed - and self edges""" + and self edges + """ def __init__(self, default_edge_type: EdgeType = EdgeType.DIRECTED) -> None: """Initialize BaseGraph with default edge type. @@ -647,7 +649,7 @@ class Graph(BaseGraph): default_edge_type Default edge type :class:`~corneto._graph.EdgeType`. - Examples + Examples: -------- >>> graph = corneto.Graph() >>> graph.add_edge(1, 2) @@ -688,7 +690,7 @@ def _add_edge( ) -> int: sv = frozenset(source) tv = frozenset(target) - #uv = sv | tv + # uv = sv | tv edge = (sv, tv) self._edges.append(edge) idx = len(self._edges) - 1 diff --git a/corneto/_io.py b/corneto/_io.py index a843151..eb22c5d 100644 --- a/corneto/_io.py +++ b/corneto/_io.py @@ -1,19 +1,18 @@ from pathlib import Path from typing import ( - List, + Dict, Iterable, - Tuple, + List, Optional, - Dict, Set, + Tuple, Union, - TypeVar, - Any, - TYPE_CHECKING, ) -from corneto._types import TupleSIF, CobraModel + import numpy as np +from corneto._types import CobraModel, TupleSIF + def _read_sif( sif_file: Union[str, Path], @@ -54,7 +53,9 @@ def _read_sif_iter( if has_header and i == 0: continue if len(line) <= 2: - raise ValueError(f"Invalid SIF line: {line}: expected at least 3 columns") + raise ValueError( + f"Invalid SIF line: {line}: expected at least 3 columns" + ) s, d, t = [line[idx] for idx in column_order] if discard_self_loops and s == t: continue @@ -95,7 +96,7 @@ def _get_reaction_species(reactions: Dict[str, Dict[str, int]]) -> Set[str]: def _stoichiometry( - reactions: Dict[str, Dict[str, int]] + reactions: Dict[str, Dict[str, int]], ) -> Tuple[np.ndarray, List[str], List[str]]: reactions_ids = list(reactions.keys()) compounds_ids = list(_get_reaction_species(reactions)) @@ -173,7 +174,7 @@ def import_cobra_model(model: CobraModel) -> Tuple[np.ndarray, np.ndarray, np.nd # Try to create a list import re - subsys = re.findall("\['(.*?)'\]", subsys) + subsys = re.findall(r"\['(.*?)'\]", subsys) if len(subsys) == 0: subsys = rxn.subsystem # A list containing a numpy array? @@ -222,8 +223,7 @@ def import_cobra_model(model: CobraModel) -> Tuple[np.ndarray, np.ndarray, np.nd def _is_url(url): - """ - Determine if the provided string is a valid url + """Determine if the provided string is a valid url :param url: string :return: True if the string is a URL """ @@ -243,8 +243,8 @@ def _download(url_file): if not _is_url(url_file): raise ValueError("Invalid url") - import tempfile import os + import tempfile from urllib.request import urlopen ext = pathlib.Path(url_file).suffix diff --git a/corneto/_legacy.py b/corneto/_legacy.py index 425b9f6..af73245 100644 --- a/corneto/_legacy.py +++ b/corneto/_legacy.py @@ -488,7 +488,7 @@ def select( if isinstance(ids, int) or isinstance(ids, str): ids = [ids] if not isinstance(ids, list): - raise ValueError(f"ids must be a list of ints or strings") + raise ValueError("ids must be a list of ints or strings") for id in ids: if isinstance(id, int): nids.append(id) @@ -998,7 +998,7 @@ def legacy_graphviz( s, t = e s = list(s) if len(s) == 0: - s = f"*_{str(t)}" + s = f"*_{t!s}" g.node(s, shape="point") elif len(s) == 1: s = str(s[0]) @@ -1008,7 +1008,7 @@ def legacy_graphviz( raise NotImplementedError("Represent- hyperedges as composite edges") t = list(t) if len(t) == 0: - t = f"{str(s)}_*" + t = f"{s!s}_*" g.node(t, shape="point") elif len(t) == 1: t = str(t[0]) diff --git a/corneto/_nx.py b/corneto/_nx.py index 00fc016..28a20fd 100644 --- a/corneto/_nx.py +++ b/corneto/_nx.py @@ -1,7 +1,8 @@ +import warnings +from typing import Any, Dict, Iterable, Optional + from corneto._legacy import ReNet from corneto._types import StrOrInt -from typing import Any, Dict, List, Optional, Iterable, Union -import warnings # TODO: Pass default style to plotting methods _default_style = { @@ -79,8 +80,8 @@ def plot( ): try: import matplotlib.pyplot as plt - from matplotlib.patches import ArrowStyle import networkx as nx + from matplotlib.patches import ArrowStyle except ImportError: raise ImportError("matplotlib and networkx are required for plotting") @@ -94,7 +95,7 @@ def plot( pos = nx.nx_pydot.graphviz_layout(G, prog="dot") except Exception as err: warnings.warn( - f"Failed to use graphviz with dot layout: {str(err)}. Using spring_layout instead." + f"Failed to use graphviz with dot layout: {err!s}. Using spring_layout instead." ) pos = nx.spring_layout(G) @@ -185,7 +186,7 @@ def to_nxgraph( reactions: Optional[Iterable[StrOrInt]] = None, ): try: - from networkx import DiGraph, set_node_attributes, set_edge_attributes + from networkx import DiGraph, set_edge_attributes, set_node_attributes except ImportError: raise ImportError( "NetworkX is required to convert a Reaction Network to a networkx graph." diff --git a/corneto/_plotting.py b/corneto/_plotting.py index 460a626..17af087 100644 --- a/corneto/_plotting.py +++ b/corneto/_plotting.py @@ -1,8 +1,10 @@ -from typing import Any, Dict, Optional, Literal -from corneto._graph import BaseGraph, Attr, EdgeType -from corneto.backend._base import EXPR_NAME_FLOW +from typing import Any, Dict, Literal, Optional + import numpy as np +from corneto._graph import Attr, BaseGraph, EdgeType +from corneto.backend._base import EXPR_NAME_FLOW + def clip_quantiles(arr, q): if q < 0 or q > 1: @@ -14,7 +16,7 @@ def clip_quantiles(arr, q): def vertex_style( P, - G, # TODO: G should not be required + G, # TODO: G should not be required vertex_var: str = "vertex_values", negative_color: str = "dodgerblue4", positive_color: str = "firebrick4", diff --git a/corneto/_settings.py b/corneto/_settings.py index 12891c6..2d878d8 100644 --- a/corneto/_settings.py +++ b/corneto/_settings.py @@ -1,9 +1,10 @@ import logging import os import sys -import numpy as np from importlib.util import find_spec +import numpy as np + LOGGER = logging.getLogger("__corneto__") LOGGER.setLevel(logging.INFO) LOGGER.propagate = False diff --git a/corneto/_types.py b/corneto/_types.py index 6380739..370ac07 100644 --- a/corneto/_types.py +++ b/corneto/_types.py @@ -1,6 +1,7 @@ -from typing import TYPE_CHECKING, FrozenSet, Tuple, Union, Any, TypeVar -from corneto._settings import LOGGER import importlib +from typing import TYPE_CHECKING, Any, FrozenSet, Tuple, TypeVar, Union + +from corneto._settings import LOGGER Edge = Tuple[FrozenSet[Any], FrozenSet[Any]] StrOrInt = Union[str, int] diff --git a/corneto/_typing.py b/corneto/_typing.py index 6d0ee5a..9ba47a1 100644 --- a/corneto/_typing.py +++ b/corneto/_typing.py @@ -1,4 +1,4 @@ -from typing import Union, Tuple +from typing import Tuple, Union StrOrInt = Union[str, int] TupleSIF = Tuple[str, int, str] diff --git a/corneto/_util.py b/corneto/_util.py index 534b730..9335ce6 100644 --- a/corneto/_util.py +++ b/corneto/_util.py @@ -40,7 +40,7 @@ def get_latest_version( if match: version = match.group(1) return version - except Exception as e: + except Exception: return None @@ -49,8 +49,6 @@ def _support_html_output(force_html: bool = False): # and https://github.com/tqdm/tqdm/blob/0bb91857eca0d4aea08f66cf1c8949abe0cd6b7a/tqdm/notebook.py#L38 try: from IPython import get_ipython - from IPython.core.display import display - from IPython.display import HTML ipy = get_ipython() if ipy is None: @@ -115,7 +113,7 @@ def _get_info() -> Dict[str, Dict]: info["graphviz_version"]["message"] = f"v{graphviz.__version__}" info["graphviz_version"]["value"] = graphviz.__version__ - except Exception as e: + except Exception: pass info["repo_url"] = { "title": "Repository", @@ -189,7 +187,7 @@ def _info(): if DEFAULT_BACKEND: print("Default backend (corneto.K):", str(DEFAULT_BACKEND)) print( - f"Available solvers for {str(DEFAULT_BACKEND)}:", + f"Available solvers for {DEFAULT_BACKEND!s}:", ", ".join([s for s in DEFAULT_BACKEND.available_solvers()]), ) else: diff --git a/corneto/backend/__init__.py b/corneto/backend/__init__.py index 6c026d7..c2ba45b 100644 --- a/corneto/backend/__init__.py +++ b/corneto/backend/__init__.py @@ -1,3 +1,4 @@ +import corneto._settings as s from corneto.backend._base import ( Backend, NoBackend, @@ -5,7 +6,6 @@ ) from corneto.backend._cvxpy_backend import CvxpyBackend from corneto.backend._picos_backend import PicosBackend -import corneto._settings as s supported_backends = [CvxpyBackend(), PicosBackend()] diff --git a/corneto/backend/_base.py b/corneto/backend/_base.py index 736a68e..98d706e 100644 --- a/corneto/backend/_base.py +++ b/corneto/backend/_base.py @@ -1,13 +1,14 @@ import abc -import numpy as np import numbers -from typing import Set, Any, Dict, Iterable, Optional, Tuple, Union, List, Callable -from corneto._settings import LOGGER, _get_matrix_builder -from corneto.utils import Attributes +from typing import Any, Callable, Dict, Iterable, List, Optional, Set, Tuple, Union + +import numpy as np from corneto._constants import * from corneto._decorators import _delegate from corneto._graph import BaseGraph +from corneto._settings import LOGGER, _get_matrix_builder +from corneto.utils import Attributes def _eq_shape(a: np.ndarray, b: np.ndarray) -> bool: @@ -982,32 +983,25 @@ def Xor(self, x: CExpression, y: CExpression, varname="_xor"): [xor >= x - y, xor >= y - x, xor <= x + y, xor <= 2 - x - y] ) - def linear_or( - self, x: CSymbol, axis: Optional[int] = None, varname="_linear_or" - ): + def linear_or(self, x: CSymbol, axis: Optional[int] = None, varname="_linear_or"): # Check if the variable is binary, otherwise throw an error if x._vartype != VarType.BINARY: raise ValueError(f"Variable x has type {x._vartype} instead of BINARY") Z = x.sum(axis=axis) - Z_norm = Z / x.shape[axis] # between 0-1 + Z_norm = Z / x.shape[axis] # between 0-1 # Create a new binary variable to compute linearized or Or = self.Variable(varname, Z.shape, 0, 1, vartype=VarType.BINARY) return self.Problem([Or >= Z_norm, Or <= Z]) - - def linear_and( - self, x: CSymbol, axis: Optional[int] = None, varname="_linear_and" - ): + def linear_and(self, x: CSymbol, axis: Optional[int] = None, varname="_linear_and"): # Check if the variable is binary, otherwise throw an error if x._vartype != VarType.BINARY: raise ValueError(f"Variable x has type {x._vartype} instead of BINARY") Z = x.sum(axis=axis) N = x.shape[axis] - Z_norm = Z / N + Z_norm = Z / N And = self.Variable(varname, Z.shape, 0, 1, vartype=VarType.BINARY) return self.Problem([And <= Z_norm, And >= Z - N + 1]) - - class NoBackend(Backend): diff --git a/corneto/backend/_cvxpy_backend.py b/corneto/backend/_cvxpy_backend.py index 841b0cf..8312b39 100644 --- a/corneto/backend/_cvxpy_backend.py +++ b/corneto/backend/_cvxpy_backend.py @@ -1,15 +1,15 @@ -from typing import Set, Any, List, Optional, Tuple, Union +from typing import Any, List, Optional, Set, Tuple, Union + +import numpy as np + +from corneto._constants import * +from corneto._settings import LOGGER from corneto.backend._base import ( + Backend, CExpression, CSymbol, ProblemDef, - Backend, - _delegate, ) -import numpy as np -from corneto._constants import * -from corneto._settings import LOGGER - try: import cvxpy as cp @@ -31,10 +31,10 @@ def _elementwise_mul(self, other: Any) -> Any: def _norm(self, p: int = 2) -> Any: return cp.norm(self._expr, p=p) - + def _sum(self, axis: Optional[int] = None) -> Any: return cp.sum(self._expr, axis=axis) - + def _max(self, axis: Optional[int] = None) -> Any: return cp.max(self._expr, axis=axis) diff --git a/corneto/backend/_picos_backend.py b/corneto/backend/_picos_backend.py index 2547fdb..7b892a9 100644 --- a/corneto/backend/_picos_backend.py +++ b/corneto/backend/_picos_backend.py @@ -1,8 +1,10 @@ +from typing import Any, List, Optional, Set, Tuple, Union + import numpy as np -from typing import Set, Any, List, Optional, Tuple, Union -from corneto._settings import _numpy_array -from corneto.backend._base import CExpression, CSymbol, Backend, ProblemDef + from corneto._constants import * +from corneto._settings import _numpy_array +from corneto.backend._base import Backend, CExpression, CSymbol, ProblemDef try: import picos as pc @@ -24,10 +26,10 @@ def _elementwise_mul(self, other: Any) -> Any: def _norm(self, p: int = 2) -> CExpression: return pc.Norm(self._expr, p=p) - + def _sum(self, axis: Optional[int] = None) -> Any: return pc.sum(self._expr, axis=axis) - + def _max(self, axis: Optional[int] = None) -> Any: raise NotImplementedError() diff --git a/corneto/contrib/networkx.py b/corneto/contrib/networkx.py index 25c4ff4..5717671 100644 --- a/corneto/contrib/networkx.py +++ b/corneto/contrib/networkx.py @@ -1,12 +1,60 @@ -import corneto as cn -from corneto._graph import BaseGraph -from corneto._types import NxGraph, NxDiGraph -from corneto.utils import import_optional_module, Attr -from corneto._graph import EdgeType +"""This module enables conversion between Corneto and NetworkX graph representations. + +It offers functions to transform Corneto graphs to NetworkX graphs and back, +and a class that interfaces with NetworkX to utilize its features directly on +Corneto graphs through transparent conversions. + +The module employs lazy loading for NetworkX, optimizing load times and memory +when NetworkX is not immediately needed. + +Functions: + corneto_graph_to_networkx(G, skip_unsupported_edges=False): + Converts a Corneto graph to a NetworkX graph, supporting directed and + undirected edges, with an option to skip unsupported edge types. + networkx_to_corneto_graph(G): + Converts a NetworkX graph to a Corneto graph, maintaining edge data. + +Classes: + NetworkXWrapper: + Wraps NetworkX, providing dynamic access to attributes and methods. + Automatically converts Corneto graphs for NetworkX methods, allowing + seamless integration. + +Example Usage: + # Convert Corneto graph to NetworkX + G_corneto = cn.Graph() + G_corneto.add_edge(1, 2) + G_networkx = corneto_graph_to_networkx(G_corneto) + + # Use NetworkX function on a Corneto graph via the wrapper + networkx.shortest_path(corneto_graph_to_networkx(G_corneto), source=1, target=2) + +Note: + Assumes 'corneto' library availability with specific structure. Designed for + basic edge types; does not support hybrid or hypergraphs unless skipped. +""" + from typing import Union +import corneto as cn +from corneto._graph import BaseGraph, EdgeType +from corneto._types import NxDiGraph, NxGraph +from corneto.utils import Attr, import_optional_module + def corneto_graph_to_networkx(G: BaseGraph, skip_unsupported_edges: bool = False): + """Converts a Corneto graph to a NetworkX graph. + + Args: + G (BaseGraph): The Corneto graph to convert. + skip_unsupported_edges (bool): If True, skip hyperedges and other unsupported edge types. Defaults to False. + + Returns: + Union[NxGraph, NxDiGraph]: A NetworkX graph. + + Raises: + ValueError: If the graph contains hyperedges or unsupported hybrid graph types. + """ nx = import_optional_module("networkx") dir_edges = [] undir_edges = [] @@ -42,6 +90,14 @@ def corneto_graph_to_networkx(G: BaseGraph, skip_unsupported_edges: bool = False def networkx_to_corneto_graph(G: Union[NxGraph, NxDiGraph]): + """Converts a NetworkX graph to a Corneto graph. + + Args: + G (Union[NxGraph, NxDiGraph]): The NetworkX graph to convert. + + Returns: + cn.Graph: A Corneto graph. + """ Gc = cn.Graph() for edge in G.edges(): e_data = G.get_edge_data(edge[0], edge[1], default=dict()) @@ -50,13 +106,27 @@ def networkx_to_corneto_graph(G: Union[NxGraph, NxDiGraph]): class NetworkXWrapper: + """Wrapper class to interface between NetworkX and Corneto graph types. + + This class dynamically imports NetworkX when needed and converts Corneto graph arguments + to NetworkX graphs for function calls. + """ + def __init__(self): + """Initializes the NetworkX wrapper.""" self.networkx = None def __getattr__(self, name): + """Dynamically handles attribute accesses and method calls on the NetworkX module. + + Args: + name (str): The attribute name to fetch from NetworkX. + + Returns: + Any: The attribute or wrapped method from the NetworkX library. + """ if self.networkx is None: self.networkx = import_optional_module("networkx") - # This method is called whenever an attribute is accessed original_attr = getattr(self.networkx, name) if callable(original_attr): diff --git a/corneto/methods/__init__.py b/corneto/methods/__init__.py index 1e5c727..68427ff 100644 --- a/corneto/methods/__init__.py +++ b/corneto/methods/__init__.py @@ -1,12 +1,13 @@ -from corneto.methods.signaling import create_flow_graph -from corneto.methods.signaling import signflow_constraints -from corneto.methods.signaling import default_sign_loss +from corneto.methods.carnival import runInverseCarnival, runVanillaCarnival from corneto.methods.shortest_path import shortest_path, solve_shortest_path +from corneto.methods.signaling import ( + create_flow_graph, + default_sign_loss, + signflow_constraints, +) # from corneto.methods.signflow import signflow - # Legacy from corneto.methods.signaling import create_flow_graph as carnival_renet -from corneto.methods.signaling import signflow_constraints as carnival_constraints from corneto.methods.signaling import default_sign_loss as carnival_loss -from corneto.methods.carnival import runVanillaCarnival, runInverseCarnival +from corneto.methods.signaling import signflow_constraints as carnival_constraints diff --git a/corneto/methods/carnival.py b/corneto/methods/carnival.py index 439717b..c7394a9 100644 --- a/corneto/methods/carnival.py +++ b/corneto/methods/carnival.py @@ -1,8 +1,9 @@ -from corneto.methods.signaling import signflow, create_flow_graph -from corneto._graph import Graph +import time from typing import Dict, List, Tuple, Union + +from corneto._graph import Graph from corneto._settings import LOGGER -import time +from corneto.methods.signaling import create_flow_graph, signflow def info(s, show=True): @@ -133,7 +134,7 @@ def heuristic_carnival( def get_result(P, G, condition="c0"): V = P.expr["vertex_values_" + condition].value E = P.expr["edge_values_" + condition].value - return {'V': G.V, 'value': V}, {'E': G.E, 'value': E} + return {"V": G.V, "value": V}, {"E": G.E, "value": E} def get_selected_edges(P, G, condition="c0"): diff --git a/corneto/methods/metabolism/_utils.py b/corneto/methods/metabolism/_utils.py index 4f27a25..959e820 100644 --- a/corneto/methods/metabolism/_utils.py +++ b/corneto/methods/metabolism/_utils.py @@ -1,6 +1,7 @@ import ast import re from multiprocessing import Pool, cpu_count + from corneto._settings import LOGGER _pattern = r"\b(?!and\b|or\b)[A-Za-z0-9_]+\b" @@ -50,8 +51,10 @@ def _eval_gpr(node, context, func_and, func_or, expression=None): elif isinstance(node, ast.Name): return context[node.id] else: - #raise ValueError(f"Unsupported AST node: {type(node).__name__}") - LOGGER.warning(f"Unsupported AST node: {type(node).__name__}, expression = {expression}") + # raise ValueError(f"Unsupported AST node: {type(node).__name__}") + LOGGER.warning( + f"Unsupported AST node: {type(node).__name__}, expression = {expression}" + ) return None diff --git a/corneto/methods/metabolism/fba.py b/corneto/methods/metabolism/fba.py index 88dd20c..b5b4a6c 100644 --- a/corneto/methods/metabolism/fba.py +++ b/corneto/methods/metabolism/fba.py @@ -1,15 +1,17 @@ +from typing import Dict, Optional, Union + +import numpy as np + +from corneto import K +from corneto._graph import BaseGraph from corneto.backend._base import ( - NonZeroIndicator, - Indicator, - VarType, - ProblemDef, Backend, Direction, + Indicator, + NonZeroIndicator, + ProblemDef, + VarType, ) -from corneto._graph import BaseGraph -from typing import Optional, Dict, Union -from corneto import K -import numpy as np class FBAProblem(ProblemDef): diff --git a/corneto/methods/shortest_path.py b/corneto/methods/shortest_path.py index ea1d950..07257ad 100644 --- a/corneto/methods/shortest_path.py +++ b/corneto/methods/shortest_path.py @@ -1,10 +1,11 @@ -import numpy as np -from corneto._graph import BaseGraph, EdgeType, Attr -from corneto.backend import Backend, DEFAULT_BACKEND -from corneto.backend._base import Indicator, DEFAULT_UB -from corneto import VarType from typing import Any, Optional + +import numpy as np + +from corneto._graph import BaseGraph from corneto._settings import LOGGER +from corneto.backend import DEFAULT_BACKEND, Backend +from corneto.backend._base import DEFAULT_UB, Indicator def shortest_path( diff --git a/corneto/methods/signal/cellnopt_ilp.py b/corneto/methods/signal/cellnopt_ilp.py index 9aee321..7a7bac4 100644 --- a/corneto/methods/signal/cellnopt_ilp.py +++ b/corneto/methods/signal/cellnopt_ilp.py @@ -1,8 +1,10 @@ -import corneto as cn import re +from typing import Literal, Optional + import numpy as np + +import corneto as cn from corneto.backend._base import EXPR_NAME_FLOW -from typing import Optional, Literal def clip_quantiles(arr, q): @@ -65,8 +67,7 @@ def get_interactions(G): def get_AND_gate_nodes(G): - """ - Get the indices of nodes that represent AND gates in the graph G. + """Get the indices of nodes that represent AND gates in the graph G. Parameters: - G (Graph): The input graph. @@ -82,8 +83,7 @@ def get_AND_gate_nodes(G): def get_incidence_matrices_of_edges(G, as_dataframe=False): - """ - Get the mapping matrices A, At, Ah from the graph G. + """Get the mapping matrices A, At, Ah from the graph G. Parameters: - G: The graph object. @@ -107,8 +107,7 @@ def get_incidence_matrices_of_edges(G, as_dataframe=False): def get_egdes_with_head(G): - """ - Get the indices of edges with a head node. + """Get the indices of edges with a head node. Parameters: G (graph): The input graph. @@ -125,7 +124,6 @@ def get_inhibited_nodes(G, exp_list): """Returns an array, with shape = (len(G.V), len(exp_list)), where each column is a boolean array indicating if the node is inhibited in the corresponding experiment. """ - V_is_inhibited = np.full((len(G.V), len(exp_list)), False) for exp, iexp in zip(exp_list, range(len(exp_list))): @@ -272,7 +270,6 @@ def cellnoptILP(G, exp_list, solver=None, alpha_flow=1e-3, verbose=False): # This is for general nodes that are not AND gates # for exp, iexp in zip(exp_list, range(len(exp_list))): - is_regular_node = np.logical_and(~V_is_and, ~V_is_inhibited[:, iexp]) P += ( diff --git a/corneto/methods/signaling.py b/corneto/methods/signaling.py index 9ea42eb..3c0d6b2 100644 --- a/corneto/methods/signaling.py +++ b/corneto/methods/signaling.py @@ -1,4 +1,4 @@ -from typing import Any, Callable, Dict, List, Optional, Set, Tuple, Union +from typing import Any, Dict, List, Optional, Set, Tuple, Union import numpy as np @@ -6,8 +6,8 @@ from corneto._constants import * # from corneto._core import Graph -from corneto._graph import Graph, BaseGraph -from corneto._settings import LOGGER, sparsify +from corneto._graph import BaseGraph +from corneto._settings import sparsify from corneto.backend import Backend from corneto.backend._base import Indicators, ProblemDef @@ -156,10 +156,10 @@ def signflow_constraints( (g.num_edges,), vartype=VarType.BINARY, ) - + p.register(f"edge_values_{c}", R_act - R_inh) p.register(f"vertex_values_{c}", N_act - N_inh) - + if len(non_reachable) > 0: # TODO: Do the same for non reachable reactions p += N_act[non_reachable] == 0 diff --git a/corneto/methods/steiner.py b/corneto/methods/steiner.py index 5a27999..501f71b 100644 --- a/corneto/methods/steiner.py +++ b/corneto/methods/steiner.py @@ -1,8 +1,7 @@ import numpy as np -from corneto._graph import BaseGraph, EdgeType, Attr -from corneto.backend import Backend, DEFAULT_BACKEND -from corneto._settings import sparsify -from corneto import VarType + +from corneto._graph import Attr, BaseGraph, EdgeType +from corneto.backend import DEFAULT_BACKEND, Backend def exact_steiner_tree( diff --git a/corneto/utils/__init__.py b/corneto/utils/__init__.py index f203001..1dc92fb 100644 --- a/corneto/utils/__init__.py +++ b/corneto/utils/__init__.py @@ -1,7 +1,8 @@ -from corneto.utils._attr import Attr, Attributes +import importlib import re from pathlib import Path -import importlib + +from corneto.utils._attr import Attr, Attributes def get_library_version(lib_name): diff --git a/docs/_extension/gallery_directive.py b/docs/_extension/gallery_directive.py index e80d2c8..8f199db 100644 --- a/docs/_extension/gallery_directive.py +++ b/docs/_extension/gallery_directive.py @@ -8,6 +8,7 @@ It currently exists for maintainers of the pydata-sphinx-theme, but might be abstracted into a standalone package if it proves useful. """ + from pathlib import Path from typing import Any, Dict, List @@ -121,9 +122,9 @@ def run(self) -> List[nodes.Node]: # Prep the options for the template grid container_options = {"gutter": 2, "class-container": "gallery-directive"} if "class-container" in self.options: - container_options[ - "class-container" - ] += f' {self.options["class-container"]}' + container_options["class-container"] += ( + f' {self.options["class-container"]}' + ) container_options_str = "\n".join( f":{k}: {v}" for k, v in container_options.items() ) diff --git a/docs/_static/css/custom.css b/docs/_static/css/custom.css index 9c9e58b..caaa2f6 100644 --- a/docs/_static/css/custom.css +++ b/docs/_static/css/custom.css @@ -15,4 +15,4 @@ h1:has(> .hidden-title-marker) { a:hover { text-decoration: none !important; filter: brightness(90%); -} \ No newline at end of file +} diff --git a/docs/_static/switcher.json b/docs/_static/switcher.json index 09dea79..edf002d 100644 --- a/docs/_static/switcher.json +++ b/docs/_static/switcher.json @@ -10,4 +10,4 @@ "url": "https://saezlab.github.io/corneto/main/", "preferred": true } -] \ No newline at end of file +] diff --git a/docs/api/index.rst b/docs/api/index.rst index dd7a7c7..c02ed8b 100644 --- a/docs/api/index.rst +++ b/docs/api/index.rst @@ -19,4 +19,4 @@ CORNETO :maxdepth: 4 :caption: Contents: - corneto \ No newline at end of file + corneto diff --git a/docs/conf.py b/docs/conf.py index 19f1391..de5c9ae 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -3,11 +3,10 @@ # For the full list of built-in configuration values, see the documentation: # https://www.sphinx-doc.org/en/master/usage/configuration.html -import sys import os +import sys from pathlib import Path - # import pydata_sphinx_theme # from sphinx.application import Sphinx @@ -25,7 +24,7 @@ # https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration extensions = [ - #"myst_parser", + # "myst_parser", "myst_nb", "sphinx_design", "sphinx.ext.autodoc", @@ -36,7 +35,7 @@ "sphinx.ext.autosummary", "sphinxcontrib.mermaid", "sphinx.ext.intersphinx", - 'sphinx.ext.doctest', + "sphinx.ext.doctest", "sphinx_favicon", "hoverxref.extension", "sphinx_multiversion", @@ -50,7 +49,7 @@ "dollarmath", "html_image", "html_admonition", - "substitution" + "substitution", ] html_context = { @@ -70,6 +69,7 @@ import corneto + myst_substitutions = { "version": corneto.__version__, } @@ -126,7 +126,7 @@ "json_url": "https://saezlab.github.io/corneto/main/_static/switcher.json", "version_match": corneto.__version__, }, - "navbar_start": ["navbar-logo", "version-switcher"] + "navbar_start": ["navbar-logo", "version-switcher"], } intersphinx_mapping = { diff --git a/docs/guide/index.md b/docs/guide/index.md index 6d46f4b..8d89810 100644 --- a/docs/guide/index.md +++ b/docs/guide/index.md @@ -21,4 +21,4 @@ metabolism/index signaling/index interactomics/index interoperability/index -``` \ No newline at end of file +``` diff --git a/docs/guide/interactomics/index.md b/docs/guide/interactomics/index.md index b12f944..77215e4 100644 --- a/docs/guide/interactomics/index.md +++ b/docs/guide/interactomics/index.md @@ -6,4 +6,4 @@ Tutorials on how to use CORNETO to integrate omics data on undirected networks t ```{toctree} :maxdepth: 3 -``` \ No newline at end of file +``` diff --git a/docs/guide/interoperability/cobrapy.ipynb b/docs/guide/interoperability/cobrapy.ipynb index 00f1b4d..ff7e007 100644 --- a/docs/guide/interoperability/cobrapy.ipynb +++ b/docs/guide/interoperability/cobrapy.ipynb @@ -48,7 +48,6 @@ ], "source": [ "import corneto as cn\n", - "import cobra\n", "\n", "cn.info()" ] diff --git a/docs/guide/interoperability/cvxpy.ipynb b/docs/guide/interoperability/cvxpy.ipynb index 97953b4..70ded87 100644 --- a/docs/guide/interoperability/cvxpy.ipynb +++ b/docs/guide/interoperability/cvxpy.ipynb @@ -102,9 +102,10 @@ } ], "source": [ - "from corneto.backend import CvxpyBackend\n", "import numpy as np\n", "\n", + "from corneto.backend import CvxpyBackend\n", + "\n", "backend = CvxpyBackend()\n", "P = backend.Problem()\n", "A = np.array([[0.12, 0.92, 0.76, 0.98, 0.79], [0.58, 0.57, 0.53, 0.71, 0.55]])\n", diff --git a/docs/guide/interoperability/index.md b/docs/guide/interoperability/index.md index 126d9a2..28177b2 100644 --- a/docs/guide/interoperability/index.md +++ b/docs/guide/interoperability/index.md @@ -17,4 +17,4 @@ omnipath.ipynb networkx.ipynb cvxpy.ipynb picos.ipynb -``` \ No newline at end of file +``` diff --git a/docs/guide/interoperability/networkx.ipynb b/docs/guide/interoperability/networkx.ipynb index 7085b72..fd21848 100644 --- a/docs/guide/interoperability/networkx.ipynb +++ b/docs/guide/interoperability/networkx.ipynb @@ -67,7 +67,9 @@ "# Print the paths and their lengths\n", "print(\"Shortest paths from node 1:\")\n", "for target, path in shortest_paths.items():\n", - " print(f\"Node 1 to node {target}: Path: {path} with total weight: {shortest_path_lengths[target]}\")" + " print(\n", + " f\"Node 1 to node {target}: Path: {path} with total weight: {shortest_path_lengths[target]}\"\n", + " )" ] }, { @@ -89,7 +91,7 @@ ], "source": [ "# Create a corneto graph\n", - "import corneto as cn \n", + "import corneto as cn\n", "\n", "Gc = cn.Graph()\n", "Gc.add_edge(1, 2, weight=1)\n", @@ -121,6 +123,7 @@ ], "source": [ "from corneto.contrib.networkx import corneto_graph_to_networkx\n", + "\n", "Gcn = corneto_graph_to_networkx(Gc)\n", "Gcn.nodes()" ] @@ -163,7 +166,9 @@ "# Print the paths and their lengths\n", "print(\"Shortest paths from node 1:\")\n", "for target, path in shortest_paths.items():\n", - " print(f\"Node 1 to node {target}: Path: {path} with total weight: {shortest_path_lengths[target]}\")" + " print(\n", + " f\"Node 1 to node {target}: Path: {path} with total weight: {shortest_path_lengths[target]}\"\n", + " )" ] }, { @@ -239,9 +244,9 @@ ], "source": [ "G = cn.Graph()\n", - "G.add_edge((), 'A')\n", - "G.add_edge('A', 'B')\n", - "G.add_edge('B', ())\n", + "G.add_edge((), \"A\")\n", + "G.add_edge(\"A\", \"B\")\n", + "G.add_edge(\"B\", ())\n", "G.plot()" ] }, diff --git a/docs/guide/interoperability/picos.ipynb b/docs/guide/interoperability/picos.ipynb index 6b8dc8c..0f733ff 100644 --- a/docs/guide/interoperability/picos.ipynb +++ b/docs/guide/interoperability/picos.ipynb @@ -108,9 +108,10 @@ } ], "source": [ - "from corneto.backend import PicosBackend\n", "import numpy as np\n", "\n", + "from corneto.backend import PicosBackend\n", + "\n", "backend = PicosBackend()\n", "P = backend.Problem()\n", "A = np.array([[0.12, 0.92, 0.76, 0.98, 0.79], [0.58, 0.57, 0.53, 0.71, 0.55]])\n", @@ -161,7 +162,7 @@ } ], "source": [ - "sum(P.symbols['x'].value)" + "sum(P.symbols[\"x\"].value)" ] }, { diff --git a/docs/guide/intro/acyclic-flows.ipynb b/docs/guide/intro/acyclic-flows.ipynb index 3938ae2..a124780 100644 --- a/docs/guide/intro/acyclic-flows.ipynb +++ b/docs/guide/intro/acyclic-flows.ipynb @@ -52,9 +52,10 @@ } ], "source": [ - "import corneto as cn\n", "import numpy as np\n", "\n", + "import corneto as cn\n", + "\n", "cn.info()" ] }, @@ -213,20 +214,22 @@ ], "source": [ "G_ex = cn.Graph()\n", - "G_ex.add_edges([\n", - " ('v1','v2'),\n", - " ('v1','v7'),\n", - " ('v3','v1'),\n", - " ('v2','v4'),\n", - " ('v4','v6'),\n", - " ('v4','v7'),\n", - " ('v5','v6'),\n", - " ('v6','v7'),\n", - " ('v7','v2'),\n", - " ('v2','v5'),\n", - " ('v3','v6'),\n", - " ('v5','v1')\n", - "])\n", + "G_ex.add_edges(\n", + " [\n", + " (\"v1\", \"v2\"),\n", + " (\"v1\", \"v7\"),\n", + " (\"v3\", \"v1\"),\n", + " (\"v2\", \"v4\"),\n", + " (\"v4\", \"v6\"),\n", + " (\"v4\", \"v7\"),\n", + " (\"v5\", \"v6\"),\n", + " (\"v6\", \"v7\"),\n", + " (\"v7\", \"v2\"),\n", + " (\"v2\", \"v5\"),\n", + " (\"v3\", \"v6\"),\n", + " (\"v5\", \"v1\"),\n", + " ]\n", + ")\n", "G_ex.plot()" ] }, @@ -413,8 +416,8 @@ ], "source": [ "G = G_ex.copy()\n", - "G.add_edge((), 'v1')\n", - "G.add_edge('v7', ())\n", + "G.add_edge((), \"v1\")\n", + "G.add_edge(\"v7\", ())\n", "G.plot()" ] }, @@ -894,7 +897,7 @@ "outputs": [], "source": [ "lb = np.zeros(G.ne)\n", - "ub = 10*np.ones(G.ne)\n", + "ub = 10 * np.ones(G.ne)\n", "\n", "# We will add a negative lower bound for\n", "# the dummy edges that we added before\n", diff --git a/docs/guide/intro/constrained-optimization.ipynb b/docs/guide/intro/constrained-optimization.ipynb index 987342b..64109b2 100644 --- a/docs/guide/intro/constrained-optimization.ipynb +++ b/docs/guide/intro/constrained-optimization.ipynb @@ -81,6 +81,7 @@ ], "source": [ "import corneto as cn\n", + "\n", "cn.info()" ] }, @@ -126,14 +127,14 @@ } ], "source": [ - "obj1 = cn.K.Variable('obj1', 1, vartype=cn.VarType.BINARY)\n", - "obj2 = cn.K.Variable('obj2', 1, vartype=cn.VarType.BINARY)\n", - "obj3 = cn.K.Variable('obj3', 1, vartype=cn.VarType.BINARY)\n", - "obj4 = cn.K.Variable('obj4', 1, vartype=cn.VarType.BINARY)\n", - "obj5 = cn.K.Variable('obj5', 1, vartype=cn.VarType.BINARY)\n", + "obj1 = cn.K.Variable(\"obj1\", 1, vartype=cn.VarType.BINARY)\n", + "obj2 = cn.K.Variable(\"obj2\", 1, vartype=cn.VarType.BINARY)\n", + "obj3 = cn.K.Variable(\"obj3\", 1, vartype=cn.VarType.BINARY)\n", + "obj4 = cn.K.Variable(\"obj4\", 1, vartype=cn.VarType.BINARY)\n", + "obj5 = cn.K.Variable(\"obj5\", 1, vartype=cn.VarType.BINARY)\n", "\n", - "total_value = 4*obj1 + 2*obj2 + 10*obj3 + 1*obj4 + 2*obj5\n", - "weight = 12*obj1 + 1*obj2 + 4*obj3 + 1*obj4 + 2*obj5\n", + "total_value = 4 * obj1 + 2 * obj2 + 10 * obj3 + 1 * obj4 + 2 * obj5\n", + "weight = 12 * obj1 + 1 * obj2 + 4 * obj3 + 1 * obj4 + 2 * obj5\n", "\n", "total_value" ] @@ -157,9 +158,10 @@ ], "source": [ "problem = cn.K.Problem(\n", - " constraints=sum(weight)<=15,\n", + " constraints=sum(weight) <= 15,\n", " objectives=sum(total_value),\n", - " direction=cn.Direction.MAX)\n", + " direction=cn.Direction.MAX,\n", + ")\n", "problem" ] }, @@ -299,27 +301,118 @@ "# https://developers.google.com/optimization/pack/knapsack\n", "\n", "values = [\n", - " 360, 83, 59, 130, 431, 67, 230, 52, 93, 125, 670, 892, 600, 38, 48, 147,\n", - " 78, 256, 63, 17, 120, 164, 432, 35, 92, 110, 22, 42, 50, 323, 514, 28,\n", - " 87, 73, 78, 15, 26, 78, 210, 36, 85, 189, 274, 43, 33, 10, 19, 389, 276,\n", - " 312\n", + " 360,\n", + " 83,\n", + " 59,\n", + " 130,\n", + " 431,\n", + " 67,\n", + " 230,\n", + " 52,\n", + " 93,\n", + " 125,\n", + " 670,\n", + " 892,\n", + " 600,\n", + " 38,\n", + " 48,\n", + " 147,\n", + " 78,\n", + " 256,\n", + " 63,\n", + " 17,\n", + " 120,\n", + " 164,\n", + " 432,\n", + " 35,\n", + " 92,\n", + " 110,\n", + " 22,\n", + " 42,\n", + " 50,\n", + " 323,\n", + " 514,\n", + " 28,\n", + " 87,\n", + " 73,\n", + " 78,\n", + " 15,\n", + " 26,\n", + " 78,\n", + " 210,\n", + " 36,\n", + " 85,\n", + " 189,\n", + " 274,\n", + " 43,\n", + " 33,\n", + " 10,\n", + " 19,\n", + " 389,\n", + " 276,\n", + " 312,\n", "]\n", "\n", "weights = [\n", - " 7, 0, 30, 22, 80, 94, 11, 81, 70, 64, 59, 18, 0, 36, 3, 8, 15, 42, 9, 0,\n", - " 42, 47, 52, 32, 26, 48, 55, 6, 29, 84, 2, 4, 18, 56, 7, 29, 93, 44, 71,\n", - " 3, 86, 66, 31, 65, 0, 79, 20, 65, 52, 13\n", + " 7,\n", + " 0,\n", + " 30,\n", + " 22,\n", + " 80,\n", + " 94,\n", + " 11,\n", + " 81,\n", + " 70,\n", + " 64,\n", + " 59,\n", + " 18,\n", + " 0,\n", + " 36,\n", + " 3,\n", + " 8,\n", + " 15,\n", + " 42,\n", + " 9,\n", + " 0,\n", + " 42,\n", + " 47,\n", + " 52,\n", + " 32,\n", + " 26,\n", + " 48,\n", + " 55,\n", + " 6,\n", + " 29,\n", + " 84,\n", + " 2,\n", + " 4,\n", + " 18,\n", + " 56,\n", + " 7,\n", + " 29,\n", + " 93,\n", + " 44,\n", + " 71,\n", + " 3,\n", + " 86,\n", + " 66,\n", + " 31,\n", + " 65,\n", + " 0,\n", + " 79,\n", + " 20,\n", + " 65,\n", + " 52,\n", + " 13,\n", "]\n", "\n", "# We use matrix notation form\n", - "obj = cn.K.Variable('obj', len(values), vartype=cn.VarType.BINARY)\n", - "total_value = values @ obj # matrix mul (1, values) x (objects, 1)\n", + "obj = cn.K.Variable(\"obj\", len(values), vartype=cn.VarType.BINARY)\n", + "total_value = values @ obj # matrix mul (1, values) x (objects, 1)\n", "total_weight = weights @ obj\n", "\n", "cn.K.Problem(\n", - " constraints=total_weight <= 850,\n", - " objectives=total_value,\n", - " direction=cn.Direction.MAX\n", + " constraints=total_weight <= 850, objectives=total_value, direction=cn.Direction.MAX\n", ").solve(verbosity=1)" ] }, diff --git a/docs/guide/intro/index.md b/docs/guide/intro/index.md index 363bda9..54f242c 100644 --- a/docs/guide/intro/index.md +++ b/docs/guide/intro/index.md @@ -8,4 +8,4 @@ prior-knowledge.ipynb constrained-optimization.ipynb multi-commodity-network-flows.ipynb acyclic-flows.ipynb -``` \ No newline at end of file +``` diff --git a/docs/guide/intro/multi-commodity-network-flows.ipynb b/docs/guide/intro/multi-commodity-network-flows.ipynb index c68c77f..03cfaef 100644 --- a/docs/guide/intro/multi-commodity-network-flows.ipynb +++ b/docs/guide/intro/multi-commodity-network-flows.ipynb @@ -42,10 +42,11 @@ } ], "source": [ - "import corneto as cn\n", "import numpy as np\n", "import pandas as pd\n", "\n", + "import corneto as cn\n", + "\n", "cn.info()" ] }, @@ -156,13 +157,13 @@ "G = cn.Graph()\n", "# We create the transportation network, and we add attributes to the edges.\n", "# These attributes are the capacity of the edge, and the profit of the edge for the two commodities.\n", - "G.add_edge('A', 'B', capacity=10, profit_c1=4, profit_c2=1)\n", - "G.add_edge('A', 'D', capacity=15, profit_c1=3, profit_c2=2)\n", - "G.add_edge('B', 'C', capacity=12, profit_c1=2, profit_c2=3)\n", - "G.add_edge('B', 'D', capacity=5, profit_c1=1, profit_c2=4)\n", - "G.add_edge('C', 'E', capacity=10, profit_c1=5, profit_c2=5)\n", - "G.add_edge('D', 'C', capacity=4, profit_c1=2, profit_c2=6)\n", - "G.add_edge('D', 'E', capacity=8, profit_c1=3, profit_c2=4)\n", + "G.add_edge(\"A\", \"B\", capacity=10, profit_c1=4, profit_c2=1)\n", + "G.add_edge(\"A\", \"D\", capacity=15, profit_c1=3, profit_c2=2)\n", + "G.add_edge(\"B\", \"C\", capacity=12, profit_c1=2, profit_c2=3)\n", + "G.add_edge(\"B\", \"D\", capacity=5, profit_c1=1, profit_c2=4)\n", + "G.add_edge(\"C\", \"E\", capacity=10, profit_c1=5, profit_c2=5)\n", + "G.add_edge(\"D\", \"C\", capacity=4, profit_c1=2, profit_c2=6)\n", + "G.add_edge(\"D\", \"E\", capacity=8, profit_c1=3, profit_c2=4)\n", "G.plot()" ] }, @@ -312,11 +313,11 @@ ], "source": [ "# First commodity, routing from A to C\n", - "G.add_edge((), 'A', capacity=1000)\n", - "G.add_edge('C', (), capacity=1000)\n", + "G.add_edge((), \"A\", capacity=1000)\n", + "G.add_edge(\"C\", (), capacity=1000)\n", "\n", "# Second commodity, routing from A to E.\n", - "G.add_edge('E', (), capacity=1000)\n", + "G.add_edge(\"E\", (), capacity=1000)\n", "\n", "G.plot()" ] @@ -339,7 +340,7 @@ } ], "source": [ - "G.get_attr_from_edges('capacity')" + "G.get_attr_from_edges(\"capacity\")" ] }, { @@ -349,7 +350,7 @@ "metadata": {}, "outputs": [], "source": [ - "#P.expr.flow.sum(axis=0).shape" + "# P.expr.flow.sum(axis=0).shape" ] }, { @@ -371,7 +372,7 @@ ], "source": [ "# We create a flow problem with 2 flows, one per commodity\n", - "P = cn.K.Flow(G, ub = G.get_attr_from_edges('capacity'), n_flows=2, shared_bounds=True)\n", + "P = cn.K.Flow(G, ub=G.get_attr_from_edges(\"capacity\"), n_flows=2, shared_bounds=True)\n", "# NOTE: Using shared bounds links shares the capacity of the edges across flows. It is equivalent to adding this constraint here:\n", "# P += P.expressions.flow[:, 0] + P.expressions.flow[:, 1] <= G.get_attr_from_edges('capacity')\n", "P.expressions" @@ -384,8 +385,8 @@ "metadata": {}, "outputs": [], "source": [ - "c1 = np.array(G.get_attr_from_edges('profit_c1', 0))\n", - "c2 = np.array(G.get_attr_from_edges('profit_c2', 0))" + "c1 = np.array(G.get_attr_from_edges(\"profit_c1\", 0))\n", + "c2 = np.array(G.get_attr_from_edges(\"profit_c2\", 0))" ] }, { @@ -653,9 +654,11 @@ } ], "source": [ - "df_result = pd.DataFrame(P.expressions.flow.value, index=G.E, columns=['Commodity 1', 'Commodity 2'])\n", + "df_result = pd.DataFrame(\n", + " P.expressions.flow.value, index=G.E, columns=[\"Commodity 1\", \"Commodity 2\"]\n", + ")\n", "df_result[\"total\"] = df_result.sum(axis=1)\n", - "df_result[\"capacity\"] = G.get_attr_from_edges('capacity')\n", + "df_result[\"capacity\"] = G.get_attr_from_edges(\"capacity\")\n", "df_result[\"Profit c1\"] = df_result[\"Commodity 1\"] * c1\n", "df_result[\"Profit c2\"] = df_result[\"Commodity 2\"] * c2\n", "df_result[\"Total profit\"] = df_result[\"Profit c1\"] + df_result[\"Profit c2\"]\n", diff --git a/docs/guide/intro/prior-knowledge.ipynb b/docs/guide/intro/prior-knowledge.ipynb index e825947..1f18a2a 100644 --- a/docs/guide/intro/prior-knowledge.ipynb +++ b/docs/guide/intro/prior-knowledge.ipynb @@ -54,6 +54,7 @@ ], "source": [ "import corneto as cn\n", + "\n", "cn.info()" ] }, @@ -600,10 +601,7 @@ } ], "source": [ - "sif_graph = cn.Graph.from_sif_tuples([\n", - " ('A', 1, 'B'),\n", - " ('A', -1, 'C')\n", - "])\n", + "sif_graph = cn.Graph.from_sif_tuples([(\"A\", 1, \"B\"), (\"A\", -1, \"C\")])\n", "sif_graph.plot()" ] }, @@ -642,7 +640,7 @@ "metadata": {}, "outputs": [], "source": [ - "#cn.Graph.from_sif_file()" + "# cn.Graph.from_sif_file()" ] }, { @@ -662,7 +660,7 @@ "metadata": {}, "outputs": [], "source": [ - "G.save('my_graph')" + "G.save(\"my_graph\")" ] }, { @@ -761,7 +759,7 @@ } ], "source": [ - "G_c = cn.Graph.load('my_graph.pkl.gz')\n", + "G_c = cn.Graph.load(\"my_graph.pkl.gz\")\n", "G_c.plot()" ] }, @@ -944,11 +942,11 @@ ], "source": [ "G = cn.Graph()\n", - "G.add_edge({'A', 'B'}, {'C', 'D'})\n", - "G.add_edge('D', {5, 6, 7})\n", - "G.add_edge((), 'A')\n", - "G.add_edge((), 'B')\n", - "G.add_edge('C', ())\n", + "G.add_edge({\"A\", \"B\"}, {\"C\", \"D\"})\n", + "G.add_edge(\"D\", {5, 6, 7})\n", + "G.add_edge((), \"A\")\n", + "G.add_edge((), \"B\")\n", + "G.add_edge(\"C\", ())\n", "G.plot()" ] }, diff --git a/docs/guide/metabolism/flux-balance-analysis.ipynb b/docs/guide/metabolism/flux-balance-analysis.ipynb index c326bd0..4e13d8d 100644 --- a/docs/guide/metabolism/flux-balance-analysis.ipynb +++ b/docs/guide/metabolism/flux-balance-analysis.ipynb @@ -81,7 +81,6 @@ } ], "source": [ - "import cobra\n", "from cobra.io import load_model\n", "\n", "model = load_model(\"textbook\")\n", @@ -188,6 +187,7 @@ ], "source": [ "import corneto as cn\n", + "\n", "cn.info()" ] }, diff --git a/docs/guide/metabolism/imat.ipynb b/docs/guide/metabolism/imat.ipynb index cb85d0b..2031615 100644 --- a/docs/guide/metabolism/imat.ipynb +++ b/docs/guide/metabolism/imat.ipynb @@ -62,9 +62,10 @@ } ], "source": [ - "import corneto as cn\n", "import numpy as np\n", "\n", + "import corneto as cn\n", + "\n", "cn.info()" ] }, @@ -302,9 +303,13 @@ ], "source": [ "Gem = cn.Graph()\n", - "Gem.add_edge({\"M1\", \"M2\"}, {\"M5\", \"M6\"}, genes=[\"E6\"], weight=-1, default_lb=0, default_ub=100)\n", + "Gem.add_edge(\n", + " {\"M1\", \"M2\"}, {\"M5\", \"M6\"}, genes=[\"E6\"], weight=-1, default_lb=0, default_ub=100\n", + ")\n", "Gem.add_edge(\"M1\", \"M4\", genes=[], default_lb=-100, default_ub=100)\n", - "Gem.add_edge({\"M3\", \"M4\"}, {\"M7\", \"M8\"}, genes=[\"E3\"], weight=1, default_lb=0, default_ub=100)\n", + "Gem.add_edge(\n", + " {\"M3\", \"M4\"}, {\"M7\", \"M8\"}, genes=[\"E3\"], weight=1, default_lb=0, default_ub=100\n", + ")\n", "Gem.add_edge(\"M6\", \"M9\", genes=[\"E7\"], weight=1, default_lb=0, default_ub=100)\n", "Gem.add_edge((), \"M1\", genes=[\"E1\", \"E2\"], weight=1, default_lb=-100, default_ub=100)\n", "Gem.add_edge((), \"M2\", genes=[\"E5\"], weight=-1, default_lb=-100, default_ub=100)\n", @@ -334,7 +339,9 @@ } ], "source": [ - "weights = np.array([Gem.get_attr_edge(i).get(\"weight\", 0) for i in range(Gem.num_edges)])\n", + "weights = np.array(\n", + " [Gem.get_attr_edge(i).get(\"weight\", 0) for i in range(Gem.num_edges)]\n", + ")\n", "weights" ] }, @@ -747,7 +754,9 @@ } ], "source": [ - "Gem.plot(custom_edge_attr=cn.pl.flow_style(P), graph_attr={\"rankdir\": \"LR\", \"center\": \"1\"})" + "Gem.plot(\n", + " custom_edge_attr=cn.pl.flow_style(P), graph_attr={\"rankdir\": \"LR\", \"center\": \"1\"}\n", + ")" ] } ], diff --git a/docs/guide/metabolism/index.md b/docs/guide/metabolism/index.md index 86fcd05..ff29f85 100644 --- a/docs/guide/metabolism/index.md +++ b/docs/guide/metabolism/index.md @@ -10,4 +10,4 @@ sparse-fba.ipynb multicondition-sfba.ipynb imat.ipynb multicondition-imat.ipynb -``` \ No newline at end of file +``` diff --git a/docs/guide/metabolism/multicondition-imat.ipynb b/docs/guide/metabolism/multicondition-imat.ipynb index b1121ee..2935c78 100644 --- a/docs/guide/metabolism/multicondition-imat.ipynb +++ b/docs/guide/metabolism/multicondition-imat.ipynb @@ -40,6 +40,7 @@ ], "source": [ "import corneto as cn\n", + "\n", "cn.info()" ] }, diff --git a/docs/guide/metabolism/multicondition-sfba.ipynb b/docs/guide/metabolism/multicondition-sfba.ipynb index 2161b52..52c5c19 100644 --- a/docs/guide/metabolism/multicondition-sfba.ipynb +++ b/docs/guide/metabolism/multicondition-sfba.ipynb @@ -40,6 +40,7 @@ ], "source": [ "import corneto as cn\n", + "\n", "cn.info()" ] }, diff --git a/docs/guide/metabolism/sparse-fba.ipynb b/docs/guide/metabolism/sparse-fba.ipynb index 6077fa1..407f5aa 100644 --- a/docs/guide/metabolism/sparse-fba.ipynb +++ b/docs/guide/metabolism/sparse-fba.ipynb @@ -35,7 +35,6 @@ ], "source": [ "from cobra.io import load_model\n", - "import numpy as np\n", "\n", "model = load_model(\"textbook\")\n", "len(model.metabolites), len(model.reactions)" @@ -74,6 +73,7 @@ ], "source": [ "import corneto as cn\n", + "\n", "cn.info()" ] }, @@ -3190,6 +3190,7 @@ "outputs": [], "source": [ "from corneto.backend._base import Indicator\n", + "\n", "# Automatically create a new indicator variable for the flow\n", "# If the indicator is 0, the flow is blocked, if it is 1, the flow is unblocked (can take any value within bounds, including 0)\n", "P += Indicator(\"unblocked_flow\")\n", diff --git a/docs/guide/networks/index.md b/docs/guide/networks/index.md index 03b2690..9574c18 100644 --- a/docs/guide/networks/index.md +++ b/docs/guide/networks/index.md @@ -6,4 +6,4 @@ shortest-paths.ipynb steiner-trees.ipynb pcst.ipynb -``` \ No newline at end of file +``` diff --git a/docs/guide/networks/pcst.ipynb b/docs/guide/networks/pcst.ipynb index 21193d3..bdd6108 100644 --- a/docs/guide/networks/pcst.ipynb +++ b/docs/guide/networks/pcst.ipynb @@ -48,9 +48,10 @@ } ], "source": [ - "import corneto as cn\n", "import numpy as np\n", "\n", + "import corneto as cn\n", + "\n", "cn.info()" ] }, @@ -263,28 +264,32 @@ "from corneto._graph import EdgeType\n", "\n", "G = cn.Graph()\n", - "G.add_edges([\n", - " ('A', 'B'),\n", - " ('A', 'C'),\n", - " ('A', 'D'),\n", - " ('D', 'C'),\n", - " ('D', 'E'),\n", - " ('B', 'E'),\n", - " ('E', 'F'),\n", - " ('A', 'F'),\n", - " ('F', 'G'),\n", - " ('F', 'H'),\n", - " ('H', 'E'),\n", - " ('I', 'F'),\n", - " ('D', 'I'),\n", - " ('J', 'C'),\n", - " ('J', 'G'),\n", - " ('C', 'F'),\n", - " ('J', 'A'),\n", - " ('I', 'K'),\n", - " ('H', 'K'),\n", - " ('B', 'K')\n", - "], type=EdgeType.UNDIRECTED, weight=1)\n", + "G.add_edges(\n", + " [\n", + " (\"A\", \"B\"),\n", + " (\"A\", \"C\"),\n", + " (\"A\", \"D\"),\n", + " (\"D\", \"C\"),\n", + " (\"D\", \"E\"),\n", + " (\"B\", \"E\"),\n", + " (\"E\", \"F\"),\n", + " (\"A\", \"F\"),\n", + " (\"F\", \"G\"),\n", + " (\"F\", \"H\"),\n", + " (\"H\", \"E\"),\n", + " (\"I\", \"F\"),\n", + " (\"D\", \"I\"),\n", + " (\"J\", \"C\"),\n", + " (\"J\", \"G\"),\n", + " (\"C\", \"F\"),\n", + " (\"J\", \"A\"),\n", + " (\"I\", \"K\"),\n", + " (\"H\", \"K\"),\n", + " (\"B\", \"K\"),\n", + " ],\n", + " type=EdgeType.UNDIRECTED,\n", + " weight=1,\n", + ")\n", "G.plot()" ] }, @@ -297,7 +302,7 @@ "source": [ "# We will put prizes only in two nodes\n", "\n", - "prizes = {'G': 10, 'B': 10}" + "prizes = {\"G\": 10, \"B\": 10}" ] }, { @@ -319,7 +324,7 @@ "from corneto.methods.steiner import exact_steiner_tree\n", "\n", "P, Gc = exact_steiner_tree(G, prizes)\n", - "P.solve(solver='SCIPY')\n", + "P.solve(solver=\"SCIPY\")\n", "\n", "for n, o in zip([\"Edge cost\", \"Prizes\"], P.objectives):\n", " print(f\"{n}:\", o.value)" @@ -416,7 +421,7 @@ } ], "source": [ - "Gc.edge_subgraph(np.where(P.symbols['_flow_i'].value)[0]).plot()" + "Gc.edge_subgraph(np.where(P.symbols[\"_flow_i\"].value)[0]).plot()" ] }, { diff --git a/docs/guide/networks/shortest-paths.ipynb b/docs/guide/networks/shortest-paths.ipynb index fd6d0bb..8c4d7cb 100644 --- a/docs/guide/networks/shortest-paths.ipynb +++ b/docs/guide/networks/shortest-paths.ipynb @@ -33,9 +33,10 @@ "metadata": {}, "outputs": [], "source": [ - "import corneto as cn\n", "import numpy as np\n", "\n", + "import corneto as cn\n", + "\n", "cn.info()" ] }, @@ -64,7 +65,7 @@ "metadata": {}, "outputs": [], "source": [ - "from corneto.methods import shortest_path, solve_shortest_path\n", + "from corneto.methods import solve_shortest_path\n", "\n", "# TODO: a graph problem should have the graph attached to it...\n", "edges, P, Gc = solve_shortest_path(G, \"A\", \"G\", solver=\"SCIPY\")\n", @@ -99,17 +100,19 @@ "# Create a function that generates a shortest path problem on a random graph created with networkx\n", "import networkx as nx\n", "\n", + "\n", "def create_random_graph(n, m=3, seed=None, directed=True):\n", " G = nx.barabasi_albert_graph(n, m, seed=seed)\n", " vertices = list(G.nodes())\n", " # Add random weights to the edges\n", " for u, v in G.edges():\n", - " G[u][v][\"weight\"] = np.random.uniform(1, 10) #np.random.randint(1, 20)\n", + " G[u][v][\"weight\"] = np.random.uniform(1, 10) # np.random.randint(1, 20)\n", " s, t = np.random.choice(vertices, 2, replace=False)\n", " if directed:\n", " G = G.to_directed()\n", " return G, s, t\n", "\n", + "\n", "G, s, t = create_random_graph(5000)" ] }, diff --git a/docs/guide/networks/steiner-trees.ipynb b/docs/guide/networks/steiner-trees.ipynb index c77bb6f..1bc151d 100644 --- a/docs/guide/networks/steiner-trees.ipynb +++ b/docs/guide/networks/steiner-trees.ipynb @@ -49,9 +49,9 @@ "import numpy as np\n", "from networkx.algorithms.approximation import steiner_tree\n", "\n", - "\n", "# Generate a random graph with networkx\n", "\n", + "\n", "def create_random_graph(n_nodes, prob, seed=0):\n", " np.random.seed(seed)\n", " random_graph = nx.erdos_renyi_graph(n_nodes, prob, seed=seed)\n", @@ -59,9 +59,10 @@ " edges_r = list(random_graph.edges())\n", " for i, weight in enumerate(weights):\n", " edge = edges_r[i]\n", - " random_graph[edge[0]][edge[1]]['weight'] = weight\n", + " random_graph[edge[0]][edge[1]][\"weight\"] = weight\n", " return random_graph\n", "\n", + "\n", "random_graph = create_random_graph(50, 0.1)" ] }, @@ -94,7 +95,7 @@ "\n", "terminals = np.random.choice(random_graph.nodes, size=10, replace=False)\n", "stree = steiner_tree(random_graph, terminals)\n", - "total_weight = sum(random_graph[u][v]['weight'] for u, v in stree.edges)\n", + "total_weight = sum(random_graph[u][v][\"weight\"] for u, v in stree.edges)\n", "print(\"Cost:\", total_weight)\n", "nx.draw(stree, with_labels=True)" ] @@ -150,6 +151,7 @@ ], "source": [ "import corneto as cn\n", + "\n", "cn.info()" ] }, @@ -180,17 +182,20 @@ ], "source": [ "from corneto._graph import EdgeType\n", + "\n", + "\n", "def to_graph(nx_graph, weights=None, directed=False):\n", " G = cn.Graph()\n", " if weights is None:\n", - " weights = [e[2].get('weight', 0) for e in nx_graph.edges(data=True)]\n", + " weights = [e[2].get(\"weight\", 0) for e in nx_graph.edges(data=True)]\n", " for e, w in zip(nx_graph.edges, weights):\n", " etype = EdgeType.DIRECTED if directed else EdgeType.UNDIRECTED\n", " G.add_edge(e[0], e[1], weight=w, type=etype)\n", " return G\n", "\n", + "\n", "G = to_graph(random_graph)\n", - "G.shape\n" + "G.shape" ] }, { @@ -493,8 +498,10 @@ } ], "source": [ - "P.solve(solver='SCIPY', verbosity=1)\n", - "G_steiner.edge_subgraph(np.where(P.symbols['_flow_i'].value > 0.5)[0]).plot(orphan_edges=False)" + "P.solve(solver=\"SCIPY\", verbosity=1)\n", + "G_steiner.edge_subgraph(np.where(P.symbols[\"_flow_i\"].value > 0.5)[0]).plot(\n", + " orphan_edges=False\n", + ")" ] }, { @@ -780,9 +787,11 @@ ], "source": [ "P, G_steiner = exact_steiner_tree(G, terminals, strict_acyclic=True)\n", - "P.solve(solver='SCIPY', verbosity=1)\n", + "P.solve(solver=\"SCIPY\", verbosity=1)\n", "print(\"Optimal value:\", P.objectives[0].value)\n", - "G_steiner.edge_subgraph(np.where(P.symbols['_flow_i'].value > 0.5)[0]).plot(orphan_edges=False)" + "G_steiner.edge_subgraph(np.where(P.symbols[\"_flow_i\"].value > 0.5)[0]).plot(\n", + " orphan_edges=False\n", + ")" ] } ], diff --git a/docs/guide/signaling/carnival.ipynb b/docs/guide/signaling/carnival.ipynb index f93ab34..f2e12c2 100644 --- a/docs/guide/signaling/carnival.ipynb +++ b/docs/guide/signaling/carnival.ipynb @@ -61,6 +61,7 @@ ], "source": [ "import corneto as cn\n", + "\n", "cn.info()" ] }, @@ -181,13 +182,12 @@ "source": [ "G = cn.Graph.from_sif_tuples(\n", " [\n", - " ('I1', 1, 'N1'), # I1 activates N1\n", - " ('N1', 1, 'M1'), # N1 activates M1\n", - " ('N1', 1, 'M2'), # N1 activaes M2\n", - " ('I2', -1, 'N2'), # I2 inhibits N2\n", - " ('N2', -1, 'M2'), # N2 inhibits M2\n", - " ('N2', -1, 'M1'), # N2 inhibits M1\n", - " \n", + " (\"I1\", 1, \"N1\"), # I1 activates N1\n", + " (\"N1\", 1, \"M1\"), # N1 activates M1\n", + " (\"N1\", 1, \"M2\"), # N1 activaes M2\n", + " (\"I2\", -1, \"N2\"), # I2 inhibits N2\n", + " (\"N2\", -1, \"M2\"), # N2 inhibits M2\n", + " (\"N2\", -1, \"M1\"), # N2 inhibits M1\n", " ]\n", ")\n", "G.plot()" @@ -253,11 +253,11 @@ "# Positive values correspond to up-regulation and negative values\n", "# with down-regulation. The bigger the absolute value is,\n", "# the bigger the importance is\n", - "measurements = {'M1': 1, 'M2': 1}\n", + "measurements = {\"M1\": 1, \"M2\": 1}\n", "\n", "# Perturbations are the upstream nodes were the signal originates on,\n", "# for example, ligands or receptors.\n", - "perturbations = {'I1': 1, 'I2': 1}\n", + "perturbations = {\"I1\": 1, \"I2\": 1}\n", "\n", "# We run the `standard` carnival problem. This interface is similar\n", "# to the old R function https://saezlab.github.io/CARNIVAL/reference/runVanillaCarnival.html\n", @@ -505,9 +505,10 @@ } ], "source": [ - "from corneto.methods.carnival import get_result, get_selected_edges\n", "import pandas as pd\n", "\n", + "from corneto.methods.carnival import get_result, get_selected_edges\n", + "\n", "V, E = get_result(P, Gf)\n", "pd.DataFrame(V)" ] diff --git a/docs/guide/signaling/index.md b/docs/guide/signaling/index.md index db9fee3..ed0b487 100644 --- a/docs/guide/signaling/index.md +++ b/docs/guide/signaling/index.md @@ -10,4 +10,4 @@ multicondition-carnival.ipynb multitimepoint-carnival.ipynb phonemes.ipynb multicondition-phonemes.ipynb -``` \ No newline at end of file +``` diff --git a/docs/guide/signaling/multicondition-carnival.ipynb b/docs/guide/signaling/multicondition-carnival.ipynb index 544f3f6..de234dc 100644 --- a/docs/guide/signaling/multicondition-carnival.ipynb +++ b/docs/guide/signaling/multicondition-carnival.ipynb @@ -40,6 +40,7 @@ ], "source": [ "import corneto as cn\n", + "\n", "cn.info()" ] }, diff --git a/docs/index.md b/docs/index.md index c313ba0..f2281ad 100644 --- a/docs/index.md +++ b/docs/index.md @@ -53,4 +53,4 @@ guide/index tutorials/index api/index GitHub -``` \ No newline at end of file +``` diff --git a/docs/tutorials/context-specific-metabolic-omics.ipynb b/docs/tutorials/context-specific-metabolic-omics.ipynb index 26f0ec7..6271da8 100644 --- a/docs/tutorials/context-specific-metabolic-omics.ipynb +++ b/docs/tutorials/context-specific-metabolic-omics.ipynb @@ -38,9 +38,10 @@ } ], "source": [ - "import corneto as cn\n", "import pandas as pd\n", "\n", + "import corneto as cn\n", + "\n", "cn.info()" ] }, @@ -370,6 +371,7 @@ ], "source": [ "from cobra.io import read_sbml_model\n", + "\n", "model = read_sbml_model(\"../../tests/gem/ecoli_core.zip\")\n", "G = cn.Graph.from_cobra_model(model)\n", "G.shape" @@ -559,6 +561,7 @@ ], "source": [ "from corneto.methods.metabolism._utils import get_unique_genes\n", + "\n", "genes = get_unique_genes(G, startswith=\"b\")\n", "len(genes)" ] @@ -818,7 +821,7 @@ "source": [ "from corneto.methods.metabolism._utils import evaluate_gpr_expression\n", "\n", - "values = df_expr[[\"gene\", \"score\"]].set_index(\"gene\").to_dict()['score']\n", + "values = df_expr[[\"gene\", \"score\"]].set_index(\"gene\").to_dict()[\"score\"]\n", "e = evaluate_gpr_expression(G.get_attr_from_edges(\"GPR\"), values)" ] }, @@ -839,9 +842,10 @@ } ], "source": [ - "from corneto.methods.metabolism.fba import multicondition_imat\n", "import numpy as np\n", "\n", + "from corneto.methods.metabolism.fba import multicondition_imat\n", + "\n", "P = multicondition_imat(G, np.array(e))\n", "P.solve(solver=\"SCIP\")" ] @@ -948,7 +952,9 @@ } ], "source": [ - "df_sol = pd.DataFrame(P.expr.flow.value, index=G.get_attr_from_edges(\"id\"), columns=['flux'])\n", + "df_sol = pd.DataFrame(\n", + " P.expr.flow.value, index=G.get_attr_from_edges(\"id\"), columns=[\"flux\"]\n", + ")\n", "df_sol" ] }, diff --git a/docs/tutorials/index.md b/docs/tutorials/index.md index fe03596..2e6e95c 100644 --- a/docs/tutorials/index.md +++ b/docs/tutorials/index.md @@ -4,4 +4,4 @@ :maxdepth: 3 context-specific-metabolic-omics.ipynb -``` \ No newline at end of file +``` diff --git a/pyproject.toml b/pyproject.toml index 5cd2f32..bf38072 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -80,14 +80,16 @@ networkx = ["networkx"] matplotlib = ["matplotlib"] [tool.ruff] -ignore-init-module-imports = true fix = true + +[tool.ruff.lint] +ignore-init-module-imports = true select = ["E", "F", "W", "I", "D", "RUF"] -[tool.ruff.flake8-quotes] +[tool.ruff.lint.flake8-quotes] docstring-quotes = "double" -[tool.ruff.pydocstyle] +[tool.ruff.lint.pydocstyle] convention = "google" [build-system] diff --git a/tests/__init__.py b/tests/__init__.py index 83b36d2..e70a20c 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -1,2 +1,2 @@ from corneto._constants import * -from corneto.backend import DEFAULT_BACKEND \ No newline at end of file +from corneto.backend import DEFAULT_BACKEND diff --git a/tests/methods/signal/test_cellnopt_ilp.py b/tests/methods/signal/test_cellnopt_ilp.py index 5d12cf9..2333316 100644 --- a/tests/methods/signal/test_cellnopt_ilp.py +++ b/tests/methods/signal/test_cellnopt_ilp.py @@ -1,7 +1,6 @@ -import corneto as cn import numpy as np - +import corneto as cn from corneto.methods.signal.cellnopt_ilp import cellnoptILP @@ -23,7 +22,6 @@ def get_test_graph_1(): def test_cellnoptILP_AND(): - G1 = get_test_graph_1() # RAS is only active iff both EGF and TNFa are active -> we need to identify the AND gate @@ -66,7 +64,6 @@ def test_cellnoptILP_AND(): def test_cellnoptILP_OR(): - G1 = get_test_graph_1() # RAS is only active iff both EGF and TNFa are active -> we need to identify the AND gate diff --git a/tests/methods/test_steiner.py b/tests/methods/test_steiner.py index 2fea13a..331fc21 100644 --- a/tests/methods/test_steiner.py +++ b/tests/methods/test_steiner.py @@ -1,10 +1,11 @@ -import pytest import pathlib -from corneto.methods.steiner import exact_steiner_tree -from corneto.backend import PicosBackend, CvxpyBackend -from corneto._graph import BaseGraph -from corneto.backend import Backend + import numpy as np +import pytest + +from corneto._graph import BaseGraph +from corneto.backend import Backend, CvxpyBackend, PicosBackend +from corneto.methods.steiner import exact_steiner_tree @pytest.fixture(params=[CvxpyBackend, PicosBackend]) diff --git a/tests/sif/mix.sif b/tests/sif/mix.sif index 51a234f..e4e3c0d 100644 --- a/tests/sif/mix.sif +++ b/tests/sif/mix.sif @@ -2,4 +2,4 @@ A 1 B B 1 r1 C 2 r1 r1 2 E -B -1 E \ No newline at end of file +B -1 E diff --git a/tests/test_backend.py b/tests/test_backend.py index 9c1efcb..a522b51 100644 --- a/tests/test_backend.py +++ b/tests/test_backend.py @@ -1,9 +1,11 @@ -import pytest import pathlib + +import cvxpy as cp import numpy as np -from corneto.backend import PicosBackend, CvxpyBackend, Backend, VarType +import pytest + from corneto._graph import Graph -import cvxpy as cp +from corneto.backend import Backend, CvxpyBackend, PicosBackend, VarType @pytest.fixture(params=[CvxpyBackend, PicosBackend]) @@ -95,7 +97,7 @@ def test_delegate_sum_axis1_shape(backend): else: # Picos assumes keepdims=True assert V.shape == (2, 1) - + def test_opt_delegate_sum_axis0(backend): x = backend.Variable("x", (2, 3)) @@ -282,7 +284,6 @@ def test_undirected_flow(backend): def test_undirected_flow_unbounded(backend): from corneto._graph import Graph - from corneto import VAR_FLOW g = Graph() g.add_edges([((), "A"), ("A", "B"), ("A", "C"), ("B", "D"), ("C", "D"), ("D", ())]) diff --git a/tests/test_core.py b/tests/test_core.py index 819a610..503aaf1 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -1,5 +1,3 @@ -import pytest -import pathlib from corneto._core import Graph @@ -12,12 +10,14 @@ def test_add_simple_edges(): assert 1 in g.vertices assert 2 in g.vertices + def test_graph_bfs(): g = Graph() g.add_edges([(1, 2), (2, 3), (1, 3), (3, 4), (4, 1), (3, 1), (4, 5)]) dist = g.bfs(2) assert dist[1] == 2 + def test_graph_bfs_rev(): g = Graph() g.add_edges([(1, 2), (2, 3), (1, 3), (3, 4), (4, 1), (3, 1), (4, 5)]) @@ -26,6 +26,7 @@ def test_graph_bfs_rev(): assert dist[4] == 2 assert 5 not in dist + def test_get_edges_with_source_vertex(): g = Graph() g.add_edges([(1, 2), (2, 3), (1, 3), (3, 4), (4, 1), (3, 1), (4, 5)]) @@ -53,7 +54,7 @@ def test_incidence_single_edge_single_source_vertex(): g = Graph() g.add_edge(1, ()) A = g.vertex_incidence_matrix() - assert A.shape == (1,1) + assert A.shape == (1, 1) assert A[0, 0] == -1 @@ -61,9 +62,9 @@ def test_incidence_single_edge_single_target_vertex(): g = Graph() g.add_edge((), 1) A = g.vertex_incidence_matrix() - assert A.shape == (1,1) + assert A.shape == (1, 1) assert A[0, 0] == 1 - + def test_incidence_two_edges_single_vertex(): g = Graph() @@ -84,31 +85,33 @@ def test_add_hyperedges(): def test_edge_vertex_properties(): g = Graph() g.add_edge({1: 10, "a": -1}, {2: -10, "b": 5}) - props, = g.get_vertex_properties_for_edge(g.edges[0]) + (props,) = g.get_vertex_properties_for_edge(g.edges[0]) assert "v" in props[1] and props[1]["v"] == 10 assert "v" in props["a"] and props["a"]["v"] == -1 assert "v" in props[2] and props[2]["v"] == -10 assert "v" in props["b"] and props["b"]["v"] == 5 + def test_source_vertices(): g = Graph() assert g.get_source_vertices() == set() - g.add_vertex('s') - assert g.get_source_vertices() == {'s'} - g.add_edge('s', 't') - assert g.get_source_vertices() == {'s'} - g.add_edge('u', 's') - assert g.get_source_vertices() == {'u'} + g.add_vertex("s") + assert g.get_source_vertices() == {"s"} + g.add_edge("s", "t") + assert g.get_source_vertices() == {"s"} + g.add_edge("u", "s") + assert g.get_source_vertices() == {"u"} def test_sink_vertices(): g = Graph() assert g.get_sink_vertices() == set() - g.add_vertex('s') - assert g.get_sink_vertices() == {'s'} - g.add_edge('s', 't') - assert g.get_sink_vertices() == {'t'} - g.add_edge('t', 'u') - assert g.get_sink_vertices() == {'u'} - -# TODO: predecessor/successor of a vertex without edges \ No newline at end of file + g.add_vertex("s") + assert g.get_sink_vertices() == {"s"} + g.add_edge("s", "t") + assert g.get_sink_vertices() == {"t"} + g.add_edge("t", "u") + assert g.get_sink_vertices() == {"u"} + + +# TODO: predecessor/successor of a vertex without edges diff --git a/tests/test_graph.py b/tests/test_graph.py index ba68d2c..df2a236 100644 --- a/tests/test_graph.py +++ b/tests/test_graph.py @@ -1,4 +1,3 @@ -import pytest from copy import deepcopy from corneto._graph import ( diff --git a/tests/test_io.py b/tests/test_io.py index 0da3c4d..b41fd7d 100644 --- a/tests/test_io.py +++ b/tests/test_io.py @@ -1,6 +1,8 @@ -import pytest import pathlib +import pytest + + def test_read_sif(): from corneto._io import _read_sif @@ -25,9 +27,9 @@ def test_read_sif(): def test_load_compressed_gem(): from corneto._io import _load_compressed_gem + file = pathlib.Path(__file__).parent.joinpath("gem", "mitocore.xz") S, R, M = _load_compressed_gem(file) assert S.shape == (441, 555) assert R.shape == (555,) assert M.shape == (441,) -