From 34ae8961a61f9d56a47099d986756f8d55c18583 Mon Sep 17 00:00:00 2001 From: "Nikolaus C. Awtrey" Date: Tue, 15 Apr 2025 20:47:20 -0700 Subject: [PATCH 1/2] ENH: Enable one-way cycle flux calculations * Changes `calc_net_cycle_flux` to `calc_cycle_flux`, and adds parameter `net` to toggle between one-way and net cycle fluxes * Updates `calc_pi_difference` to allow for retrieving the forward cycle rate product by adding the same `net` parameter (`net=True` returns the cycle product difference) * Updates call signatures throughout `calculations.py` and `test_kda.py` * Related to issue #57 --- kda/calculations.py | 50 ++++++++++++++++++++++++++++--------------- kda/tests/test_kda.py | 8 +++---- 2 files changed, 37 insertions(+), 21 deletions(-) diff --git a/kda/calculations.py b/kda/calculations.py index 8a474bc..ec0eea5 100644 --- a/kda/calculations.py +++ b/kda/calculations.py @@ -10,7 +10,7 @@ probabilities and fluxes from a user-defined kinetic diagram. .. autofunction:: calc_state_probs -.. autofunction:: calc_net_cycle_flux +.. autofunction:: calc_cycle_flux .. autofunction:: calc_sigma .. autofunction:: calc_sigma_K .. autofunction:: calc_pi_difference @@ -282,7 +282,8 @@ def calc_sigma_K(G, cycle, flux_diags, key="name", output_strings=True): return sigma_K -def calc_pi_difference(G, cycle, order, key="name", output_strings=True): +def calc_pi_difference(G, cycle, order, key="name", + output_strings=True, net=True): r""" Generates the expression for the cycle-based componenet of the sum of flux diagrams for some ``cycle`` in kinetic diagram ``G``. @@ -312,6 +313,10 @@ def calc_pi_difference(G, cycle, order, key="name", output_strings=True): using numbers. If ``True``, this will assume the input ``'key'`` will return strings of variable names to join into the analytic function. + net : bool (optional) + Used to determine whether to return the _forward_ cycle product + (i.e., ``net=False``) or the _difference_ of the forward and reverse + cycle products (i.e., ``net=True``). Default is ``True``. Returns ------- @@ -357,14 +362,20 @@ def calc_pi_difference(G, cycle, order, key="name", output_strings=True): for edge in cycle_edges: ccw_rates.append(G.edges[edge[0], edge[1], edge[2]][key]) cw_rates.append(G.edges[edge[1], edge[0], edge[2]][key]) - pi_difference = "-".join(["*".join(ccw_rates), "*".join(cw_rates)]) + if net: + pi_difference = "-".join(["*".join(ccw_rates), "*".join(cw_rates)]) + else: + pi_difference = "*".join(ccw_rates) else: ccw_rates = 1 cw_rates = 1 for edge in cycle_edges: ccw_rates *= G.edges[edge[0], edge[1], edge[2]][key] cw_rates *= G.edges[edge[1], edge[0], edge[2]][key] - pi_difference = ccw_rates - cw_rates + if net: + pi_difference = ccw_rates - cw_rates + else: + pi_difference = ccw_rates return pi_difference @@ -563,10 +574,10 @@ def calc_state_probs(G, key="name", output_strings=True, dir_edges=None): return state_probs -def calc_net_cycle_flux(G, cycle, order, key="name", - output_strings=True, dir_edges=None): - r"""Generates the expression for the net cycle flux for - some ``cycle`` in kinetic diagram ``G``. +def calc_cycle_flux(G, cycle, order, key="name", + output_strings=True, dir_edges=None, net=True): + r"""Generates the expression for the one-way or net cycle + flux for a ``cycle`` in the kinetic diagram ``G``. Parameters ---------- @@ -598,11 +609,14 @@ def calc_net_cycle_flux(G, cycle, order, key="name", generate the directional diagram edges up front and provide them). Created using :meth:`~kda.diagrams.generate_directional_diagrams` with ``return_edges=True``. + net : bool (optional) + Used to determine whether to return the _one-way_ or _net_ cycle flux. + Default is ``True`` (i.e., to generate the _net_ cycle flux). Returns ------- - net_cycle_flux : float or ``SymPy`` expression - Net cycle flux for the input ``cycle``. + cycle_flux : float or ``SymPy`` expression + The one-way or net cycle flux for the input ``cycle``. Notes ----- @@ -628,18 +642,19 @@ def calc_net_cycle_flux(G, cycle, order, key="name", # construct the expressions for (Pi+ - Pi-), sigma, and sigma_k # from the directional diagram edges pi_diff = calc_pi_difference( - G=G, cycle=cycle, order=order, key=key, output_strings=output_strings) + G=G, cycle=cycle, order=order, key=key, + output_strings=output_strings, net=net) sigma_K = calc_sigma_K( G=G, cycle=cycle, flux_diags=flux_diags, key=key, output_strings=output_strings) sigma = calc_sigma( G=G, dirpar_edges=dir_edges, key=key, output_strings=output_strings) if output_strings: - net_cycle_flux = expressions.construct_sympy_net_cycle_flux_func( + cycle_flux = expressions.construct_sympy_net_cycle_flux_func( pi_diff_str=pi_diff, sigma_K_str=sigma_K, sigma_str=sigma) else: - net_cycle_flux = pi_diff * sigma_K / sigma - return net_cycle_flux + cycle_flux = pi_diff * sigma_K / sigma + return cycle_flux def calc_state_probs_from_diags(G, dirpar_edges, key="name", output_strings=True): @@ -697,7 +712,7 @@ def calc_net_cycle_flux_from_diags( """Generates the expression for the net cycle flux for some ``cycle`` in kinetic diagram ``G``. If directional diagram edges are already generated this offers better performance than - :meth:`~kda.calculations.calc_net_cycle_flux`. + :meth:`~kda.calculations.calc_cycle_flux`. Parameters ---------- @@ -734,13 +749,14 @@ def calc_net_cycle_flux_from_diags( """ msg = """`kda.calculations.calc_net_cycle_flux_from_diags` will be deprecated. - Use `kda.calculations.calc_net_cycle_flux` with parameter `dir_edges`.""" + Use `kda.calculations.calc_cycle_flux` with parameter `dir_edges`.""" warnings.warn(msg, DeprecationWarning) - return calc_net_cycle_flux( + return calc_cycle_flux( G=G, cycle=cycle, order=order, key=key, output_strings=output_strings, dir_edges=dirpar_edges, + net=True, ) diff --git a/kda/tests/test_kda.py b/kda/tests/test_kda.py index 5d1adc2..fadc9e7 100644 --- a/kda/tests/test_kda.py +++ b/kda/tests/test_kda.py @@ -467,7 +467,7 @@ def test_calc_net_cycle_flux_4WL(self, k_vals): cycle = [0, 1, 3] order = [0, 1] # calculate the net cycle flux - net_cycle_flux = calculations.calc_net_cycle_flux( + net_cycle_flux = calculations.calc_cycle_flux( G, dir_edges=dir_edges, cycle=cycle, @@ -476,7 +476,7 @@ def test_calc_net_cycle_flux_4WL(self, k_vals): output_strings=False, ) # generate the net cycle flux function - net_cycle_flux_sympy_func = calculations.calc_net_cycle_flux( + net_cycle_flux_sympy_func = calculations.calc_cycle_flux( G, dir_edges=dir_edges, cycle=cycle, @@ -522,11 +522,11 @@ def test_calc_net_cycle_flux_3(self, k_vals): cycle = [0, 2, 1] order = [0, 1] # calculate the net cycle flux - net_cycle_flux = calculations.calc_net_cycle_flux( + net_cycle_flux = calculations.calc_cycle_flux( G, cycle=cycle, order=order, key="val", output_strings=False ) # generate the sympy net cycle flux function - sympy_net_cycle_flux_func = calculations.calc_net_cycle_flux( + sympy_net_cycle_flux_func = calculations.calc_cycle_flux( G, cycle=cycle, order=order, key="name", output_strings=True ) # make sure the sympy function agrees with the known solution From 0e23260833c7baa1906180ace55c957a81fbb9a0 Mon Sep 17 00:00:00 2001 From: "Nikolaus C. Awtrey" Date: Tue, 15 Apr 2025 21:09:26 -0700 Subject: [PATCH 2/2] MAINT: Minor docstring changes * Removes italicized text in docstrings * Removes redundant statements --- kda/calculations.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/kda/calculations.py b/kda/calculations.py index ec0eea5..ac5253e 100644 --- a/kda/calculations.py +++ b/kda/calculations.py @@ -306,7 +306,6 @@ def calc_pi_difference(G, cycle, order, key="name", ``NetworkX`` edge key is ``"weight"``, however the ``kda`` edge keys are ``"name"`` (for rate constant names, e.g. ``"k12"``) and ``"val"`` (for the rate constant values, e.g. ``100``). Default is ``"name"``. - Default is ``"name"``. output_strings : bool (optional) Used to denote whether values or strings will be combined. Default is ``False``, which tells the function to calculate the difference @@ -314,8 +313,8 @@ def calc_pi_difference(G, cycle, order, key="name", will return strings of variable names to join into the analytic function. net : bool (optional) - Used to determine whether to return the _forward_ cycle product - (i.e., ``net=False``) or the _difference_ of the forward and reverse + Used to determine whether to return the forward cycle product + (i.e., ``net=False``) or the difference of the forward and reverse cycle products (i.e., ``net=True``). Default is ``True``. Returns @@ -595,7 +594,6 @@ def calc_cycle_flux(G, cycle, order, key="name", ``NetworkX`` edge key is ``"weight"``, however the ``kda`` edge keys are ``"name"`` (for rate constant names, e.g. ``"k12"``) and ``"val"`` (for the rate constant values, e.g. ``100``). Default is ``"name"``. - Default is ``"name"``. output_strings : bool (optional) Used to denote whether values or strings will be combined. Default is ``False``, which tells the function to calculate the cycle flux @@ -610,8 +608,8 @@ def calc_cycle_flux(G, cycle, order, key="name", Created using :meth:`~kda.diagrams.generate_directional_diagrams` with ``return_edges=True``. net : bool (optional) - Used to determine whether to return the _one-way_ or _net_ cycle flux. - Default is ``True`` (i.e., to generate the _net_ cycle flux). + Used to determine whether to return the one-way or net cycle flux. + Default is ``True`` (i.e., to generate the net cycle flux). Returns -------