strainOptimizer 0.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.
Files changed (93) hide show
  1. strainOptimizer/__init__.py +12 -0
  2. strainOptimizer/analysis/FCC.py +109 -0
  3. strainOptimizer/analysis/__init__.py +4 -0
  4. strainOptimizer/analysis/dataset.py +73 -0
  5. strainOptimizer/analysis/ecGEM_utils.py +47 -0
  6. strainOptimizer/analysis/enzyme_variety_analysis.py +139 -0
  7. strainOptimizer/analysis/etfl_utils.py +54 -0
  8. strainOptimizer/analysis/flux_variety_analysis.py +1 -0
  9. strainOptimizer/analysis/model_process.py +512 -0
  10. strainOptimizer/analysis/network.py +251 -0
  11. strainOptimizer/analysis/optimal_yield.py +37 -0
  12. strainOptimizer/analysis/protein_process.py +737 -0
  13. strainOptimizer/etfl/__init__.py +0 -0
  14. strainOptimizer/etfl/analysis/__init__.py +0 -0
  15. strainOptimizer/etfl/analysis/dynamic.py +633 -0
  16. strainOptimizer/etfl/analysis/summary.py +103 -0
  17. strainOptimizer/etfl/analysis/utils.py +33 -0
  18. strainOptimizer/etfl/core/__init__.py +3 -0
  19. strainOptimizer/etfl/core/allocation.py +845 -0
  20. strainOptimizer/etfl/core/carbohydrate.py +36 -0
  21. strainOptimizer/etfl/core/dna.py +60 -0
  22. strainOptimizer/etfl/core/enzyme.py +152 -0
  23. strainOptimizer/etfl/core/expression.py +315 -0
  24. strainOptimizer/etfl/core/genes.py +237 -0
  25. strainOptimizer/etfl/core/ion.py +36 -0
  26. strainOptimizer/etfl/core/lipid.py +36 -0
  27. strainOptimizer/etfl/core/macromolecule.py +102 -0
  28. strainOptimizer/etfl/core/memodel.py +2163 -0
  29. strainOptimizer/etfl/core/reactions.py +273 -0
  30. strainOptimizer/etfl/core/rna.py +129 -0
  31. strainOptimizer/etfl/core/thermomemodel.py +112 -0
  32. strainOptimizer/etfl/data/__init__.py +0 -0
  33. strainOptimizer/etfl/data/ecoli.py +1064 -0
  34. strainOptimizer/etfl/data/ecoli_utils.py +65 -0
  35. strainOptimizer/etfl/debugging/__init__.py +1 -0
  36. strainOptimizer/etfl/debugging/debugging.py +400 -0
  37. strainOptimizer/etfl/integration/__init__.py +0 -0
  38. strainOptimizer/etfl/integration/transcriptomics.py +82 -0
  39. strainOptimizer/etfl/io/__init__.py +0 -0
  40. strainOptimizer/etfl/io/dict.py +938 -0
  41. strainOptimizer/etfl/io/json.py +70 -0
  42. strainOptimizer/etfl/optim/__init__.py +0 -0
  43. strainOptimizer/etfl/optim/config.py +87 -0
  44. strainOptimizer/etfl/optim/constraints.py +307 -0
  45. strainOptimizer/etfl/optim/utils.py +500 -0
  46. strainOptimizer/etfl/optim/variables.py +210 -0
  47. strainOptimizer/etfl/tests/__init__.py +0 -0
  48. strainOptimizer/etfl/tests/small_model.py +400 -0
  49. strainOptimizer/etfl/utils/__init__.py +0 -0
  50. strainOptimizer/etfl/utils/parsing.py +115 -0
  51. strainOptimizer/etfl/utils/utils.py +87 -0
  52. strainOptimizer/io.py +68 -0
  53. strainOptimizer/manipulation/__init__.py +0 -0
  54. strainOptimizer/manipulation/constraint/__init__.py +2 -0
  55. strainOptimizer/manipulation/constraint/enzyme.py +129 -0
  56. strainOptimizer/manipulation/constraint/reaction.py +11 -0
  57. strainOptimizer/manipulation/constraint/total_resource_allocation.py +122 -0
  58. strainOptimizer/manipulation/integration/__init__.py +1 -0
  59. strainOptimizer/manipulation/integration/gimme.py +121 -0
  60. strainOptimizer/manipulation/integration/proteome.py +2 -0
  61. strainOptimizer/manipulation/integration/transcriptome.py +46 -0
  62. strainOptimizer/manipulation/mainFunction.py +621 -0
  63. strainOptimizer/manipulation/model_process.py +536 -0
  64. strainOptimizer/manipulation/protein_process.py +737 -0
  65. strainOptimizer/manipulation/variable/__init__.py +6 -0
  66. strainOptimizer/manipulation/variable/enzyme.py +52 -0
  67. strainOptimizer/manipulation/variable/metabolite.py +2 -0
  68. strainOptimizer/manipulation/variable/reaction.py +2 -0
  69. strainOptimizer/simulation/FBA.py +14 -0
  70. strainOptimizer/simulation/MOMA.py +152 -0
  71. strainOptimizer/simulation/MOPA.py +162 -0
  72. strainOptimizer/simulation/TFA.py +123 -0
  73. strainOptimizer/simulation/__init__.py +8 -0
  74. strainOptimizer/simulation/ecYeastFlux.py +434 -0
  75. strainOptimizer/simulation/pFBA.py +32 -0
  76. strainOptimizer/simulation/pprotFBA.py +156 -0
  77. strainOptimizer/simulation/utils.py +42 -0
  78. strainOptimizer/strainDesign/__init__.py +7 -0
  79. strainOptimizer/strainDesign/ecFactory/__init__.py +2 -0
  80. strainOptimizer/strainDesign/ecFactory/ecFactory_other.py +309 -0
  81. strainOptimizer/strainDesign/ecFactory/ecfseof.py +386 -0
  82. strainOptimizer/strainDesign/ecFactory/find_min_sets.py +109 -0
  83. strainOptimizer/strainDesign/ecFactory/run_ecFactory.py +424 -0
  84. strainOptimizer/strainDesign/iBridge/__init__.py +6 -0
  85. strainOptimizer/strainDesign/iBridge/ibridge.py +486 -0
  86. strainOptimizer/strainDesign/workflow_engine.py +396 -0
  87. strainOptimizer/visualization/__init__.py +1 -0
  88. strainOptimizer/visualization/phase_plane.py +85 -0
  89. strainoptimizer-0.1.0.dist-info/METADATA +161 -0
  90. strainoptimizer-0.1.0.dist-info/RECORD +93 -0
  91. strainoptimizer-0.1.0.dist-info/WHEEL +5 -0
  92. strainoptimizer-0.1.0.dist-info/licenses/LICENSE +21 -0
  93. strainoptimizer-0.1.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,12 @@
