gsrap 0.8.0__tar.gz → 0.8.1__tar.gz

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.
Files changed (97) hide show
  1. {gsrap-0.8.0 → gsrap-0.8.1}/PKG-INFO +1 -1
  2. {gsrap-0.8.0 → gsrap-0.8.1}/pyproject.toml +1 -1
  3. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/.ipynb_checkpoints/__init__-checkpoint.py +2 -2
  4. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/__init__.py +2 -2
  5. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/commons/.ipynb_checkpoints/medium-checkpoint.py +3 -4
  6. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/commons/medium.py +3 -4
  7. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/mkmodel/.ipynb_checkpoints/mkmodel-checkpoint.py +6 -0
  8. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/mkmodel/mkmodel.py +6 -0
  9. gsrap-0.8.1/src/gsrap/parsedb/.ipynb_checkpoints/cycles-checkpoint.py +128 -0
  10. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/parsedb/.ipynb_checkpoints/introduce-checkpoint.py +1 -9
  11. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/parsedb/.ipynb_checkpoints/manual-checkpoint.py +27 -0
  12. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/parsedb/.ipynb_checkpoints/parsedb-checkpoint.py +5 -0
  13. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/parsedb/.ipynb_checkpoints/repeating-checkpoint.py +9 -0
  14. gsrap-0.8.1/src/gsrap/parsedb/cycles.py +128 -0
  15. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/parsedb/introduce.py +1 -9
  16. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/parsedb/manual.py +27 -0
  17. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/parsedb/parsedb.py +5 -0
  18. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/parsedb/repeating.py +9 -0
  19. {gsrap-0.8.0 → gsrap-0.8.1}/LICENSE.txt +0 -0
  20. {gsrap-0.8.0 → gsrap-0.8.1}/README.md +0 -0
  21. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/assets/.ipynb_checkpoints/PM1-checkpoint.csv +0 -0
  22. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/assets/.ipynb_checkpoints/PM2A-checkpoint.csv +0 -0
  23. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/assets/.ipynb_checkpoints/PM3B-checkpoint.csv +0 -0
  24. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/assets/.ipynb_checkpoints/PM4A-checkpoint.csv +0 -0
  25. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/assets/PM1.csv +0 -0
  26. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/assets/PM2A.csv +0 -0
  27. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/assets/PM3B.csv +0 -0
  28. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/assets/PM4A.csv +0 -0
  29. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/assets/__init__.py +0 -0
  30. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/assets/kegg_compound_to_others.pickle +0 -0
  31. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/assets/kegg_reaction_to_others.pickle +0 -0
  32. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/commons/.ipynb_checkpoints/__init__-checkpoint.py +0 -0
  33. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/commons/.ipynb_checkpoints/biomass-checkpoint.py +0 -0
  34. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/commons/.ipynb_checkpoints/coeffs-checkpoint.py +0 -0
  35. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/commons/.ipynb_checkpoints/downloads-checkpoint.py +0 -0
  36. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/commons/.ipynb_checkpoints/escherutils-checkpoint.py +0 -0
  37. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/commons/.ipynb_checkpoints/excelhub-checkpoint.py +0 -0
  38. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/commons/.ipynb_checkpoints/figures-checkpoint.py +0 -0
  39. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/commons/.ipynb_checkpoints/fluxbal-checkpoint.py +0 -0
  40. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/commons/.ipynb_checkpoints/keggutils-checkpoint.py +0 -0
  41. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/commons/.ipynb_checkpoints/logutils-checkpoint.py +0 -0
  42. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/commons/.ipynb_checkpoints/metrics-checkpoint.py +0 -0
  43. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/commons/.ipynb_checkpoints/sbmlutils-checkpoint.py +0 -0
  44. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/commons/__init__.py +0 -0
  45. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/commons/biomass.py +0 -0
  46. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/commons/coeffs.py +0 -0
  47. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/commons/downloads.py +0 -0
  48. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/commons/escherutils.py +0 -0
  49. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/commons/excelhub.py +0 -0
  50. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/commons/figures.py +0 -0
  51. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/commons/fluxbal.py +0 -0
  52. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/commons/keggutils.py +0 -0
  53. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/commons/logutils.py +0 -0
  54. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/commons/metrics.py +0 -0
  55. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/commons/sbmlutils.py +0 -0
  56. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/getmaps/.ipynb_checkpoints/__init__-checkpoint.py +0 -0
  57. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/getmaps/.ipynb_checkpoints/getmaps-checkpoint.py +0 -0
  58. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/getmaps/.ipynb_checkpoints/kdown-checkpoint.py +0 -0
  59. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/getmaps/__init__.py +0 -0
  60. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/getmaps/getmaps.py +0 -0
  61. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/getmaps/kdown.py +0 -0
  62. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/mkmodel/.ipynb_checkpoints/__init__-checkpoint.py +0 -0
  63. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/mkmodel/.ipynb_checkpoints/biologcuration-checkpoint.py +0 -0
  64. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/mkmodel/.ipynb_checkpoints/gapfill-checkpoint.py +0 -0
  65. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/mkmodel/.ipynb_checkpoints/gapfillutils-checkpoint.py +0 -0
  66. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/mkmodel/.ipynb_checkpoints/polishing-checkpoint.py +0 -0
  67. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/mkmodel/.ipynb_checkpoints/pruner-checkpoint.py +0 -0
  68. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/mkmodel/__init__.py +0 -0
  69. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/mkmodel/biologcuration.py +0 -0
  70. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/mkmodel/gapfill.py +0 -0
  71. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/mkmodel/gapfillutils.py +0 -0
  72. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/mkmodel/polishing.py +0 -0
  73. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/mkmodel/pruner.py +0 -0
  74. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/parsedb/.ipynb_checkpoints/__init__-checkpoint.py +0 -0
  75. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/parsedb/.ipynb_checkpoints/annotation-checkpoint.py +0 -0
  76. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/parsedb/.ipynb_checkpoints/completeness-checkpoint.py +0 -0
  77. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/parsedb/__init__.py +0 -0
  78. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/parsedb/annotation.py +0 -0
  79. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/parsedb/completeness.py +0 -0
  80. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/runsims/.ipynb_checkpoints/__init__-checkpoint.py +0 -0
  81. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/runsims/.ipynb_checkpoints/biosynth-checkpoint.py +0 -0
  82. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/runsims/.ipynb_checkpoints/cnps-checkpoint.py +0 -0
  83. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/runsims/.ipynb_checkpoints/essentialgenes-checkpoint.py +0 -0
  84. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/runsims/.ipynb_checkpoints/growthfactors-checkpoint.py +0 -0
  85. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/runsims/.ipynb_checkpoints/precursors-checkpoint.py +0 -0
  86. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/runsims/.ipynb_checkpoints/runsims-checkpoint.py +0 -0
  87. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/runsims/.ipynb_checkpoints/simplegrowth-checkpoint.py +0 -0
  88. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/runsims/.ipynb_checkpoints/singleomission-checkpoint.py +0 -0
  89. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/runsims/__init__.py +0 -0
  90. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/runsims/biosynth.py +0 -0
  91. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/runsims/cnps.py +0 -0
  92. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/runsims/essentialgenes.py +0 -0
  93. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/runsims/growthfactors.py +0 -0
  94. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/runsims/precursors.py +0 -0
  95. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/runsims/runsims.py +0 -0
  96. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/runsims/simplegrowth.py +0 -0
  97. {gsrap-0.8.0 → gsrap-0.8.1}/src/gsrap/runsims/singleomission.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: gsrap
