-
Notifications
You must be signed in to change notification settings - Fork 54
/
Copy pathaddRxnsGenesMets.m
executable file
·184 lines (169 loc) · 7.21 KB
/
addRxnsGenesMets.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
function model=addRxnsGenesMets(model,sourceModel,rxns,addGene,rxnNote,confidence)
% addRxnsGenesMets
% Copies reactions from a source model to a new model, including
% (new) metabolites and genes
%
% model draft model where reactions should be copied to
% sourceModel model where reactions and metabolites are sourced from
% rxns cell array with reaction IDs (from source model). Can also
% be string if only one reaction is added
% addGene three options:
% false no genes are annotated to the new reactions
% true grRules ared copied from the sourceModel and
% new genes are added when required
% string or cell array
% new grRules are specified as string or cell
% array, and any new genes are added when
% required
% (optional, default false)
% rxnNote cell array with strings explaining why reactions were copied
% to the model, to be included as newModel.rxnNotes. Can also
% be string if same rxnNotes should be added for each new
% reaction, or only one reaction is to be added (optional, default
% 'Added via addRxnsAndMets()')
% confidence integer specifying confidence score for all reactions.
% 4: biochemical data: direct evidence from enzymes
% assays
% 3: genetic data: knockout/-in or overexpression
% analysis
% 2: physiological data: indirect evidence, e.g.
% secretion products or defined medium requirement
% sequence data: genome annotation
% 1: modeling data: required for functional model,
% hypothetical reaction
% 0: no evidence
% following doi:10.1038/nprot.2009.203 (optional, default 0)
%
% newModel an updated model structure
%
% This function only works if the draft model and source model follow
% the same metabolite and compartment naming convention. Metabolites are
% only matched by metaboliteName[compartment]. Useful if one wants to copy
% additional reactions from source to draft after getModelFromHomology was
% used involving the same models.
%
% Usage: newModel=addRxnsGenesMets(model,sourceModel,rxns,addGene,rxnNote,confidence)
if nargin<6
confidence=0;
end
rxns=convertCharArray(rxns);
if nargin<5
rxnNote={'Added via addRxnsGenesMets()'};
else
rxnNote=convertCharArray(rxnNote);
end
if numel(rxnNote)==1 && numel(rxns)>1
rxnNoteArray=cell(1,numel(rxns));
rxnNoteArray(:)=rxnNote;
rxnNote=rxnNoteArray;
end
if nargin<4
addGene=false;
end
% Obtain indexes of reactions in source model
[notNewRxn,oldRxn]=ismember(rxns,model.rxns);
rxns=rxns(~notNewRxn);
if isempty(rxns)
error('All reactions are already in the model.');
elseif ~isempty(notNewRxn)
fprintf('The following reactions were already present in the model and will not be added:\n')
fprintf([strjoin(model.rxns(oldRxn(find(oldRxn))),'\n') '\n'])
end
[~, rxnIdx]=ismember(rxns,sourceModel.rxns); % Get rxnIDs
if any(rxnIdx==0)
dispEM('The following reaction IDs could not be found in the source model:',true,...
rxns(rxnIdx==0));
end
% Add new metabolites
metIdx=find(any(sourceModel.S(:,rxnIdx),2)); % Get metabolite IDs
% Many of the metabolites in are already in the draft model, so only add
% the new metabolites
% Match by metNames[metComps]. First make these structures for each model.
metCompsN =cellstr(num2str(model.metComps));
map=containers.Map(cellstr(num2str(transpose([1:length(model.comps)]))),model.comps);
metCompsN = map.values(metCompsN);
metCompsN = strcat(model.metNames,'[',metCompsN,']');
sourcemetCompsN=cellstr(num2str(sourceModel.metComps));
map=containers.Map(cellstr(num2str(transpose([1:length(sourceModel.comps)]))),sourceModel.comps);
sourcemetCompsN = map.values(sourcemetCompsN);
sourcemetCompsN=strcat(sourceModel.metNames,'[',sourcemetCompsN,']');
newMetCompsN=sourcemetCompsN(metIdx);
notNewMet=newMetCompsN(ismember(newMetCompsN,metCompsN));
if ~isempty(notNewMet)
fprintf('\nThe following metabolites were already present in the model and will not be added:\n')
fprintf([strjoin(transpose(notNewMet),'\n') '\n'])
end
metIdx=metIdx(~ismember(sourcemetCompsN(metIdx),metCompsN));
if ~isempty(metIdx)
fprintf('\nThe following metabolites will be added to the model:\n')
fprintf([strjoin(transpose(sourcemetCompsN(metIdx)),'\n') '\n'])
if isfield(sourceModel,'mets')
metsToAdd.mets=sourceModel.mets(metIdx);
end
if isfield(sourceModel,'metNames')
metsToAdd.metNames=sourceModel.metNames(metIdx);
end
if isfield(sourceModel,'metFormulas')
metsToAdd.metFormulas=sourceModel.metFormulas(metIdx);
end
if isfield(sourceModel,'metCharges')
metsToAdd.metCharges=sourceModel.metCharges(metIdx);
end
if isfield(sourceModel,'metMiriams')
metsToAdd.metMiriams=sourceModel.metMiriams(metIdx);
end
if isfield(sourceModel,'metNotes')
metsToAdd.metNotes=sourceModel.metNotes(metIdx);
end
if isfield(sourceModel,'inchis')
metsToAdd.inchis=sourceModel.inchis(metIdx);
end
if isfield(sourceModel,'metSmiles')
metsToAdd.metSmiles=sourceModel.metSmiles(metIdx);
end
if isfield(sourceModel,'metDeltaG')
metsToAdd.metDeltaG=sourceModel.metDeltaG(metIdx);
end
metsToAdd.compartments=strtrim(cellstr(num2str(sourceModel.metComps(metIdx)))); % Convert from compartment string to compartment number
[~,idx]=ismember(metsToAdd.compartments,strsplit(num2str(1:length(sourceModel.comps)))); % Match compartment number to compartment abbreviation
metsToAdd.compartments=sourceModel.comps(idx); % Fill in compartment abbreviations
model=addMets(model,metsToAdd);
end
fprintf('\nNumber of metabolites added to the model:\n')
fprintf([num2str(numel(metIdx)),'\n'])
% Add new genes
if ~islogical(addGene) | addGene ~= false
if ischar(addGene)
rxnToAdd.grRules={addGene};
elseif iscell(addGene)
rxnToAdd.grRules=addGene(~notNewRxn);
else
rxnToAdd.grRules=sourceModel.grRules(rxnIdx); % Get the relevant grRules
end
end
% Add new reactions
rxnToAdd.equations=constructEquations(sourceModel,rxnIdx);
rxnToAdd.rxnNames=sourceModel.rxnNames(rxnIdx);
rxnToAdd.rxns=sourceModel.rxns(rxnIdx);
rxnToAdd.lb=sourceModel.lb(rxnIdx);
rxnToAdd.ub=sourceModel.ub(rxnIdx);
rxnToAdd.rxnNotes(:)=rxnNote(~notNewRxn);
rxnToAdd.rxnConfidenceScores=NaN(1,numel(rxnToAdd.rxns));
if ~isnumeric(confidence)
EM='confidence score must be numeric';
dispEM(EM, true);
end
rxnToAdd.rxnConfidenceScores(:)=confidence;
if isfield(sourceModel,'rxnDeltaG')
rxnToAdd.rxnDeltaG=sourceModel.rxnDeltaG(rxnIdx);
end
if isfield(sourceModel,'subSystems')
rxnToAdd.subSystems=sourceModel.subSystems(rxnIdx);
end
if isfield(sourceModel,'eccodes')
rxnToAdd.eccodes=sourceModel.eccodes(rxnIdx);
end
model=addRxns(model,rxnToAdd,3,'',false,true);
fprintf('\nNumber of reactions added to the model:\n')
fprintf([num2str(numel(rxnIdx)),'\n'])
end