CARNIVAL#
CARNIVAL (CAusal Reasoning for Network identification using Integer VALue programming) is a method for the identification of upstream reguatory signalling pathways from downstream gene expression (GEX). Applications of CARNIVAL include the identification of drug’s modes of action and of deregulated processes in diseases (even if the molecular targets remain unknown) by deciphering the alterations of main signalling pathways as well as alternative pathways and off-target effects.
Figure 1: Liu A., Trairatphisan P., Gjerga E. et al. From expression footprints to causal pathways: contextualizing large signaling networks with CARNIVAL npj Systems Biology and Applications volume 5, Article number: 40 (2019).
The aim of the CARNIVAL pipeline is to identify a subset of interactions from a prior knowledge network that represent potential regulated pathways linking known or potential targets of perturbation towards active transcription factors derived from GEX data. The pipeline includes a number improved functionalities comparing to the original version and consists of the following processes:
Transcription factors’ (TFs) activities and pathway scores from gene expressions can be inferred with our in-house tools (Dorothea, CollecTRI).
TFs’ activities and signed directed protein-protein interaction networks with or without the provided target of perturbations and pathway scores are then used to construct an optimization problem with CORNETO.
CORNETO is used to solve the optimization problem with any of the supported solvers (CPLEX, GUROBI, SCIPY, etc), which identifies the sub-network topology with minimised fitting error and model size.
The original version of CARNIVAL was implemented in R and CPLEX. The new re-implementationo of CARNIVAL in CORNETO support a wide variety of solvers thanks to the support of both CVXPY and PICOS. It also has more flexibility since the problem is symbolically defined, and can be modified through the CORNETO API after creating the CARNIVAL problem. This gives user extra flexibility to modify the problem or to use CORNETO as a building block for other optimization problems.
import numpy as np
import pandas as pd
import corneto as cn
cn.info()
|
|
|
Creating a toy example#
from corneto.graph import Graph
G = Graph.from_tuples(
[
("rec1", 1, "a"),
("rec1", -1, "b"),
("rec1", 1, "f"),
("rec1", -1, "c"),
("rec2", 1, "b"),
("rec2", 1, "tf2"),
("b", 1, "g"),
("g", -1, "d"),
("rec2", -1, "d"),
("a", 1, "c"),
("a", -1, "d"),
("c", 1, "d"),
("c", -1, "e"),
("c", 1, "tf3"),
("e", 1, "a"),
("d", -1, "c"),
("e", 1, "tf1"),
("a", -1, "tf1"),
("d", 1, "tf2"),
("c", -1, "tf2"),
("tf1", 1, "tf2"),
("tf1", -1, "rec2"),
("tf2", 1, "rec1"),
("tf1", 1, "f"),
]
)
# Plot our PKN
G.plot()
from corneto.methods.future.carnival import CarnivalFlow, CarnivalILP
samples = {
"input_example": {
"rec2": {"value": 1, "mapping": "vertex", "role": "input"},
"tf1": {"value": -2, "mapping": "vertex", "role": "output"},
"tf2": {"value": 1, "mapping": "vertex", "role": "output"},
}
}
data = cn.Data.from_cdict(samples)
data
Data(n_samples=1, n_feats=[3])
CarnivalFlow#
Carnival Flow is a generalization of Carnival for multi-samples, using the structured sparsity inducing penalty to regularize solutions taking into account multiple samples. However, in the single sample case, it is equivalent to the original Carnival, although using a complete different formulation.
c = CarnivalFlow(lambda_reg=1e-3)
P = c.build(G, data)
P.solve(verbosity=0, solver="scipy")
for o in P.objectives:
print(o.value)
c.processed_graph.edge_subgraph(np.flatnonzero(P.expr.edge_has_signal.value)).plot()
Unreachable vertices for sample: 0
0.0
5.0
# Extract the values from the problem
pd.DataFrame(P.expr.edge_value.value, index=c.processed_graph.E, columns=["edge_activity"]).astype(int)
| edge_activity | ||
|---|---|---|
| (rec1) | (a) | 1 |
| (b) | 0 | |
| (c) | 0 | |
| (rec2) | (b) | 0 |
| (tf2) | 1 | |
| (b) | (g) | 0 |
| (g) | (d) | 0 |
| (rec2) | (d) | 0 |
| (a) | (c) | 0 |
| (d) | 0 | |
| (c) | (d) | 0 |
| (e) | 0 | |
| (e) | (a) | 0 |
| (d) | (c) | 0 |
| (e) | (tf1) | 0 |
| (a) | (tf1) | -1 |
| (d) | (tf2) | 0 |
| (c) | (tf2) | 0 |
| (tf1) | (tf2) | 0 |
| (rec2) | 0 | |
| (tf2) | (rec1) | 1 |
| (tf1) | () | 0 |
| (tf2) | () | 0 |
| () | (rec2) | 1 |
pd.DataFrame(P.expr.vertex_value.value, index=c.processed_graph.V, columns=["node_activity"]).astype(int)
| node_activity | |
|---|---|
| g | 0 |
| e | 0 |
| c | 0 |
| b | 0 |
| a | 1 |
| d | 0 |
| rec2 | 1 |
| tf1 | -1 |
| rec1 | 1 |
| tf2 | 1 |
c.processed_graph.plot_values(vertex_values=P.expr.vertex_value.value, edge_values=P.expr.edge_value.value)
---------------------------------------------------------------------------
FileNotFoundError Traceback (most recent call last)
File /private/var/folders/b4/gwkwsdb93sv11rtztqbm3l040000gn/T/tmp.Dst0hQI0PJ/wt-v1.0.0-beta.2/.venv/lib/python3.13/site-packages/graphviz/backend/execute.py:76, in run_check(cmd, input_lines, encoding, quiet, **kwargs)
75 kwargs['stdout'] = kwargs['stderr'] = subprocess.PIPE
---> 76 proc = _run_input_lines(cmd, input_lines, kwargs=kwargs)
77 else:
File /private/var/folders/b4/gwkwsdb93sv11rtztqbm3l040000gn/T/tmp.Dst0hQI0PJ/wt-v1.0.0-beta.2/.venv/lib/python3.13/site-packages/graphviz/backend/execute.py:96, in _run_input_lines(cmd, input_lines, kwargs)
95 def _run_input_lines(cmd, input_lines, *, kwargs):
---> 96 popen = subprocess.Popen(cmd, stdin=subprocess.PIPE, **kwargs)
98 stdin_write = popen.stdin.write
File /opt/homebrew/Cellar/python@3.13/3.13.11_2/Frameworks/Python.framework/Versions/3.13/lib/python3.13/subprocess.py:1039, in Popen.__init__(self, args, bufsize, executable, stdin, stdout, stderr, preexec_fn, close_fds, shell, cwd, env, universal_newlines, startupinfo, creationflags, restore_signals, start_new_session, pass_fds, user, group, extra_groups, encoding, errors, text, umask, pipesize, process_group)
1036 self.stderr = io.TextIOWrapper(self.stderr,
1037 encoding=encoding, errors=errors)
-> 1039 self._execute_child(args, executable, preexec_fn, close_fds,
1040 pass_fds, cwd, env,
1041 startupinfo, creationflags, shell,
1042 p2cread, p2cwrite,
1043 c2pread, c2pwrite,
1044 errread, errwrite,
1045 restore_signals,
1046 gid, gids, uid, umask,
1047 start_new_session, process_group)
1048 except:
1049 # Cleanup if the child failed starting.
File /opt/homebrew/Cellar/python@3.13/3.13.11_2/Frameworks/Python.framework/Versions/3.13/lib/python3.13/subprocess.py:1991, in Popen._execute_child(self, args, executable, preexec_fn, close_fds, pass_fds, cwd, env, startupinfo, creationflags, shell, p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite, restore_signals, gid, gids, uid, umask, start_new_session, process_group)
1990 if err_filename is not None:
-> 1991 raise child_exception_type(errno_num, err_msg, err_filename)
1992 else:
FileNotFoundError: [Errno 2] No such file or directory: PosixPath('dot')
The above exception was the direct cause of the following exception:
ExecutableNotFound Traceback (most recent call last)
File /private/var/folders/b4/gwkwsdb93sv11rtztqbm3l040000gn/T/tmp.Dst0hQI0PJ/wt-v1.0.0-beta.2/.venv/lib/python3.13/site-packages/IPython/core/formatters.py:1036, in MimeBundleFormatter.__call__(self, obj, include, exclude)
1033 method = get_real_method(obj, self.print_method)
1035 if method is not None:
-> 1036 return method(include=include, exclude=exclude)
1037 return None
1038 else:
File /private/var/folders/b4/gwkwsdb93sv11rtztqbm3l040000gn/T/tmp.Dst0hQI0PJ/wt-v1.0.0-beta.2/corneto/_plotting.py:27, in suppress_repr_warnings.<locals>.make_wrapper.<locals>.wrapper(*args, **kwargs)
25 def wrapper(*args, **kwargs):
26 with contextlib.redirect_stderr(io.StringIO()):
---> 27 return orig_func(*args, **kwargs)
File /private/var/folders/b4/gwkwsdb93sv11rtztqbm3l040000gn/T/tmp.Dst0hQI0PJ/wt-v1.0.0-beta.2/.venv/lib/python3.13/site-packages/graphviz/jupyter_integration.py:98, in JupyterIntegration._repr_mimebundle_(self, include, exclude, **_)
96 include = set(include) if include is not None else {self._jupyter_mimetype}
97 include -= set(exclude or [])
---> 98 return {mimetype: getattr(self, method_name)()
99 for mimetype, method_name in MIME_TYPES.items()
100 if mimetype in include}
File /private/var/folders/b4/gwkwsdb93sv11rtztqbm3l040000gn/T/tmp.Dst0hQI0PJ/wt-v1.0.0-beta.2/corneto/_plotting.py:27, in suppress_repr_warnings.<locals>.make_wrapper.<locals>.wrapper(*args, **kwargs)
25 def wrapper(*args, **kwargs):
26 with contextlib.redirect_stderr(io.StringIO()):
---> 27 return orig_func(*args, **kwargs)
File /private/var/folders/b4/gwkwsdb93sv11rtztqbm3l040000gn/T/tmp.Dst0hQI0PJ/wt-v1.0.0-beta.2/.venv/lib/python3.13/site-packages/graphviz/jupyter_integration.py:112, in JupyterIntegration._repr_image_svg_xml(self)
110 def _repr_image_svg_xml(self) -> str:
111 """Return the rendered graph as SVG string."""
--> 112 return self.pipe(format='svg', encoding=SVG_ENCODING)
File /private/var/folders/b4/gwkwsdb93sv11rtztqbm3l040000gn/T/tmp.Dst0hQI0PJ/wt-v1.0.0-beta.2/.venv/lib/python3.13/site-packages/graphviz/piping.py:104, in Pipe.pipe(self, format, renderer, formatter, neato_no_op, quiet, engine, encoding)
55 def pipe(self,
56 format: typing.Optional[str] = None,
57 renderer: typing.Optional[str] = None,
(...)
61 engine: typing.Optional[str] = None,
62 encoding: typing.Optional[str] = None) -> typing.Union[bytes, str]:
63 """Return the source piped through the Graphviz layout command.
64
65 Args:
(...)
102 '<?xml version='
103 """
--> 104 return self._pipe_legacy(format,
105 renderer=renderer,
106 formatter=formatter,
107 neato_no_op=neato_no_op,
108 quiet=quiet,
109 engine=engine,
110 encoding=encoding)
File /private/var/folders/b4/gwkwsdb93sv11rtztqbm3l040000gn/T/tmp.Dst0hQI0PJ/wt-v1.0.0-beta.2/.venv/lib/python3.13/site-packages/graphviz/_tools.py:171, in deprecate_positional_args.<locals>.decorator.<locals>.wrapper(*args, **kwargs)
162 wanted = ', '.join(f'{name}={value!r}'
163 for name, value in deprecated.items())
164 warnings.warn(f'The signature of {func.__name__} will be reduced'
165 f' to {supported_number} positional args'
166 f' {list(supported)}: pass {wanted}'
167 ' as keyword arg(s)',
168 stacklevel=stacklevel,
169 category=category)
--> 171 return func(*args, **kwargs)
File /private/var/folders/b4/gwkwsdb93sv11rtztqbm3l040000gn/T/tmp.Dst0hQI0PJ/wt-v1.0.0-beta.2/.venv/lib/python3.13/site-packages/graphviz/piping.py:121, in Pipe._pipe_legacy(self, format, renderer, formatter, neato_no_op, quiet, engine, encoding)
112 @_tools.deprecate_positional_args(supported_number=2)
113 def _pipe_legacy(self,
114 format: typing.Optional[str] = None,
(...)
119 engine: typing.Optional[str] = None,
120 encoding: typing.Optional[str] = None) -> typing.Union[bytes, str]:
--> 121 return self._pipe_future(format,
122 renderer=renderer,
123 formatter=formatter,
124 neato_no_op=neato_no_op,
125 quiet=quiet,
126 engine=engine,
127 encoding=encoding)
File /private/var/folders/b4/gwkwsdb93sv11rtztqbm3l040000gn/T/tmp.Dst0hQI0PJ/wt-v1.0.0-beta.2/.venv/lib/python3.13/site-packages/graphviz/piping.py:149, in Pipe._pipe_future(self, format, renderer, formatter, neato_no_op, quiet, engine, encoding)
146 if encoding is not None:
147 if codecs.lookup(encoding) is codecs.lookup(self.encoding):
148 # common case: both stdin and stdout need the same encoding
--> 149 return self._pipe_lines_string(*args, encoding=encoding, **kwargs)
150 try:
151 raw = self._pipe_lines(*args, input_encoding=self.encoding, **kwargs)
File /private/var/folders/b4/gwkwsdb93sv11rtztqbm3l040000gn/T/tmp.Dst0hQI0PJ/wt-v1.0.0-beta.2/.venv/lib/python3.13/site-packages/graphviz/backend/piping.py:212, in pipe_lines_string(engine, format, input_lines, encoding, renderer, formatter, neato_no_op, quiet)
206 cmd = dot_command.command(engine, format,
207 renderer=renderer,
208 formatter=formatter,
209 neato_no_op=neato_no_op)
210 kwargs = {'input_lines': input_lines, 'encoding': encoding}
--> 212 proc = execute.run_check(cmd, capture_output=True, quiet=quiet, **kwargs)
213 return proc.stdout
File /private/var/folders/b4/gwkwsdb93sv11rtztqbm3l040000gn/T/tmp.Dst0hQI0PJ/wt-v1.0.0-beta.2/.venv/lib/python3.13/site-packages/graphviz/backend/execute.py:81, in run_check(cmd, input_lines, encoding, quiet, **kwargs)
79 except OSError as e:
80 if e.errno == errno.ENOENT:
---> 81 raise ExecutableNotFound(cmd) from e
82 raise
84 if not quiet and proc.stderr:
ExecutableNotFound: failed to execute PosixPath('dot'), make sure the Graphviz executables are on your systems' PATH
<graphviz.graphs.Digraph at 0x13e25d090>
Carnival ILP#
For completion, we have a version of the original Carnival that is not based on the modern formulation of CarnivalFlow, cannot be used for multi-samples, and is slower for larger problems.
c = CarnivalILP(beta_weight=1e-3)
P = c.build(G, data)
P.solve(verbosity=0, solver="scipy");
for o in P.objectives:
print(o.value)
0.0
4.0
c.processed_graph.edge_subgraph(np.flatnonzero(P.expr.edge_values.value)).plot()
# Extract the values from the problem
pd.DataFrame(P.expr.edge_values.value, index=c.processed_graph.E, columns=["edge_activity"]).astype(int)
| edge_activity | ||
|---|---|---|
| (rec1) | (a) | 1 |
| (b) | 0 | |
| (c) | 0 | |
| (rec2) | (b) | 0 |
| (tf2) | 1 | |
| (b) | (g) | 0 |
| (g) | (d) | 0 |
| (rec2) | (d) | 0 |
| (a) | (c) | 0 |
| (d) | 0 | |
| (c) | (d) | 0 |
| (e) | 0 | |
| (e) | (a) | 0 |
| (d) | (c) | 0 |
| (e) | (tf1) | 0 |
| (a) | (tf1) | -1 |
| (d) | (tf2) | 0 |
| (c) | (tf2) | 0 |
| (tf1) | (tf2) | 0 |
| (rec2) | 0 | |
| (tf2) | (rec1) | 1 |
pd.DataFrame(P.expr.vertex_values.value, index=c.processed_graph.V, columns=["node_activity"]).astype(int)
| node_activity | |
|---|---|
| g | 0 |
| e | 0 |
| c | 0 |
| b | 0 |
| a | 1 |
| d | 0 |
| rec2 | 1 |
| tf1 | -1 |
| rec1 | 1 |
| tf2 | 1 |
c.processed_graph.plot_values(vertex_values=P.expr.vertex_values.value, edge_values=P.expr.edge_values.value)
---------------------------------------------------------------------------
FileNotFoundError Traceback (most recent call last)
File /private/var/folders/b4/gwkwsdb93sv11rtztqbm3l040000gn/T/tmp.Dst0hQI0PJ/wt-v1.0.0-beta.2/.venv/lib/python3.13/site-packages/graphviz/backend/execute.py:76, in run_check(cmd, input_lines, encoding, quiet, **kwargs)
75 kwargs['stdout'] = kwargs['stderr'] = subprocess.PIPE
---> 76 proc = _run_input_lines(cmd, input_lines, kwargs=kwargs)
77 else:
File /private/var/folders/b4/gwkwsdb93sv11rtztqbm3l040000gn/T/tmp.Dst0hQI0PJ/wt-v1.0.0-beta.2/.venv/lib/python3.13/site-packages/graphviz/backend/execute.py:96, in _run_input_lines(cmd, input_lines, kwargs)
95 def _run_input_lines(cmd, input_lines, *, kwargs):
---> 96 popen = subprocess.Popen(cmd, stdin=subprocess.PIPE, **kwargs)
98 stdin_write = popen.stdin.write
File /opt/homebrew/Cellar/python@3.13/3.13.11_2/Frameworks/Python.framework/Versions/3.13/lib/python3.13/subprocess.py:1039, in Popen.__init__(self, args, bufsize, executable, stdin, stdout, stderr, preexec_fn, close_fds, shell, cwd, env, universal_newlines, startupinfo, creationflags, restore_signals, start_new_session, pass_fds, user, group, extra_groups, encoding, errors, text, umask, pipesize, process_group)
1036 self.stderr = io.TextIOWrapper(self.stderr,
1037 encoding=encoding, errors=errors)
-> 1039 self._execute_child(args, executable, preexec_fn, close_fds,
1040 pass_fds, cwd, env,
1041 startupinfo, creationflags, shell,
1042 p2cread, p2cwrite,
1043 c2pread, c2pwrite,
1044 errread, errwrite,
1045 restore_signals,
1046 gid, gids, uid, umask,
1047 start_new_session, process_group)
1048 except:
1049 # Cleanup if the child failed starting.
File /opt/homebrew/Cellar/python@3.13/3.13.11_2/Frameworks/Python.framework/Versions/3.13/lib/python3.13/subprocess.py:1991, in Popen._execute_child(self, args, executable, preexec_fn, close_fds, pass_fds, cwd, env, startupinfo, creationflags, shell, p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite, restore_signals, gid, gids, uid, umask, start_new_session, process_group)
1990 if err_filename is not None:
-> 1991 raise child_exception_type(errno_num, err_msg, err_filename)
1992 else:
FileNotFoundError: [Errno 2] No such file or directory: PosixPath('dot')
The above exception was the direct cause of the following exception:
ExecutableNotFound Traceback (most recent call last)
File /private/var/folders/b4/gwkwsdb93sv11rtztqbm3l040000gn/T/tmp.Dst0hQI0PJ/wt-v1.0.0-beta.2/.venv/lib/python3.13/site-packages/IPython/core/formatters.py:1036, in MimeBundleFormatter.__call__(self, obj, include, exclude)
1033 method = get_real_method(obj, self.print_method)
1035 if method is not None:
-> 1036 return method(include=include, exclude=exclude)
1037 return None
1038 else:
File /private/var/folders/b4/gwkwsdb93sv11rtztqbm3l040000gn/T/tmp.Dst0hQI0PJ/wt-v1.0.0-beta.2/corneto/_plotting.py:27, in suppress_repr_warnings.<locals>.make_wrapper.<locals>.wrapper(*args, **kwargs)
25 def wrapper(*args, **kwargs):
26 with contextlib.redirect_stderr(io.StringIO()):
---> 27 return orig_func(*args, **kwargs)
File /private/var/folders/b4/gwkwsdb93sv11rtztqbm3l040000gn/T/tmp.Dst0hQI0PJ/wt-v1.0.0-beta.2/.venv/lib/python3.13/site-packages/graphviz/jupyter_integration.py:98, in JupyterIntegration._repr_mimebundle_(self, include, exclude, **_)
96 include = set(include) if include is not None else {self._jupyter_mimetype}
97 include -= set(exclude or [])
---> 98 return {mimetype: getattr(self, method_name)()
99 for mimetype, method_name in MIME_TYPES.items()
100 if mimetype in include}
File /private/var/folders/b4/gwkwsdb93sv11rtztqbm3l040000gn/T/tmp.Dst0hQI0PJ/wt-v1.0.0-beta.2/corneto/_plotting.py:27, in suppress_repr_warnings.<locals>.make_wrapper.<locals>.wrapper(*args, **kwargs)
25 def wrapper(*args, **kwargs):
26 with contextlib.redirect_stderr(io.StringIO()):
---> 27 return orig_func(*args, **kwargs)
File /private/var/folders/b4/gwkwsdb93sv11rtztqbm3l040000gn/T/tmp.Dst0hQI0PJ/wt-v1.0.0-beta.2/.venv/lib/python3.13/site-packages/graphviz/jupyter_integration.py:112, in JupyterIntegration._repr_image_svg_xml(self)
110 def _repr_image_svg_xml(self) -> str:
111 """Return the rendered graph as SVG string."""
--> 112 return self.pipe(format='svg', encoding=SVG_ENCODING)
File /private/var/folders/b4/gwkwsdb93sv11rtztqbm3l040000gn/T/tmp.Dst0hQI0PJ/wt-v1.0.0-beta.2/.venv/lib/python3.13/site-packages/graphviz/piping.py:104, in Pipe.pipe(self, format, renderer, formatter, neato_no_op, quiet, engine, encoding)
55 def pipe(self,
56 format: typing.Optional[str] = None,
57 renderer: typing.Optional[str] = None,
(...)
61 engine: typing.Optional[str] = None,
62 encoding: typing.Optional[str] = None) -> typing.Union[bytes, str]:
63 """Return the source piped through the Graphviz layout command.
64
65 Args:
(...)
102 '<?xml version='
103 """
--> 104 return self._pipe_legacy(format,
105 renderer=renderer,
106 formatter=formatter,
107 neato_no_op=neato_no_op,
108 quiet=quiet,
109 engine=engine,
110 encoding=encoding)
File /private/var/folders/b4/gwkwsdb93sv11rtztqbm3l040000gn/T/tmp.Dst0hQI0PJ/wt-v1.0.0-beta.2/.venv/lib/python3.13/site-packages/graphviz/_tools.py:171, in deprecate_positional_args.<locals>.decorator.<locals>.wrapper(*args, **kwargs)
162 wanted = ', '.join(f'{name}={value!r}'
163 for name, value in deprecated.items())
164 warnings.warn(f'The signature of {func.__name__} will be reduced'
165 f' to {supported_number} positional args'
166 f' {list(supported)}: pass {wanted}'
167 ' as keyword arg(s)',
168 stacklevel=stacklevel,
169 category=category)
--> 171 return func(*args, **kwargs)
File /private/var/folders/b4/gwkwsdb93sv11rtztqbm3l040000gn/T/tmp.Dst0hQI0PJ/wt-v1.0.0-beta.2/.venv/lib/python3.13/site-packages/graphviz/piping.py:121, in Pipe._pipe_legacy(self, format, renderer, formatter, neato_no_op, quiet, engine, encoding)
112 @_tools.deprecate_positional_args(supported_number=2)
113 def _pipe_legacy(self,
114 format: typing.Optional[str] = None,
(...)
119 engine: typing.Optional[str] = None,
120 encoding: typing.Optional[str] = None) -> typing.Union[bytes, str]:
--> 121 return self._pipe_future(format,
122 renderer=renderer,
123 formatter=formatter,
124 neato_no_op=neato_no_op,
125 quiet=quiet,
126 engine=engine,
127 encoding=encoding)
File /private/var/folders/b4/gwkwsdb93sv11rtztqbm3l040000gn/T/tmp.Dst0hQI0PJ/wt-v1.0.0-beta.2/.venv/lib/python3.13/site-packages/graphviz/piping.py:149, in Pipe._pipe_future(self, format, renderer, formatter, neato_no_op, quiet, engine, encoding)
146 if encoding is not None:
147 if codecs.lookup(encoding) is codecs.lookup(self.encoding):
148 # common case: both stdin and stdout need the same encoding
--> 149 return self._pipe_lines_string(*args, encoding=encoding, **kwargs)
150 try:
151 raw = self._pipe_lines(*args, input_encoding=self.encoding, **kwargs)
File /private/var/folders/b4/gwkwsdb93sv11rtztqbm3l040000gn/T/tmp.Dst0hQI0PJ/wt-v1.0.0-beta.2/.venv/lib/python3.13/site-packages/graphviz/backend/piping.py:212, in pipe_lines_string(engine, format, input_lines, encoding, renderer, formatter, neato_no_op, quiet)
206 cmd = dot_command.command(engine, format,
207 renderer=renderer,
208 formatter=formatter,
209 neato_no_op=neato_no_op)
210 kwargs = {'input_lines': input_lines, 'encoding': encoding}
--> 212 proc = execute.run_check(cmd, capture_output=True, quiet=quiet, **kwargs)
213 return proc.stdout
File /private/var/folders/b4/gwkwsdb93sv11rtztqbm3l040000gn/T/tmp.Dst0hQI0PJ/wt-v1.0.0-beta.2/.venv/lib/python3.13/site-packages/graphviz/backend/execute.py:81, in run_check(cmd, input_lines, encoding, quiet, **kwargs)
79 except OSError as e:
80 if e.errno == errno.ENOENT:
---> 81 raise ExecutableNotFound(cmd) from e
82 raise
84 if not quiet and proc.stderr:
ExecutableNotFound: failed to execute PosixPath('dot'), make sure the Graphviz executables are on your systems' PATH
<graphviz.graphs.Digraph at 0x122cd9f90>
Old implementation#
An older implementation used in previous versions of CORNETO is still available in the corneto.methods.carnival package. It uses a simpler interface and a formulation more similar to the original CarnivalR:
from corneto.methods.carnival import milp_carnival
P = milp_carnival(
G,
{"rec2": 1},
{"tf1": -2, "tf2": 1},
beta_weight=1e-3,
)
P.solve(solver="scipy");
for o in P.objectives:
print(o.value)
0.0
4.0
G.edge_subgraph(np.flatnonzero(P.expr.edge_values.value)).plot()