Welcome to LoopDetect’s documentation!¶
LoopDetect provides functions to determine all feedback loops of an ordinary differential equation (ODE) system. The example workflow description shows how to use the provided functions, the glossary provides an overview over all functions.
Other implementations
This documentation is for the implementation in Python (Github: Source). For other programming languages, see:
Contents:
- Example workflow with LoopDetect
- Installation
- In brief and quick start
- Introduction
- Solving the ODE model to generate variable values of interest
- Calculating the Jacobian matrix
- Computing all feedback loops
- Finding certain loops or edges in a loop list
- Writing to files and loading loop lists
- Computing feedback loops over multiple sets of variable values of interest
- Comparing two loop lists
- Example for a possible input function
- References
-
LoopDetect.compare_loops(loop_list_a, loop_list_b, list_b_inds='True')¶ Compares two loop lists to find identical loops. Same node indices are considered to encode the same nodes in the compared loops. Sets of indices are returned.
- Parameters
loop_list_a (pandas dataframe): loop list, i.e. pandas dataframe with columns loop, length, sign
loop_list_b (pandas dataframe): loop list, i.e. pandas dataframe with columns loop, length, sign
list_b_inds (boolean, optional): whether also the indices for the second list are computed (might take long)
- Details
Loop lists could be generated from functions find_loops or find_loops_noscc. Indices of the loops are sorted internally with the function sort_loop_index() to start with the lowest node index and make comparison possible.
- Returns
A dictionary containing five entries
ind_a_id: indices of the loops in the first loop list that occur identically in the second loop list
ind_a_switch: indices of the loops in the first loop list that occur in the second loop list with a different sign
ind_a_notin: indices of the loops in the first loop list that do not occur in the second loop list
ind_b_id: indices of loops in the second loop list corresponding to the loops reported in ind_a_id
ind_b_switch: indices of loops in the second loop list corresponding to loops reported in ind_a_switch.
- See Also
find_loops, find_loops_noscc
- Example
Comparing loop lists from two systems of size 4 with coinciding nodes:
#import the relevant packages import LoopDetect import numpy as np #define the Jacobian matrix as numpy array jac = np.array([[-1,0,0,-1],[1,-1,0,1],[0,1,-1,0],[0,0,1,-1]]) #compute the loop list loop_list = LoopDetect.find_loops(jac) #define a slightly different Jacobian matrix jac2 = np.array([[-1,0,0,0],[1,-1,0,-1],[0,1,1,0],[0,0,1,-1]]) #compute the loop list loop_list2 = LoopDetect.find_loops(jac2) #compare the loop lists loop_compare = compare_loops(loop_list,loop_list2) #get sublist of all loops that match loop_list.iloc(loop_compare['ind_a_id']) #get only loops in first list that match exactly a loop in the second list loop_list.loop[loop_compare['ind_a_id']]
-
LoopDetect.find_edge(loop_list, source_node, target_node)¶ Reports which loops in a loop list contain a certain edge.
- Parameters
loop_list (pandas dataframe): loop list as generated from find_loops, has to contain a column named ‘loop’
source_node (int): index of the source node of the edge
target_node (int): index of the target node of the edge
- Returns
A list with Boolean values of the same length as the number of rows in the loop list. The values are True if the rows contain the edge, False if not.
- See Also
find_loops, find_loops_noscc
- Example
Finding all loops with an edge between species 0 and 1:
#import the relevant packages import LoopDetect import numpy as np #define the Jacobian matrix as numpy array jac = np.array([[-1,0,0,-1],[1,-1,0,1],[0,1,-1,0],[0,0,1,-1]]) #compute the loop list loop_list = LoopDetect.find_loops_noscc(jac) #find loops containing the edge [0,1] first_edge = LoopDetect.find_edge(loop_list,0,1) #return the loops containing the edge loop_list.iloc[first_edge]
-
LoopDetect.find_loops(jacobian, max_num_loops=100000)¶ Function to determine all feedback loops in an ordinary differential equation (ODE) model given by its Jacobian matrix. Strongly connected components are determined before cycle detection.
- Parameters
jacobian (numpy array): matrix indicating the Jacobian of the ODE, \(J_ij = df_i/dx_j\).
max_num_loops (int, optional): positive integer (default: 1e5) giving the maximal number of reported feedback loops. Note that only up to max_num_loops feedback loops are returned (without warning).
- Returns
A pandas dataframe: dataframe with the three columns “loop”, “length” and “sign” that contain the information on one feedback loop in each row. “loop” gives the order of the variables (indices) forming the loop as tuple, “length” indicates the number of participating species and “sign” is +1 or -1 indicating a positive or a negative loop, respectively.
- Details
A feedback loop is a circular regulation without visiting any node twice. This function relies on the Python modules networkx to detect strongly connected components and simple cycles in the graph generated by the Jacobian matrix.
- Example
Define the Jacobian matrix of a four-variable system (jac) and compute all feedback loops:
#import the relevant packages import LoopDetect import numpy as np #define the Jacobian matrix as numpy array jac = np.array([[-1,0,0,-1],[1,-1,0,1],[0,1,-1,0],[0,0,1,-1]]) #compute the loop list loop_list = LoopDetect.find_loops(jac)
-
LoopDetect.find_loops_noscc(jacobian, max_num_loops=100000)¶ Function to determine all feedback loops in an ordinary differential equation (ODE) model given by its Jacobian matrix. No strongly connected components are determined before cycle detection.
- Parameters
jacobian (numpy array): matrix indicating the Jacobian of the ODE, \(J_ij = df_i/dx_j\).
max_num_loops (int, optional): positive integer (default: 1e5) giving the maximal number of reported feedback loops. Note that only up to max_num_loops feedback loops are returned (without warning).
- Returns
A pandas dataframe: dataframe with the three columns “loop”, “length” and “sign” that contain the information on one feedback loop in each row. “loop” gives the order of the variables (indices) forming the loop as tuple, “length” indicates the number of participating species and “sign” is +1 or -1 indicating a positive or a negative loop, respectively.
- Details
A feedback loop is a circular regulation without visiting any node twice. This function relies on the Python modules networkx to detect simple cycles in the graph generated by the Jacobian matrix.
- See Also
find_loops
- Example
Define the Jacobian matrix of a four-variable system (jac) and compute all feedback loops:
#import the relevant packages import LoopDetect import numpy as np #define the Jacobian matrix as numpy array jac = np.array([[-1,0,0,-1],[1,-1,0,1],[0,1,-1,0],[0,0,1,-1]]) #compute the loop list loop_list = LoopDetect.find_loops_noscc(jac)
-
LoopDetect.find_loops_vset(fun, vset, *args, numdiff_method='central', max_num_loops=100000, compute_full_list=True, **kwargs)¶ Determines loop lists for an ODE system given by a function and at multiple sets of variables. Loop lists are reported if signs of Jacobian matrix have changed.
- Parameters
fun (function): function defining the ODE system, returns the vector \(dx/dt\) of derivatives of the variables as a numpy ndarray. The derivative is taken in direction of the first parameter of the function (i.e. \(x\) if the function returns \(dx/dt\)). It may depend on further parameters (defined in *args, **kwargs).
vset (list): list of lists or list of tuples of variable values at which the loops are determined.
*args Further parameters except variable values to the function fun.
numdiff_method (string, optional): central finite difference approach for derivative calculation (‘central’,default) or ‘complex’ for complex-step approach.
max_num_loops (int, optional): Positive numeric value indicating the maximal number of loops that are reported in a loop list. Defaults to \(10^5\).
compute_full_list (bool, optional): Logical value indicating whether for each Jacobian matrix with any different sign the loop list is computed (True, default), or whether further checks are performed to ensure that loops may be altered (see Details).
**kwargs: any number of further (named) parameters that are all used as input to the function fun.
- Details
The Jacobian matrices are computed for each of the variable values defined in vset with the package numdifftools using the standard central finite difference approach or the complex-step approach, depending on the input numdiff_method. The complex-step will only deliver correct results if the function works with complex numbers and does not contain non-analytic parts such as min, max or abs. Please be aware that functions have to return numpy arrays! If compute_full_list is set to False, loop lists are not re-computed for Jacobians that clearly do not allow for altered loop lists. These two criteria are checked: (a) no new regulations appear, and (b) only signs of regulations are altered that are not member of any loop. Loop lists can still be identical for different Jacobians, e.g. if two sign switches occur that are both affecting the same loops.
- Returns
dictionary: containing four entries:
loop_rep: List of loop lists (pandas dataframes).
loop_rep_index: Vector of integer numbers returning the index of the loop list in loop_rep belonging to each entry in vset.
jac_rep: List of signed Jacobian matrices.
jac_rep_index: Vector of integer numbers returning the index of the Jacobian matrix in jac_rep belonging to each entry in vset.
- Details
If there is only one class of Jacobian matrix (i.e. the signs of the Jacobian matrix are the same for all entries in vset), loop_rep and jac_rep will have only one entry each. The number of entries for loop_rep_index and jac_rep_index corresponds to the length of vset. Only if compute_full_list is set to False, loop_rep can contain fewer elements than jac_rep, otherwise both have the same number of elements.
- See Also
find_loops numdifftools.Jacobian
- Examples
Perform the loop analysis for a bacterial cell cycle system:
#import the relevant packages import LoopDetect as ld import numpy as np #Note: the example function from the script func_li08.py is loaded together #with the other functions from LoopDetect #read in solutions from the data accompanying the package, file li08_solution.tsv sols=ld.load_li08_sol() sols_as_tuples=[tuple(sols.iloc[i,1:20]) for i in range(len(sols))] #removing the time column #we reduce the loop lists as much as possible loop_results = ld.find_loops_vset(ld.func_li08,vset=sols_as_tuples,numdiff_method='central', max_num_loops=100000,compute_full_list=False,t=0) loop_results['loop_rep']
Perform the loop analysis for a simpler system with a function with more input parameters and defined in complex numbers:
#The example function func_POSm4_comp() is that of a 4-variable system and is supplied #together with the other functions in LoopDetect. #define 5 possible variables (4-variable-system) in as list, as tuples vset_def = [f for f in zip([1,1,2,2,3],[0,1,2,3,4],[2,2,2,2,2],[3,0,1,2,3])] #we compute the loop lists at parameter values klin = [1,2,3,4,5,6,7,8] (in *args) #and knonlin=[2,2] (as **kwargs) using complex step derivatives loop_results = ld.find_loops_vset(ld.func_POSm4_comp,vset_def,[1,2,3,4,5,6,7,8], numdiff_method='complex',compute_full_list=True,knonlin=[2,2]) #please be aware that the function func_POSm4_comp defines complex values # (otherwise the Jacobian would be always zeros everywhere for numdiff_method='complex')
-
LoopDetect.loop_summary(loop_list, column_val='length')¶ Reports a summary of the loops in a loop list: numbers of positive (pos) loops or negative (neg) loops of a certain length
- Parameters
loop_list (pandas dataframe): loop list as generated from find_loops, has to contain a column named ‘loop’
column_val (string, optional): if this is ‘length’ (default), the column names are the length, otherwise the sign of the loop are the columns
- Returns
A pandas dataframe containing the counts of negative (neg), positive (pos) or all loops (total) subdivided by their length. Lengths that do not occur are omitted.
- See Also
find_loops, find_loops_noscc
- Example
Summarize a short loop list.:
#import the relevant packages import LoopDetect import numpy as np #define the Jacobian matrix as numpy array jac = np.array([[-1,0,0,-1],[1,-1,0,1],[0,1,-1,0],[0,0,1,-1]]) #compute the loop list loop_list = LoopDetect.find_loops_noscc(jac) #determine summary sum_tab = loop_summary(loop_list)
-
LoopDetect.sort_loop_index(loop_list)¶ Sort all loops in a loop list such that they start with the node with the smallest index. This is a helper function for comparing loop lists.
- Parameters
loop_list (pandas dataframe): loop list as generated from find_loops, has to contain a column named ‘loop’
- Returns
pandas dataframe containing the sorted list of loops
- See Also
find_loops, find_loops_noscc
- Example
Create a new loop list with sorted entries (starting from the smalles node index).:
#import the relevant packages import LoopDetect import numpy as np #define the Jacobian matrix as numpy array jac = np.array([[-1,0,0,-1],[1,-1,0,1],[0,1,-1,0],[0,0,1,-1]]) #compute the loop list loop_list = find_loops(jac) #manipulate the second loop to start with a different entry than the smallest loop_list.loop[1]=tuple([2,3,1,3]) #sort loop order sorted_loop_list = LoopDetect.sort_loop_index(loop_list)
-
func_li08.func_li08(x, t)¶ example function: bacterial cell cycle [modelwtin(t,y), Li et al. 2008]
- Parameters
x (numpy array, list, tuple): numerical of length 18, ordered input of the variable values
t (float): time variable. Note that the function is independent from time.
- Returns
A numpy array of length 18 containing the temporal derivative of the 18 variables.
- Details
This is a function encoding an ordinary differential equation model that delivers the dynamics of the Caulobacter cell cycle. Note that to obtain the solution as published, also events have to be considered, i.e. certain conditions lead to a change in certain variable values; see Li et al., 2008 for details.
- Reference
Li S, Brazhnik P, Sobral B, Tyson JJ. A Quantitative Study of the Division Cycle of Caulobacter crescentus Stalked Cells. Plos Comput Biol. 2008;4(1):e9.
-
func_li08.load_li08_sol()¶ Loads solutions for an example function of the bacterial cell cycle, Li et al. 2008, as dataframe.
- Returns
A pandas dataframe that provides the solution for 18 species over time (roughly 3 cycles, up to 360 minutes, 634 time points in between). It contains the following columns:
time, y1=x0, y2=x1,…, y18=x17
All are numbers. Time is given in minutes.
- Reference
Li S, Brazhnik P, Sobral B, Tyson JJ. A Quantitative Study of the Division Cycle of Caulobacter crescentus Stalked Cells. Plos Comput Biol. 2008;4(1):e9.
-
func_POSm4.func_POSm4(x, klin, knonlin)¶ example function: chain model with positive feedback regulation as from Baum et al., 2016
::Parameters:
x (numpy array, list, tuple): numerical, ordered values of length 4; these are the variable values.
klin: (numpy array, list, tuple): numerical, ordered values of length 8; these are some of the kinetic parameters of the model
knonlin:
- Returns
A numpy array of length 4 that contains the time-derivatives of the four variables.
- Details
It is a function delivering an ordinary differential equation system with chain structure with 4 species and a positive feedback regulation from the last species on the conversion between species 1 and 2. The system can give rise to oscillations; see Baum et al., 2016 for details.
- Reference
Baum K, Politi AZ, Kofahl B, Steuer R, Wolf J: Feedback, Mass Conservation and Reaction Kinetics Impact the Robustness of Cellular Oscillationss. Plos Comput Biol. 2016;12(12):e1005298.
-
func_POSm4.func_POSm4_comp(x, klin, knonlin)¶ example function: complex-valued chain model with positive feedback regulation as from Baum et al., 2016
- Parameters
x (numpy array, list, tuple): numerical, ordered values of length 4; these are the variable values.
klin: (numpy array, list, tuple): numerical, ordered values of length 8; these are some of the kinetic parameters of the model
knonlin:
- Returns
A complex-valued numpy array of length 4 that contains the time-derivatives of the four variables.
- Details
This function is the same as func_POSm4(), only that the output is complex. Thus, it can be used with complex-step derivatives. It is a function delivering an ordinary differential equation system with chain structure with 4 species and a positive feedback regulation from the last species on the conversion between species 1 and 2. The system can give rise to oscillations; see Baum et al., 2016 for details.
- Reference
Baum K, Politi AZ, Kofahl B, Steuer R, Wolf J: Feedback, Mass Conservation and Reaction Kinetics Impact the Robustness of Cellular Oscillationss. Plos Comput Biol. 2016;12(12):e1005298.