3
- Version: 0.8.0
3
+ Version: 0.8.1
4
4
  Summary:
5
5
  License: GNU General Public License v3.0
6
6
  Author: Gioele Lazzari
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "gsrap"
3
- version = "0.8.0"
3
+ version = "0.8.1"
4
4
  description = ""
5
5
  authors = ["Gioele Lazzari"]
6
6
  license = "GNU General Public License v3.0"
@@ -72,7 +72,7 @@ def main():
72
72
  parsedb_parser.add_argument("--precursors", action='store_true', help="Verify biosynthesis of biomass precursors and show blocked ones.")
73
73
  parsedb_parser.add_argument("--biosynth", action='store_true', help="Check biosynthesis of all metabolites and detect dead-ends.")
74
74
  parsedb_parser.add_argument("-e", "--eggnog", nargs='+', metavar='', type=str, default='-', help="Path to the optional eggnog-mapper annotation table(s).")
75
- parsedb_parser.add_argument("-k", "--keggorg", metavar='', type=str, default='-', help="A single KEGG Organism code.")
75
+ parsedb_parser.add_argument("-k", "--keggorg", metavar='', type=str, default='-', help="A single KEGG Organism code. If provided, it takes precedence over --eggnog.")
76
76
  parsedb_parser.add_argument("--goodbefore", metavar='', type=str, default='-', help="Syntax is {pure_mid}-{rid1}-{rid2}. From top to bottom, build the universe until reaction {rid1}, transport {rid2} and metabolite {pure_mid} are reached.")
77
77
  parsedb_parser.add_argument("--onlyauthor", metavar='', type=str, default='-', help="Build the universe by parsing contents of the specified author ID only. Contents affected by --goodbefore are parsed anyway.")
78
78
  parsedb_parser.add_argument("--nofigs", action='store_true', help="Do not generate figures.")
