-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbuildFullModel2.m
285 lines (240 loc) · 12.5 KB
/
buildFullModel2.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
function [outModel] = buildFullModel2(ecModelCorr, fracC, fracF, fracECM, fracGAGsInECM)
% buildFullModel
%
% Generates a combined ec model with tumor cells, fibroblasts, and other cells (immune cells etc).
% The model supports a total tumor biomass objective function which builds
% ECM and tumor cells. The other cell types are assumed to be imported into
% the tumor.
%
% Input:
%
% ecModelCorr Should be an ec model derived from Human-GEM
%
% fracC fracCion of cancer cells in the model
%
% fracF fracCion of fibroblasts in the model. fracCion other cells
% is calculated as 1 - fracC - fracF
%
% fracECM fracCion extracellular matrix in the tumor. The rest is
% cells
%
% fracGAGsInECM fracCion of GAGs in the ECM. The rest is protein.
%
% Output:
%
% outModel The full model
%
%for debugging
%load('C:/Work/MatlabCode/projects/HMASandbox/HMA_Sandbox/Johan/OptimalTMEGrowthStrategy/ecHumanGEM_batch.mat')
%ecModelOrig = ecModel_batch;
%length(getExchangeRxns(ecModelCorr)) %3347
%constructEquations(ecModelCorr, getExchangeRxns(ecModelCorr))
%sum(getMetsInComp(ecModelCorr, 'S'))
%ecModelCorr.metNames(getMetsInComp(ecModelCorr, 'S'))
%ecModelCorr.metComps
%figure out which metabolite is the protein pool, i.e. in the
%'prot_pool_exchange' reaction
%constructEquations(ecModelCorr, ecModelCorr.rxns(length(ecModelCorr.rxns))) %{' => prot_pool[c]'}
%So, this is not an exchange flux from the s compartment, which means we do not need to have any
%special treatment of this when copying the model
%The strategy for creating the three cell types combined model is to
%1. create 3 copies of all metabolites, where the metabolites in the s
%compartment are not copied.
%2. create 3 copies of all reactions, where the exchange reactions are
%excluded
%3. In the matrix, the second copy of the reactions should have the second
%copy of the metabolites. The first and third should be zero, except for
%the [s] metabolites in the first part.
%Identify metabolites to copy
metsToCopy = true(length(ecModelCorr.mets),1);
%identify rxns to copy
rxnsToCopy = true(1,length(ecModelCorr.rxns));
model2 = ecModelCorr;
%generate new compartments
nms = ecModelCorr.comps;
nmsF = strcat('f_', nms);
nmsO = strcat('o_', nms);
model2.comps = [ecModelCorr.comps;nmsF;nmsO];
model2.compNames = [ecModelCorr.compNames;strcat('f_',ecModelCorr.compNames);strcat('o_',ecModelCorr.compNames)];
%extend the metabolites
nms = ecModelCorr.mets(metsToCopy);
nmsF = strcat('f_', nms);
nmsO = strcat('o_', nms);
model2.mets = [ecModelCorr.mets; nmsF; nmsO];
model2.metNames = [ecModelCorr.metNames; ecModelCorr.metNames(metsToCopy); ecModelCorr.metNames(metsToCopy)];
%met compartments
metComps = ecModelCorr.metComps(metsToCopy);
toAdd = length(ecModelCorr.comps);
compsF = metComps + toAdd;
compsO = metComps + toAdd.*2;
%unique(compsF)
%unique(compsO) %looks good
model2.metComps = [ecModelCorr.metComps;compsF;compsO];
%b
model2.b = [ecModelCorr.b;ecModelCorr.b(metsToCopy);ecModelCorr.b(metsToCopy)];
%now, the reactions
nms = ecModelCorr.rxns(rxnsToCopy);
nmsF = strcat('f_', nms);
nmsO = strcat('o_', nms);
model2.rxns = [ecModelCorr.rxns; nmsF; nmsO];
nms = ecModelCorr.rxnNames(rxnsToCopy);
nmsF = strcat('f_', nms);
nmsO = strcat('o_', nms);
model2.rxnNames = [ecModelCorr.rxnNames; nmsF; nmsO];
%lb, ub, rev and c
model2.lb = [ecModelCorr.lb;ecModelCorr.lb(rxnsToCopy);ecModelCorr.lb(rxnsToCopy)];
model2.ub = [ecModelCorr.ub;ecModelCorr.ub(rxnsToCopy);ecModelCorr.ub(rxnsToCopy)];
model2.rev = [ecModelCorr.rev;ecModelCorr.rev(rxnsToCopy);ecModelCorr.rev(rxnsToCopy)];
model2.c = [ecModelCorr.c;ecModelCorr.c(rxnsToCopy);ecModelCorr.c(rxnsToCopy)];
%grRules subSystems and eccodes
model2.grRules = [ecModelCorr.grRules;ecModelCorr.grRules(rxnsToCopy);ecModelCorr.grRules(rxnsToCopy)];
model2.subSystems = [ecModelCorr.subSystems;ecModelCorr.subSystems(rxnsToCopy);ecModelCorr.subSystems(rxnsToCopy)];
model2.eccodes = [ecModelCorr.eccodes;ecModelCorr.eccodes(rxnsToCopy);ecModelCorr.eccodes(rxnsToCopy)];
%rxnGeneMat
model2.rxnGeneMat = [ecModelCorr.rxnGeneMat;ecModelCorr.rxnGeneMat(rxnsToCopy,:);ecModelCorr.rxnGeneMat(rxnsToCopy,:)];
%And now finally the S matrix:
%first just add zeros in both directions
model2.S(length(model2.mets), length(model2.rxns)) = 0;
[nm,nr] = size(ecModelCorr.S);
model2.S(1:nm,1:nr) = ecModelCorr.S;
model2.S((1:nm)+nm,(1:nr)+nr) = ecModelCorr.S;
model2.S((1:nm)+2*nm,(1:nr)+2*nr) = ecModelCorr.S;
%Now, redirect the exchange reactions. The uptake reactions of both f and o
%should take up everything from the S compartment, not from nothing. They
%should also be unconstrained
rxnSelC = 1:nr;
rxnSelF = (1:nr) + nr;
rxnSelO = (1:nr) + nr*2;
metSelC = (1:nm).';
metSelF = (1:nm).' + nm;
metSelO = (1:nm).' + nm*2;
[inExchRxns,inExchRxnsInd] = getExchangeRxns(ecModelCorr, 'in');
%skip protein pool exchange
inExchRxnsInd = inExchRxnsInd(~strcmp(inExchRxns,'prot_pool_exchange'));
%constructEquations(model2,inExchRxns)%looks good
%constructEquations(model2,model2.rxns(inExchRxnsInd + nr))%looks good
model2.S(metSelC, rxnSelF(inExchRxnsInd)) = -ecModelCorr.S(metSelC, rxnSelC(inExchRxnsInd));
model2.S(metSelC, rxnSelO(inExchRxnsInd)) = -ecModelCorr.S(metSelC, rxnSelC(inExchRxnsInd));
%constructEquations(model2,model2.rxns(inExchRxnsInd + nr))%looks good
%constructEquations(model2,model2.rxns(inExchRxnsInd + 2*nr))%looks good
%relax the constraints - the input to the S compartment is constrained
model2.ub(inExchRxnsInd + nr) = Inf;
model2.ub(inExchRxnsInd + 2*nr) = Inf;
%Now redirect the output of the fibroblasts S compartment to the S
%compartment instead of to nothing
[outExchRxns,outExchRxnsInd] = getExchangeRxns(ecModelCorr, 'out');
%constructEquations(ecModelCorr,ecModelCorr.rxns(outExchRxnsInd))%
%constructEquations(model2,model2.rxns(outExchRxnsInd + nr))%
model2.S(metSelC, rxnSelF(outExchRxnsInd)) = -ecModelCorr.S(metSelC, rxnSelC(outExchRxnsInd));
%constructEquations(model2,model2.rxns(outExchRxnsInd + nr))%looks good
%% Now add the specialized objective functions and maintenance
%So, we define a few variables:
%cell type fracCions
%fracC = 0.6; - input param to function
%fracF = 0.2; - input param to function
fracO = 1 - fracC - fracF;
%ECM vs cells fracCion (dry weight)
%fracECM = 0.3; - input param to function
%fracGAGsInECM = 0.2; - input param to function
% We normalize everything around the cancer cells, meaning that we don't
% need to modify the biomass function or the protein pool constraint for
% cancer cells
% This means that the protein pool for fibroblasts should be scaled with
% fracF/fracC and for other cells fracO/fracC
% It also means that the maintenance cost (i.e. lower bound) should be
% scaled with the same constant.
% The ECM function should be scaled to produce the same dryweight biomass as
% the tumor cell biomass function scaled with
% fracECM/((1-fracECM)*fracC)
%Add maintenance
cell_maintenance = 1.833; %mmol ATP per gDW and hour, from "A Systematic Evaluation of Methods for Tailoring Genome-Scale Metabolic Models"
model2.lb(strcmp(model2.rxns,'MAR03964')) = cell_maintenance; %tumor cells
model2.lb(strcmp(model2.rxns,'f_MAR03964')) = cell_maintenance * fracF/fracC; %fibroblasts
model2.lb(strcmp(model2.rxns,'o_MAR03964')) = cell_maintenance * fracO/fracC; %tumor cells
%change protein pool
t_prot_ub = model2.ub(strcmp(model2.rxns,'prot_pool_exchange'));
model2.ub(strcmp(model2.rxns,'f_prot_pool_exchange')) = t_prot_ub * fracF/fracC; %fibroblasts
model2.ub(strcmp(model2.rxns,'o_prot_pool_exchange')) = t_prot_ub * fracO/fracC; %other cells
%Add reactions for ecm
modelBackup = model2;
model2 = modelBackup;
%first ECM_protein_pool_biomass, i.e. the collagen biomass
metsToAdd.mets = {'ECM_protein_pool_biomass', 'ECM_protein_pool_biomass_e'};
metsToAdd.metNames = {'ECM_protein_pool_biomass', 'ECM_protein_pool_biomass'};
metsToAdd.compartments = {'f_c', 'f_e'};
model2 = addMets(model2, metsToAdd, false);
rxnsToAdd.rxns = {'ecm_protein_pool_biomass'};
rxnsToAdd.equations = {'0.0948 L-alanyl-tRNA(ala)[f_c] + 0.0499 L-arginyl-tRNA(arg)[f_c] + 0.0228 L-asparaginyl-tRNA(asn)[f_c] + 0.0405 L-aspartyl-tRNA(asp)[f_c] + 0.0104 L-cysteinyl-tRNA(cys)[f_c] + 0.0304 L-glutaminyl-tRNA(gln)[f_c] + 0.0503 L-glutamyl-tRNA(glu)[f_c] + 0.2710 glycyl-tRNA(gly)[f_c] + 0.0078 L-histidyl-tRNA(his)[f_c] + 0.0187 L-isoleucyl-tRNA(ile)[f_c] + 0.0367 L-leucyl-tRNA(leu)[f_c] + 0.0382 L-lysyl-tRNA(lys)[f_c] + 0.0084 L-methionyl-tRNA(met)[f_c] + 0.0177 L-phenylalanyl-tRNA(phe)[f_c] + 0.1832 L-prolyl-tRNA(pro)[f_c] + 0.0400 L-seryl-tRNA(ser)[f_c] + 0.0307 L-threonyl-tRNA(thr)[f_c] + 0.0040 L-tryptophanyl-tRNA(trp)[f_c] + 0.0098 L-tyrosyl-tRNA(tyr)[f_c] + 0.0348 L-valyl-tRNA(val)[f_c] => ECM_protein_pool_biomass[f_c] + 0.0948 tRNA(ala)[f_c] + 0.0499 tRNA(arg)[f_c] + 0.0228 tRNA(asn)[f_c] + 0.0405 tRNA(asp)[f_c] + 0.0104 tRNA(cys)[f_c] + 0.0304 tRNA(gln)[f_c] + 0.0503 tRNA(glu)[f_c] + 0.2710 tRNA(gly)[f_c] + 0.0078 tRNA(his)[f_c] + 0.0187 tRNA(ile)[f_c] + 0.0367 tRNA(leu)[f_c] + 0.0382 tRNA(lys)[f_c] + 0.0084 tRNA(met)[f_c] + 0.0177 tRNA(phe)[f_c] + 0.1832 tRNA(pro)[f_c] + 0.0400 tRNA(ser)[f_c] + 0.0307 tRNA(thr)[f_c] + 0.0040 tRNA(trp)[f_c] + 0.0098 tRNA(tyr)[f_c] + 0.0348 tRNA(val)[f_c]'};
model2 = addRxns(model2,rxnsToAdd, 3);
%and, export it out
rxnsToAdd.rxns = {'ecm_protein_pool_biomass_transport'};
rxnsToAdd.equations = {'ECM_protein_pool_biomass[f_c] => ECM_protein_pool_biomass[f_e]'};
model2 = addRxns(model2,rxnsToAdd, 3);
%Now the GAGs
%The strategy is to not include the cost for generating the protein
%structures, but only the xylose and attached heparan sulfate.
%The metabolite to produce is heparan sulfate proteoglycan[s]
%We should shut down possible production of this in other cell types, i.e.
%set the flux (ub) from [g] and [o_g] to [e] to zero in t (HMR_7223). Also shut down
%degradation of it in the lysosome (HMR_7224).
%To make this work, we also need to provide protein to attach the GAGs on.
%We don't want to create the proteins, since that is accounted for in the
%ECM_protein_pool_biomass. Instead, we open up an unlimited influx of such
%protein scaffolds, i.e. an exchange reaction of [protein]-L-serine[f_c]
%Also, shut down generation of this protein scaffold in the fibroblasts, to make
%sure it is not used: f_HMR_7197 should have zero flux
%first, shut down heparan sulfate proteoglycan[s] production from other
%cells:
model2.ub(strcmp(model2.rxns,'MAR07223')) = 0;
model2.ub(strcmp(model2.rxns,'o_MAR07223')) = 0;
%and not degraded at all
model2.ub(strcmp(model2.rxns,'MAR07224')) = 0;
model2.ub(strcmp(model2.rxns,'f_MAR07224')) = 0;
model2.ub(strcmp(model2.rxns,'o_MAR07224')) = 0;
%Now, create an exchange reaction for uptake of [protein]-L-serine[f_c]
model2.ub(strcmp(model2.rxns,'f_MAR07197')) = 0; %Make sure protein scaffold is not created inside the cell
%add the protein scaffold in the [e] compartment
metsToAdd.mets = {'gag_scaffold_protein_e'};
metsToAdd.metNames = {'[protein]-L-serine'};
metsToAdd.compartments = {'f_e'};
model2 = addMets(model2, metsToAdd, false);
%and the import reactions
rxnsToAdd.rxns = {'gag_scaffold_protein_import', 'gag_scaffold_protein_exchange'};
rxnsToAdd.equations = {'[protein]-L-serine[f_e] => [protein]-L-serine[f_c]', '=> [protein]-L-serine[f_e]'};
model2 = addRxns(model2,rxnsToAdd, 3);
%Now create an ECM biomass reaction containing both GAGs and protein
protPoolBiomassMW = 94.81;
gagBiomassMW = 3133.44;
protPoolStoichiometry = (1-fracGAGsInECM)/protPoolBiomassMW*1000;
gagStoichiometry = fracGAGsInECM/gagBiomassMW*1000;
metsToAdd.mets = {'ECM_biomass'};
metsToAdd.metNames = {'ECM_biomass'};
metsToAdd.compartments = {'f_e'};
model2 = addMets(model2, metsToAdd, false);
rxn = [num2str(protPoolStoichiometry), ' ECM_protein_pool_biomass[f_e] + ', ...
num2str(gagStoichiometry), ' heparan sulfate proteoglycan[f_e]', ...
' => ECM_biomass[f_e]'];
%rxn = [num2str(protPoolStoichiometry), ' ECM_protein_pool_biomass[e]', ...
% ' => ECM_biomass[e]'];
rxnsToAdd.rxns = {'ECM_biomass'};
rxnsToAdd.equations = {rxn};
model2 = addRxns(model2,rxnsToAdd, 3);
%And finally, the total biomass function
%So, we still strive for that the biomass equation should have the unit
%growth per hour, so the stoichiometric constant for tumor growth should be
%1, while the ECM should be adapted. That should be
%fracECM/((1-fracECM)*fracC)
sc = fracECM/((1-fracECM)*fracC);
rxn = ['biomass[c] + ', ...
num2str(sc), ' ECM_biomass[f_e]', ...
' =>'];
rxnsToAdd.rxns = {'total_biomass'};
rxnsToAdd.equations = {rxn};
model2 = addRxns(model2,rxnsToAdd, 3);
outModel = model2;
%for test:
%ecModelCorr = ltModel;
%fracC = 0.6;
%fracF = 0.2;
%fracECM = 0.2;
%fracGAGsInECM = 0.2;