seed2lp 2.0.0__py3-none-any.whl → 2.1.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.
- seed2lp/__main__.py +124 -70
- seed2lp/_version.py +1 -1
- seed2lp/argument.py +6 -6
- seed2lp/asp/enum-cc.lp +3 -3
- seed2lp/clingo_lpx.py +14 -6
- seed2lp/description.py +44 -33
- seed2lp/file.py +6 -3
- seed2lp/flux.py +23 -17
- seed2lp/linear.py +37 -36
- seed2lp/log_conf.yaml +4 -4
- seed2lp/logger.py +83 -39
- seed2lp/network.py +55 -68
- seed2lp/reaction.py +4 -2
- seed2lp/reasoning.py +29 -26
- seed2lp/reasoningcom.py +27 -20
- seed2lp/reasoninghybrid.py +30 -25
- seed2lp/sbml.py +4 -2
- seed2lp/scope.py +14 -12
- seed2lp/solver.py +44 -41
- seed2lp/utils.py +7 -3
- seed2lp-2.1.0.dist-info/METADATA +621 -0
- {seed2lp-2.0.0.dist-info → seed2lp-2.1.0.dist-info}/RECORD +28 -28
- {seed2lp-2.0.0.dist-info → seed2lp-2.1.0.dist-info}/WHEEL +1 -1
- tests/normalization.py +8 -8
- tests/utils.py +18 -10
- seed2lp-2.0.0.dist-info/METADATA +0 -404
- {seed2lp-2.0.0.dist-info → seed2lp-2.1.0.dist-info}/entry_points.txt +0 -0
- {seed2lp-2.0.0.dist-info → seed2lp-2.1.0.dist-info}/licenses/LICENCE.txt +0 -0
- {seed2lp-2.0.0.dist-info → seed2lp-2.1.0.dist-info}/top_level.txt +0 -0
seed2lp/scope.py
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import logging
|
|
1
2
|
from .network import Network
|
|
2
3
|
from menetools import run_menescope
|
|
3
4
|
from .file import is_valid_dir, save
|
|
@@ -7,7 +8,7 @@ import libsbml
|
|
|
7
8
|
from padmet.utils.sbmlPlugin import convert_from_coded_id
|
|
8
9
|
from padmet.utils.connection import sbmlGenerator
|
|
9
10
|
import sys
|
|
10
|
-
from . import logger
|
|
11
|
+
#from . import logger
|
|
11
12
|
|
|
12
13
|
|
|
13
14
|
class Scope:
|
|
@@ -23,6 +24,7 @@ class Scope:
|
|
|
23
24
|
self.output_dir = output_dir
|
|
24
25
|
self.dir_seeds_sbml = is_valid_dir(join(output_dir,'sbml'))
|
|
25
26
|
self.dir_scope = is_valid_dir(join(output_dir,'scope'))
|
|
27
|
+
self.logger = logging.getLogger("s2lp")
|
|
26
28
|
|
|
27
29
|
######################## METHODS ########################
|
|
28
30
|
def execute(self):
|
|
@@ -59,12 +61,12 @@ class Scope:
|
|
|
59
61
|
|
|
60
62
|
# Write the seed into sbl format for each solutions
|
|
61
63
|
create_species_sbml(seeds, seeds_sbml_path)
|
|
62
|
-
logger.
|
|
64
|
+
self.logger.info(f"Seeds sbml file created: {seeds_sbml_path}")
|
|
63
65
|
|
|
64
66
|
# Run menescope from seed to get the scope
|
|
65
|
-
logger.
|
|
67
|
+
self.logger.info(f"Scope running for {seeds_sbml_path}...")
|
|
66
68
|
scope_model = run_menescope(self.file, seeds_sbml_path)
|
|
67
|
-
logger.
|
|
69
|
+
self.logger.info(f"Scope terminated.")
|
|
68
70
|
scope_model["size_scope"] = len(scope_model["scope"])
|
|
69
71
|
scope_model["size_all_metabolites"] = len(set_used_metabolites)
|
|
70
72
|
|
|
@@ -73,7 +75,7 @@ class Scope:
|
|
|
73
75
|
print("size of scope", scope_model["size_scope"])
|
|
74
76
|
print("size of all metabolites", scope_model["size_all_metabolites"],"\n\n")
|
|
75
77
|
save(f'{result.name}', scope_dir_path, scope_model, "json")
|
|
76
|
-
logger.
|
|
78
|
+
self.logger.info(f"Scope saved in: {scope_dir_path}/{result.name}.json.")
|
|
77
79
|
|
|
78
80
|
|
|
79
81
|
|
|
@@ -99,26 +101,26 @@ def create_species_sbml(metabolites, outputfile):
|
|
|
99
101
|
sbmlGenerator.check(s, 'create species')
|
|
100
102
|
forbidden_characters_detacted = [char for char in forbidden_charlist if char in compound]
|
|
101
103
|
if len(forbidden_characters_detacted) > 0:
|
|
102
|
-
logger.
|
|
104
|
+
self.logger.warning("Forbidden character ({0}) in {1}. SBML creation will failed.".format(' '.join(forbidden_characters_detacted), compound))
|
|
103
105
|
forbidden_character_in_metabolites = True
|
|
104
106
|
try:
|
|
105
107
|
sbmlGenerator.check(s.setId(compound), 'set species id')
|
|
106
108
|
except:
|
|
107
109
|
issue_trying_to_add_species = True
|
|
108
|
-
logger.
|
|
110
|
+
self.logger.warning("Issue when trying to add compound {0}.".format(compound))
|
|
109
111
|
|
|
110
112
|
if comp is not None:
|
|
111
113
|
sbmlGenerator.check(s.setCompartment(comp), 'set species compartment')
|
|
112
114
|
elif comp is None:
|
|
113
|
-
logger.
|
|
115
|
+
self.logger.warning("No compartment for " + compound)
|
|
114
116
|
|
|
115
117
|
if issue_trying_to_add_species is True and forbidden_character_in_metabolites is True:
|
|
116
|
-
logger.
|
|
117
|
-
logger.
|
|
118
|
+
self.logger.warning("Forbidden character in compound ID, SBML creation will failed.")
|
|
119
|
+
self.logger.warning("Modify the metabolic networks SBMl file by renaming these metabolites and removing the forbidden character.")
|
|
118
120
|
sys.exit(1)
|
|
119
121
|
if issue_trying_to_add_species is True and forbidden_character_in_metabolites is None:
|
|
120
|
-
logger.
|
|
121
|
-
logger.
|
|
122
|
+
self.logger.warning("Issue when trying to add metabolite into SBML file, potential issue with SBML format.")
|
|
123
|
+
self.logger.warning("Modify the metabolic networks SBMl file by renaming these metabolites and removing the forbidden character.")
|
|
122
124
|
sys.exit(1)
|
|
123
125
|
|
|
124
126
|
libsbml.writeSBMLToFile(document, outputfile)
|
seed2lp/solver.py
CHANGED
|
@@ -18,11 +18,12 @@
|
|
|
18
18
|
# - timer_list (dict): List of all timers to find solution
|
|
19
19
|
# - verbose (bool): Set debug mode
|
|
20
20
|
|
|
21
|
+
import logging
|
|
21
22
|
from os import path
|
|
22
23
|
from .network import Network
|
|
23
24
|
from .file import write_instance_file
|
|
24
25
|
from dataclasses import dataclass
|
|
25
|
-
from . import
|
|
26
|
+
from .logger import print_log
|
|
26
27
|
from . import color
|
|
27
28
|
|
|
28
29
|
|
|
@@ -63,7 +64,7 @@ class GROUNDING:
|
|
|
63
64
|
########################## Class Solver ##########################
|
|
64
65
|
###################################################################
|
|
65
66
|
class Solver:
|
|
66
|
-
def __init__(self, run_mode:str, network:Network,
|
|
67
|
+
def __init__(self, run_mode:str, network:Network, log_path:str,
|
|
67
68
|
time_limit_minute:float=None, number_solution:int=None,
|
|
68
69
|
clingo_configuration:str=None, clingo_strategy:str=None,
|
|
69
70
|
intersection:bool=False, union:bool=False,
|
|
@@ -89,11 +90,13 @@ class Solver:
|
|
|
89
90
|
verbose (bool, optional): Set debug mode. Defaults to False.
|
|
90
91
|
"""
|
|
91
92
|
|
|
93
|
+
self.logger = logging.getLogger("s2lp")
|
|
92
94
|
self.is_linear:bool
|
|
93
95
|
self.asp = ASP_CLINGO()
|
|
94
96
|
self.ground = GROUNDING().GROUND
|
|
95
97
|
self.run_mode = run_mode
|
|
96
98
|
self.network = network
|
|
99
|
+
self.log_path = log_path
|
|
97
100
|
self.time_limit_minute = time_limit_minute
|
|
98
101
|
self.set_time_limit()
|
|
99
102
|
self.number_solution = number_solution
|
|
@@ -170,7 +173,7 @@ class Solver:
|
|
|
170
173
|
self.network.instance_file = path.join(self.temp_dir,f'{filename}.lp')
|
|
171
174
|
write_instance_file(self.network.instance_file, self.network.facts)
|
|
172
175
|
self.asp_files.append(self.network.instance_file)
|
|
173
|
-
logger.
|
|
176
|
+
self.logger.info(f"Instance file written: {self.network.instance_file}")
|
|
174
177
|
|
|
175
178
|
|
|
176
179
|
def _set_temp_result_file(self):
|
|
@@ -230,41 +233,41 @@ class Solver:
|
|
|
230
233
|
self.clingo_constant = ['-c']
|
|
231
234
|
match self.run_mode:
|
|
232
235
|
case 'target':
|
|
233
|
-
|
|
236
|
+
print_log(self.logger, "Mode : TARGET", "info")
|
|
234
237
|
if not self.network.targets_as_seeds:
|
|
235
|
-
|
|
236
|
-
|
|
238
|
+
print_log(self.logger, 'Option: TARGETS ARE FORBIDDEN SEEDS', "info", verbose=self.verbose)
|
|
239
|
+
print_log(self.logger, f'Search seeds validating the {len(self.network.targets)} targets…','debug', verbose=self.verbose)
|
|
237
240
|
self.clingo_constant.append('run_mode=target')
|
|
238
241
|
case 'full':
|
|
239
|
-
|
|
240
|
-
|
|
242
|
+
print_log(self.logger, "Mode : FULL NETWORK", "info", verbose=self.verbose)
|
|
243
|
+
print_log(self.logger, "Search seeds validating all metabolites as targets…",'debug', verbose=self.verbose)
|
|
241
244
|
self.clingo_constant.append('run_mode=full')
|
|
242
245
|
case 'fba':
|
|
243
|
-
|
|
246
|
+
print_log(self.logger, "Mode : FBA", "info", verbose=self.verbose)
|
|
244
247
|
if not self.network.targets_as_seeds:
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
+
print_log(self.logger, 'Option: TARGETS ARE FORBIDDEN SEEDS', "info", verbose=self.verbose)
|
|
249
|
+
print_log(self.logger, 'Info: Targets are reactant of objective', "info", verbose=self.verbose)
|
|
250
|
+
print_log(self.logger, "Search seeds aleatory…",'debug')
|
|
248
251
|
self.clingo_constant.append('run_mode=fba')
|
|
249
252
|
case 'community':
|
|
250
253
|
match self.community_mode:
|
|
251
254
|
case "global":
|
|
252
|
-
|
|
255
|
+
print_log(self.logger, "Community Mode : Global Subset Minimal", "info", verbose=self.verbose)
|
|
253
256
|
case "bisteps":
|
|
254
|
-
|
|
257
|
+
print_log(self.logger, "Community Mode : Bisteps Subset Minimal", "info", verbose=self.verbose)
|
|
255
258
|
case "delsupset":
|
|
256
|
-
|
|
259
|
+
print_log(self.logger, "Community Mode : Delete superset of seeds", "info", verbose=self.verbose)
|
|
257
260
|
if not self.network.targets_as_seeds:
|
|
258
|
-
|
|
259
|
-
|
|
261
|
+
print_log(self.logger, 'Option: TARGETS ARE FORBIDDEN SEEDS', "info", verbose=self.verbose)
|
|
262
|
+
print_log(self.logger, f'Search seeds validating the {len(self.network.targets)} targets…','debug', verbose=self.verbose)
|
|
260
263
|
self.clingo_constant.append('run_mode=target')
|
|
261
264
|
|
|
262
265
|
if self.network.accumulation:
|
|
263
|
-
|
|
266
|
+
print_log(self.logger, 'ACCUMULATION: Authorized', "info", verbose=self.verbose)
|
|
264
267
|
self.clingo_constant.append('-c')
|
|
265
268
|
self.clingo_constant.append('accu=1')
|
|
266
269
|
else:
|
|
267
|
-
|
|
270
|
+
print_log(self.logger, 'ACCUMULATION: Forbidden', "info", verbose=self.verbose)
|
|
268
271
|
self.clingo_constant.append('-c')
|
|
269
272
|
self.clingo_constant.append('accu=0')
|
|
270
273
|
|
|
@@ -291,43 +294,43 @@ class Solver:
|
|
|
291
294
|
"""
|
|
292
295
|
match mode:
|
|
293
296
|
case 'subsetmin':
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
297
|
+
print_log(self.logger, "\n____________________________________________","info",color.purple)
|
|
298
|
+
print_log(self.logger, "____________________________________________\n", "info",color.purple)
|
|
299
|
+
print_log(self.logger, f"Sub Mode: {color.bold}SUBSET MINIMAL{color.reset}".center(55), "info")
|
|
300
|
+
print_log(self.logger, "____________________________________________", "info",color.purple)
|
|
301
|
+
print_log(self.logger, "____________________________________________\n", "info",color.purple)
|
|
299
302
|
case "minimize":
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
303
|
+
print_log(self.logger, "\n____________________________________________","info",color.purple)
|
|
304
|
+
print_log(self.logger, "____________________________________________\n", "info",color.purple)
|
|
305
|
+
print_log(self.logger, f"Sub Mode: {color.bold}MINIMIZE{color.reset}".center(55), "info")
|
|
306
|
+
print_log(self.logger, "____________________________________________", "info",color.purple)
|
|
307
|
+
print_log(self.logger, "____________________________________________\n", "info",color.purple)
|
|
305
308
|
case "one solution":
|
|
306
|
-
|
|
309
|
+
print_log(self.logger, f"\n~~~~~~~~~~~~~~~ {color.bold}One solution{color.reset} ~~~~~~~~~~~~~~~", "info")
|
|
307
310
|
case "intersection":
|
|
308
|
-
|
|
311
|
+
print_log(self.logger, f"\n~~~~~~~~~~~~~~~ {color.bold}Intersection{color.reset} ~~~~~~~~~~~~~~~", "info")
|
|
309
312
|
case "enumeration":
|
|
310
|
-
|
|
313
|
+
print_log(self.logger, f"\n~~~~~~~~~~~~~~~~ {color.bold}Enumeration{color.reset} ~~~~~~~~~~~~~~~", "info")
|
|
311
314
|
case "union":
|
|
312
|
-
|
|
315
|
+
print_log(self.logger, f"\n~~~~~~~~~~~~~~~~~~~ {color.bold}Union{color.reset} ~~~~~~~~~~~~~~~~~~", "info")
|
|
313
316
|
case "end":
|
|
314
|
-
|
|
317
|
+
print_log(self.logger, '############################################\n\n', "info", color.cyan_light)
|
|
315
318
|
case "optimum error":
|
|
316
|
-
|
|
317
|
-
|
|
319
|
+
print_log(self.logger, "\n____________________________________________","info")
|
|
320
|
+
print_log(self.logger, 'ABORTED: No objective funcion found \
|
|
318
321
|
\nPlease correct the SBML file to contain either \
|
|
319
322
|
\n - a function with "BIOMASS" (not case sensiive) in the name \
|
|
320
323
|
\n - a function in the objective list', "error")
|
|
321
324
|
case "command":
|
|
322
|
-
|
|
325
|
+
print_log(self.logger, " Command", "debug")
|
|
323
326
|
case "classic":
|
|
324
|
-
|
|
327
|
+
print_log(self.logger, f"\n················ {color.bold}Classic mode{color.reset} ···············", "info")
|
|
325
328
|
case "filter":
|
|
326
|
-
|
|
329
|
+
print_log(self.logger, f"\n················ {color.bold}Filter mode{color.reset} ···············", "info")
|
|
327
330
|
case "guess_check":
|
|
328
|
-
|
|
331
|
+
print_log(self.logger, f"\n·············· {color.bold}Guess-Check mode{color.reset} ············", "info")
|
|
329
332
|
case "guess_check_div":
|
|
330
|
-
|
|
333
|
+
print_log(self.logger, f"\n····· {color.bold}Guess-Check with diversity mode{color.reset} ······", "info")
|
|
331
334
|
|
|
332
335
|
|
|
333
336
|
|
seed2lp/utils.py
CHANGED
|
@@ -3,18 +3,20 @@ import os
|
|
|
3
3
|
import clyngor
|
|
4
4
|
import re
|
|
5
5
|
from re import findall
|
|
6
|
-
from . import logger
|
|
6
|
+
#from . import logger
|
|
7
7
|
from csv import reader
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
def solve(*args, **kwargs):
|
|
11
|
+
logger = logging.getLogger("s2lp")
|
|
12
|
+
|
|
11
13
|
"Wrapper around clyngor.solve"
|
|
12
14
|
kwargs.setdefault('use_clingo_module', False)
|
|
13
15
|
try:
|
|
14
16
|
return clyngor.solve(*args, **kwargs)
|
|
15
17
|
except FileNotFoundError as err:
|
|
16
18
|
if 'clingo' in err.filename:
|
|
17
|
-
logger.
|
|
19
|
+
logger.error('Binary file clingo is not accessible in the PATH.')
|
|
18
20
|
exit(1)
|
|
19
21
|
else: raise err
|
|
20
22
|
|
|
@@ -188,6 +190,8 @@ def repair_json(json_str:str, is_clingo_lpx:bool=False):
|
|
|
188
190
|
Returns:
|
|
189
191
|
str: complete output on json format
|
|
190
192
|
"""
|
|
193
|
+
logger = logging.getLogger("s2lp")
|
|
194
|
+
|
|
191
195
|
close = {'{': '}',
|
|
192
196
|
'[': ']'}
|
|
193
197
|
if is_clingo_lpx:
|
|
@@ -209,7 +213,7 @@ def repair_json(json_str:str, is_clingo_lpx:bool=False):
|
|
|
209
213
|
close_str=""
|
|
210
214
|
for i, open in reversed(list(enumerate(missing_list))):
|
|
211
215
|
close_str += "\n" + i * "\t" + close[open]
|
|
212
|
-
logger.
|
|
216
|
+
logger.warning("Output not totally recovered. Json has been repaired but might miss results")
|
|
213
217
|
return output+close_str
|
|
214
218
|
|
|
215
219
|
def prefix_id_network(is_community:bool, name:str, species:str="", type_element:str=""):
|