@@ -85,7 +85,7 @@ def main():
85
85
  mkmodel_parser.add_argument("-c", "--cores", metavar='', type=int, default=0, help="Number of cores to use (if 0, use all available cores).")
86
86
  mkmodel_parser.add_argument("-o", "--outdir", metavar='', type=str, default='./', help="Main output directory (will be created if not existing).")
87
87
  mkmodel_parser.add_argument("-e", "--eggnog", nargs='+', metavar='', type=str, default='-', help="Path to the eggnog-mapper annotation table(s).")
88
- mkmodel_parser.add_argument("-k", "--keggorg", metavar='', type=str, default='-', help="A single KEGG Organism code.")
88
+ mkmodel_parser.add_argument("-k", "--keggorg", metavar='', type=str, default='-', help="A single KEGG Organism code. If provided, it takes precedence over --eggnog.")
89
89
  mkmodel_parser.add_argument("-u", "--universe", metavar='', type=str, default='-', help="Path to the universe model (SBML format).")
90
90
  mkmodel_parser.add_argument("-i", "--force_inclusion", metavar='', type=str, default='-', help="Force the inclusion of the specified reactions (comma-separated IDs).")
91
91
  mkmodel_parser.add_argument("-f", "--gap_fill", metavar='', type=str, default='-', help="Media to use during gap-filling (comma-separated IDs); if not provided, gap-filling will be skipped.")
@@ -72,7 +72,7 @@ def main():
72
72
  parsedb_parser.add_argument("--precursors", action='store_true', help="Verify biosynthesis of biomass precursors and show blocked ones.")
73
73
  parsedb_parser.add_argument("--biosynth", action='store_true', help="Check biosynthesis of all metabolites and detect dead-ends.")
74
74
  parsedb_parser.add_argument("-e", "--eggnog", nargs='+', metavar='', type=str, default='-', help="Path to the optional eggnog-mapper annotation table(s).")
75
- parsedb_parser.add_argument("-k", "--keggorg", metavar='', type=str, default='-', help="A single KEGG Organism code.")
75
+ parsedb_parser.add_argument("-k", "--keggorg", metavar='', type=str, default='-', help="A single KEGG Organism code. If provided, it takes precedence over --eggnog.")
76
76
  parsedb_parser.add_argument("--goodbefore", metavar='', type=str, default='-', help="Syntax is {pure_mid}-{rid1}-{rid2}. From top to bottom, build the universe until reaction {rid1}, transport {rid2} and metabolite {pure_mid} are reached.")
77
77
  parsedb_parser.add_argument("--onlyauthor", metavar='', type=str, default='-', help="Build the universe by parsing contents of the specified author ID only. Contents affected by --goodbefore are parsed anyway.")
78
78
  parsedb_parser.add_argument("--nofigs", action='store_true', help="Do not generate figures.")
@@ -85,7 +85,7 @@ def main():
85
85
  mkmodel_parser.add_argument("-c", "--cores", metavar='', type=int, default=0, help="Number of cores to use (if 0, use all available cores).")
86
86
  mkmodel_parser.add_argument("-o", "--outdir", metavar='', type=str, default='./', help="Main output directory (will be created if not existing).")
87
87
  mkmodel_parser.add_argument("-e", "--eggnog", nargs='+', metavar='', type=str, default='-', help="Path to the eggnog-mapper annotation table(s).")
88
- mkmodel_parser.add_argument("-k", "--keggorg", metavar='', type=str, default='-', help="A single KEGG Organism code.")
88
+ mkmodel_parser.add_argument("-k", "--keggorg", metavar='', type=str, default='-', help="A single KEGG Organism code. If provided, it takes precedence over --eggnog.")
89
89
  mkmodel_parser.add_argument("-u", "--universe", metavar='', type=str, default='-', help="Path to the universe model (SBML format).")
90
90
  mkmodel_parser.add_argument("-i", "--force_inclusion", metavar='', type=str, default='-', help="Force the inclusion of the specified reactions (comma-separated IDs).")
91
91
  mkmodel_parser.add_argument("-f", "--gap_fill", metavar='', type=str, default='-', help="Media to use during gap-filling (comma-separated IDs); if not provided, gap-filling will be skipped.")
@@ -17,10 +17,9 @@ def apply_medium_given_column(logger, model, medium, column, is_reference=False)
17
17
  column = column.to_dict()
18
18
 
19
19
 
20
- # add trace elements:
21
- column['fe2'] = 'NL'
22
- column['mobd'] = 'NL'
23
- column['cobalt2'] = 'NL'
20
+ # add default elements (acqueous media)
21
+ column['h2o'] = 'NL'
22
+ column['h'] = '-0.0001' # pH=7
24
23
 
25
24
 
