mxlpy 0.24.0__py3-none-any.whl → 0.25.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
mxlpy/model.py CHANGED
@@ -2271,6 +2271,24 @@ class Model:
2271
2271
  dxdt[k] += n * dependent[flux]
2272
2272
  return tuple(dxdt[i] for i in cache.var_names)
2273
2273
 
2274
+ def _get_right_hand_side(
2275
+ self,
2276
+ *,
2277
+ args: dict[str, float],
2278
+ var_names: list[str],
2279
+ cache: ModelCache,
2280
+ ) -> pd.Series:
2281
+ dxdt = pd.Series(np.zeros(len(var_names), dtype=float), index=var_names)
2282
+ for k, stoc in cache.stoich_by_cpds.items():
2283
+ for flux, n in stoc.items():
2284
+ dxdt[k] += n * args[flux]
2285
+
2286
+ for k, sd in cache.dyn_stoich_by_cpds.items():
2287
+ for flux, dv in sd.items():
2288
+ n = dv.fn(*(args[i] for i in dv.args))
2289
+ dxdt[k] += n * args[flux]
2290
+ return dxdt
2291
+
2274
2292
  def get_right_hand_side(
2275
2293
  self,
2276
2294
  variables: dict[str, float] | None = None,
@@ -2307,16 +2325,22 @@ class Model:
2307
2325
  time=time,
2308
2326
  cache=cache,
2309
2327
  )
2310
- dxdt = pd.Series(np.zeros(len(var_names), dtype=float), index=var_names)
2311
- for k, stoc in cache.stoich_by_cpds.items():
2312
- for flux, n in stoc.items():
2313
- dxdt[k] += n * args[flux]
2328
+ return self._get_right_hand_side(args=args, var_names=var_names, cache=cache)
2314
2329
 
2315
- for k, sd in cache.dyn_stoich_by_cpds.items():
2316
- for flux, dv in sd.items():
2317
- n = dv.fn(*(args[i] for i in dv.args))
2318
- dxdt[k] += n * args[flux]
2319
- return dxdt
2330
+ def get_right_hand_side_time_course(self, args: pd.DataFrame) -> pd.DataFrame:
2331
+ """Calculate the right-hand side of the differential equations for the model."""
2332
+ if (cache := self._cache) is None:
2333
+ cache = self._create_cache()
2334
+ var_names = self.get_variable_names()
2335
+
2336
+ rhs_by_time = {}
2337
+ for time, variables in args.iterrows():
2338
+ rhs_by_time[time] = self._get_right_hand_side(
2339
+ args=variables.to_dict(),
2340
+ var_names=var_names,
2341
+ cache=cache,
2342
+ )
2343
+ return pd.DataFrame(rhs_by_time).T
2320
2344
 
2321
2345
  ##########################################################################
2322
2346
  # Check units