1
+ # StrainOptimizer package
2
+ from .strainDesign import (
3
+ strainOptimizer_engine,
4
+ WorkflowParameters,
5
+ )
6
+
7
+
8
+ __version__ = "0.1.0"
9
+ __all__ = [
10
+ "strainOptimizer_engine",
11
+ "WorkflowParameters",
12
+ ]
@@ -0,0 +1,109 @@
1
+ from strainOptimizer.simulation import mopa,moma
2
+
3
+ def calculate_FCC_by_abundance(protID,model,productID,c_source='r_1714_REV', c_uptake=10, growthID='r_2111',objective='r_4046',objective_direction='max',delta_conc=1):
4
+ """
5
+ Calculate the flux control coefficient (FCC) for a given product and growth reaction by disturb enzyme abundance.
6
+
7
+ Args:
8
+ model (cobra.Model): The GEM model object.
9
+ c_source (str): The reaction ID of the carbon source uptake reaction. default is 'r_1714_REV' (glucose uptake).
10
+ c_uptake (float): The uptake rate of the carbon source.
11
+ productID (str): The reaction ID of the product output reaction.
12
+ growthID (str): The reaction ID of the growth reaction.
13
+ protID (str): The protein ID to calculate FCC for.
14
+ objective (str): The reaction ID of the objective reaction. default is NGAM (r_4046).
15
+ objective_direction (str): The direction of the objective reaction. 'max' or 'min'. default is 'max'.
16
+
17
+ Returns:
18
+ tuple: FCCg, FCCp
19
+ """
20
+
21
+ # calculate the reference strain by maximizing NGAM
22
+ # ref_growth=0.2
23
+ with model:
24
+ model.reactions.get_by_id(c_source).bounds = (c_uptake, c_uptake) # set uptake rate
25
+ model.objective = growthID
26
+ model.objective_direction='max'
27
+ ref_growth=model.slim_optimize()/4 # set growth rate to 25% of max to allow for production
28
+ model.objective=productID
29
+ model.objective_direction='max'
30
+ max_production=model.slim_optimize()
31
+ ref_production=max_production/4
32
+ model.reactions.get_by_id(productID).bounds = (ref_production, 1000)
33
+ model.reactions.get_by_id(growthID).bounds = (ref_growth, 1000) # set growth reaction bounds
34
+
35
+ model.objective = objective # NGAM maximize as objective
36
+ model.objective_direction=objective_direction
37
+ ref_solution= model.optimize()
38
+
39
+ # calculate FCCg and FCCp
40
+ with model:
41
+ # overexpression for target protein
42
+ ref_conc=ref_solution.fluxes[protID]
43
+ new_conc=ref_conc*(1+delta_conc) # increase protein concentration by delta_conc
44
+ # set the protein concentration
45
+ model.reactions.get_by_id(protID).lower_bound= new_conc
46
+
47
+ solution=mopa(model,reference_solution=ref_solution,linear=True)
48
+ # solution=moma(model,reference_solution=ref_solution,linear=False)
49
+
50
+ new_growth=solution.fluxes[growthID]
51
+ new_production=solution.fluxes[productID]
52
+
53
+ # FCCg
54
+ FCCg= ((new_growth-ref_growth)/ref_growth)/delta_conc
55
+ # calculate FCCp
56
+ FCCp=((new_production-ref_production)/ref_production)/delta_conc
57
+ # print('growth:',new_growth,'vs',ref_growth,'production:',new_production,'vs',ref_production)
58
+
59
+ return FCCg, FCCp
60
+
61
+
62
+ def calculate_FCC_by_kcat(protID,model,productID, c_uptake=10, growthID='r_2111',delta_kcat=1):
63
+ '''
64
+ Calculate the flux control coefficient (FCC) for a given product and growth reaction by disturb enzyme kcat.
65
+ v/kcat<=protein_pool/MW
66
+ v/(kcat*(1+delta_kcat))<=protein_pool/MW
67
+ therefore, disturb kcat could be processed by modify the draw protein reaction coefficient
68
+ v/kcat<=protein_pool*(1+delta_kcat)/MW
69
+ v/kcat<=protein_pool/(MW/(1+delta_kcat))
70
+ MW'=MW/(1+delta_kcat)
71
+
72
+ Args:
73
+ model (cobra.Model): The GEM model object.
74
+ c_uptake (float): The uptake rate of the carbon source.
75
+ productID (str): The reaction ID of the product output reaction.
76
+ growthID (str): The reaction ID of the growth reaction.
77
+ protID (str): The protein ID to calculate FCC for.
78
+ '''
79
+ c_source='r_1714_REV' # glucose uptake reaction
80
+ model.reactions.get_by_id(c_source).bounds = 0, c_uptake # set uptake rate
81
+ with model:
82
+ model.objective=productID
83
+ model.objective_direction='max'
84
+ ref_production=model.slim_optimize()
85
+
86
+ model.objective = growthID
87
+ model.objective_direction='max'
88
+ ref_growth=model.slim_optimize()
89
+
90
+ # desturbe kcat
91
+ with model:
92
+ prot_pool=model.metabolites.get_by_id('prot_pool[c]')
93
+ ref_mw=model.reactions.get_by_id(protID).metabolites[prot_pool]
94
+ model.reactions.get_by_id(protID).metabolites[prot_pool]=ref_mw/(1+delta_kcat)
95
+
96
+ model.objective = productID
97
+ model.objective_direction='max'
98
+ new_production=model.slim_optimize()
99
+
100
+ model.objective = growthID
101
+ model.objective_direction='max'
102
+ new_growth=model.slim_optimize()
103
+
104
+ FCCg=((new_growth-ref_growth)/ref_growth)/delta_kcat
105
+ FCCp=((new_production-ref_production)/ref_production)/delta_kcat
106
+
107
+ return FCCg,FCCp
108
+
109
+
@@ -0,0 +1,4 @@
1
+ from .ecGEM_utils import prepare_prot_solution_for_ec, prepare_metabolic_solution_for_ec
2
+ from .etfl_utils import prepare_prot_solution_for_etfl, prepare_metabolic_solution_for_etfl
3
+
4
+
@@ -0,0 +1,73 @@
1
+ # -*- coding: utf-8 -*-
2
+ '''Load standard datasets foe strain design algorithm evaluation
3
+ '''
4
+
5
+ import pandas as pd
6
+ import os
7
+ # get the path of this file
8
+ FILE_PATH = os.path.dirname(os.path.abspath(__file__))
9
+ def load_experiment_targets(product:str, data_dir=FILE_PATH+'/../../../data/experiment_targets'):
10
+ '''Load experiment targets for a specific product
11
+ '''
12
+ available_products = [f.replace('_exp_targets.tsv','') for f in os.listdir(data_dir) if f.endswith('_exp_targets.tsv')]
13
+ if product not in available_products:
14
+ print('Available products:', available_products)
15
+ raise ValueError('The product %s is not available!' % product)
16
+ else:
17
+ df = pd.read_csv(os.path.join(data_dir, product+'_exp_targets.tsv'), sep='\t', index_col=0)
18
+ return df
19
+
20
+
21
+ def calculate_exp_consistency(predict_result, exp_data, show=True, merge_ko_kd=False):
22
+ '''
23
+ Calculate the experimental consistency of the prediction results by comparing the predicted gene targets with the experimental gene targets.
24
+
25
+ Args:
26
+ merge_ko_kd: if True, treat KO and KD as one down-regulation category ('KD') before comparison.
27
+ '''
28
+ predict_result = predict_result[predict_result['action'].isin(['OE', 'KD', 'KO'])].copy()
29
+ exp_data = exp_data.copy()
30
+
31
+ if merge_ko_kd:
32
+ predict_result['action'] = predict_result['action'].replace('KO', 'KD')
33
+ exp_data['action'] = exp_data['action'].replace('KO', 'KD')
34
+
35
+ predict_group = predict_result.groupby('action')
36
+ exp_group = exp_data.groupby('action')
37
+ exp_consistency = dict()
38
+ overall_exp_num = 0
39
+ overall_hit_num = 0
40
+ overall_predict_num = 0
41
+ for key in exp_group.groups.keys():
42
+ exp_geneList = exp_group.get_group(key).index.tolist()
43
+ try:
44
+ predict_geneList = predict_group.get_group(key).index.tolist()
45
+ except:
46
+ predict_geneList = []
47
+ hit_geneList = list(set(exp_geneList).intersection(set(predict_geneList)))
48
+ overall_exp_num += len(exp_geneList)
49
+ overall_hit_num += len(hit_geneList)
50
+ overall_predict_num += len(predict_geneList)
51
+ exp_consistency[key] = {'exp': exp_geneList, 'predict': predict_geneList, 'hit': hit_geneList,
52
+ 'exp_num': len(exp_geneList), 'hit_num': len(hit_geneList),
53
+ 'consistency': len(set(exp_geneList).intersection(set(hit_geneList))) / len(
54
+ exp_geneList)}
55
+ if overall_predict_num==0:
56
+ return None
57
+ exp_consistency['overall'] = {'exp_num': overall_exp_num, 'hit_num': overall_hit_num,
58
+ 'predict_num': overall_predict_num,
59
+ 'consistency': overall_hit_num / overall_exp_num,
60
+ 'precision': overall_hit_num / overall_predict_num}
61
+
62
+ if show==True:
63
+ for key in exp_consistency.keys():
64
+ print(f'{key}:')
65
+ print(exp_consistency[key])
66
+
67
+ return exp_consistency
68
+
69
+
70
+ def gene_id_to_name(geneIDlist,annotation_file=FILE_PATH+'/../../../data/s288c_geneNames.csv'):
71
+ df=pd.read_csv(annotation_file,index_col=0)
72
+ df_geneName=df[df.index.isin(geneIDlist)]['geneName']
73
+ return df_geneName
@@ -0,0 +1,47 @@
1
+ # -*- coding: utf-8 -*-
2
+ # date : 2024/3/20
3
+ # author : wangh
4
+ import pandas as pd
5
+
6
+
7
+ def prepare_prot_solution_for_ec(solution, enzymeIDlist=None):
8
+ '''Extract the protein abundances result from solution for ecGEM model.
9
+ parameters:
10
+ solution: Cobra solution
11
+ enzymeIDlist: a list of enzyme ID(optional)
12
+ return:
13
+ prots_solution: pd.Series, the protein abundances result
14
+ '''
15
+ prots_solution = pd.Series()
16
+
17
+ if enzymeIDlist is None:
18
+ for id in solution.fluxes.index:
19
+ if 'draw_prot_' in id:
20
+ prots_solution[id] = solution.fluxes[id]
21
+
22
+ else:
23
+ for enz in enzymeIDlist:
24
+ prots_solution[enz] = solution.fluxes[enz]
25
+
26
+ return prots_solution
27
+
28
+
29
+ def prepare_metabolic_solution_for_ec(solution, rxnList=None):
30
+ '''Ectract all metabolic fluxes data result from solution for etfl model.
31
+ parameters:
32
+ solution: Cobra solution
33
+ rxnList: a list of reaction ID
34
+ return:
35
+ fluxes: pd.Series, the fluxes data
36
+ '''
37
+ metabolic_solution = pd.Series()
38
+ if rxnList is None:
39
+ for id in solution.fluxes.index:
40
+ if id.startswith('r_'):
41
+ metabolic_solution[id] = solution.fluxes[id]
42
+ else:
43
+ for rxn in rxnList:
44
+ if rxn in solution.fluxes.index:
45
+ metabolic_solution[rxn] = solution.fluxes[rxn]
46
+
47
+ return metabolic_solution
@@ -0,0 +1,139 @@
1
+ # -*- coding: utf-8 -*-
2
+ # date : 2023/3/18
3
+ # author : wangh
4
+ import numpy as np
5
+ import pandas as pd
6
+ from tqdm import tqdm
7
+ from pytfa.analysis.variability import _variability_analysis_element
8
+ from ..etfl.optim.utils import safe_optim
9
+ from cobra.flux_analysis import flux_variability_analysis
10
+ from strainOptimizer.manipulation.constraint.enzyme import saturate_enzymes
11
+
12
+
13
+ def etfl_EVA(model,target_id,enzymeIDlist,c_source,c_uptake,fraction_of_optimum=0.99,obj_direction='max'):
14
+ '''do enzyme variety analysis for ETFL model
15
+ para:
16
+ model: ETFL model
17
+ enzymeIDlist: a list of enzyme ID
18
+ fraction_of_optimum: Requires that the objective value is at least the
19
+ fraction times maximum objective value.Must be <= 1.0. (default 0.95)
20
+ return:
21
+ a dataframe of FVA result
22
+ '''
23
+ with model:
24
+ # fix substrate uptake
25
+ model.reactions.get_by_id(c_source).bounds = -c_uptake, -c_uptake
26
+
27
+ # 1.Optimize a given objective
28
+ model.objective = target_id
29
+ model.objective_direction = obj_direction
30
+ sol = safe_optim(model)
31
+ obj_value = sol.objective_value
32
+
33
+ # 1.5 saturate the model
34
+ all_rxnList = [reaction for reaction in model.reactions if type(reaction).__name__ == 'EnzymaticReaction']
35
+ all_rxnList = [reaction for reaction in all_rxnList if reaction.id.startswith('r_')]
36
+ rxnList=[]
37
+ for rxn in all_rxnList:
38
+ for enz in rxn.enzymes:
39
+ if enz.id in enzymeIDlist:
40
+ rxnList.append(rxn)
41
+ break
42
+ # remove duplicated rxns
43
+ rxnlist=list(set(rxnList))
44
+ model=saturate_enzymes(model,rxnList=rxnlist,sol=sol)
45
+
46
+ # 2. get all enzyme variable
47
+ all_enz = model.get_variables_of_type('EnzymeVariable')
48
+ all_enzIDlist = [enz.id for enz in all_enz]
49
+ # get the target enzyme list
50
+ target_enzlist = {}
51
+ for enzID in enzymeIDlist:
52
+ if enzID in all_enzIDlist:
53
+ target_enzlist[enzID] = model.enzymes.get_by_id(enzID).variable
54
+ else:
55
+ print(f"can't find Enzyme {enzID} in the {model.name}")
56
+
57
+ # 3. fix old objective value and add constraint
58
+ if model.solver.objective.direction == "max":
59
+ fva_old_objective = model.problem.Variable(
60
+ "fva_old_objective",
61
+ lb=fraction_of_optimum * obj_value,
62
+ )
63
+ else:
64
+ fva_old_objective = model.problem.Variable(
65
+ "fva_old_objective",
66
+ ub=fraction_of_optimum * obj_value,
67
+ )
68
+ fva_old_obj_constraint = model.problem.Constraint(
69
+ model.solver.objective.expression - fva_old_objective,
70
+ lb=0,
71
+ ub=0,
72
+ name="fva_old_objective_constraint",
73
+ )
74
+ model.add_cons_vars([fva_old_objective, fva_old_obj_constraint])
75
+ # model.repiar()
76
+
77
+ # 5.do enzyme variety analysis
78
+ results = {'min': {}, 'max': {}}
79
+ for sense in ['min', 'max']:
80
+ for k, var in tqdm(target_enzlist.items(), desc=sense + 'imizing'):
81
+ model.logger.debug(sense + '-' + k)
82
+ results[sense][k] = _variability_analysis_element(model, var, sense)
83
+
84
+ # 6.remove fixed constraint and old objective
85
+ model.remove_cons_vars([fva_old_objective, fva_old_obj_constraint])
86
+ # restore old objective
87
+ model.objective = target_id
88
+
89
+ df = pd.DataFrame(results)
90
+ df.rename(columns={'min': 'minimum', 'max': 'maximum'}, inplace=True)
91
+
92
+ return df
93
+
94
+
95
+ def ecGEM_EVA(model,target_id,enzymeIDlist,c_source,c_uptake,fraction_of_optimum=1,obj_direction='max'):
96
+ '''do enzyme variety analysis for ecGEM
97
+ para:
98
+ model: ecGEM model
99
+ enzymeIDlist: a list of enzyme ID
100
+ fraction_of_optimum: Requires that the objective value is at least the
101
+ fraction times maximum objective value.Must be <= 1.0. (default 0.95)
102
+ return:
103
+ a dataframe of FVA result
104
+ '''
105
+ # fix substrate uptake
106
+ model.reactions.get_by_id(c_source).bounds = c_uptake, c_uptake
107
+
108
+ # set the objective function
109
+ model.objective = target_id
110
+ model.objective_direction = obj_direction
111
+
112
+ df_fva_result=flux_variability_analysis(model=model,reaction_list=enzymeIDlist,fraction_of_optimum=fraction_of_optimum)
113
+
114
+ return df_fva_result
115
+
116
+
117
+ def enzymeVA(model,target_id,enzymeIDlist,c_source,c_uptake,fraction_of_optimum=0.99,obj_direction='max',model_type='etfl'):
118
+ '''do enzyme variety analysis for ecGEM/ETFL model
119
+ para:
120
+ model: ecGEM/ETFL model
121
+ target_id: the target reaction ID
122
+ enzymeIDlist: a list of enzyme ID
123
+ c_source: the carbon source ID
124
+ c_uptake: the carbon source uptake rate(default=1 mmol/gDW/h)
125
+ fraction_of_optimum: Requires that the objective value is at least the
126
+ fraction times maximum objective value.Must be <= 1.0. (default 0.99)
127
+ obj_direction: the direction of the objective function(default='max')
128
+ model_type: the type of the model(default='etfl')
129
+
130
+ return:
131
+ a dataframe of FVA result
132
+ '''
133
+
134
+ if model_type=='etfl':
135
+ eva_result= etfl_EVA(model=model,target_id=target_id,enzymeIDlist=enzymeIDlist,c_source=c_source,c_uptake=c_uptake,fraction_of_optimum=fraction_of_optimum,obj_direction=obj_direction)
136
+ elif model_type=='ecGEM':
137
+ eva_result=ecGEM_EVA(model=model,target_id=target_id,enzymeIDlist=enzymeIDlist,c_source=c_source,c_uptake=c_uptake,fraction_of_optimum=fraction_of_optimum,obj_direction=obj_direction)
138
+
139
+ return eva_result
@@ -0,0 +1,54 @@
1
+ # -*- coding: utf-8 -*-
2
+ # date : 2024/3/20
3
+ # author : wangh
4
+ import pandas as pd
5
+
6
+
7
+ def prepare_prot_solution_for_etfl(solution,enzymeIDlist=None):
8
+ '''Extract the protein abundances result from solution for ecGEM model.
9
+ parameters:
10
+ solution: Cobra solution
11
+ enzymeIDlist: a list of enzyme ID(optional)
12
+ return:
13
+ prots_solution: pd.Series, the protein abundances result
14
+ '''
15
+ prots_solution = pd.Series()
16
+
17
+ if enzymeIDlist is None:
18
+ for id in solution.raw.index:
19
+ if id.startswith('EZ_'):
20
+ prots_solution[id]=solution.raw[id]
21
+
22
+ else:
23
+ for enz in enzymeIDlist:
24
+ prots_solution[enz]=solution.raw[enz]
25
+
26
+ return prots_solution
27
+
28
+
29
+ def prepare_metabolic_solution_for_etfl(solution, rxnList=None, flux_tol=1e-6):
30
+ '''Extract metabolic fluxes from an ETFL solution for use as MOMA reference.
31
+
32
+ Only reactions with |flux| > flux_tol are returned. Filtering out near-zero
33
+ fluxes avoids over-constraining the MOMA problem when the perturbed model
34
+ has a slightly different feasible region.
35
+
36
+ parameters:
37
+ solution: pyTFA solution
38
+ rxnList: a list of reaction IDs (None = all r_ reactions)
39
+ flux_tol: minimum absolute flux to include (default 1e-6)
40
+ return:
41
+ fluxes: pd.Series, the fluxes data
42
+ '''
43
+ metabolic_solution = pd.Series(dtype=float)
44
+ if rxnList is None:
45
+ for id in solution.fluxes.index:
46
+ if id.startswith('r_') and abs(solution.fluxes[id]) > flux_tol:
47
+ metabolic_solution[id] = solution.fluxes[id]
48
+ else:
49
+ for rxn in rxnList:
50
+ if rxn in solution.fluxes.index and abs(solution.fluxes[rxn]) > flux_tol:
51
+ metabolic_solution[rxn] = solution.fluxes[rxn]
52
+
53
+ return metabolic_solution
54
+
@@ -0,0 +1 @@
1
+ # -*- coding: utf-8 -*-