26
25
  # reset exchanges
@@ -17,10 +17,9 @@ def apply_medium_given_column(logger, model, medium, column, is_reference=False)
17
17
  column = column.to_dict()
18
18
 
19
19
 
20
- # add trace elements:
21
- column['fe2'] = 'NL'
22
- column['mobd'] = 'NL'
23
- column['cobalt2'] = 'NL'
20
+ # add default elements (acqueous media)
21
+ column['h2o'] = 'NL'
22
+ column['h'] = '-0.0001' # pH=7
24
23
 
25
24
 
26
25
  # reset exchanges
@@ -44,6 +44,9 @@ from ..commons import download_keggorg
44
44
 
45
45
  from ..runsims.biosynth import biosynthesis_on_media
46
46
 
47
+ from ..parsedb.cycles import verify_egc_all
48
+
49
+
47
50
 
48
51
 
49
52
  def create_model_incore(params):
@@ -140,6 +143,9 @@ def create_model_incore(params):
140
143
 
141
144
 
142
145
  ###### CHECKS
146
+ # check erroneous EGCs
147
+ verify_egc_all(logger, model, args.outdir)
148
+
143
149
  # check blocked metabolites / dead-ends
144
150
  df_S = biosynthesis_on_media(logger, model, dbexp, args.gap_fill, args.biosynth)
145
151
  if type(df_S)==int: return 1
@@ -44,6 +44,9 @@ from ..commons import download_keggorg
44
44
 
45
45
  from ..runsims.biosynth import biosynthesis_on_media
46
46
 
47
+ from ..parsedb.cycles import verify_egc_all
48
+
49
+
47
50
 
48
51
 
49
52
  def create_model_incore(params):
@@ -140,6 +143,9 @@ def create_model_incore(params):
140
143
 
141
144
 
142
145
  ###### CHECKS
146
+ # check erroneous EGCs
147
+ verify_egc_all(logger, model, args.outdir)
148
+
143
149
  # check blocked metabolites / dead-ends
144
150
  df_S = biosynthesis_on_media(logger, model, dbexp, args.gap_fill, args.biosynth)
145
151
  if type(df_S)==int: return 1