mxlpy/types.py CHANGED
@@ -798,6 +798,177 @@ class Result:
798
798
  """
799
799
  return pd.concat((self.variables, self.fluxes), axis=1)
800
800
 
801
+ @overload
802
+ def get_right_hand_side( # type: ignore
803
+ self,
804
+ *,
805
+ normalise: float | ArrayLike | None = None,
806
+ concatenated: Literal[False],
807
+ ) -> list[pd.DataFrame]: ...
808
+
809
+ @overload
810
+ def get_right_hand_side(
811
+ self,
812
+ *,
813
+ normalise: float | ArrayLike | None = None,
814
+ concatenated: Literal[True],
815
+ ) -> pd.DataFrame: ...
816
+
817
+ @overload
818
+ def get_right_hand_side(
819
+ self,
820
+ *,
821
+ normalise: float | ArrayLike | None = None,
822
+ concatenated: bool = True,
823
+ ) -> pd.DataFrame: ...
824
+
825
+ def get_right_hand_side(
826
+ self,
827
+ *,
828
+ normalise: float | ArrayLike | None = None,
829
+ concatenated: bool = True,
830
+ ) -> pd.DataFrame | list[pd.DataFrame]:
831
+ """Get right hand side over time."""
832
+ args_by_simulation = self._compute_args()
833
+ return self._adjust_data(
834
+ [
835
+ self.model.update_parameters(p).get_right_hand_side_time_course(
836
+ args=args
837
+ )
838
+ for args, p in zip(args_by_simulation, self.raw_parameters, strict=True)
839
+ ],
840
+ normalise=normalise,
841
+ concatenated=concatenated,
842
+ )
843
+
844
+ @overload
845
+ def get_producers( # type: ignore
846
+ self,
847
+ variable: str,
848
+ *,
849
+ scaled: bool = False,
850
+ normalise: float | ArrayLike | None = None,
851
+ concatenated: Literal[False],
852
+ ) -> list[pd.DataFrame]: ...
853
+
854
+ @overload
855
+ def get_producers(
856
+ self,
857
+ variable: str,
858
+ *,
859
+ scaled: bool = False,
860
+ normalise: float | ArrayLike | None = None,
861
+ concatenated: Literal[True],
862
+ ) -> pd.DataFrame: ...
863
+
864
+ @overload
865
+ def get_producers(
866
+ self,
867
+ variable: str,
868
+ *,
869
+ scaled: bool = False,
870
+ normalise: float | ArrayLike | None = None,
871
+ concatenated: bool = True,
872
+ ) -> pd.DataFrame: ...
873
+
874
+ def get_producers(
875
+ self,
876
+ variable: str,
877
+ *,
878
+ scaled: bool = False,
879
+ normalise: float | ArrayLike | None = None,
880
+ concatenated: bool = True,
881
+ ) -> pd.DataFrame | list[pd.DataFrame]:
882
+ """Get fluxes of variable with positive stoichiometry."""
883
+ self.model.update_parameters(self.raw_parameters[0])
884
+ names = [
885
+ k
886
+ for k, v in self.model.get_stoichiometries_of_variable(variable).items()
887
+ if v > 0
888
+ ]
889
+
890
+ fluxes: list[pd.DataFrame] = [
891
+ i.loc[:, names]
892
+ for i in self.get_fluxes(normalise=normalise, concatenated=False)
893
+ ]
894
+
895
+ if scaled:
896
+ fluxes = [i.copy() for i in fluxes]
897
+ for v, p in zip(fluxes, self.raw_parameters, strict=True):
898
+ self.model.update_parameters(p)
899
+ stoichs = self.model.get_stoichiometries_of_variable(variable)
900
+ for k in names:
901
+ v.loc[:, k] *= stoichs[k]
902
+
903
+ self.model.update_parameters(self.raw_parameters[-1])
904
+ if concatenated:
905
+ return pd.concat(fluxes, axis=0)
906
+ return fluxes
907
+
908
+ @overload
909
+ def get_consumers( # type: ignore
910
+ self,
911
+ variable: str,
912
+ *,
913
+ scaled: bool = False,
914
+ normalise: float | ArrayLike | None = None,
915
+ concatenated: Literal[False],
916
+ ) -> list[pd.DataFrame]: ...
917
+
918
+ @overload
919
+ def get_consumers(
920
+ self,
921
+ variable: str,
922
+ *,
923
+ scaled: bool = False,
924
+ normalise: float | ArrayLike | None = None,
925
+ concatenated: Literal[True],
926
+ ) -> pd.DataFrame: ...
927
+
928
+ @overload
929
+ def get_consumers(
930
+ self,
931
+ variable: str,
932
+ *,
933
+ scaled: bool = False,
934
+ normalise: float | ArrayLike | None = None,
935
+ concatenated: bool = True,
936
+ ) -> pd.DataFrame: ...
937
+
938
+ def get_consumers(
939
+ self,
940
+ variable: str,
941
+ *,
942
+ scaled: bool = False,
943
+ normalise: float | ArrayLike | None = None,
944
+ concatenated: bool = True,
945
+ ) -> pd.DataFrame | list[pd.DataFrame]:
946
+ """Get fluxes of variable with negative stoichiometry."""
947
+ self.model.update_parameters(self.raw_parameters[0])
948
+ names = [
949
+ k
950
+ for k, v in self.model.get_stoichiometries_of_variable(variable).items()
951
+ if v < 0
952
+ ]
953
+
954
+ fluxes: list[pd.DataFrame] = [
955
+ i.loc[:, names]
956
+ for i in self.get_fluxes(normalise=normalise, concatenated=False)
957
+ ]
958
+
959
+ if scaled:
960
+ fluxes = [i.copy() for i in fluxes]
961
+ for v, p in zip(fluxes, self.raw_parameters, strict=True):
962
+ self.model.update_parameters(p)
963
+ stoichs = self.model.get_stoichiometries_of_variable(variable)
964
+ for k in names:
965
+ v.loc[:, k] *= -stoichs[k]
966
+
967
+ self.model.update_parameters(self.raw_parameters[-1])
968
+ if concatenated:
969
+ return pd.concat(fluxes, axis=0)
970
+ return fluxes
971
+
801
972
  def get_new_y0(self) -> dict[str, float]:
802
973
  """Get the new initial conditions after the simulation.
803
974
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mxlpy
3
- Version: 0.24.0
3
+ Version: 0.25.0
4
4
  Summary: A package to build metabolic models
5
5
  Author-email: Marvin van Aalst <marvin.vanaalst@gmail.com>
6
6
  Maintainer-email: Marvin van Aalst <marvin.vanaalst@gmail.com>
@@ -124,3 +124,10 @@ You have two choices here, using `uv` (pypi-only) or using `pixi` (conda-forge,
124
124
  ## LLMs
125
125
 
126
126
  We support the [llms.txt](https://llmstxt.org/) convention for making documentation available to large language models and the applications that make use of them. It is located at [docs/llms.txt](https://github.com/Computational-Biology-Aachen/MxlPy/tree/main/docs/llms.txt)
127
+
128
+ ## Tool family 🏠
129
+
130
+ `MxlPy` is part of a larger family of tools that are designed with a similar set of abstractions. Check them out!
131
+
132
+ - [MxlBricks](https://github.com/Computational-Biology-Aachen/mxl-bricks) is built on top of `MxlPy` to build mechanistic models composed of pre-defined reactions (bricks)
133
+ - [MxlWeb](https://github.com/Computational-Biology-Aachen/mxl-web) brings simulation of mechanistic models to the browser!
@@ -1,15 +1,14 @@
1
- mxlpy/__init__.py,sha256=MzR_lZLel95RyWISsF16mDLscGoaw79oD976MFo5_TI,4453
1
+ mxlpy/__init__.py,sha256=coeuRJf1axEjUZEgMGLyM2CzroUutoHZfbb5fAO_1II,4544
2
2
  mxlpy/carousel.py,sha256=3M2rqi2bx87y8D-oqEKTKZ6Q_clDQHbdLNdVjLJeO7c,6013
3
3
  mxlpy/compare.py,sha256=rJPOXc-aX6I1EC3ERAAW5Jn04kMwrlqUqdBgbZa6LA4,8098
4
4
  mxlpy/distributions.py,sha256=ce6RTqn19YzMMec-u09fSIUA8A92M6rehCuHuXWcX7A,8734
5
- mxlpy/fit.py,sha256=UTNvbUcL9mg7NuH5qq3syqpXXqynT_lXmKQudxwWcsE,22880
6
5
  mxlpy/fns.py,sha256=NLxYwa3ylS7SkISBjw_TgQSKEm7WnkZF9wPigX_ZCAM,13915
7
- mxlpy/identify.py,sha256=G-Zyr_l-K2mDtIV1xGrQ52QJxoBYqRoNA5RW6GpbNjs,2213
6
+ mxlpy/identify.py,sha256=4odLBh6Jq7_MttQBmrmyqZ6ASVMsVxHsaEqgJz9lTMY,2265
8
7
  mxlpy/label_map.py,sha256=PwYanfg07hC0ayyOOP72RFlCQNvhCTbpOhW6kZZ2GUU,17826
9
8
  mxlpy/linear_label_map.py,sha256=6Ye6IziWGKkYD_5z3FmTVwnJ2T9SvVGN3U4CfXjXseo,10320
10
9
  mxlpy/mc.py,sha256=uMHknTNHmK5b4REM3PtCpCjEr9LoSIBsGsCNU4_yHpg,18639
11
10
  mxlpy/mca.py,sha256=IoOHJbjPnAEDqKk64OjFjgRPX5K_aE9D4RrCJ1xFIkw,9457
12
- mxlpy/model.py,sha256=kjZTQo8yM62JX2GedwTCfxtTQpdprg8vJzgJvp_5XCI,79643
11
+ mxlpy/model.py,sha256=ji5zM9CmNPGMYLMA2mh12DfB3-mSVbkVmZbemcUM6iE,80495
13
12
  mxlpy/parallel.py,sha256=yLQLw5O4vnPVp_Zmtw1UhPWtB3483foimxQB-TwFKPg,5016
14
13
  mxlpy/parameterise.py,sha256=IgbvfEnkmaqVq_5GgFjHqApGUN9CJrsVD3Fr7pg9iFA,758
15
14
  mxlpy/paths.py,sha256=TK2wO4N9lG-UV1JGfeB64q48JVDbwqIUj63rl55MKuQ,1022
@@ -18,10 +17,14 @@ mxlpy/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
18
17
  mxlpy/report.py,sha256=v597yzKecgtoNmlNZ_nVhBCa3czNw0tksOK5mLtAQvE,10631
19
18
  mxlpy/scan.py,sha256=KXFdeWwgUBqJBCiOGDdMAGU5nS3PRVn7Cg0ISpzzK1U,17160
20
19
  mxlpy/simulator.py,sha256=-jsSP1fEnJnHj1hcj37cAPUyyP57mP_ow2cL-xd9iw8,16699
21
- mxlpy/types.py,sha256=Vg3ekCkhbH8HjqdDTA7vaAdFp9Diney3ARZZfbq0MoA,33475
20
+ mxlpy/types.py,sha256=zcbC9XyBd2Vp4UxOr4rI7hznlJPe_iA1XvxFGWNO1y8,38456
22
21
  mxlpy/units.py,sha256=4bKXkCYsONUVWRdzV7aVcWFQSA6sxilebgXXFUEKw_c,2091
23
22
  mxlpy/experimental/__init__.py,sha256=kZTE-92OErpHzNRqmgSQYH4CGXrogGJ5EL35XGZQ81M,206
24
23
  mxlpy/experimental/diff.py,sha256=fmsM53lH86TD2iglQILK-XeZnIAtwHAcGC3Afs8V-tc,9457
24
+ mxlpy/fit/__init__.py,sha256=rvIlXrWzuHfz5xYKpSeZpf7wACvweyBlvl9iE7SZJ3w,121
25
+ mxlpy/fit/common.py,sha256=CQyg39oePkYACwwYxOhG3M8Yw4byf6yvG58i5Tg12XM,7600
26
+ mxlpy/fit/global_.py,sha256=kIKyn1uQKA2Sc_0zLYuDuyo0zjGya6Yg1lPXDMxoZ30,15139
27
+ mxlpy/fit/local_.py,sha256=-KtnIhCh1ytU9zORRKmkJ3bgrSsEceM-JYs5H7CJ_sU,16689
25
28
  mxlpy/integrators/__init__.py,sha256=TKo2dkJqdW3_n7YrmF6k3kEjr8_kr3-7MDaLu-zFWRg,533
26
29
  mxlpy/integrators/int_assimulo.py,sha256=1cvR8cOBdrl_DQs9v0o7wItSG5iyYqwZVh7EO0fg3ro,5021
27
30
  mxlpy/integrators/int_diffrax.py,sha256=q_8NZgIZ6T-SRRcI8kSjEb6l-DbXqPv6rjj9KApkQac,3326
@@ -51,7 +54,7 @@ mxlpy/surrogates/_torch.py,sha256=gU0secuRBYgewhNqZmSo6_Xf804dSzwWwIYmdKA7y60,63
51
54
  mxlpy/symbolic/__init__.py,sha256=_vM5YM5I6OH0QDbFt9uGYKO8Z5Vly0wbGuvUScVrPRU,258
52
55
  mxlpy/symbolic/strikepy.py,sha256=tzo3uvPpXLDex09hWTuitVzuTNwbgl7jWGjD8g6a8iI,20033
53
56
  mxlpy/symbolic/symbolic_model.py,sha256=cKfWoktvFmXjuo8egE7gXKrKBq2iBUiy_BcIKIvvz8A,3026
54
- mxlpy-0.24.0.dist-info/METADATA,sha256=Hqld-ntG-lfZey_b-aHgJo-T8KYylrC-iSf9CxMs-XA,4980
55
- mxlpy-0.24.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
56
- mxlpy-0.24.0.dist-info/licenses/LICENSE,sha256=lHX9Eu70g3Iv1aOxXTWNHa3vq9vaVYSPQx4jOLYmDpw,1096
57
- mxlpy-0.24.0.dist-info/RECORD,,
57
+ mxlpy-0.25.0.dist-info/METADATA,sha256=ENFh6nylpjiupCmhYEhozQCuP1FuyO0vGMegm3VPyvU,5413
58
+ mxlpy-0.25.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
59
+ mxlpy-0.25.0.dist-info/licenses/LICENSE,sha256=lHX9Eu70g3Iv1aOxXTWNHa3vq9vaVYSPQx4jOLYmDpw,1096
60
+ mxlpy-0.25.0.dist-info/RECORD,,
File without changes