@@ -0,0 +1,128 @@
1
+ import warnings
2
+ import os
3
+ import logging
4
+
5
+
6
+ import cobra
7
+ import gempipe
8
+
9
+
10
+ from ..commons import fba_no_warnings
11
+ from ..commons import get_optthr
12
+
13
+
14
+
15
+ def verify_egc(logger, model, mid, outdir):
16
+
17
+
18
+ # changes as not permament:
19
+ found_egc = False
20
+ with model:
21
+
22
+ # close (0; 0) all the exchange reactions:
23
+ gempipe.close_boundaries(model)
24
+
25
+
26
+ # create a dissipation reaction:
27
+ dissip = cobra.Reaction(f'__dissip__{mid}')
28
+ model.add_reactions([dissip])
29
+ dissip = model.reactions.get_by_id(f'__dissip__{mid}')
30
+
31
+
32
+ # define the dissipation reaction:
33
+ modeled_mids = [m.id for m in model.metabolites]
34
+ if mid == 'atp':
35
+ dissip_string = 'atp_c + h2o_c --> adp_c + pi_c + h_c'
36
+ elif mid == 'ctp':
37
+ dissip_string = 'ctp_c + h2o_c --> cdp_c + pi_c + h_c'
38
+ elif mid == 'gtp':
39
+ dissip_string = 'gtp_c + h2o_c --> gdp_c + pi_c + h_c'
40
+ elif mid == 'utp':
41
+ dissip_string = 'utp_c + h2o_c --> udp_c + pi_c + h_c'
42
+ elif mid == 'itp':
43
+ dissip_string = 'itp_c + h2o_c --> idp_c + pi_c + h_c'
44
+ elif mid == 'nadh':
45
+ dissip_string = 'nadh_c --> nad_c + h_c'
46
+ elif mid == 'nadph':
47
+ dissip_string = 'nadph_c --> nadp_c + h_c'
48
+ elif mid == 'fadh2':
49
+ dissip_string = 'fadh2_c --> fad_c + 2.0 h_c'
50
+ elif mid == 'accoa':
51
+ dissip_string = 'accoa_c + h2o_c --> ac_c + coa_c + h_c'
52
+ elif mid == 'glu__L':
53
+ dissip_string = 'glu__L_c + h2o_c --> akg_c + nh4_c + 2.0 h_c'
54
+ elif mid == 'q8h2':
55
+ dissip_string = 'q8h2_c --> q8_c + 2.0 h_c'
56
+ dissip.build_reaction_from_string(dissip_string)
57
+
58
+
59
+ # set the objective and optimize:
60
+ model.objective = f'__dissip__{mid}'
61
+ res, obj_value, status = fba_no_warnings(model)
62
+
63
+
64
+ # apply the threshold:
65
+ obj_value = res.objective_value
66
+ status = res.status
67
+ if status == 'optimal' and obj_value >= get_optthr():
68
+ found_egc = True
69
+
70
+
71
+ # get suspect !=0 fluxes
72
+ fluxes = res.fluxes
73
+ # get interesting fluxes (get_optthr() tries to take into account the approximation in glpk and cplex solvers)
74
+ fluxes_interesting = fluxes[(fluxes > get_optthr()) | (fluxes < -get_optthr())]
75
+
76
+
77
+ # create a model for escher, remove Rs not beloning to the cycle
78
+ model_copy = model.copy()
79
+ all_rids = [r.id for r in model_copy.reactions]
80
+ to_delete = set(all_rids) - set(fluxes_interesting.index)
81
+
82
+
83
+ # trick to avoid the WARNING "cobra/core/group.py:147: UserWarning: need to pass in a list"
84
+ # triggered when trying to remove reactions that are included in groups.
85
+ with warnings.catch_warnings(): # temporarily suppress warnings for this block
86
+ warnings.simplefilter("ignore") # ignore all warnings
87
+ cobra_logger = logging.getLogger("cobra.util.solver")
88
+ old_level = cobra_logger.level
89
+ cobra_logger.setLevel(logging.ERROR)
90
+
91
+ # triggering code
92
+ model_copy.remove_reactions(to_delete) # should work also with IDs
93
+
94
+ # restore original behaviour:
95
+ cobra_logger.setLevel(old_level)
96
+
97
+
98
+ # save JSON to direct import in Escher:
99
+ outfile = os.path.join(outdir, f'EGC_{mid}.json')
100
+ cobra.io.save_json_model(model_copy, outfile)
101
+
102
+
103
+ # log some messages
104
+ rid_labels = []
105
+ for rid, flux in fluxes_interesting.to_dict().items():
106
+ rid_label = "'" + rid + "'"
107
+ # mark reversible reactions composing the cycle:
108
+ r = model.reactions.get_by_id(rid)
109
+ if r.lower_bound < 0 and r.upper_bound > 0:
110
+ rid_label = rid_label + '(<=>)'
111
+ rid_labels.append(rid_label)
112
+ logger.warning(f"Found erroneous EGC (N={len(model_copy.reactions)}) for '{mid}' (f={obj_value}): [{', '.join(rid_labels)}]. EGC saved to '{outfile}' to be inspected with Escher-FBA.")
113
+
114
+
115
+ return found_egc
116
+
117
+
118
+
119
+ def verify_egc_all(logger, model, outdir='./', mids_to_check=['atp','ctp','gtp','utp','itp','nadh','nadph','fadh2','accoa','glu__L','q8h2']):
120
+
121
+
122
+ all_results = []
123
+ for mid in mids_to_check:
124
+ all_results.append(verify_egc(logger, model, mid, outdir))
125
+ if any(all_results)==False:
126
+ logger.info("Found 0 erroneous energy-generating cycles (EGCs).")
127
+
128
+
@@ -287,15 +287,7 @@ def introduce_transporters(logger, db, model, idcollection_dict, kegg_reaction_t
287
287
  r = model.reactions.get_by_id(f'EX_{mid_e}')
288
288
  r.name = f"Exchange for {model.metabolites.get_by_id(mid_e).name}"
289
289
  r.build_reaction_from_string(f'{mid_e} --> ')
290
- if mid_e in [
291
- # basics:
292
- 'glc__D_e', 'nh4_e', 'pi_e', 'so4_e', 'h2o_e', 'h_e', 'o2_e', 'co2_e',
293
- # metals:
294
- 'cu2_e', 'mobd_e', 'fe2_e', 'cobalt2_e',
295
- ]:
296
- r.bounds = (-1000, 1000)
297
- else:
298
- r.bounds = (0, 1000)
290
+ r.bounds = (0, 1000)
299
291
 
300
292
  # add SBO annotation
301
293
  r.annotation['sbo'] = ['SBO:0000627'] # exchange reaction
@@ -19,6 +19,33 @@ def get_rids_with_mancheck_gpr():
19
19
  return rids_mancheck_gpr
20
20
 
21
21
 
22
+ def get_rids_with_mancheck_balancing():
23
+ rids_mancheck_bal = [ # same reactions involving ATP can be reversible
24
+
25
+ # SECTION "reversible both in KEGG and MetaCyc"
26
+ 'PGK', 'SUCOAS', 'ADK1', 'GK1', 'NNATr', 'CYTK1', 'ACKr',
27
+ 'DGK1', 'PPAKr', 'ATPSr', 'NDPK10',
28
+
29
+ ### SECTION "reversible in KEGG but not in MetaCyc" ###
30
+ 'CYTK2', # clearly reversible in KEGG but not in MetaCyc (RXN-7913)
31
+ 'DADK', # clearly reversible in KEGG but not in MetaCyc (DEOXYADENYLATE-KINASE-RXN)
32
+ 'UMPK', # clearly reversible in KEGG but not in MetaCyc (RXN-12002)
33
+ 'NDPK1', # clearly reversible in KEGG but not in MetaCyc (GDPKIN-RXN)
34
+ 'NDPK2', # clearly reversible in KEGG but not in MetaCyc (UDPKIN-RXN)
35
+ 'NDPK3', # clearly reversible in KEGG but not in MetaCyc (CDPKIN-RXN)
36
+ 'NDPK4', # clearly reversible in KEGG but not in MetaCyc (DTDPKIN-RXN)
37
+ 'NDPK5', # clearly reversible in KEGG but not in MetaCyc (DGDPKIN-RXN)
38
+ 'NDPK6', # clearly reversible in KEGG but not in MetaCyc (DUDPKIN-RXN)
39
+ 'NDPK7', # clearly reversible in KEGG but not in MetaCyc (DCDPKIN-RXN)
40
+ 'NDPK8', # clearly reversible in KEGG but not in MetaCyc (DADPKIN-RXN)
41
+ 'NDPK9', # clearly reversible in KEGG but not in MetaCyc (RXN-14120)
42
+
43
+ ### SECTION "missing reversibility info" ###
44
+ 'LPHERA',
45
+ ]
46
+ return rids_mancheck_bal
47
+
48
+
22
49
 
23
50
  def get_manual_sinks():
24
51
 
@@ -35,6 +35,8 @@ from ..runsims.biosynth import biosynthesis_on_media
35
35
 
36
36
  from ..mkmodel.polishing import remove_disconnected
37
37
 
38
+ from .cycles import verify_egc_all
39
+
38
40
 
39
41
 
40
42
 
@@ -173,6 +175,9 @@ def main(args, logger):
173
175
 
174
176
 
175
177
  ###### CHECKS 2
178
+ # check erroneous EGCs
179
+ verify_egc_all(logger, universe, args.outdir)
180
+
176
181
  # check growth on minmal media
177
182
  df_G = grow_on_media(logger, universe, dbexp, args.media, '-', True)
178
183
  if type(df_G)==int: return 1
@@ -4,6 +4,7 @@ import cobra
4
4
 
5
5
  from .manual import get_deprecated_kos
6
6
  from .manual import get_rids_with_mancheck_gpr
7
+ from .manual import get_rids_with_mancheck_balancing
7
8
 
8
9
 
9
10
 
@@ -138,6 +139,14 @@ def add_reaction(logger, model, rid, row, kr_ids, kegg_reaction_to_others, addty
138
139
  return 1
139
140
 
140
141
 
142
+ # check if reversible and using ATP
143
+ if r.lower_bound < 0 and r.upper_bound > 0:
144
+ for m in r.metabolites:
145
+ if m.id.rsplit('_', 1)[0] == 'atp':
146
+ if rid not in get_rids_with_mancheck_balancing():
147
+ logger.warning(f"Reaction '{rid}' involves ATP and is reversible: are you sure?")
148
+
149
+
141
150
  return 0
142
151
 
143
152
 
@@ -0,0 +1,128 @@
1
+ import warnings
2
+ import os
3
+ import logging
4
+
5
+
6
+ import cobra
7
+ import gempipe
8
+
9
+
10
+ from ..commons import fba_no_warnings
11
+ from ..commons import get_optthr
12
+
13
+
14
+
15
+ def verify_egc(logger, model, mid, outdir):
16
+
17
+
18
+ # changes as not permament:
19
+ found_egc = False
20
+ with model:
21
+
22
+ # close (0; 0) all the exchange reactions:
23
+ gempipe.close_boundaries(model)
24
+
25
+
26
+ # create a dissipation reaction:
27
+ dissip = cobra.Reaction(f'__dissip__{mid}')
28
+ model.add_reactions([dissip])
29
+ dissip = model.reactions.get_by_id(f'__dissip__{mid}')
30
+
31
+
32
+ # define the dissipation reaction:
33
+ modeled_mids = [m.id for m in model.metabolites]
34
+ if mid == 'atp':
35
+ dissip_string = 'atp_c + h2o_c --> adp_c + pi_c + h_c'
36
+ elif mid == 'ctp':
37
+ dissip_string = 'ctp_c + h2o_c --> cdp_c + pi_c + h_c'
38
+ elif mid == 'gtp':
39
+ dissip_string = 'gtp_c + h2o_c --> gdp_c + pi_c + h_c'
40
+ elif mid == 'utp':
41
+ dissip_string = 'utp_c + h2o_c --> udp_c + pi_c + h_c'
42
+ elif mid == 'itp':
43
+ dissip_string = 'itp_c + h2o_c --> idp_c + pi_c + h_c'
44
+ elif mid == 'nadh':
45
+ dissip_string = 'nadh_c --> nad_c + h_c'
46
+ elif mid == 'nadph':
47
+ dissip_string = 'nadph_c --> nadp_c + h_c'
48
+ elif mid == 'fadh2':
49
+ dissip_string = 'fadh2_c --> fad_c + 2.0 h_c'
50
+ elif mid == 'accoa':
51
+ dissip_string = 'accoa_c + h2o_c --> ac_c + coa_c + h_c'
52
+ elif mid == 'glu__L':
53
+ dissip_string = 'glu__L_c + h2o_c --> akg_c + nh4_c + 2.0 h_c'
54
+ elif mid == 'q8h2':
55
+ dissip_string = 'q8h2_c --> q8_c + 2.0 h_c'
56
+ dissip.build_reaction_from_string(dissip_string)
57
+
58
+
59
+ # set the objective and optimize:
60
+ model.objective = f'__dissip__{mid}'
61
+ res, obj_value, status = fba_no_warnings(model)
62
+
63
+
64
+ # apply the threshold:
65
+ obj_value = res.objective_value
66
+ status = res.status
67
+ if status == 'optimal' and obj_value >= get_optthr():
68
+ found_egc = True
69
+
70
+
71
+ # get suspect !=0 fluxes
72
+ fluxes = res.fluxes
73
+ # get interesting fluxes (get_optthr() tries to take into account the approximation in glpk and cplex solvers)
74
+ fluxes_interesting = fluxes[(fluxes > get_optthr()) | (fluxes < -get_optthr())]
75
+
76
+
77
+ # create a model for escher, remove Rs not beloning to the cycle
78
+ model_copy = model.copy()
79
+ all_rids = [r.id for r in model_copy.reactions]
80
+ to_delete = set(all_rids) - set(fluxes_interesting.index)
81
+
82
+
83
+ # trick to avoid the WARNING "cobra/core/group.py:147: UserWarning: need to pass in a list"
84
+ # triggered when trying to remove reactions that are included in groups.
85
+ with warnings.catch_warnings(): # temporarily suppress warnings for this block
86
+ warnings.simplefilter("ignore") # ignore all warnings
87
+ cobra_logger = logging.getLogger("cobra.util.solver")
88
+ old_level = cobra_logger.level
89
+ cobra_logger.setLevel(logging.ERROR)
90
+
91
+ # triggering code
92
+ model_copy.remove_reactions(to_delete) # should work also with IDs
93
+
94
+ # restore original behaviour:
95
+ cobra_logger.setLevel(old_level)
96
+
97
+
98
+ # save JSON to direct import in Escher:
99
+ outfile = os.path.join(outdir, f'EGC_{mid}.json')
100
+ cobra.io.save_json_model(model_copy, outfile)
101
+
102
+
103
+ # log some messages
104
+ rid_labels = []
105
+ for rid, flux in fluxes_interesting.to_dict().items():
106
+ rid_label = "'" + rid + "'"
107
+ # mark reversible reactions composing the cycle:
108
+ r = model.reactions.get_by_id(rid)
109
+ if r.lower_bound < 0 and r.upper_bound > 0:
110
+ rid_label = rid_label + '(<=>)'
111
+ rid_labels.append(rid_label)
112
+ logger.warning(f"Found erroneous EGC (N={len(model_copy.reactions)}) for '{mid}' (f={obj_value}): [{', '.join(rid_labels)}]. EGC saved to '{outfile}' to be inspected with Escher-FBA.")
113
+
114
+
115
+ return found_egc
116
+
117
+
118
+
119
+ def verify_egc_all(logger, model, outdir='./', mids_to_check=['atp','ctp','gtp','utp','itp','nadh','nadph','fadh2','accoa','glu__L','q8h2']):
120
+
121
+
122
+ all_results = []
123
+ for mid in mids_to_check:
124
+ all_results.append(verify_egc(logger, model, mid, outdir))
125
+ if any(all_results)==False:
126
+ logger.info("Found 0 erroneous energy-generating cycles (EGCs).")
127
+
128
+
@@ -287,15 +287,7 @@ def introduce_transporters(logger, db, model, idcollection_dict, kegg_reaction_t
287
287
  r = model.reactions.get_by_id(f'EX_{mid_e}')
288
288
  r.name = f"Exchange for {model.metabolites.get_by_id(mid_e).name}"
289
289
  r.build_reaction_from_string(f'{mid_e} --> ')
290
- if mid_e in [
291
- # basics:
292
- 'glc__D_e', 'nh4_e', 'pi_e', 'so4_e', 'h2o_e', 'h_e', 'o2_e', 'co2_e',
293
- # metals:
294
- 'cu2_e', 'mobd_e', 'fe2_e', 'cobalt2_e',
295
- ]:
296
- r.bounds = (-1000, 1000)
297
- else:
298
- r.bounds = (0, 1000)
290
+ r.bounds = (0, 1000)
299
291
 
300
292
  # add SBO annotation
301
293
  r.annotation['sbo'] = ['SBO:0000627'] # exchange reaction
@@ -19,6 +19,33 @@ def get_rids_with_mancheck_gpr():
19
19
  return rids_mancheck_gpr
20
20
 
21
21
 
22
+ def get_rids_with_mancheck_balancing():
23
+ rids_mancheck_bal = [ # same reactions involving ATP can be reversible
24
+
25
+ # SECTION "reversible both in KEGG and MetaCyc"
26
+ 'PGK', 'SUCOAS', 'ADK1', 'GK1', 'NNATr', 'CYTK1', 'ACKr',
27
+ 'DGK1', 'PPAKr', 'ATPSr', 'NDPK10',
28
+
29
+ ### SECTION "reversible in KEGG but not in MetaCyc" ###
30
+ 'CYTK2', # clearly reversible in KEGG but not in MetaCyc (RXN-7913)
31
+ 'DADK', # clearly reversible in KEGG but not in MetaCyc (DEOXYADENYLATE-KINASE-RXN)
32
+ 'UMPK', # clearly reversible in KEGG but not in MetaCyc (RXN-12002)
33
+ 'NDPK1', # clearly reversible in KEGG but not in MetaCyc (GDPKIN-RXN)
34
+ 'NDPK2', # clearly reversible in KEGG but not in MetaCyc (UDPKIN-RXN)
35
+ 'NDPK3', # clearly reversible in KEGG but not in MetaCyc (CDPKIN-RXN)
36
+ 'NDPK4', # clearly reversible in KEGG but not in MetaCyc (DTDPKIN-RXN)
37
+ 'NDPK5', # clearly reversible in KEGG but not in MetaCyc (DGDPKIN-RXN)
38
+ 'NDPK6', # clearly reversible in KEGG but not in MetaCyc (DUDPKIN-RXN)
39
+ 'NDPK7', # clearly reversible in KEGG but not in MetaCyc (DCDPKIN-RXN)
40
+ 'NDPK8', # clearly reversible in KEGG but not in MetaCyc (DADPKIN-RXN)
41
+ 'NDPK9', # clearly reversible in KEGG but not in MetaCyc (RXN-14120)
42
+
43
+ ### SECTION "missing reversibility info" ###
44
+ 'LPHERA',
45
+ ]
46
+ return rids_mancheck_bal
47
+
48
+
22
49
 
23
50
  def get_manual_sinks():
24
51
 
@@ -35,6 +35,8 @@ from ..runsims.biosynth import biosynthesis_on_media
35
35
 
36
36
  from ..mkmodel.polishing import remove_disconnected
37
37
 
38
+ from .cycles import verify_egc_all
39
+
38
40
 
39
41
 
40
42
 
@@ -173,6 +175,9 @@ def main(args, logger):
173
175
 
174
176
 
175
177
  ###### CHECKS 2
178
+ # check erroneous EGCs
179
+ verify_egc_all(logger, universe, args.outdir)
180
+
176
181
  # check growth on minmal media
177
182
  df_G = grow_on_media(logger, universe, dbexp, args.media, '-', True)
178
183
  if type(df_G)==int: return 1
@@ -4,6 +4,7 @@ import cobra
4
4
 
5
5
  from .manual import get_deprecated_kos
6
6
  from .manual import get_rids_with_mancheck_gpr
7
+ from .manual import get_rids_with_mancheck_balancing
7
8
 
8
9
 
9
10
 
@@ -138,6 +139,14 @@ def add_reaction(logger, model, rid, row, kr_ids, kegg_reaction_to_others, addty
138
139
  return 1
139
140
 
140
141
 
142
+ # check if reversible and using ATP
143
+ if r.lower_bound < 0 and r.upper_bound > 0:
144
+ for m in r.metabolites:
145
+ if m.id.rsplit('_', 1)[0] == 'atp':
146
+ if rid not in get_rids_with_mancheck_balancing():
147
+ logger.warning(f"Reaction '{rid}' involves ATP and is reversible: are you sure?")
148
+
149
+
141
150
  return 0
142
151
 
143
152
 
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes