From 9d0c48aba80445d6eb139d951601e3a5726a9de0 Mon Sep 17 00:00:00 2001 From: Eduard Kerkhoven Date: Sat, 15 Jul 2023 16:55:52 +0200 Subject: [PATCH] feat: deltaG fields (#500) * feat: I/O YAML of deltaG fields * feat: support rxnDeltaG and metDeltaG fields * fix: rxnDeltaG and metDeltaG fields in csv files --- core/addExchangeRxns.m | 3 + core/addMets.m | 27 + core/addRxns.m | 21 +- core/addRxnsGenesMets.m | 14 +- core/addTransport.m | 3 + core/changeRxns.m | 3 + core/checkModelStruct.m | 45 + core/convertToIrrev.m | 3 + core/expandModel.m | 3 + core/mergeModels.m | 26 + core/permuteModel.m | 6 + core/predictLocalization.m | 9 + core/removeMets.m | 3 + core/removeReactions.m | 3 + core/replaceMets.m | 6 + doc/core/addExchangeRxns.html | 5 +- doc/core/addMets.html | 652 +++++----- doc/core/addRxns.html | 1213 +++++++++--------- doc/core/addRxnsGenesMets.html | 100 +- doc/core/addTransport.html | 9 +- doc/core/changeRxns.html | 31 +- doc/core/checkModelStruct.html | 451 ++++--- doc/core/convertToIrrev.html | 33 +- doc/core/expandModel.html | 137 +- doc/core/mergeModels.html | 788 ++++++------ doc/core/permuteModel.html | 136 +- doc/core/predictLocalization.html | 649 +++++----- doc/core/removeMets.html | 59 +- doc/core/removeReactions.html | 93 +- doc/core/replaceMets.html | 110 +- doc/io/closeModel.html | 27 +- doc/io/readYAMLmodel.html | 1064 +++++++-------- doc/io/writeYAMLmodel.html | 554 ++++---- doc/struct_conversion/ravenCobraWrapper.html | 2 +- io/closeModel.m | 3 + io/readYAMLmodel.m | 32 +- io/writeYAMLmodel.m | 2 + readme/RAVEN_structure_fields.csv | 4 +- struct_conversion/orderRavenFields.csv | 4 + struct_conversion/ravenCobraWrapper.m | 2 +- 40 files changed, 3349 insertions(+), 2986 deletions(-) diff --git a/core/addExchangeRxns.m b/core/addExchangeRxns.m index 660b08bf..dd5a9fb6 100755 --- a/core/addExchangeRxns.m +++ b/core/addExchangeRxns.m @@ -89,4 +89,7 @@ if isfield(model,'rxnConfidenceScores') model.rxnConfidenceScores=[model.rxnConfidenceScores;NaN(numel(J),1)]; end +if isfield(model,'rxnDeltaG') + model.rxnDeltaG=[model.rxnDeltaG;NaN(numel(J),1)]; +end end diff --git a/core/addMets.m b/core/addMets.m index af14b907..09f6ede3 100755 --- a/core/addMets.m +++ b/core/addMets.m @@ -29,6 +29,9 @@ % metMiriams cell array with MIRIAM structures (opt, % default []) % metCharges metabolite charge (opt, default NaN) +% metDeltaG Gibbs free energy of formation at +% biochemical standard condition in kJ/mole +% (opt, default NaN) % metNotes cell array with metabolite notes as strings % (opt, default '') % copyInfo when adding metabolites to a compartment where it previously @@ -261,6 +264,27 @@ end end +if isfield(metsToAdd,'metDeltaG') + if numel(metsToAdd.metDeltaG)~=nMets + EM='metsToAdd.metDeltaG must have the same number of elements as metsToAdd.mets'; + dispEM(EM); + end + if ~isnumeric(metsToAdd.metDeltaG) + EM='metsToAdd.metDeltaG must be of type "double"'; + dispEM(EM); + end + if ~isfield(newModel,'metDeltaG') + newModel.metDeltaG=NaN(numel(largeFiller),1); + end + newModel.metDeltaG=[newModel.metDeltaG;metsToAdd.metDeltaG(:)]; +else + %Add default + if isfield(newModel,'metDeltaG') + newModel.metDeltaG=[newModel.metDeltaG;NaN(numel(filler),1)]; + end +end + + if isfield(metsToAdd,'metNotes') metsToAdd.metNotes=convertCharArray(metsToAdd.metNotes); if numel(metsToAdd.metNotes)==1 && numel(metsToAdd.mets)>1 @@ -345,6 +369,9 @@ if isfield(newModel,'metCharges') newModel.metCharges(I(i))=newModel.metCharges(J(i)); end + if isfield(newModel,'metDeltaG') + newModel.metDeltaG(I(i))=newModel.metDeltaG(J(i)); + end end end end diff --git a/core/addRxns.m b/core/addRxns.m index 776f3a22..6509b454 100755 --- a/core/addRxns.m +++ b/core/addRxns.m @@ -52,6 +52,8 @@ % model.comps) (opt, default {}) % rxnNotes cell array with reaction notes (opt, % default '') +% rxnDeltaG Gibbs free energy at biochemical standard +% condition in kJ/mole (opt, default NaN) % rxnReferences cell array with reaction references (opt, % default '') % rxnConfidenceScores vector with reaction confidence scores @@ -504,8 +506,6 @@ %Fill with standard if it doesn't exist if ~isfield(newModel,'rxnConfidenceScores') newModel.rxnConfidenceScores=NaN(nOldRxns,1); - EM='Adding reactions with confidence scores without such information. All existing reactions will have confidence scores as NaNs'; - dispEM(EM,false); end newModel.rxnConfidenceScores=[newModel.rxnConfidenceScores;rxnsToAdd.rxnConfidenceScores(:)]; else @@ -515,6 +515,23 @@ end end +if isfield(rxnsToAdd,'rxnDeltaG') + if numel(rxnsToAdd.rxnDeltaG)~=nRxns + EM='rxnsToAdd.rxnDeltaG must have the same number of elements as rxnsToAdd.rxns'; + dispEM(EM); + end + %Fill with standard if it doesn't exist + if ~isfield(newModel,'rxnDeltaG') + newModel.rxnDeltaG=NaN(nOldRxns,1); + end + newModel.rxnDeltaG=[newModel.rxnDeltaG;rxnsToAdd.rxnDeltaG(:)]; +else + %Fill with standard if it doesn't exist + if isfield(newModel,'rxnDeltaG') + newModel.rxnDeltaG=[newModel.rxnDeltaG;NaN(nRxns,1)]; + end +end + %***Start parsing the equations and adding the info to the S matrix The %mets are matched to model.mets diff --git a/core/addRxnsGenesMets.m b/core/addRxnsGenesMets.m index 502da7d8..59531762 100755 --- a/core/addRxnsGenesMets.m +++ b/core/addRxnsGenesMets.m @@ -116,14 +116,14 @@ if isfield(sourceModel,'metFormulas') metsToAdd.metFormulas=sourceModel.metFormulas(metIdx); end - if isfield(sourceModel,'metCharge') - metsToAdd.metCharge=sourceModel.metCharge(metIdx); + if isfield(sourceModel,'metCharges') + metsToAdd.metCharges=sourceModel.metCharges(metIdx); end if isfield(sourceModel,'metMiriams') metsToAdd.metMiriams=sourceModel.metMiriams(metIdx); end - if isfield(sourceModel,'metFormulas') - metsToAdd.metFormulas=sourceModel.metFormulas(metIdx); + if isfield(sourceModel,'metNotes') + metsToAdd.metNotes=sourceModel.metNotes(metIdx); end if isfield(sourceModel,'inchis') metsToAdd.inchis=sourceModel.inchis(metIdx); @@ -131,6 +131,9 @@ 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 @@ -164,6 +167,9 @@ 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 diff --git a/core/addTransport.m b/core/addTransport.m index a97aa836..7b2ec403 100755 --- a/core/addTransport.m +++ b/core/addTransport.m @@ -167,6 +167,9 @@ if isfield(model,'rxnConfidenceScores') model.rxnConfidenceScores=[model.rxnConfidenceScores;ones(nRxns,1)]; end + if isfield(model,'rxnDeltaG') + model.rxnDeltaG=[model.rxnDeltaG;zeros(nRxns,1)]; + end addedRxns = [addedRxns; addedRxnsID]; end end diff --git a/core/changeRxns.m b/core/changeRxns.m index aee91e85..21d0be44 100755 --- a/core/changeRxns.m +++ b/core/changeRxns.m @@ -129,6 +129,9 @@ if isfield(model,'rxnConfidenceScores') rxnsToChange.rxnConfidenceScores=model.rxnConfidenceScores(J); end +if isfield(model,'rxnDeltaG') + rxnsToChange.rxnDeltaG=model.rxnDeltaG(J); +end if isfield(model,'pwys') rxnsToChange.pwys=model.pwys(J); end diff --git a/core/checkModelStruct.m b/core/checkModelStruct.m index c958247d..a1a0b2df 100755 --- a/core/checkModelStruct.m +++ b/core/checkModelStruct.m @@ -151,6 +151,12 @@ function checkModelStruct(model,throwErrors,trimWarnings) dispEM(EM,throwErrors); end end +if isfield(model,'metDeltaG') + if ~isnumeric(model.metDeltaG) + EM='The "metDeltaG" field must be a double'; + dispEM(EM,throwErrors); + end +end if isfield(model,'subSystems') for i=1:numel(model.subSystems) if ~iscell(model.subSystems{i,1}) @@ -189,6 +195,12 @@ function checkModelStruct(model,throwErrors,trimWarnings) dispEM(EM,throwErrors); end end +if isfield(model,'rxnDeltaG') + if ~isnumeric(model.rxnDeltaG) + EM='The "rxnDeltaG" field must be a double'; + dispEM(EM,throwErrors); + end +end %Empty strings if isempty(model.id) @@ -363,6 +375,39 @@ function checkModelStruct(model,throwErrors,trimWarnings) EM='The following InChI strings are associated to more than one unique metabolite name:'; dispEM(EM,false,allInchis(hasMultiple),trimWarnings); end + +% %Check if there are metabolites with different names but the same SMILES +% if isfield(model,'metSmiles') +% metSmiles=containers.Map(); +% for i=1:numel(model.mets) +% if ~isempty(model.metSmiles{i}) +% %Get existing metabolite indexes +% if isKey(metSmiles,model.metSmiles{i}) +% existing=metSmiles(model.metSmiles{i}); +% else +% existing=[]; +% end +% metSmiles(model.metSmiles{i})=[existing;i]; +% end +% end +% +% %Get all keys +% allmetSmiles=keys(metSmiles); +% +% hasMultiple=false(numel(metSmiles),1); +% for i=1:numel(metSmiles) +% if numel(metSmiles(metSmiles{i}))>1 +% %Check if they all have the same name +% if numel(unique(model.metNames(metSmiles(allmetSmiles{i}))))>1 +% hasMultiple(i)=true; +% end +% end +% end +% +% %Print output +% EM='The following metSmiles strings are associated to more than one unique metabolite name:'; +% dispEM(EM,false,allmetSmiles(hasMultiple),trimWarnings); +% end end function I=duplicates(strings) diff --git a/core/convertToIrrev.m b/core/convertToIrrev.m index c580a89d..ac4d699d 100755 --- a/core/convertToIrrev.m +++ b/core/convertToIrrev.m @@ -96,6 +96,9 @@ if isfield(irrevModel,'rxnConfidenceScores') irrevModel.rxnConfidenceScores=[irrevModel.rxnConfidenceScores;irrevModel.rxnConfidenceScores(revIndexes)]; end + if isfield(irrevModel,'rxnDeltaG') + irrevModel.rxnDeltaG=[irrevModel.rxnDeltaG;-irrevModel.rxnDeltaG(revIndexes)]; % Invert dG for reversed rxns + end if isfield(irrevModel,'rxnReferences') irrevModel.rxnReferences=[irrevModel.rxnReferences;irrevModel.rxnReferences(revIndexes)]; end diff --git a/core/expandModel.m b/core/expandModel.m index ea4cb45b..f7af4383 100755 --- a/core/expandModel.m +++ b/core/expandModel.m @@ -71,6 +71,9 @@ if isfield(model,'rxnConfidenceScores') model.rxnConfidenceScores=[model.rxnConfidenceScores;model.rxnConfidenceScores(cpyIndices)]; end + if isfield(model,'rxnDeltaG') + model.rxnDeltaG=[model.rxnDeltaG;model.rxnDeltaG(cpyIndices)]; + end %now expand the more complex fields - will be filled in later model.rxns=[model.rxns;cell(toAdd,1)]; diff --git a/core/mergeModels.m b/core/mergeModels.m index 8a219cb0..7fac9d64 100755 --- a/core/mergeModels.m +++ b/core/mergeModels.m @@ -177,6 +177,18 @@ model.rxnConfidenceScores=[model.rxnConfidenceScores;NaN(numel(models{i}.rxns),1)]; end end + + if isfield(models{i},'rxnDeltaG') + if isfield(model,'rxnDeltaG') + model.rxnDeltaG=[model.rxnDeltaG;models{i}.rxnDeltaG]; + else + model.rxnDeltaG=[NaN(numel(model.rxns)-numel(models{i}.rxns),1);models{i}.rxnDeltaG]; + end + else + if isfield(model,'rxnDeltaG') + model.rxnDeltaG=[model.rxnDeltaG;NaN(numel(models{i}.rxns),1)]; + end + end if isfield(models{i},'rxnComps') if isfield(model,'rxnComps') @@ -359,6 +371,20 @@ model.metCharges=[model.metCharges;emptyMetCharge]; end end + + if isfield(models{i},'metDeltaG') + if isfield(model,'metDeltaG') + model.metDeltaG=[model.metDeltaG;models{i}.metDeltaG(metsToAdd)]; + else + emptyMetCharge=nan(numel(model.mets)-numel(metsToAdd),1); + model.metDeltaG=[emptyMetCharge;models{i}.metDeltaG(metsToAdd)]; + end + else + if isfield(model,'metDeltaG') + emptyMetCharge=nan(numel(metsToAdd),1); + model.metDeltaG=[model.metDeltaG;emptyMetCharge]; + end + end if isfield(models{i},'metMiriams') if isfield(model,'metMiriams') diff --git a/core/permuteModel.m b/core/permuteModel.m index 53bd6ded..200bf283 100755 --- a/core/permuteModel.m +++ b/core/permuteModel.m @@ -76,6 +76,9 @@ if isfield(newModel,'rxnConfidenceScores') newModel.rxnConfidenceScores=newModel.rxnConfidenceScores(indexes); end + if isfield(newModel,'rxnDeltaG') + newModel.rxnDeltaG=newModel.rxnDeltaG(indexes); + end case 'mets' if isfield(newModel,'mets') newModel.mets=newModel.mets(indexes); @@ -113,6 +116,9 @@ if isfield(newModel,'metCharges') newModel.metCharges=newModel.metCharges(indexes); end + if isfield(newModel,'metDeltaG') + newModel.metDeltaG=newModel.metDeltaG(indexes); + end case 'genes' if isfield(newModel,'genes') newModel.genes=newModel.genes(indexes); diff --git a/core/predictLocalization.m b/core/predictLocalization.m index 5d0af998..afb5c20e 100755 --- a/core/predictLocalization.m +++ b/core/predictLocalization.m @@ -652,6 +652,9 @@ if isfield(outModel,'rxnConfidenceScores') outModel.rxnConfidenceScores=[outModel.rxnConfidenceScores;outModel.rxnConfidenceScores(nER+1:nER+nRxns)]; end + if isfield(outModel,'rxnDeltaG') + outModel.rxnDeltaG=[outModel.rxnDeltaG;outModel.rxnDeltaG(nER+1:nER+nRxns)]; + end outModel.mets=[outModel.mets;strcat(outModel.mets(nEM+1:nEM+nMets),'_',GSS.compartments{i+1})]; outModel.metNames=[outModel.metNames;outModel.metNames(nEM+1:nEM+nMets)]; outModel.b=[outModel.b;outModel.b(nEM+1:nEM+nMets,:)]; @@ -678,6 +681,9 @@ if isfield(outModel,'metCharges') outModel.metCharges=[outModel.metCharges;outModel.metCharges(nEM+1:nEM+nMets)]; end + if isfield(outModel,'metDeltaG') + outModel.metDeltaG=[outModel.metDeltaG;outModel.metDeltaG(nEM+1:nEM+nMets)]; + end end %Add the transport reactions @@ -725,6 +731,9 @@ if isfield(outModel,'rxnConfidenceScores') outModel.rxnConfidenceScores=[outModel.rxnConfidenceScores;NaN]; end + if isfield(outModel,'rxnDeltaG') + outModel.rxnDeltaG=[outModel.rxnDeltaG;NaN]; + end end %Then remove all reactions and metabolites that aren't used in the final diff --git a/core/removeMets.m b/core/removeMets.m index 01a8469c..9070bbb6 100755 --- a/core/removeMets.m +++ b/core/removeMets.m @@ -92,6 +92,9 @@ if isfield(reducedModel,'metCharges') reducedModel.metCharges(indexesToDelete)=[]; end + if isfield(reducedModel,'metDeltaG') + reducedModel.metDeltaG(indexesToDelete)=[]; + end end %Remove unused reactions diff --git a/core/removeReactions.m b/core/removeReactions.m index 59b6c6e5..2ee81e3c 100755 --- a/core/removeReactions.m +++ b/core/removeReactions.m @@ -93,6 +93,9 @@ if isfield(reducedModel,'rxnConfidenceScores') reducedModel.rxnConfidenceScores(indexesToDelete,:)=[]; end + if isfield(reducedModel,'rxnDeltaG') + reducedModel.rxnDeltaG(indexesToDelete,:)=[]; + end if isfield(reducedModel,'pwys') reducedModel.pwys(indexesToDelete,:)=[]; end diff --git a/core/replaceMets.m b/core/replaceMets.m index 0045f3b3..8a9c9071 100755 --- a/core/replaceMets.m +++ b/core/replaceMets.m @@ -52,6 +52,9 @@ if isfield(model,'metCharges') model.metCharges(metIdx) = model.metCharges(repIdx(1)); end +if isfield(model,'metDeltaG') + model.metDeltaG(metIdx) = model.metDeltaG(repIdx(1)); +end if isfield(model,'inchis') model.inchis(metIdx) = model.inchis(repIdx(1)); end @@ -98,6 +101,9 @@ if isfield(model,'metCharges') model.metCharges(idxDelete) = []; end + if isfield(model,'metDeltaG') + model.metDeltaG(idxDelete) = []; + end if isfield(model,'inchis') model.inchis(idxDelete) = []; end diff --git a/doc/core/addExchangeRxns.html b/doc/core/addExchangeRxns.html index 709cbea7..d8be2c19 100644 --- a/doc/core/addExchangeRxns.html +++ b/doc/core/addExchangeRxns.html @@ -153,7 +153,10 @@

SOURCE CODE ^if isfield(model,'rxnConfidenceScores') 0090 model.rxnConfidenceScores=[model.rxnConfidenceScores;NaN(numel(J),1)]; 0091 end -0092 end +0092 if isfield(model,'rxnDeltaG') +0093 model.rxnDeltaG=[model.rxnDeltaG;NaN(numel(J),1)]; +0094 end +0095 end
Generated by m2html © 2005
\ No newline at end of file diff --git a/doc/core/addMets.html b/doc/core/addMets.html index 7317c03d..f8afb906 100644 --- a/doc/core/addMets.html +++ b/doc/core/addMets.html @@ -57,6 +57,9 @@

DESCRIPTION ^SOURCE CODE ^% metMiriams cell array with MIRIAM structures (opt, 0030 % default []) 0031 % metCharges metabolite charge (opt, default NaN) -0032 % metNotes cell array with metabolite notes as strings -0033 % (opt, default '') -0034 % copyInfo when adding metabolites to a compartment where it previously -0035 % doesn't exist, the function will copy any available annotation -0036 % from the metabolite in another compartment (opt, default true) -0037 % prefix when metsToAdd.mets is not specified, new metabolite IDs -0038 % are generated with the prefix specified here. If IDs with -0039 % the prefix are already used in the model then the -0040 % numbering will start from the highest existing integer+1 -0041 % (opt, default 'm_') -0042 % -0043 % newModel an updated model structure -0044 % -0045 % NOTE: This function does not make extensive checks about MIRIAM formats, -0046 % forbidden characters or such. +0032 % metDeltaG Gibbs free energy of formation at +0033 % biochemical standard condition in kJ/mole +0034 % (opt, default NaN) +0035 % metNotes cell array with metabolite notes as strings +0036 % (opt, default '') +0037 % copyInfo when adding metabolites to a compartment where it previously +0038 % doesn't exist, the function will copy any available annotation +0039 % from the metabolite in another compartment (opt, default true) +0040 % prefix when metsToAdd.mets is not specified, new metabolite IDs +0041 % are generated with the prefix specified here. If IDs with +0042 % the prefix are already used in the model then the +0043 % numbering will start from the highest existing integer+1 +0044 % (opt, default 'm_') +0045 % +0046 % newModel an updated model structure 0047 % -0048 % Example: If multiple metabolites are added at once, the metMiriams cell -0049 % array should be defined as (example with ChEBI and KEGG): +0048 % NOTE: This function does not make extensive checks about MIRIAM formats, +0049 % forbidden characters or such. 0050 % -0051 % metsToAdd.metMiriams{1} = struct('name',{{'chebi';'kegg.compound'}},... -0052 % 'value',{{'CHEBI:18072';'C11821'}}); -0053 % metsToAdd.metMiriams{2} = struct('name',{{'chebi';'kegg.compound'}},... -0054 % 'value',{{'CHEBI:31132';'C12248'}}); -0055 % -0056 % Usage: newModel=addMets(model,metsToAdd,copyInfo,prefix) -0057 -0058 if nargin<3 -0059 copyInfo=true; -0060 end -0061 if nargin<4 -0062 prefix='m_'; -0063 else -0064 prefix=char(prefix); -0065 end -0066 -0067 newModel=model; -0068 -0069 if isempty(metsToAdd) -0070 return; -0071 end -0072 -0073 %Check some stuff regarding the required fields -0074 if ~isfield(metsToAdd,'mets') -0075 metsToAdd.mets=generateNewIds(newModel,'mets',prefix,numel(metsToAdd.metNames)); -0076 else -0077 metsToAdd.mets=convertCharArray(metsToAdd.mets); -0078 end -0079 if ~isfield(metsToAdd,'metNames') -0080 metsToAdd.metNames=metsToAdd.mets; -0081 else -0082 metsToAdd.metNames=convertCharArray(metsToAdd.metNames); -0083 end -0084 if ~isfield(metsToAdd,'compartments') -0085 EM='compartments is a required field in metsToAdd'; -0086 dispEM(EM); -0087 else -0088 metsToAdd.compartments=convertCharArray(metsToAdd.compartments); -0089 %If only one compartment is given, assume it is for all metabolites -0090 if numel(metsToAdd.compartments)==1 && numel(metsToAdd.mets)>1 -0091 temp=cell(numel(metsToAdd.mets),1); -0092 temp(:)=metsToAdd.compartments; -0093 metsToAdd.compartments=temp; -0094 end -0095 end -0096 -0097 %Number of metabolites -0098 nMets=numel(metsToAdd.mets); -0099 nOldMets=numel(model.mets); -0100 filler=cell(nMets,1); -0101 filler(:)={''}; -0102 largeFiller=cell(nOldMets,1); -0103 largeFiller(:)={''}; -0104 -0105 %Check that no metabolite ids are already present in the model -0106 I=ismember(metsToAdd.mets,model.mets); -0107 if any(I) -0108 error('One or more elements in metsToAdd.mets are already present in model.mets: %s',... -0109 strjoin(metsToAdd.mets(I),', ')); -0110 else -0111 newModel.mets=[newModel.mets;metsToAdd.mets(:)]; -0112 end -0113 -0114 %Check that all the compartments could be found -0115 [I, compMap]=ismember(metsToAdd.compartments,model.comps); -0116 if ~all(I) -0117 EM='metsToAdd.compartments must match model.comps'; -0118 dispEM(EM); -0119 end -0120 -0121 %Check that the metabolite names aren't present in the same compartment. -0122 %Not the neatest way maybe.. -0123 t1=strcat(metsToAdd.metNames(:),'***',metsToAdd.compartments(:)); -0124 t2=strcat(model.metNames,'***',model.comps(model.metComps)); -0125 if any(ismember(t1,t2)) -0126 EM='One or more elements in metsToAdd.metNames already exist in the same compartments as the one it is being added to'; -0127 dispEM(EM); -0128 end -0129 -0130 %Some more checks and if they pass then add each field to the structure -0131 if numel(metsToAdd.metNames)~=nMets -0132 EM='metsToAdd.metNames must have the same number of elements as metsToAdd.mets'; -0133 dispEM(EM); -0134 else -0135 newModel.metNames=[newModel.metNames;metsToAdd.metNames(:)]; -0136 end -0137 -0138 if numel(compMap)~=nMets -0139 EM='metsToAdd.compartments must have the same number of elements as metsToAdd.mets'; -0140 dispEM(EM); -0141 else -0142 newModel.metComps=[newModel.metComps;compMap(:)]; -0143 end -0144 -0145 if isfield(metsToAdd,'b') -0146 if size(metsToAdd.b,1)~=nMets -0147 EM='metsToAdd.b must have the same number of elements as metsToAdd.mets'; -0148 dispEM(EM); -0149 else -0150 %Add empty field if it doesn't exist -0151 if ~isfield(newModel,'b') -0152 newModel.b=zeros(nOldMets,1); -0153 end -0154 -0155 %If the original is only one vector -0156 if size(metsToAdd.b,2)>size(newModel.b,2) -0157 newModel.b=[newModel.b newModel.b]; -0158 end -0159 %Add the new ones -0160 newModel.b=[newModel.b;metsToAdd.b]; -0161 end -0162 else -0163 if isfield(newModel,'b') -0164 %Add the default -0165 newModel.b=[newModel.b;zeros(nMets,size(newModel.b,2))]; -0166 end -0167 end -0168 -0169 if isfield(metsToAdd,'unconstrained') -0170 if numel(metsToAdd.unconstrained)~=nMets -0171 EM='metsToAdd.unconstrained must have the same number of elements as metsToAdd.mets'; -0172 dispEM(EM); -0173 else -0174 %Add empty field if it doesn't exist -0175 if ~isfield(newModel,'unconstrained') -0176 newModel.unconstrained=zeros(nOldMets,1); -0177 end -0178 -0179 %Add the new ones -0180 newModel.unconstrained=[newModel.unconstrained;metsToAdd.unconstrained(:)]; -0181 end -0182 else -0183 if isfield(newModel,'unconstrained') -0184 %Add the default -0185 newModel.unconstrained=[newModel.unconstrained;zeros(nMets,1)]; -0186 end -0187 end -0188 -0189 if isfield(metsToAdd,'inchis') -0190 metsToAdd.inchis=convertCharArray(metsToAdd.inchis); -0191 if numel(metsToAdd.inchis)~=nMets -0192 EM='metsToAdd.inchis must have the same number of elements as metsToAdd.mets'; -0193 dispEM(EM); -0194 end -0195 %Add empty field if it doesn't exist -0196 if ~isfield(newModel,'inchis') -0197 newModel.inchis=largeFiller; -0198 end -0199 newModel.inchis=[newModel.inchis;metsToAdd.inchis(:)]; -0200 else -0201 %Add empty strings if structure is in model -0202 if isfield(newModel,'inchis') -0203 newModel.inchis=[newModel.inchis;filler]; -0204 end -0205 end -0206 -0207 -0208 if isfield(metsToAdd,'metSmiles') -0209 metsToAdd.metSmiles=convertCharArray(metsToAdd.metSmiles); -0210 if numel(metsToAdd.metSmiles)~=nMets -0211 EM='metsToAdd.metSmiles must have the same number of elements as metsToAdd.mets'; -0212 dispEM(EM); -0213 end -0214 %Add empty field if it doesn't exist -0215 if ~isfield(newModel,'metSmiles') -0216 newModel.metSmiles=largeFiller; -0217 end -0218 newModel.metSmiles=[newModel.metSmiles;metsToAdd.metSmiles(:)]; -0219 else -0220 %Add empty strings if structure is in model -0221 if isfield(newModel,'metSmiles') -0222 newModel.metSmiles=[newModel.metSmiles;filler]; -0223 end -0224 end -0225 -0226 if isfield(metsToAdd,'metFormulas') -0227 metsToAdd.metFormulas=convertCharArray(metsToAdd.metFormulas); -0228 if numel(metsToAdd.metFormulas)~=nMets -0229 EM='metsToAdd.metFormulas must have the same number of elements as metsToAdd.mets'; -0230 dispEM(EM); -0231 end -0232 %Add empty field if it doesn't exist -0233 if ~isfield(newModel,'metFormulas') -0234 newModel.metFormulas=largeFiller; -0235 end -0236 newModel.metFormulas=[newModel.metFormulas;metsToAdd.metFormulas(:)]; -0237 else -0238 %Add default -0239 if isfield(newModel,'metFormulas') -0240 newModel.metFormulas=[newModel.metFormulas;filler]; -0241 end -0242 end -0243 -0244 if isfield(metsToAdd,'metCharges') -0245 if numel(metsToAdd.metCharges)~=nMets -0246 EM='metsToAdd.metCharges must have the same number of elements as metsToAdd.mets'; -0247 dispEM(EM); -0248 end -0249 if ~isnumeric(metsToAdd.metCharges) -0250 EM='metsToAdd.metCharges must be of type "double"'; -0251 dispEM(EM); -0252 end -0253 if ~isfield(newModel,'metCharges') -0254 newModel.metCharges=NaN(numel(largeFiller),1); +0051 % Example: If multiple metabolites are added at once, the metMiriams cell +0052 % array should be defined as (example with ChEBI and KEGG): +0053 % +0054 % metsToAdd.metMiriams{1} = struct('name',{{'chebi';'kegg.compound'}},... +0055 % 'value',{{'CHEBI:18072';'C11821'}}); +0056 % metsToAdd.metMiriams{2} = struct('name',{{'chebi';'kegg.compound'}},... +0057 % 'value',{{'CHEBI:31132';'C12248'}}); +0058 % +0059 % Usage: newModel=addMets(model,metsToAdd,copyInfo,prefix) +0060 +0061 if nargin<3 +0062 copyInfo=true; +0063 end +0064 if nargin<4 +0065 prefix='m_'; +0066 else +0067 prefix=char(prefix); +0068 end +0069 +0070 newModel=model; +0071 +0072 if isempty(metsToAdd) +0073 return; +0074 end +0075 +0076 %Check some stuff regarding the required fields +0077 if ~isfield(metsToAdd,'mets') +0078 metsToAdd.mets=generateNewIds(newModel,'mets',prefix,numel(metsToAdd.metNames)); +0079 else +0080 metsToAdd.mets=convertCharArray(metsToAdd.mets); +0081 end +0082 if ~isfield(metsToAdd,'metNames') +0083 metsToAdd.metNames=metsToAdd.mets; +0084 else +0085 metsToAdd.metNames=convertCharArray(metsToAdd.metNames); +0086 end +0087 if ~isfield(metsToAdd,'compartments') +0088 EM='compartments is a required field in metsToAdd'; +0089 dispEM(EM); +0090 else +0091 metsToAdd.compartments=convertCharArray(metsToAdd.compartments); +0092 %If only one compartment is given, assume it is for all metabolites +0093 if numel(metsToAdd.compartments)==1 && numel(metsToAdd.mets)>1 +0094 temp=cell(numel(metsToAdd.mets),1); +0095 temp(:)=metsToAdd.compartments; +0096 metsToAdd.compartments=temp; +0097 end +0098 end +0099 +0100 %Number of metabolites +0101 nMets=numel(metsToAdd.mets); +0102 nOldMets=numel(model.mets); +0103 filler=cell(nMets,1); +0104 filler(:)={''}; +0105 largeFiller=cell(nOldMets,1); +0106 largeFiller(:)={''}; +0107 +0108 %Check that no metabolite ids are already present in the model +0109 I=ismember(metsToAdd.mets,model.mets); +0110 if any(I) +0111 error('One or more elements in metsToAdd.mets are already present in model.mets: %s',... +0112 strjoin(metsToAdd.mets(I),', ')); +0113 else +0114 newModel.mets=[newModel.mets;metsToAdd.mets(:)]; +0115 end +0116 +0117 %Check that all the compartments could be found +0118 [I, compMap]=ismember(metsToAdd.compartments,model.comps); +0119 if ~all(I) +0120 EM='metsToAdd.compartments must match model.comps'; +0121 dispEM(EM); +0122 end +0123 +0124 %Check that the metabolite names aren't present in the same compartment. +0125 %Not the neatest way maybe.. +0126 t1=strcat(metsToAdd.metNames(:),'***',metsToAdd.compartments(:)); +0127 t2=strcat(model.metNames,'***',model.comps(model.metComps)); +0128 if any(ismember(t1,t2)) +0129 EM='One or more elements in metsToAdd.metNames already exist in the same compartments as the one it is being added to'; +0130 dispEM(EM); +0131 end +0132 +0133 %Some more checks and if they pass then add each field to the structure +0134 if numel(metsToAdd.metNames)~=nMets +0135 EM='metsToAdd.metNames must have the same number of elements as metsToAdd.mets'; +0136 dispEM(EM); +0137 else +0138 newModel.metNames=[newModel.metNames;metsToAdd.metNames(:)]; +0139 end +0140 +0141 if numel(compMap)~=nMets +0142 EM='metsToAdd.compartments must have the same number of elements as metsToAdd.mets'; +0143 dispEM(EM); +0144 else +0145 newModel.metComps=[newModel.metComps;compMap(:)]; +0146 end +0147 +0148 if isfield(metsToAdd,'b') +0149 if size(metsToAdd.b,1)~=nMets +0150 EM='metsToAdd.b must have the same number of elements as metsToAdd.mets'; +0151 dispEM(EM); +0152 else +0153 %Add empty field if it doesn't exist +0154 if ~isfield(newModel,'b') +0155 newModel.b=zeros(nOldMets,1); +0156 end +0157 +0158 %If the original is only one vector +0159 if size(metsToAdd.b,2)>size(newModel.b,2) +0160 newModel.b=[newModel.b newModel.b]; +0161 end +0162 %Add the new ones +0163 newModel.b=[newModel.b;metsToAdd.b]; +0164 end +0165 else +0166 if isfield(newModel,'b') +0167 %Add the default +0168 newModel.b=[newModel.b;zeros(nMets,size(newModel.b,2))]; +0169 end +0170 end +0171 +0172 if isfield(metsToAdd,'unconstrained') +0173 if numel(metsToAdd.unconstrained)~=nMets +0174 EM='metsToAdd.unconstrained must have the same number of elements as metsToAdd.mets'; +0175 dispEM(EM); +0176 else +0177 %Add empty field if it doesn't exist +0178 if ~isfield(newModel,'unconstrained') +0179 newModel.unconstrained=zeros(nOldMets,1); +0180 end +0181 +0182 %Add the new ones +0183 newModel.unconstrained=[newModel.unconstrained;metsToAdd.unconstrained(:)]; +0184 end +0185 else +0186 if isfield(newModel,'unconstrained') +0187 %Add the default +0188 newModel.unconstrained=[newModel.unconstrained;zeros(nMets,1)]; +0189 end +0190 end +0191 +0192 if isfield(metsToAdd,'inchis') +0193 metsToAdd.inchis=convertCharArray(metsToAdd.inchis); +0194 if numel(metsToAdd.inchis)~=nMets +0195 EM='metsToAdd.inchis must have the same number of elements as metsToAdd.mets'; +0196 dispEM(EM); +0197 end +0198 %Add empty field if it doesn't exist +0199 if ~isfield(newModel,'inchis') +0200 newModel.inchis=largeFiller; +0201 end +0202 newModel.inchis=[newModel.inchis;metsToAdd.inchis(:)]; +0203 else +0204 %Add empty strings if structure is in model +0205 if isfield(newModel,'inchis') +0206 newModel.inchis=[newModel.inchis;filler]; +0207 end +0208 end +0209 +0210 +0211 if isfield(metsToAdd,'metSmiles') +0212 metsToAdd.metSmiles=convertCharArray(metsToAdd.metSmiles); +0213 if numel(metsToAdd.metSmiles)~=nMets +0214 EM='metsToAdd.metSmiles must have the same number of elements as metsToAdd.mets'; +0215 dispEM(EM); +0216 end +0217 %Add empty field if it doesn't exist +0218 if ~isfield(newModel,'metSmiles') +0219 newModel.metSmiles=largeFiller; +0220 end +0221 newModel.metSmiles=[newModel.metSmiles;metsToAdd.metSmiles(:)]; +0222 else +0223 %Add empty strings if structure is in model +0224 if isfield(newModel,'metSmiles') +0225 newModel.metSmiles=[newModel.metSmiles;filler]; +0226 end +0227 end +0228 +0229 if isfield(metsToAdd,'metFormulas') +0230 metsToAdd.metFormulas=convertCharArray(metsToAdd.metFormulas); +0231 if numel(metsToAdd.metFormulas)~=nMets +0232 EM='metsToAdd.metFormulas must have the same number of elements as metsToAdd.mets'; +0233 dispEM(EM); +0234 end +0235 %Add empty field if it doesn't exist +0236 if ~isfield(newModel,'metFormulas') +0237 newModel.metFormulas=largeFiller; +0238 end +0239 newModel.metFormulas=[newModel.metFormulas;metsToAdd.metFormulas(:)]; +0240 else +0241 %Add default +0242 if isfield(newModel,'metFormulas') +0243 newModel.metFormulas=[newModel.metFormulas;filler]; +0244 end +0245 end +0246 +0247 if isfield(metsToAdd,'metCharges') +0248 if numel(metsToAdd.metCharges)~=nMets +0249 EM='metsToAdd.metCharges must have the same number of elements as metsToAdd.mets'; +0250 dispEM(EM); +0251 end +0252 if ~isnumeric(metsToAdd.metCharges) +0253 EM='metsToAdd.metCharges must be of type "double"'; +0254 dispEM(EM); 0255 end -0256 newModel.metCharges=[newModel.metCharges;metsToAdd.metCharges(:)]; -0257 else -0258 %Add default -0259 if isfield(newModel,'metCharges') -0260 newModel.metCharges=[newModel.metCharges;NaN(numel(filler),1)]; -0261 end -0262 end -0263 -0264 if isfield(metsToAdd,'metNotes') -0265 metsToAdd.metNotes=convertCharArray(metsToAdd.metNotes); -0266 if numel(metsToAdd.metNotes)==1 && numel(metsToAdd.mets)>1 -0267 temp=cell(numel(metsToAdd.mets),1); -0268 temp(:)=metsToAdd.metNotes; -0269 metsToAdd.metNotes=temp; -0270 end -0271 if numel(metsToAdd.metNotes)~=nMets -0272 EM='metsToAdd.metNotes must have the same number of elements as metsToAdd.mets'; -0273 dispEM(EM); -0274 end -0275 %Add empty field if it doesn't exist -0276 if ~isfield(newModel,'metNotes') -0277 newModel.metNotes=largeFiller; +0256 if ~isfield(newModel,'metCharges') +0257 newModel.metCharges=NaN(numel(largeFiller),1); +0258 end +0259 newModel.metCharges=[newModel.metCharges;metsToAdd.metCharges(:)]; +0260 else +0261 %Add default +0262 if isfield(newModel,'metCharges') +0263 newModel.metCharges=[newModel.metCharges;NaN(numel(filler),1)]; +0264 end +0265 end +0266 +0267 if isfield(metsToAdd,'metDeltaG') +0268 if numel(metsToAdd.metDeltaG)~=nMets +0269 EM='metsToAdd.metDeltaG must have the same number of elements as metsToAdd.mets'; +0270 dispEM(EM); +0271 end +0272 if ~isnumeric(metsToAdd.metDeltaG) +0273 EM='metsToAdd.metDeltaG must be of type "double"'; +0274 dispEM(EM); +0275 end +0276 if ~isfield(newModel,'metDeltaG') +0277 newModel.metDeltaG=NaN(numel(largeFiller),1); 0278 end -0279 newModel.metNotes=[newModel.metNotes;metsToAdd.metNotes(:)]; +0279 newModel.metDeltaG=[newModel.metDeltaG;metsToAdd.metDeltaG(:)]; 0280 else -0281 %Add empty strings if structure is in model -0282 if isfield(newModel,'metNotes') -0283 newModel.metNotes=[newModel.metNotes;filler]; +0281 %Add default +0282 if isfield(newModel,'metDeltaG') +0283 newModel.metDeltaG=[newModel.metDeltaG;NaN(numel(filler),1)]; 0284 end 0285 end 0286 -0287 %Don't check the type of metMiriams -0288 if isfield(metsToAdd,'metMiriams') -0289 if numel(metsToAdd.metMiriams)==1 && numel(metsToAdd.mets)>1 -0290 temp=cell(numel(metsToAdd.mets),1); -0291 temp(:)={metsToAdd.metMiriams}; -0292 metsToAdd.metMiriams=temp; -0293 end -0294 if numel(metsToAdd.metMiriams)~=nMets -0295 EM='metsToAdd.metMiriams must have the same number of elements as metsToAdd.mets'; -0296 dispEM(EM); -0297 end -0298 %Add empty field if it doesn't exist -0299 if ~isfield(newModel,'metMiriams') -0300 newModel.metMiriams=cell(nOldMets,1); -0301 end -0302 newModel.metMiriams=[newModel.metMiriams;metsToAdd.metMiriams(:)]; -0303 else -0304 if isfield(newModel,'metMiriams') -0305 newModel.metMiriams=[newModel.metMiriams;cell(nMets,1)]; -0306 end -0307 end -0308 -0309 if isfield(newModel,'metFrom') -0310 newModel.metFrom=[newModel.metFrom;filler]; -0311 end -0312 -0313 %Expand the S matrix -0314 newModel.S=[newModel.S;sparse(nMets,size(newModel.S,2))]; -0315 -0316 if copyInfo==true -0317 [I, J]=ismember(metsToAdd.metNames,model.metNames); -0318 J=J(I); -0319 %I is the indexes of the new metabolites for which a metabolite with -0320 %the same name existed -0321 I=find(I)+nOldMets; -0322 %Go through each of the added mets and copy annotation if it doesn't -0323 %exist -0324 for i=1:numel(I) -0325 if isfield(newModel,'inchis') -0326 if isempty(newModel.inchis{I(i)}) -0327 newModel.inchis(I(i))=newModel.inchis(J(i)); -0328 end -0329 end -0330 if isfield(newModel,'metSmiles') -0331 if isempty(newModel.metSmiles{I(i)}) -0332 newModel.metSmiles(I(i))=newModel.metSmiles(J(i)); -0333 end -0334 end -0335 if isfield(newModel,'metFormulas') -0336 if isempty(newModel.metFormulas{I(i)}) -0337 newModel.metFormulas(I(i))=newModel.metFormulas(J(i)); -0338 end -0339 end -0340 if isfield(newModel,'metMiriams') -0341 if isempty(newModel.metMiriams{I(i)}) -0342 newModel.metMiriams(I(i))=newModel.metMiriams(J(i)); -0343 end -0344 end -0345 if isfield(newModel,'metCharges') -0346 newModel.metCharges(I(i))=newModel.metCharges(J(i)); -0347 end -0348 end -0349 end -0350 end +0287 +0288 if isfield(metsToAdd,'metNotes') +0289 metsToAdd.metNotes=convertCharArray(metsToAdd.metNotes); +0290 if numel(metsToAdd.metNotes)==1 && numel(metsToAdd.mets)>1 +0291 temp=cell(numel(metsToAdd.mets),1); +0292 temp(:)=metsToAdd.metNotes; +0293 metsToAdd.metNotes=temp; +0294 end +0295 if numel(metsToAdd.metNotes)~=nMets +0296 EM='metsToAdd.metNotes must have the same number of elements as metsToAdd.mets'; +0297 dispEM(EM); +0298 end +0299 %Add empty field if it doesn't exist +0300 if ~isfield(newModel,'metNotes') +0301 newModel.metNotes=largeFiller; +0302 end +0303 newModel.metNotes=[newModel.metNotes;metsToAdd.metNotes(:)]; +0304 else +0305 %Add empty strings if structure is in model +0306 if isfield(newModel,'metNotes') +0307 newModel.metNotes=[newModel.metNotes;filler]; +0308 end +0309 end +0310 +0311 %Don't check the type of metMiriams +0312 if isfield(metsToAdd,'metMiriams') +0313 if numel(metsToAdd.metMiriams)==1 && numel(metsToAdd.mets)>1 +0314 temp=cell(numel(metsToAdd.mets),1); +0315 temp(:)={metsToAdd.metMiriams}; +0316 metsToAdd.metMiriams=temp; +0317 end +0318 if numel(metsToAdd.metMiriams)~=nMets +0319 EM='metsToAdd.metMiriams must have the same number of elements as metsToAdd.mets'; +0320 dispEM(EM); +0321 end +0322 %Add empty field if it doesn't exist +0323 if ~isfield(newModel,'metMiriams') +0324 newModel.metMiriams=cell(nOldMets,1); +0325 end +0326 newModel.metMiriams=[newModel.metMiriams;metsToAdd.metMiriams(:)]; +0327 else +0328 if isfield(newModel,'metMiriams') +0329 newModel.metMiriams=[newModel.metMiriams;cell(nMets,1)]; +0330 end +0331 end +0332 +0333 if isfield(newModel,'metFrom') +0334 newModel.metFrom=[newModel.metFrom;filler]; +0335 end +0336 +0337 %Expand the S matrix +0338 newModel.S=[newModel.S;sparse(nMets,size(newModel.S,2))]; +0339 +0340 if copyInfo==true +0341 [I, J]=ismember(metsToAdd.metNames,model.metNames); +0342 J=J(I); +0343 %I is the indexes of the new metabolites for which a metabolite with +0344 %the same name existed +0345 I=find(I)+nOldMets; +0346 %Go through each of the added mets and copy annotation if it doesn't +0347 %exist +0348 for i=1:numel(I) +0349 if isfield(newModel,'inchis') +0350 if isempty(newModel.inchis{I(i)}) +0351 newModel.inchis(I(i))=newModel.inchis(J(i)); +0352 end +0353 end +0354 if isfield(newModel,'metSmiles') +0355 if isempty(newModel.metSmiles{I(i)}) +0356 newModel.metSmiles(I(i))=newModel.metSmiles(J(i)); +0357 end +0358 end +0359 if isfield(newModel,'metFormulas') +0360 if isempty(newModel.metFormulas{I(i)}) +0361 newModel.metFormulas(I(i))=newModel.metFormulas(J(i)); +0362 end +0363 end +0364 if isfield(newModel,'metMiriams') +0365 if isempty(newModel.metMiriams{I(i)}) +0366 newModel.metMiriams(I(i))=newModel.metMiriams(J(i)); +0367 end +0368 end +0369 if isfield(newModel,'metCharges') +0370 newModel.metCharges(I(i))=newModel.metCharges(J(i)); +0371 end +0372 if isfield(newModel,'metDeltaG') +0373 newModel.metDeltaG(I(i))=newModel.metDeltaG(J(i)); +0374 end +0375 end +0376 end +0377 end
Generated by m2html © 2005
\ No newline at end of file diff --git a/doc/core/addRxns.html b/doc/core/addRxns.html index 909c8b17..d93d2d05 100644 --- a/doc/core/addRxns.html +++ b/doc/core/addRxns.html @@ -80,6 +80,8 @@

DESCRIPTION ^SOURCE CODE ^% model.comps) (opt, default {}) 0053 % rxnNotes cell array with reaction notes (opt, 0054 % default '') -0055 % rxnReferences cell array with reaction references (opt, -0056 % default '') -0057 % rxnConfidenceScores vector with reaction confidence scores -0058 % (opt, default NaN) -0059 % eqnType double describing how the equation string should be -0060 % interpreted -0061 % 1 - The metabolites are matched to model.mets. New -0062 % metabolites (if allowed) are added to -0063 % "compartment" (default) -0064 % 2 - The metabolites are matched to model.metNames and -0065 % all metabolites are assigned to "compartment". Any -0066 % new metabolites that are added will be assigned -0067 % IDs "m1", "m2"... If IDs on the same form are -0068 % already used in the model then the numbering will -0069 % start from the highest used integer+1 -0070 % 3 - The metabolites are written as -0071 % "metNames[comps]". Only compartments in -0072 % model.comps are allowed. Any -0073 % new metabolites that are added will be assigned -0074 % IDs "m1", "m2"... If IDs on the same form are -0075 % already used in the model then the numbering will -0076 % start from the highest used integer+1 -0077 % compartment a string with the compartment the metabolites should -0078 % be placed in when using eqnType=2. Must match -0079 % model.comps (opt when eqnType=1 or eqnType=3) -0080 % allowNewMets true if the function is allowed to add new -0081 % metabolites. Can also be a string, which will be used -0082 % as prefix for the new metabolite IDs. It is highly -0083 % recommended to first add any new metabolites with -0084 % addMets rather than automatically through this -0085 % function. addMets supports more annotation of -0086 % metabolites, allows for the use of exchange -0087 % metabolites, and using it reduces the risk of parsing -0088 % errors (opt, default false) -0089 % allowNewGenes true if the functions is allowed to add new genes -0090 % (opt, default false) -0091 % -0092 % newModel an updated model structure +0055 % rxnDeltaG Gibbs free energy at biochemical standard +0056 % condition in kJ/mole (opt, default NaN) +0057 % rxnReferences cell array with reaction references (opt, +0058 % default '') +0059 % rxnConfidenceScores vector with reaction confidence scores +0060 % (opt, default NaN) +0061 % eqnType double describing how the equation string should be +0062 % interpreted +0063 % 1 - The metabolites are matched to model.mets. New +0064 % metabolites (if allowed) are added to +0065 % "compartment" (default) +0066 % 2 - The metabolites are matched to model.metNames and +0067 % all metabolites are assigned to "compartment". Any +0068 % new metabolites that are added will be assigned +0069 % IDs "m1", "m2"... If IDs on the same form are +0070 % already used in the model then the numbering will +0071 % start from the highest used integer+1 +0072 % 3 - The metabolites are written as +0073 % "metNames[comps]". Only compartments in +0074 % model.comps are allowed. Any +0075 % new metabolites that are added will be assigned +0076 % IDs "m1", "m2"... If IDs on the same form are +0077 % already used in the model then the numbering will +0078 % start from the highest used integer+1 +0079 % compartment a string with the compartment the metabolites should +0080 % be placed in when using eqnType=2. Must match +0081 % model.comps (opt when eqnType=1 or eqnType=3) +0082 % allowNewMets true if the function is allowed to add new +0083 % metabolites. Can also be a string, which will be used +0084 % as prefix for the new metabolite IDs. It is highly +0085 % recommended to first add any new metabolites with +0086 % addMets rather than automatically through this +0087 % function. addMets supports more annotation of +0088 % metabolites, allows for the use of exchange +0089 % metabolites, and using it reduces the risk of parsing +0090 % errors (opt, default false) +0091 % allowNewGenes true if the functions is allowed to add new genes +0092 % (opt, default false) 0093 % -0094 % NOTE: This function does not make extensive checks about formatting of -0095 % gene-reaction rules. -0096 % -0097 % NOTE: When adding metabolites to a compartment where it previously -0098 % doesn't exist, the function will copy any available information from -0099 % the metabolite in another compartment. -0100 % -0101 % Usage: newModel=addRxns(model,rxnsToAdd,eqnType,compartment,... -0102 % allowNewMets,allowNewGenes) -0103 -0104 if nargin<3 -0105 eqnType=1; -0106 elseif ~isnumeric(eqnType) -0107 EM='eqnType must be numeric'; -0108 dispEM(EM); -0109 elseif ~ismember(eqnType,[1 2 3]) -0110 EM='eqnType must be 1, 2, or 3'; -0111 dispEM(EM); -0112 end -0113 -0114 if nargin<4 -0115 compartment=[]; -0116 else -0117 compartment=char(compartment); -0118 end -0119 if nargin<5 -0120 allowNewMets=false; -0121 elseif ~islogical(allowNewMets) -0122 allowNewMets=char(allowNewMets); -0123 end -0124 if nargin<6 -0125 allowNewGenes=false; -0126 end -0127 -0128 if allowNewGenes & isfield(rxnsToAdd,'grRules') -0129 genesToAdd.genes = strjoin(convertCharArray(rxnsToAdd.grRules)); -0130 genesToAdd.genes = regexp(genesToAdd.genes,' |)|(|and|or','split'); % Remove all grRule punctuation -0131 genesToAdd.genes = genesToAdd.genes(~cellfun(@isempty,genesToAdd.genes)); % Remove spaces and empty genes -0132 genesToAdd.genes = setdiff(unique(genesToAdd.genes),model.genes); % Only keep new genes -0133 if isfield(model,'geneComps') -0134 genesToAdd.geneComps(1:numel(genesToAdd.genes)) = repmat(11,numel(genesToAdd.genes),1); -0135 end -0136 if ~isempty(genesToAdd.genes) -0137 fprintf('\nNew genes added to the model:\n') -0138 fprintf([strjoin(genesToAdd.genes,'\n') '\n']) -0139 newModel=addGenesRaven(model,genesToAdd); -0140 else -0141 newModel=model; -0142 end -0143 else -0144 newModel=model; -0145 end -0146 -0147 %If no reactions should be added -0148 if isempty(rxnsToAdd) -0149 return; -0150 end -0151 -0152 if eqnType==2 || (eqnType==1 && allowNewMets==true) -0153 compartment=char(compartment); -0154 if ~ismember(compartment,model.comps) -0155 EM='compartment must match one of the compartments in model.comps'; -0156 dispEM(EM); -0157 end -0158 end -0159 -0160 if ~isfield(rxnsToAdd,'rxns') -0161 EM='rxns is a required field in rxnsToAdd'; -0162 dispEM(EM); -0163 else -0164 rxnsToAdd.rxns=convertCharArray(rxnsToAdd.rxns); -0165 %To fit with some later printing -0166 rxnsToAdd.rxns=rxnsToAdd.rxns(:); -0167 end -0168 if ~(isfield(rxnsToAdd,'equations') || (isfield(rxnsToAdd,'mets') && isfield(rxnsToAdd,'stoichCoeffs'))) -0169 EM='Either "equations" or "mets"+"stoichCoeffs" are required fields in rxnsToAdd'; -0170 dispEM(EM); -0171 end -0172 -0173 if any(ismember(rxnsToAdd.rxns,model.rxns)) -0174 EM='One or more reaction id was already present in the model. Use changeRxns or remove the existing reactions before adding new ones'; -0175 dispEM(EM); -0176 end -0177 -0178 %Normal case: equations provided -0179 if isfield(rxnsToAdd,'equations') -0180 rxnsToAdd.equations=convertCharArray(rxnsToAdd.equations); -0181 -0182 %Alternative case: mets+stoichiometry provided -0183 else -0184 %In the case of 1 rxn added (array of strings + vector), transform to -0185 %cells of length=1: -0186 if iscellstr(rxnsToAdd.mets) -0187 rxnsToAdd.mets={rxnsToAdd.mets}; -0188 end -0189 if isnumeric(rxnsToAdd.stoichCoeffs) -0190 rxnsToAdd.stoichCoeffs = {rxnsToAdd.stoichCoeffs}; -0191 end -0192 %Now both rxnsToAdd.mets and rxnsToAdd.stoichCoeffs should be cell -0193 %arrays & of the same size: -0194 if ~iscell(rxnsToAdd.mets) || ~iscell(rxnsToAdd.stoichCoeffs) -0195 EM='rxnsToAdd.mets & rxnsToAdd.stoichCoeffs must be cell arrays'; -0196 dispEM(EM); -0197 elseif length(rxnsToAdd.stoichCoeffs) ~= length(rxnsToAdd.mets) -0198 EM = 'rxnsToAdd.stoichCoeffs must have the same number of elements as rxnsToAdd.mets'; -0199 dispEM(EM); -0200 end -0201 %In this case we need lb to decide if the reaction is reversible or not: -0202 if ~isfield(rxnsToAdd,'lb') -0203 %Fill with standard if it doesn't exist -0204 rxnsToAdd.lb=-inf(size(rxnsToAdd.mets)); -0205 elseif ~isnumeric(rxnsToAdd.lb) -0206 EM = 'rxnsToAdd.lb must be a vector'; -0207 dispEM(EM); -0208 elseif length(rxnsToAdd.lb) ~= length(rxnsToAdd.mets) -0209 EM = 'rxnsToAdd.lb must have the same number of elements as rxnsToAdd.mets'; -0210 dispEM(EM); -0211 end -0212 %Now we construct equations, to comply with the rest of the script: -0213 rxnsToAdd.equations = cell(size(rxnsToAdd.mets)); -0214 for i = 1:length(rxnsToAdd.mets) -0215 mets = rxnsToAdd.mets{i}; -0216 stoichCoeffs = rxnsToAdd.stoichCoeffs{i}; -0217 if isfield(rxnsToAdd,'ub') -0218 isrev = rxnsToAdd.lb(i) < 0 && rxnsToAdd.ub(i) > 0; -0219 else -0220 isrev = rxnsToAdd.lb(i) < 0; -0221 end -0222 rxnsToAdd.equations{i} = buildEquation(mets,stoichCoeffs,isrev); -0223 end -0224 end -0225 -0226 nRxns=numel(rxnsToAdd.rxns); -0227 nOldRxns=numel(model.rxns); -0228 filler=cell(nRxns,1); -0229 filler(:)={''}; -0230 cellfiller=cellfun(@(x) cell(0,0),filler,'UniformOutput',false); -0231 largeFiller=cell(nOldRxns,1); -0232 largeFiller(:)={''}; -0233 celllargefiller=cellfun(@(x) cell(0,0),largeFiller,'UniformOutput',false); -0234 -0235 %***Add everything to the model except for the equations. -0236 if numel(rxnsToAdd.equations)~=nRxns -0237 EM='rxnsToAdd.equations must have the same number of elements as rxnsToAdd.rxns'; -0238 dispEM(EM); -0239 end -0240 -0241 %Parse the equations. This is done at this early stage since I need the -0242 %reversibility info -0243 [S, mets, badRxns, reversible]=constructS(rxnsToAdd.equations); -0244 EM='The following equations have one or more metabolites both as substrate and product. Only the net equations will be added:'; -0245 dispEM(EM,false,rxnsToAdd.rxns(badRxns)); -0246 -0247 newModel.rev=[newModel.rev;reversible]; -0248 newModel.rxns=[newModel.rxns;rxnsToAdd.rxns(:)]; -0249 -0250 if isfield(rxnsToAdd,'rxnNames') -0251 rxnsToAdd.rxnNames=convertCharArray(rxnsToAdd.rxnNames); -0252 if numel(rxnsToAdd.rxnNames)~=nRxns -0253 EM='rxnsToAdd.rxnNames must have the same number of elements as rxnsToAdd.rxns'; -0254 dispEM(EM); -0255 end -0256 %Fill with standard if it doesn't exist -0257 if ~isfield(newModel,'rxnNames') -0258 newModel.rxnNames=largeFiller; -0259 end -0260 newModel.rxnNames=[newModel.rxnNames;rxnsToAdd.rxnNames(:)]; -0261 else -0262 %Fill with standard if it doesn't exist -0263 if isfield(newModel,'rxnNames') -0264 newModel.rxnNames=[newModel.rxnNames;filler]; -0265 end -0266 end -0267 -0268 if isfield(newModel,'annotation') & isfield(newModel.annotation,'defaultLB') -0269 newLb=newModel.annotation.defaultLB; -0270 else -0271 newLb=-inf; -0272 end -0273 -0274 if isfield(rxnsToAdd,'lb') -0275 if numel(rxnsToAdd.lb)~=nRxns -0276 EM='rxnsToAdd.lb must have the same number of elements as rxnsToAdd.rxns'; -0277 dispEM(EM); -0278 end -0279 %Fill with standard if it doesn't exist -0280 if ~isfield(newModel,'lb') -0281 newModel.lb=zeros(nOldRxns,1); -0282 newModel.lb(newModel.rev~=0)=newLb; -0283 end -0284 newModel.lb=[newModel.lb;rxnsToAdd.lb(:)]; -0285 else -0286 %Fill with standard if it doesn't exist -0287 if isfield(newModel,'lb') -0288 I=zeros(nRxns,1); -0289 I(reversible~=0)=newLb; -0290 newModel.lb=[newModel.lb;I]; -0291 end -0292 end -0293 -0294 if isfield(newModel,'annotation') & isfield(newModel.annotation,'defaultUB') -0295 newUb=newModel.annotation.defaultUB; -0296 else -0297 newUb=inf; -0298 end -0299 -0300 if isfield(rxnsToAdd,'ub') -0301 if numel(rxnsToAdd.ub)~=nRxns -0302 EM='rxnsToAdd.ub must have the same number of elements as rxnsToAdd.rxns'; -0303 dispEM(EM); -0304 end -0305 %Fill with standard if it doesn't exist -0306 if ~isfield(newModel,'ub') -0307 newModel.ub=repmat(newUb,nOldRxns,1); -0308 end -0309 newModel.ub=[newModel.ub;rxnsToAdd.ub(:)]; -0310 else -0311 %Fill with standard if it doesn't exist -0312 if isfield(newModel,'ub') -0313 newModel.ub=[newModel.ub;repmat(newUb,nRxns,1)]; -0314 end -0315 end -0316 -0317 if isfield(rxnsToAdd,'c') -0318 if numel(rxnsToAdd.c)~=nRxns -0319 EM='rxnsToAdd.c must have the same number of elements as rxnsToAdd.rxns'; -0320 dispEM(EM); -0321 end -0322 %Fill with standard if it doesn't exist -0323 if ~isfield(newModel,'c') -0324 newModel.c=zeros(nOldRxns,1); -0325 end -0326 newModel.c=[newModel.c;rxnsToAdd.c(:)]; -0327 else -0328 %Fill with standard if it doesn't exist -0329 if isfield(newModel,'c') -0330 newModel.c=[newModel.c;zeros(nRxns,1)]; -0331 end -0332 end -0333 -0334 if isfield(rxnsToAdd,'eccodes') -0335 rxnsToAdd.eccodes=convertCharArray(rxnsToAdd.eccodes); -0336 if numel(rxnsToAdd.eccodes)~=nRxns -0337 EM='rxnsToAdd.eccodes must have the same number of elements as rxnsToAdd.rxns'; -0338 dispEM(EM); -0339 end -0340 %Fill with standard if it doesn't exist -0341 if ~isfield(newModel,'eccodes') -0342 newModel.eccodes=largeFiller; -0343 end -0344 newModel.eccodes=[newModel.eccodes;rxnsToAdd.eccodes(:)]; -0345 else -0346 %Fill with standard if it doesn't exist -0347 if isfield(newModel,'eccodes') -0348 newModel.eccodes=[newModel.eccodes;filler]; -0349 end -0350 end -0351 -0352 if isfield(rxnsToAdd,'subSystems') -0353 if numel(rxnsToAdd.subSystems)~=nRxns -0354 EM='rxnsToAdd.subSystems must have the same number of elements as rxnsToAdd.rxns'; -0355 dispEM(EM); -0356 end -0357 for i=1:numel(rxnsToAdd.subSystems) -0358 if ischar(rxnsToAdd.subSystems{i}) -0359 rxnsToAdd.subSystems{i}=rxnsToAdd.subSystems(i); -0360 end -0361 end -0362 %Fill with standard if it doesn't exist -0363 if ~isfield(newModel,'subSystems') -0364 newModel.subSystems=celllargefiller; -0365 end -0366 newModel.subSystems=[newModel.subSystems;rxnsToAdd.subSystems]; -0367 else -0368 %Fill with standard if it doesn't exist -0369 if isfield(newModel,'subSystems') -0370 newModel.subSystems=[newModel.subSystems;cellfiller]; -0371 end -0372 end -0373 if isfield(rxnsToAdd,'rxnMiriams') -0374 if numel(rxnsToAdd.rxnMiriams)~=nRxns -0375 EM='rxnsToAdd.rxnMiriams must have the same number of elements as rxnsToAdd.rxns'; -0376 dispEM(EM); -0377 end -0378 %Fill with standard if it doesn't exist -0379 if ~isfield(newModel,'rxnMiriams') -0380 newModel.rxnMiriams=cell(nOldRxns,1); -0381 end -0382 newModel.rxnMiriams=[newModel.rxnMiriams;rxnsToAdd.rxnMiriams(:)]; -0383 else -0384 %Fill with standard if it doesn't exist -0385 if isfield(newModel,'rxnMiriams') -0386 newModel.rxnMiriams=[newModel.rxnMiriams;cell(nRxns,1)]; -0387 end -0388 end -0389 if isfield(rxnsToAdd,'rxnComps') -0390 if numel(rxnsToAdd.rxnComps)~=nRxns -0391 EM='rxnsToAdd.rxnComps must have the same number of elements as rxnsToAdd.rxns'; -0392 dispEM(EM); -0393 end -0394 %Fill with standard if it doesn't exist -0395 if ~isfield(newModel,'rxnComps') -0396 newModel.rxnComps=ones(nOldRxns,1); -0397 EM='Adding reactions with compartment information to a model without such information. All existing reactions will be assigned to the first compartment'; -0398 dispEM(EM,false); -0399 end -0400 newModel.rxnComps=[newModel.rxnComps;rxnsToAdd.rxnComps(:)]; -0401 else -0402 %Fill with standard if it doesn't exist -0403 if isfield(newModel,'rxnComps') -0404 newModel.rxnComps=[newModel.rxnComps;ones(nRxns,1)]; -0405 %fprintf('NOTE: The added reactions will be assigned to the first -0406 %compartment\n'); -0407 end -0408 end -0409 if isfield(rxnsToAdd,'grRules') -0410 rxnsToAdd.grRules=convertCharArray(rxnsToAdd.grRules); -0411 if numel(rxnsToAdd.grRules)~=nRxns -0412 EM='rxnsToAdd.grRules must have the same number of elements as rxnsToAdd.rxns'; -0413 dispEM(EM); -0414 end -0415 %Fill with standard if it doesn't exist -0416 if ~isfield(newModel,'grRules') -0417 newModel.grRules=largeFiller; -0418 end -0419 newModel.grRules=[newModel.grRules;rxnsToAdd.grRules(:)]; -0420 else -0421 %Fill with standard if it doesn't exist -0422 if isfield(newModel,'grRules') -0423 newModel.grRules=[newModel.grRules;filler]; -0424 end -0425 end -0426 -0427 if isfield(rxnsToAdd,'rxnFrom') -0428 rxnsToAdd.rxnFrom=convertCharArray(rxnsToAdd.rxnFrom); -0429 if numel(rxnsToAdd.rxnFrom)~=nRxns -0430 EM='rxnsToAdd.rxnFrom must have the same number of elements as rxnsToAdd.rxns'; -0431 dispEM(EM); -0432 end -0433 %Fill with standard if it doesn't exist -0434 if ~isfield(newModel,'rxnFrom') -0435 newModel.rxnFrom=largeFiller; -0436 end -0437 newModel.rxnFrom=[newModel.rxnFrom;rxnsToAdd.rxnFrom(:)]; -0438 else -0439 %Fill with standard if it doesn't exist -0440 if isfield(newModel,'rxnFrom') -0441 newModel.rxnFrom=[newModel.rxnFrom;filler]; -0442 end -0443 end -0444 -0445 if isfield(rxnsToAdd,'rxnNotes') -0446 rxnsToAdd.rxnNotes=convertCharArray(rxnsToAdd.rxnNotes); -0447 if numel(rxnsToAdd.rxnNotes)~=nRxns -0448 EM='rxnsToAdd.rxnNotes must have the same number of elements as rxnsToAdd.rxns'; -0449 dispEM(EM); -0450 end -0451 %Fill with standard if it doesn't exist -0452 if ~isfield(newModel,'rxnNotes') -0453 newModel.rxnNotes=largeFiller; -0454 end -0455 newModel.rxnNotes=[newModel.rxnNotes;rxnsToAdd.rxnNotes(:)]; -0456 else -0457 %Fill with standard if it doesn't exist -0458 if isfield(newModel,'rxnNotes') -0459 newModel.rxnNotes=[newModel.rxnNotes;filler]; -0460 end -0461 end -0462 -0463 if isfield(rxnsToAdd,'rxnReferences') -0464 rxnsToAdd.rxnReferences=convertCharArray(rxnsToAdd.rxnReferences); -0465 if numel(rxnsToAdd.rxnReferences)~=nRxns -0466 EM='rxnsToAdd.rxnReferences must have the same number of elements as rxnsToAdd.rxns'; -0467 dispEM(EM); -0468 end -0469 %Fill with standard if it doesn't exist -0470 if ~isfield(newModel,'rxnReferences') -0471 newModel.rxnReferences=largeFiller; -0472 end -0473 newModel.rxnReferences=[newModel.rxnReferences;rxnsToAdd.rxnReferences(:)]; -0474 else -0475 %Fill with standard if it doesn't exist -0476 if isfield(newModel,'rxnReferences') -0477 newModel.rxnReferences=[newModel.rxnReferences;filler]; -0478 end -0479 end -0480 -0481 if isfield(rxnsToAdd,'pwys') -0482 rxnsToAdd.pwys=convertCharArray(rxnsToAdd.pwys); -0483 if numel(rxnsToAdd.pwys)~=nRxns -0484 EM='rxnsToAdd.pwys must have the same number of elements as rxnsToAdd.rxns'; -0485 dispEM(EM); -0486 end -0487 %Fill with standard if it doesn't exist -0488 if ~isfield(newModel,'pwys') -0489 newModel.pwys=largeFiller; -0490 end -0491 newModel.pwys=[newModel.pwys;rxnsToAdd.pwys(:)]; -0492 else -0493 %Fill with standard if it doesn't exist -0494 if isfield(newModel,'pwys') -0495 newModel.pwys=[newModel.pwys;filler]; -0496 end -0497 end -0498 -0499 if isfield(rxnsToAdd,'rxnConfidenceScores') -0500 if numel(rxnsToAdd.rxnConfidenceScores)~=nRxns -0501 EM='rxnsToAdd.rxnConfidenceScores must have the same number of elements as rxnsToAdd.rxns'; -0502 dispEM(EM); -0503 end -0504 %Fill with standard if it doesn't exist -0505 if ~isfield(newModel,'rxnConfidenceScores') -0506 newModel.rxnConfidenceScores=NaN(nOldRxns,1); -0507 EM='Adding reactions with confidence scores without such information. All existing reactions will have confidence scores as NaNs'; -0508 dispEM(EM,false); +0094 % newModel an updated model structure +0095 % +0096 % NOTE: This function does not make extensive checks about formatting of +0097 % gene-reaction rules. +0098 % +0099 % NOTE: When adding metabolites to a compartment where it previously +0100 % doesn't exist, the function will copy any available information from +0101 % the metabolite in another compartment. +0102 % +0103 % Usage: newModel=addRxns(model,rxnsToAdd,eqnType,compartment,... +0104 % allowNewMets,allowNewGenes) +0105 +0106 if nargin<3 +0107 eqnType=1; +0108 elseif ~isnumeric(eqnType) +0109 EM='eqnType must be numeric'; +0110 dispEM(EM); +0111 elseif ~ismember(eqnType,[1 2 3]) +0112 EM='eqnType must be 1, 2, or 3'; +0113 dispEM(EM); +0114 end +0115 +0116 if nargin<4 +0117 compartment=[]; +0118 else +0119 compartment=char(compartment); +0120 end +0121 if nargin<5 +0122 allowNewMets=false; +0123 elseif ~islogical(allowNewMets) +0124 allowNewMets=char(allowNewMets); +0125 end +0126 if nargin<6 +0127 allowNewGenes=false; +0128 end +0129 +0130 if allowNewGenes & isfield(rxnsToAdd,'grRules') +0131 genesToAdd.genes = strjoin(convertCharArray(rxnsToAdd.grRules)); +0132 genesToAdd.genes = regexp(genesToAdd.genes,' |)|(|and|or','split'); % Remove all grRule punctuation +0133 genesToAdd.genes = genesToAdd.genes(~cellfun(@isempty,genesToAdd.genes)); % Remove spaces and empty genes +0134 genesToAdd.genes = setdiff(unique(genesToAdd.genes),model.genes); % Only keep new genes +0135 if isfield(model,'geneComps') +0136 genesToAdd.geneComps(1:numel(genesToAdd.genes)) = repmat(11,numel(genesToAdd.genes),1); +0137 end +0138 if ~isempty(genesToAdd.genes) +0139 fprintf('\nNew genes added to the model:\n') +0140 fprintf([strjoin(genesToAdd.genes,'\n') '\n']) +0141 newModel=addGenesRaven(model,genesToAdd); +0142 else +0143 newModel=model; +0144 end +0145 else +0146 newModel=model; +0147 end +0148 +0149 %If no reactions should be added +0150 if isempty(rxnsToAdd) +0151 return; +0152 end +0153 +0154 if eqnType==2 || (eqnType==1 && allowNewMets==true) +0155 compartment=char(compartment); +0156 if ~ismember(compartment,model.comps) +0157 EM='compartment must match one of the compartments in model.comps'; +0158 dispEM(EM); +0159 end +0160 end +0161 +0162 if ~isfield(rxnsToAdd,'rxns') +0163 EM='rxns is a required field in rxnsToAdd'; +0164 dispEM(EM); +0165 else +0166 rxnsToAdd.rxns=convertCharArray(rxnsToAdd.rxns); +0167 %To fit with some later printing +0168 rxnsToAdd.rxns=rxnsToAdd.rxns(:); +0169 end +0170 if ~(isfield(rxnsToAdd,'equations') || (isfield(rxnsToAdd,'mets') && isfield(rxnsToAdd,'stoichCoeffs'))) +0171 EM='Either "equations" or "mets"+"stoichCoeffs" are required fields in rxnsToAdd'; +0172 dispEM(EM); +0173 end +0174 +0175 if any(ismember(rxnsToAdd.rxns,model.rxns)) +0176 EM='One or more reaction id was already present in the model. Use changeRxns or remove the existing reactions before adding new ones'; +0177 dispEM(EM); +0178 end +0179 +0180 %Normal case: equations provided +0181 if isfield(rxnsToAdd,'equations') +0182 rxnsToAdd.equations=convertCharArray(rxnsToAdd.equations); +0183 +0184 %Alternative case: mets+stoichiometry provided +0185 else +0186 %In the case of 1 rxn added (array of strings + vector), transform to +0187 %cells of length=1: +0188 if iscellstr(rxnsToAdd.mets) +0189 rxnsToAdd.mets={rxnsToAdd.mets}; +0190 end +0191 if isnumeric(rxnsToAdd.stoichCoeffs) +0192 rxnsToAdd.stoichCoeffs = {rxnsToAdd.stoichCoeffs}; +0193 end +0194 %Now both rxnsToAdd.mets and rxnsToAdd.stoichCoeffs should be cell +0195 %arrays & of the same size: +0196 if ~iscell(rxnsToAdd.mets) || ~iscell(rxnsToAdd.stoichCoeffs) +0197 EM='rxnsToAdd.mets & rxnsToAdd.stoichCoeffs must be cell arrays'; +0198 dispEM(EM); +0199 elseif length(rxnsToAdd.stoichCoeffs) ~= length(rxnsToAdd.mets) +0200 EM = 'rxnsToAdd.stoichCoeffs must have the same number of elements as rxnsToAdd.mets'; +0201 dispEM(EM); +0202 end +0203 %In this case we need lb to decide if the reaction is reversible or not: +0204 if ~isfield(rxnsToAdd,'lb') +0205 %Fill with standard if it doesn't exist +0206 rxnsToAdd.lb=-inf(size(rxnsToAdd.mets)); +0207 elseif ~isnumeric(rxnsToAdd.lb) +0208 EM = 'rxnsToAdd.lb must be a vector'; +0209 dispEM(EM); +0210 elseif length(rxnsToAdd.lb) ~= length(rxnsToAdd.mets) +0211 EM = 'rxnsToAdd.lb must have the same number of elements as rxnsToAdd.mets'; +0212 dispEM(EM); +0213 end +0214 %Now we construct equations, to comply with the rest of the script: +0215 rxnsToAdd.equations = cell(size(rxnsToAdd.mets)); +0216 for i = 1:length(rxnsToAdd.mets) +0217 mets = rxnsToAdd.mets{i}; +0218 stoichCoeffs = rxnsToAdd.stoichCoeffs{i}; +0219 if isfield(rxnsToAdd,'ub') +0220 isrev = rxnsToAdd.lb(i) < 0 && rxnsToAdd.ub(i) > 0; +0221 else +0222 isrev = rxnsToAdd.lb(i) < 0; +0223 end +0224 rxnsToAdd.equations{i} = buildEquation(mets,stoichCoeffs,isrev); +0225 end +0226 end +0227 +0228 nRxns=numel(rxnsToAdd.rxns); +0229 nOldRxns=numel(model.rxns); +0230 filler=cell(nRxns,1); +0231 filler(:)={''}; +0232 cellfiller=cellfun(@(x) cell(0,0),filler,'UniformOutput',false); +0233 largeFiller=cell(nOldRxns,1); +0234 largeFiller(:)={''}; +0235 celllargefiller=cellfun(@(x) cell(0,0),largeFiller,'UniformOutput',false); +0236 +0237 %***Add everything to the model except for the equations. +0238 if numel(rxnsToAdd.equations)~=nRxns +0239 EM='rxnsToAdd.equations must have the same number of elements as rxnsToAdd.rxns'; +0240 dispEM(EM); +0241 end +0242 +0243 %Parse the equations. This is done at this early stage since I need the +0244 %reversibility info +0245 [S, mets, badRxns, reversible]=constructS(rxnsToAdd.equations); +0246 EM='The following equations have one or more metabolites both as substrate and product. Only the net equations will be added:'; +0247 dispEM(EM,false,rxnsToAdd.rxns(badRxns)); +0248 +0249 newModel.rev=[newModel.rev;reversible]; +0250 newModel.rxns=[newModel.rxns;rxnsToAdd.rxns(:)]; +0251 +0252 if isfield(rxnsToAdd,'rxnNames') +0253 rxnsToAdd.rxnNames=convertCharArray(rxnsToAdd.rxnNames); +0254 if numel(rxnsToAdd.rxnNames)~=nRxns +0255 EM='rxnsToAdd.rxnNames must have the same number of elements as rxnsToAdd.rxns'; +0256 dispEM(EM); +0257 end +0258 %Fill with standard if it doesn't exist +0259 if ~isfield(newModel,'rxnNames') +0260 newModel.rxnNames=largeFiller; +0261 end +0262 newModel.rxnNames=[newModel.rxnNames;rxnsToAdd.rxnNames(:)]; +0263 else +0264 %Fill with standard if it doesn't exist +0265 if isfield(newModel,'rxnNames') +0266 newModel.rxnNames=[newModel.rxnNames;filler]; +0267 end +0268 end +0269 +0270 if isfield(newModel,'annotation') & isfield(newModel.annotation,'defaultLB') +0271 newLb=newModel.annotation.defaultLB; +0272 else +0273 newLb=-inf; +0274 end +0275 +0276 if isfield(rxnsToAdd,'lb') +0277 if numel(rxnsToAdd.lb)~=nRxns +0278 EM='rxnsToAdd.lb must have the same number of elements as rxnsToAdd.rxns'; +0279 dispEM(EM); +0280 end +0281 %Fill with standard if it doesn't exist +0282 if ~isfield(newModel,'lb') +0283 newModel.lb=zeros(nOldRxns,1); +0284 newModel.lb(newModel.rev~=0)=newLb; +0285 end +0286 newModel.lb=[newModel.lb;rxnsToAdd.lb(:)]; +0287 else +0288 %Fill with standard if it doesn't exist +0289 if isfield(newModel,'lb') +0290 I=zeros(nRxns,1); +0291 I(reversible~=0)=newLb; +0292 newModel.lb=[newModel.lb;I]; +0293 end +0294 end +0295 +0296 if isfield(newModel,'annotation') & isfield(newModel.annotation,'defaultUB') +0297 newUb=newModel.annotation.defaultUB; +0298 else +0299 newUb=inf; +0300 end +0301 +0302 if isfield(rxnsToAdd,'ub') +0303 if numel(rxnsToAdd.ub)~=nRxns +0304 EM='rxnsToAdd.ub must have the same number of elements as rxnsToAdd.rxns'; +0305 dispEM(EM); +0306 end +0307 %Fill with standard if it doesn't exist +0308 if ~isfield(newModel,'ub') +0309 newModel.ub=repmat(newUb,nOldRxns,1); +0310 end +0311 newModel.ub=[newModel.ub;rxnsToAdd.ub(:)]; +0312 else +0313 %Fill with standard if it doesn't exist +0314 if isfield(newModel,'ub') +0315 newModel.ub=[newModel.ub;repmat(newUb,nRxns,1)]; +0316 end +0317 end +0318 +0319 if isfield(rxnsToAdd,'c') +0320 if numel(rxnsToAdd.c)~=nRxns +0321 EM='rxnsToAdd.c must have the same number of elements as rxnsToAdd.rxns'; +0322 dispEM(EM); +0323 end +0324 %Fill with standard if it doesn't exist +0325 if ~isfield(newModel,'c') +0326 newModel.c=zeros(nOldRxns,1); +0327 end +0328 newModel.c=[newModel.c;rxnsToAdd.c(:)]; +0329 else +0330 %Fill with standard if it doesn't exist +0331 if isfield(newModel,'c') +0332 newModel.c=[newModel.c;zeros(nRxns,1)]; +0333 end +0334 end +0335 +0336 if isfield(rxnsToAdd,'eccodes') +0337 rxnsToAdd.eccodes=convertCharArray(rxnsToAdd.eccodes); +0338 if numel(rxnsToAdd.eccodes)~=nRxns +0339 EM='rxnsToAdd.eccodes must have the same number of elements as rxnsToAdd.rxns'; +0340 dispEM(EM); +0341 end +0342 %Fill with standard if it doesn't exist +0343 if ~isfield(newModel,'eccodes') +0344 newModel.eccodes=largeFiller; +0345 end +0346 newModel.eccodes=[newModel.eccodes;rxnsToAdd.eccodes(:)]; +0347 else +0348 %Fill with standard if it doesn't exist +0349 if isfield(newModel,'eccodes') +0350 newModel.eccodes=[newModel.eccodes;filler]; +0351 end +0352 end +0353 +0354 if isfield(rxnsToAdd,'subSystems') +0355 if numel(rxnsToAdd.subSystems)~=nRxns +0356 EM='rxnsToAdd.subSystems must have the same number of elements as rxnsToAdd.rxns'; +0357 dispEM(EM); +0358 end +0359 for i=1:numel(rxnsToAdd.subSystems) +0360 if ischar(rxnsToAdd.subSystems{i}) +0361 rxnsToAdd.subSystems{i}=rxnsToAdd.subSystems(i); +0362 end +0363 end +0364 %Fill with standard if it doesn't exist +0365 if ~isfield(newModel,'subSystems') +0366 newModel.subSystems=celllargefiller; +0367 end +0368 newModel.subSystems=[newModel.subSystems;rxnsToAdd.subSystems]; +0369 else +0370 %Fill with standard if it doesn't exist +0371 if isfield(newModel,'subSystems') +0372 newModel.subSystems=[newModel.subSystems;cellfiller]; +0373 end +0374 end +0375 if isfield(rxnsToAdd,'rxnMiriams') +0376 if numel(rxnsToAdd.rxnMiriams)~=nRxns +0377 EM='rxnsToAdd.rxnMiriams must have the same number of elements as rxnsToAdd.rxns'; +0378 dispEM(EM); +0379 end +0380 %Fill with standard if it doesn't exist +0381 if ~isfield(newModel,'rxnMiriams') +0382 newModel.rxnMiriams=cell(nOldRxns,1); +0383 end +0384 newModel.rxnMiriams=[newModel.rxnMiriams;rxnsToAdd.rxnMiriams(:)]; +0385 else +0386 %Fill with standard if it doesn't exist +0387 if isfield(newModel,'rxnMiriams') +0388 newModel.rxnMiriams=[newModel.rxnMiriams;cell(nRxns,1)]; +0389 end +0390 end +0391 if isfield(rxnsToAdd,'rxnComps') +0392 if numel(rxnsToAdd.rxnComps)~=nRxns +0393 EM='rxnsToAdd.rxnComps must have the same number of elements as rxnsToAdd.rxns'; +0394 dispEM(EM); +0395 end +0396 %Fill with standard if it doesn't exist +0397 if ~isfield(newModel,'rxnComps') +0398 newModel.rxnComps=ones(nOldRxns,1); +0399 EM='Adding reactions with compartment information to a model without such information. All existing reactions will be assigned to the first compartment'; +0400 dispEM(EM,false); +0401 end +0402 newModel.rxnComps=[newModel.rxnComps;rxnsToAdd.rxnComps(:)]; +0403 else +0404 %Fill with standard if it doesn't exist +0405 if isfield(newModel,'rxnComps') +0406 newModel.rxnComps=[newModel.rxnComps;ones(nRxns,1)]; +0407 %fprintf('NOTE: The added reactions will be assigned to the first +0408 %compartment\n'); +0409 end +0410 end +0411 if isfield(rxnsToAdd,'grRules') +0412 rxnsToAdd.grRules=convertCharArray(rxnsToAdd.grRules); +0413 if numel(rxnsToAdd.grRules)~=nRxns +0414 EM='rxnsToAdd.grRules must have the same number of elements as rxnsToAdd.rxns'; +0415 dispEM(EM); +0416 end +0417 %Fill with standard if it doesn't exist +0418 if ~isfield(newModel,'grRules') +0419 newModel.grRules=largeFiller; +0420 end +0421 newModel.grRules=[newModel.grRules;rxnsToAdd.grRules(:)]; +0422 else +0423 %Fill with standard if it doesn't exist +0424 if isfield(newModel,'grRules') +0425 newModel.grRules=[newModel.grRules;filler]; +0426 end +0427 end +0428 +0429 if isfield(rxnsToAdd,'rxnFrom') +0430 rxnsToAdd.rxnFrom=convertCharArray(rxnsToAdd.rxnFrom); +0431 if numel(rxnsToAdd.rxnFrom)~=nRxns +0432 EM='rxnsToAdd.rxnFrom must have the same number of elements as rxnsToAdd.rxns'; +0433 dispEM(EM); +0434 end +0435 %Fill with standard if it doesn't exist +0436 if ~isfield(newModel,'rxnFrom') +0437 newModel.rxnFrom=largeFiller; +0438 end +0439 newModel.rxnFrom=[newModel.rxnFrom;rxnsToAdd.rxnFrom(:)]; +0440 else +0441 %Fill with standard if it doesn't exist +0442 if isfield(newModel,'rxnFrom') +0443 newModel.rxnFrom=[newModel.rxnFrom;filler]; +0444 end +0445 end +0446 +0447 if isfield(rxnsToAdd,'rxnNotes') +0448 rxnsToAdd.rxnNotes=convertCharArray(rxnsToAdd.rxnNotes); +0449 if numel(rxnsToAdd.rxnNotes)~=nRxns +0450 EM='rxnsToAdd.rxnNotes must have the same number of elements as rxnsToAdd.rxns'; +0451 dispEM(EM); +0452 end +0453 %Fill with standard if it doesn't exist +0454 if ~isfield(newModel,'rxnNotes') +0455 newModel.rxnNotes=largeFiller; +0456 end +0457 newModel.rxnNotes=[newModel.rxnNotes;rxnsToAdd.rxnNotes(:)]; +0458 else +0459 %Fill with standard if it doesn't exist +0460 if isfield(newModel,'rxnNotes') +0461 newModel.rxnNotes=[newModel.rxnNotes;filler]; +0462 end +0463 end +0464 +0465 if isfield(rxnsToAdd,'rxnReferences') +0466 rxnsToAdd.rxnReferences=convertCharArray(rxnsToAdd.rxnReferences); +0467 if numel(rxnsToAdd.rxnReferences)~=nRxns +0468 EM='rxnsToAdd.rxnReferences must have the same number of elements as rxnsToAdd.rxns'; +0469 dispEM(EM); +0470 end +0471 %Fill with standard if it doesn't exist +0472 if ~isfield(newModel,'rxnReferences') +0473 newModel.rxnReferences=largeFiller; +0474 end +0475 newModel.rxnReferences=[newModel.rxnReferences;rxnsToAdd.rxnReferences(:)]; +0476 else +0477 %Fill with standard if it doesn't exist +0478 if isfield(newModel,'rxnReferences') +0479 newModel.rxnReferences=[newModel.rxnReferences;filler]; +0480 end +0481 end +0482 +0483 if isfield(rxnsToAdd,'pwys') +0484 rxnsToAdd.pwys=convertCharArray(rxnsToAdd.pwys); +0485 if numel(rxnsToAdd.pwys)~=nRxns +0486 EM='rxnsToAdd.pwys must have the same number of elements as rxnsToAdd.rxns'; +0487 dispEM(EM); +0488 end +0489 %Fill with standard if it doesn't exist +0490 if ~isfield(newModel,'pwys') +0491 newModel.pwys=largeFiller; +0492 end +0493 newModel.pwys=[newModel.pwys;rxnsToAdd.pwys(:)]; +0494 else +0495 %Fill with standard if it doesn't exist +0496 if isfield(newModel,'pwys') +0497 newModel.pwys=[newModel.pwys;filler]; +0498 end +0499 end +0500 +0501 if isfield(rxnsToAdd,'rxnConfidenceScores') +0502 if numel(rxnsToAdd.rxnConfidenceScores)~=nRxns +0503 EM='rxnsToAdd.rxnConfidenceScores must have the same number of elements as rxnsToAdd.rxns'; +0504 dispEM(EM); +0505 end +0506 %Fill with standard if it doesn't exist +0507 if ~isfield(newModel,'rxnConfidenceScores') +0508 newModel.rxnConfidenceScores=NaN(nOldRxns,1); 0509 end 0510 newModel.rxnConfidenceScores=[newModel.rxnConfidenceScores;rxnsToAdd.rxnConfidenceScores(:)]; 0511 else @@ -659,150 +661,167 @@

SOURCE CODE ^end 0516 end 0517 -0518 -0519 %***Start parsing the equations and adding the info to the S matrix The -0520 %mets are matched to model.mets -0521 if eqnType==1 -0522 [I, J]=ismember(mets,model.mets); -0523 if ~all(I) -0524 if allowNewMets==true || ischar(allowNewMets) -0525 %Add the new mets -0526 metsToAdd.mets=mets(~I); -0527 metsToAdd.metNames=metsToAdd.mets; -0528 metsToAdd.compartments=compartment; -0529 if ischar(allowNewMets) -0530 newModel=addMets(newModel,metsToAdd,true,allowNewMets); -0531 else -0532 newModel=addMets(newModel,metsToAdd,true); -0533 end -0534 else -0535 EM='One or more equations contain metabolites that are not in model.mets. Set allowNewMets to true to allow this function to add metabolites or use addMets to add them before calling this function. Are you sure that eqnType=1?'; -0536 dispEM(EM); -0537 end -0538 end -0539 %Calculate the indexes of the metabolites and add the info -0540 metIndexes=J; -0541 metIndexes(~I)=numel(newModel.mets)-sum(~I)+1:numel(newModel.mets); -0542 end -0543 -0544 %Do some stuff that is the same for eqnType=2 and eqnType=3 -0545 if eqnType==2 || eqnType==3 -0546 %For later.. -0547 t2=strcat(model.metNames,'***',model.comps(model.metComps)); -0548 end -0549 -0550 %The mets are matched to model.metNames and assigned to "compartment" -0551 if eqnType==2 -0552 %%Check that the metabolite names aren't present in the same -0553 %%compartment. -0554 %Not the neatest way maybe.. -0555 t1=strcat(mets,'***',compartment); -0556 [I, J]=ismember(t1,t2); -0557 -0558 if ~all(I) -0559 if allowNewMets==true || ischar(allowNewMets) -0560 %Add the new mets -0561 metsToAdd.metNames=mets(~I); -0562 metsToAdd.compartments=compartment; -0563 if ischar(allowNewMets) -0564 newModel=addMets(newModel,metsToAdd,true,allowNewMets); -0565 else -0566 newModel=addMets(newModel,metsToAdd,true); -0567 end -0568 else -0569 EM='One or more equations contain metabolites that are not in model.mets. Set allowNewMets to true to allow this function to add metabolites or use addMets to add them before calling this function'; -0570 dispEM(EM); -0571 end -0572 end -0573 -0574 %Calculate the indexes of the metabolites -0575 metIndexes=J; -0576 metIndexes(~I)=numel(newModel.mets)-sum(~I)+1:numel(newModel.mets); -0577 end -0578 -0579 %The equations are on the form metNames[compName] -0580 if eqnType==3 -0581 %Parse the metabolite names -0582 metNames=cell(numel(mets),1); -0583 compartments=metNames; -0584 for i=1:numel(mets) -0585 starts=max(strfind(mets{i},'[')); -0586 ends=max(strfind(mets{i},']')); -0587 -0588 %Check that the formatting is correct -0589 if isempty(starts) || isempty(ends) || ends<numel(mets{i}) -0590 EM=['The metabolite ' mets{i} ' is not correctly formatted for eqnType=3']; -0591 dispEM(EM); -0592 end -0593 -0594 %Check that the compartment is correct -0595 compartments{i}=mets{i}(starts+1:ends-1); -0596 I=ismember(compartments(i),newModel.comps); -0597 if ~I -0598 EM=['The metabolite ' mets{i} ' has a compartment that is not in model.comps']; -0599 dispEM(EM); -0600 end -0601 metNames{i}=mets{i}(1:starts-1); -0602 end -0603 -0604 %Check if the metabolite exists already -0605 t1=strcat(metNames,'***',compartments); -0606 [I, J]=ismember(t1,t2); -0607 -0608 if ~all(I) -0609 if allowNewMets==true | ischar(allowNewMets) -0610 %Add the new mets -0611 metsToAdd.metNames=metNames(~I); -0612 metsToAdd.compartments=compartments(~I); -0613 if ischar(allowNewMets) -0614 newModel=addMets(newModel,metsToAdd,true,allowNewMets); -0615 else -0616 newModel=addMets(newModel,metsToAdd,true); -0617 end -0618 else -0619 EM='One or more equations contain metabolites that are not in model.metNames. Set allowNewMets to true to allow this function to add metabolites or use addMets to add them before calling this function'; -0620 dispEM(EM); -0621 end -0622 end -0623 -0624 %Calculate the indexes of the metabolites -0625 metIndexes=J; -0626 metIndexes(~I)=numel(newModel.mets)-sum(~I)+1:numel(newModel.mets); -0627 end -0628 -0629 %Add the info to the stoichiometric matrix -0630 newModel.S=[newModel.S sparse(size(newModel.S,1),nRxns)]; -0631 -0632 for i=1:nRxns -0633 newModel.S(metIndexes,nOldRxns+i)=S(:,i); -0634 %Parse the grRules and check whether all genes in grRules appear in -0635 %genes -0636 if isfield(newModel,'grRules') -0637 rule=newModel.grRules{nOldRxns+i}; -0638 rule=strrep(rule,'(',''); -0639 rule=strrep(rule,')',''); -0640 rule=strrep(rule,' or ',' '); -0641 rule=strrep(rule,' and ',' '); -0642 genes=regexp(rule,' ','split'); -0643 [I, J]=ismember(genes,newModel.genes); -0644 if ~all(I) && any(rule) -0645 EM=['Not all genes for reaction ' rxnsToAdd.rxns{i} ' were found in model.genes. If needed, add genes with addGenesRaven before calling this function, or set the ''allowNewGenes'' flag to true']; -0646 dispEM(EM); -0647 end -0648 end -0649 end -0650 -0651 %Make temporary minimal model structure with only new rxns, to parse to -0652 %standardizeGrRules -0653 newRxnsModel.genes=newModel.genes; -0654 newRxnsModel.grRules=newModel.grRules(length(model.rxns)+1:end); -0655 newRxnsModel.rxns=newModel.rxns(length(model.rxns)+1:end); -0656 -0657 %Fix grRules and reconstruct rxnGeneMat -0658 [grRules,rxnGeneMat] = standardizeGrRules(newRxnsModel,true); -0659 newModel.rxnGeneMat = [newModel.rxnGeneMat; rxnGeneMat]; -0660 newModel.grRules = [newModel.grRules(1:nOldRxns); grRules]; -0661 end +0518 if isfield(rxnsToAdd,'rxnDeltaG') +0519 if numel(rxnsToAdd.rxnDeltaG)~=nRxns +0520 EM='rxnsToAdd.rxnDeltaG must have the same number of elements as rxnsToAdd.rxns'; +0521 dispEM(EM); +0522 end +0523 %Fill with standard if it doesn't exist +0524 if ~isfield(newModel,'rxnDeltaG') +0525 newModel.rxnDeltaG=NaN(nOldRxns,1); +0526 end +0527 newModel.rxnDeltaG=[newModel.rxnDeltaG;rxnsToAdd.rxnDeltaG(:)]; +0528 else +0529 %Fill with standard if it doesn't exist +0530 if isfield(newModel,'rxnDeltaG') +0531 newModel.rxnDeltaG=[newModel.rxnDeltaG;NaN(nRxns,1)]; +0532 end +0533 end +0534 +0535 +0536 %***Start parsing the equations and adding the info to the S matrix The +0537 %mets are matched to model.mets +0538 if eqnType==1 +0539 [I, J]=ismember(mets,model.mets); +0540 if ~all(I) +0541 if allowNewMets==true || ischar(allowNewMets) +0542 %Add the new mets +0543 metsToAdd.mets=mets(~I); +0544 metsToAdd.metNames=metsToAdd.mets; +0545 metsToAdd.compartments=compartment; +0546 if ischar(allowNewMets) +0547 newModel=addMets(newModel,metsToAdd,true,allowNewMets); +0548 else +0549 newModel=addMets(newModel,metsToAdd,true); +0550 end +0551 else +0552 EM='One or more equations contain metabolites that are not in model.mets. Set allowNewMets to true to allow this function to add metabolites or use addMets to add them before calling this function. Are you sure that eqnType=1?'; +0553 dispEM(EM); +0554 end +0555 end +0556 %Calculate the indexes of the metabolites and add the info +0557 metIndexes=J; +0558 metIndexes(~I)=numel(newModel.mets)-sum(~I)+1:numel(newModel.mets); +0559 end +0560 +0561 %Do some stuff that is the same for eqnType=2 and eqnType=3 +0562 if eqnType==2 || eqnType==3 +0563 %For later.. +0564 t2=strcat(model.metNames,'***',model.comps(model.metComps)); +0565 end +0566 +0567 %The mets are matched to model.metNames and assigned to "compartment" +0568 if eqnType==2 +0569 %%Check that the metabolite names aren't present in the same +0570 %%compartment. +0571 %Not the neatest way maybe.. +0572 t1=strcat(mets,'***',compartment); +0573 [I, J]=ismember(t1,t2); +0574 +0575 if ~all(I) +0576 if allowNewMets==true || ischar(allowNewMets) +0577 %Add the new mets +0578 metsToAdd.metNames=mets(~I); +0579 metsToAdd.compartments=compartment; +0580 if ischar(allowNewMets) +0581 newModel=addMets(newModel,metsToAdd,true,allowNewMets); +0582 else +0583 newModel=addMets(newModel,metsToAdd,true); +0584 end +0585 else +0586 EM='One or more equations contain metabolites that are not in model.mets. Set allowNewMets to true to allow this function to add metabolites or use addMets to add them before calling this function'; +0587 dispEM(EM); +0588 end +0589 end +0590 +0591 %Calculate the indexes of the metabolites +0592 metIndexes=J; +0593 metIndexes(~I)=numel(newModel.mets)-sum(~I)+1:numel(newModel.mets); +0594 end +0595 +0596 %The equations are on the form metNames[compName] +0597 if eqnType==3 +0598 %Parse the metabolite names +0599 metNames=cell(numel(mets),1); +0600 compartments=metNames; +0601 for i=1:numel(mets) +0602 starts=max(strfind(mets{i},'[')); +0603 ends=max(strfind(mets{i},']')); +0604 +0605 %Check that the formatting is correct +0606 if isempty(starts) || isempty(ends) || ends<numel(mets{i}) +0607 EM=['The metabolite ' mets{i} ' is not correctly formatted for eqnType=3']; +0608 dispEM(EM); +0609 end +0610 +0611 %Check that the compartment is correct +0612 compartments{i}=mets{i}(starts+1:ends-1); +0613 I=ismember(compartments(i),newModel.comps); +0614 if ~I +0615 EM=['The metabolite ' mets{i} ' has a compartment that is not in model.comps']; +0616 dispEM(EM); +0617 end +0618 metNames{i}=mets{i}(1:starts-1); +0619 end +0620 +0621 %Check if the metabolite exists already +0622 t1=strcat(metNames,'***',compartments); +0623 [I, J]=ismember(t1,t2); +0624 +0625 if ~all(I) +0626 if allowNewMets==true | ischar(allowNewMets) +0627 %Add the new mets +0628 metsToAdd.metNames=metNames(~I); +0629 metsToAdd.compartments=compartments(~I); +0630 if ischar(allowNewMets) +0631 newModel=addMets(newModel,metsToAdd,true,allowNewMets); +0632 else +0633 newModel=addMets(newModel,metsToAdd,true); +0634 end +0635 else +0636 EM='One or more equations contain metabolites that are not in model.metNames. Set allowNewMets to true to allow this function to add metabolites or use addMets to add them before calling this function'; +0637 dispEM(EM); +0638 end +0639 end +0640 +0641 %Calculate the indexes of the metabolites +0642 metIndexes=J; +0643 metIndexes(~I)=numel(newModel.mets)-sum(~I)+1:numel(newModel.mets); +0644 end +0645 +0646 %Add the info to the stoichiometric matrix +0647 newModel.S=[newModel.S sparse(size(newModel.S,1),nRxns)]; +0648 +0649 for i=1:nRxns +0650 newModel.S(metIndexes,nOldRxns+i)=S(:,i); +0651 %Parse the grRules and check whether all genes in grRules appear in +0652 %genes +0653 if isfield(newModel,'grRules') +0654 rule=newModel.grRules{nOldRxns+i}; +0655 rule=strrep(rule,'(',''); +0656 rule=strrep(rule,')',''); +0657 rule=strrep(rule,' or ',' '); +0658 rule=strrep(rule,' and ',' '); +0659 genes=regexp(rule,' ','split'); +0660 [I, J]=ismember(genes,newModel.genes); +0661 if ~all(I) && any(rule) +0662 EM=['Not all genes for reaction ' rxnsToAdd.rxns{i} ' were found in model.genes. If needed, add genes with addGenesRaven before calling this function, or set the ''allowNewGenes'' flag to true']; +0663 dispEM(EM); +0664 end +0665 end +0666 end +0667 +0668 %Make temporary minimal model structure with only new rxns, to parse to +0669 %standardizeGrRules +0670 newRxnsModel.genes=newModel.genes; +0671 newRxnsModel.grRules=newModel.grRules(length(model.rxns)+1:end); +0672 newRxnsModel.rxns=newModel.rxns(length(model.rxns)+1:end); +0673 +0674 %Fix grRules and reconstruct rxnGeneMat +0675 [grRules,rxnGeneMat] = standardizeGrRules(newRxnsModel,true); +0676 newModel.rxnGeneMat = [newModel.rxnGeneMat; rxnGeneMat]; +0677 newModel.grRules = [newModel.grRules(1:nOldRxns); grRules]; +0678 end
Generated by m2html © 2005
\ No newline at end of file diff --git a/doc/core/addRxnsGenesMets.html b/doc/core/addRxnsGenesMets.html index 0ed9e07f..15dd7667 100644 --- a/doc/core/addRxnsGenesMets.html +++ b/doc/core/addRxnsGenesMets.html @@ -203,14 +203,14 @@

SOURCE CODE ^if isfield(sourceModel,'metFormulas') 0117 metsToAdd.metFormulas=sourceModel.metFormulas(metIdx); 0118 end -0119 if isfield(sourceModel,'metCharge') -0120 metsToAdd.metCharge=sourceModel.metCharge(metIdx); +0119 if isfield(sourceModel,'metCharges') +0120 metsToAdd.metCharges=sourceModel.metCharges(metIdx); 0121 end 0122 if isfield(sourceModel,'metMiriams') 0123 metsToAdd.metMiriams=sourceModel.metMiriams(metIdx); 0124 end -0125 if isfield(sourceModel,'metFormulas') -0126 metsToAdd.metFormulas=sourceModel.metFormulas(metIdx); +0125 if isfield(sourceModel,'metNotes') +0126 metsToAdd.metNotes=sourceModel.metNotes(metIdx); 0127 end 0128 if isfield(sourceModel,'inchis') 0129 metsToAdd.inchis=sourceModel.inchis(metIdx); @@ -218,50 +218,56 @@

SOURCE CODE ^if isfield(sourceModel,'metSmiles') 0132 metsToAdd.metSmiles=sourceModel.metSmiles(metIdx); 0133 end -0134 -0135 metsToAdd.compartments=strtrim(cellstr(num2str(sourceModel.metComps(metIdx)))); % Convert from compartment string to compartment number -0136 [~,idx]=ismember(metsToAdd.compartments,strsplit(num2str(1:length(sourceModel.comps)))); % Match compartment number to compartment abbreviation -0137 metsToAdd.compartments=sourceModel.comps(idx); % Fill in compartment abbreviations -0138 -0139 model=addMets(model,metsToAdd); -0140 end -0141 fprintf('\nNumber of metabolites added to the model:\n') -0142 fprintf([num2str(numel(metIdx)),'\n']) -0143 -0144 % Add new genes -0145 if ~islogical(addGene) | addGene ~= false -0146 if ischar(addGene) -0147 rxnToAdd.grRules={addGene}; -0148 elseif iscell(addGene) -0149 rxnToAdd.grRules=addGene(~notNewRxn); -0150 else -0151 rxnToAdd.grRules=sourceModel.grRules(rxnIdx); % Get the relevant grRules -0152 end -0153 end -0154 % Add new reactions -0155 rxnToAdd.equations=constructEquations(sourceModel,rxnIdx); -0156 rxnToAdd.rxnNames=sourceModel.rxnNames(rxnIdx); -0157 rxnToAdd.rxns=sourceModel.rxns(rxnIdx); -0158 rxnToAdd.lb=sourceModel.lb(rxnIdx); -0159 rxnToAdd.ub=sourceModel.ub(rxnIdx); -0160 rxnToAdd.rxnNotes(:)=rxnNote(~notNewRxn); -0161 rxnToAdd.rxnConfidenceScores=NaN(1,numel(rxnToAdd.rxns)); -0162 if ~isnumeric(confidence) -0163 EM='confidence score must be numeric'; -0164 dispEM(EM, true); -0165 end -0166 rxnToAdd.rxnConfidenceScores(:)=confidence; -0167 if isfield(sourceModel,'subSystems') -0168 rxnToAdd.subSystems=sourceModel.subSystems(rxnIdx); -0169 end -0170 if isfield(sourceModel,'eccodes') -0171 rxnToAdd.eccodes=sourceModel.eccodes(rxnIdx); +0134 if isfield(sourceModel,'metDeltaG') +0135 metsToAdd.metDeltaG=sourceModel.metDeltaG(metIdx); +0136 end +0137 +0138 metsToAdd.compartments=strtrim(cellstr(num2str(sourceModel.metComps(metIdx)))); % Convert from compartment string to compartment number +0139 [~,idx]=ismember(metsToAdd.compartments,strsplit(num2str(1:length(sourceModel.comps)))); % Match compartment number to compartment abbreviation +0140 metsToAdd.compartments=sourceModel.comps(idx); % Fill in compartment abbreviations +0141 +0142 model=addMets(model,metsToAdd); +0143 end +0144 fprintf('\nNumber of metabolites added to the model:\n') +0145 fprintf([num2str(numel(metIdx)),'\n']) +0146 +0147 % Add new genes +0148 if ~islogical(addGene) | addGene ~= false +0149 if ischar(addGene) +0150 rxnToAdd.grRules={addGene}; +0151 elseif iscell(addGene) +0152 rxnToAdd.grRules=addGene(~notNewRxn); +0153 else +0154 rxnToAdd.grRules=sourceModel.grRules(rxnIdx); % Get the relevant grRules +0155 end +0156 end +0157 % Add new reactions +0158 rxnToAdd.equations=constructEquations(sourceModel,rxnIdx); +0159 rxnToAdd.rxnNames=sourceModel.rxnNames(rxnIdx); +0160 rxnToAdd.rxns=sourceModel.rxns(rxnIdx); +0161 rxnToAdd.lb=sourceModel.lb(rxnIdx); +0162 rxnToAdd.ub=sourceModel.ub(rxnIdx); +0163 rxnToAdd.rxnNotes(:)=rxnNote(~notNewRxn); +0164 rxnToAdd.rxnConfidenceScores=NaN(1,numel(rxnToAdd.rxns)); +0165 if ~isnumeric(confidence) +0166 EM='confidence score must be numeric'; +0167 dispEM(EM, true); +0168 end +0169 rxnToAdd.rxnConfidenceScores(:)=confidence; +0170 if isfield(sourceModel,'rxnDeltaG') +0171 rxnToAdd.rxnDeltaG=sourceModel.rxnDeltaG(rxnIdx); 0172 end -0173 model=addRxns(model,rxnToAdd,3,'',false,true); -0174 -0175 fprintf('\nNumber of reactions added to the model:\n') -0176 fprintf([num2str(numel(rxnIdx)),'\n']) -0177 end +0173 if isfield(sourceModel,'subSystems') +0174 rxnToAdd.subSystems=sourceModel.subSystems(rxnIdx); +0175 end +0176 if isfield(sourceModel,'eccodes') +0177 rxnToAdd.eccodes=sourceModel.eccodes(rxnIdx); +0178 end +0179 model=addRxns(model,rxnToAdd,3,'',false,true); +0180 +0181 fprintf('\nNumber of reactions added to the model:\n') +0182 fprintf([num2str(numel(rxnIdx)),'\n']) +0183 end
Generated by m2html © 2005
\ No newline at end of file diff --git a/doc/core/addTransport.html b/doc/core/addTransport.html index 4c81dae1..f1dd635c 100644 --- a/doc/core/addTransport.html +++ b/doc/core/addTransport.html @@ -235,9 +235,12 @@

SOURCE CODE ^if isfield(model,'rxnConfidenceScores') 0168 model.rxnConfidenceScores=[model.rxnConfidenceScores;ones(nRxns,1)]; 0169 end -0170 addedRxns = [addedRxns; addedRxnsID]; -0171 end -0172 end +0170 if isfield(model,'rxnDeltaG') +0171 model.rxnDeltaG=[model.rxnDeltaG;zeros(nRxns,1)]; +0172 end +0173 addedRxns = [addedRxns; addedRxnsID]; +0174 end +0175 end
Generated by m2html © 2005
\ No newline at end of file diff --git a/doc/core/changeRxns.html b/doc/core/changeRxns.html index 10c1310c..21518c46 100644 --- a/doc/core/changeRxns.html +++ b/doc/core/changeRxns.html @@ -225,22 +225,25 @@

SOURCE CODE ^if isfield(model,'rxnConfidenceScores') 0130 rxnsToChange.rxnConfidenceScores=model.rxnConfidenceScores(J); 0131 end -0132 if isfield(model,'pwys') -0133 rxnsToChange.pwys=model.pwys(J); +0132 if isfield(model,'rxnDeltaG') +0133 rxnsToChange.rxnDeltaG=model.rxnDeltaG(J); 0134 end -0135 -0136 %Calculate the new order of reactions -0137 order=ones(numel(model.rxns),1); -0138 order(J)=0; -0139 order=cumsum(order); -0140 order(J)=order(end)+1:order(end)+numel(rxns); -0141 -0142 %Remove the original reactions -0143 model=removeReactions(model,rxns); +0135 if isfield(model,'pwys') +0136 rxnsToChange.pwys=model.pwys(J); +0137 end +0138 +0139 %Calculate the new order of reactions +0140 order=ones(numel(model.rxns),1); +0141 order(J)=0; +0142 order=cumsum(order); +0143 order(J)=order(end)+1:order(end)+numel(rxns); 0144 -0145 model=addRxns(model,rxnsToChange,eqnType,compartment,allowNewMets); -0146 model=permuteModel(model,order,'rxns'); -0147 end +0145 %Remove the original reactions +0146 model=removeReactions(model,rxns); +0147 +0148 model=addRxns(model,rxnsToChange,eqnType,compartment,allowNewMets); +0149 model=permuteModel(model,order,'rxns'); +0150 end
Generated by m2html © 2005
\ No newline at end of file diff --git a/doc/core/checkModelStruct.html b/doc/core/checkModelStruct.html index 18a56263..e7a691b4 100644 --- a/doc/core/checkModelStruct.html +++ b/doc/core/checkModelStruct.html @@ -210,229 +210,274 @@

SOURCE CODE ^dispEM(EM,throwErrors); 0152 end 0153 end -0154 if isfield(model,'subSystems') -0155 for i=1:numel(model.subSystems) -0156 if ~iscell(model.subSystems{i,1}) -0157 EM='The "subSystems" field must be a cell array'; -0158 dispEM(EM,throwErrors); -0159 end -0160 end -0161 end -0162 if isfield(model,'eccodes') -0163 if ~iscellstr(model.eccodes) -0164 EM='The "eccodes" field must be a cell array of strings'; -0165 dispEM(EM,throwErrors); +0154 if isfield(model,'metDeltaG') +0155 if ~isnumeric(model.metDeltaG) +0156 EM='The "metDeltaG" field must be a double'; +0157 dispEM(EM,throwErrors); +0158 end +0159 end +0160 if isfield(model,'subSystems') +0161 for i=1:numel(model.subSystems) +0162 if ~iscell(model.subSystems{i,1}) +0163 EM='The "subSystems" field must be a cell array'; +0164 dispEM(EM,throwErrors); +0165 end 0166 end 0167 end -0168 if isfield(model,'unconstrained') -0169 if ~isnumeric(model.unconstrained) -0170 EM='The "unconstrained" field must be of type "double"'; +0168 if isfield(model,'eccodes') +0169 if ~iscellstr(model.eccodes) +0170 EM='The "eccodes" field must be a cell array of strings'; 0171 dispEM(EM,throwErrors); 0172 end 0173 end -0174 if isfield(model,'rxnNotes') -0175 if ~iscellstr(model.rxnNotes) -0176 EM='The "rxnNotes" field must be a cell array of strings'; +0174 if isfield(model,'unconstrained') +0175 if ~isnumeric(model.unconstrained) +0176 EM='The "unconstrained" field must be of type "double"'; 0177 dispEM(EM,throwErrors); 0178 end 0179 end -0180 if isfield(model,'rxnReferences') -0181 if ~iscellstr(model.rxnReferences) -0182 EM='The "rxnReferences" field must be a cell array of strings'; +0180 if isfield(model,'rxnNotes') +0181 if ~iscellstr(model.rxnNotes) +0182 EM='The "rxnNotes" field must be a cell array of strings'; 0183 dispEM(EM,throwErrors); 0184 end 0185 end -0186 if isfield(model,'rxnConfidenceScores') -0187 if ~isnumeric(model.rxnConfidenceScores) -0188 EM='The "rxnConfidenceScores" field must be a double'; +0186 if isfield(model,'rxnReferences') +0187 if ~iscellstr(model.rxnReferences) +0188 EM='The "rxnReferences" field must be a cell array of strings'; 0189 dispEM(EM,throwErrors); 0190 end 0191 end -0192 -0193 %Empty strings -0194 if isempty(model.id) -0195 EM='The "id" field cannot be empty'; -0196 dispEM(EM,throwErrors); +0192 if isfield(model,'rxnConfidenceScores') +0193 if ~isnumeric(model.rxnConfidenceScores) +0194 EM='The "rxnConfidenceScores" field must be a double'; +0195 dispEM(EM,throwErrors); +0196 end 0197 end -0198 if any(cellfun(@isempty,model.rxns)) -0199 EM='The model contains empty reaction IDs'; -0200 dispEM(EM,throwErrors); -0201 end -0202 if any(cellfun(@isempty,model.mets)) -0203 EM='The model contains empty metabolite IDs'; -0204 dispEM(EM,throwErrors); -0205 end -0206 if any(cellfun(@isempty,model.comps)) -0207 EM='The model contains empty compartment IDs'; +0198 if isfield(model,'rxnDeltaG') +0199 if ~isnumeric(model.rxnDeltaG) +0200 EM='The "rxnDeltaG" field must be a double'; +0201 dispEM(EM,throwErrors); +0202 end +0203 end +0204 +0205 %Empty strings +0206 if isempty(model.id) +0207 EM='The "id" field cannot be empty'; 0208 dispEM(EM,throwErrors); 0209 end -0210 EM='The following metabolites have empty names:'; -0211 dispEM(EM,throwErrors,model.mets(cellfun(@isempty,model.metNames)),trimWarnings); -0212 -0213 if isfield(model,'genes') -0214 if any(cellfun(@isempty,model.genes)) -0215 EM='The model contains empty gene IDs'; -0216 dispEM(EM,throwErrors); -0217 end -0218 end -0219 -0220 %Duplicates -0221 EM='The following reaction IDs are duplicates:'; -0222 dispEM(EM,throwErrors,model.rxns(duplicates(model.rxns)),trimWarnings); -0223 EM='The following metabolite IDs are duplicates:'; -0224 dispEM(EM,throwErrors,model.mets(duplicates(model.mets)),trimWarnings); -0225 EM='The following compartment IDs are duplicates:'; -0226 dispEM(EM,throwErrors,model.comps(duplicates(model.comps)),trimWarnings); -0227 if isfield(model,'genes') -0228 EM='The following genes are duplicates:'; -0229 dispEM(EM,throwErrors,model.genes(duplicates(model.genes)),trimWarnings); +0210 if any(cellfun(@isempty,model.rxns)) +0211 EM='The model contains empty reaction IDs'; +0212 dispEM(EM,throwErrors); +0213 end +0214 if any(cellfun(@isempty,model.mets)) +0215 EM='The model contains empty metabolite IDs'; +0216 dispEM(EM,throwErrors); +0217 end +0218 if any(cellfun(@isempty,model.comps)) +0219 EM='The model contains empty compartment IDs'; +0220 dispEM(EM,throwErrors); +0221 end +0222 EM='The following metabolites have empty names:'; +0223 dispEM(EM,throwErrors,model.mets(cellfun(@isempty,model.metNames)),trimWarnings); +0224 +0225 if isfield(model,'genes') +0226 if any(cellfun(@isempty,model.genes)) +0227 EM='The model contains empty gene IDs'; +0228 dispEM(EM,throwErrors); +0229 end 0230 end -0231 metInComp=strcat(model.metNames,'[',model.comps(model.metComps),']'); -0232 EM='The following metabolites already exist in the same compartment:'; -0233 dispEM(EM,throwErrors,metInComp(duplicates(metInComp)),trimWarnings); -0234 -0235 %Elements never used (print only as warnings -0236 EM='The following reactions are empty (no involved metabolites):'; -0237 dispEM(EM,false,model.rxns(~any(model.S,1)),trimWarnings); -0238 EM='The following metabolites are never used in a reaction:'; -0239 dispEM(EM,false,model.mets(~any(model.S,2)),trimWarnings); -0240 if isfield(model,'genes') -0241 EM='The following genes are not associated to a reaction:'; -0242 dispEM(EM,false,model.genes(~any(model.rxnGeneMat,1)),trimWarnings); -0243 end -0244 I=true(numel(model.comps),1); -0245 I(model.metComps)=false; -0246 EM='The following compartments contain no metabolites:'; -0247 dispEM(EM,false,model.comps(I),trimWarnings); -0248 -0249 %Contradicting bounds -0250 EM='The following reactions have contradicting bounds:'; -0251 dispEM(EM,throwErrors,model.rxns(model.lb>model.ub),trimWarnings); -0252 EM='The following reactions have bounds contradicting their reversibility:'; -0253 dispEM(EM,throwErrors,model.rxns(model.lb<0 & model.rev==0),trimWarnings); -0254 -0255 %Multiple or no objective functions not allowed in SBML L3V1 FBCv2 -0256 if numel(find(model.c))>1 -0257 EM='Multiple objective functions found. This might be intended, but results in FBCv2 non-compliant SBML file when exported'; -0258 dispEM(EM,false,model.rxns(find(model.c)),trimWarnings); -0259 elseif ~any(model.c) -0260 EM='No objective function found. This might be intended, but results in FBCv2 non-compliant SBML file when exported'; -0261 dispEM(EM,false); -0262 end -0263 -0264 EM='The following reactions have contradicting bounds:'; -0265 dispEM(EM,throwErrors,model.rxns(model.lb>model.ub),trimWarnings); +0231 +0232 %Duplicates +0233 EM='The following reaction IDs are duplicates:'; +0234 dispEM(EM,throwErrors,model.rxns(duplicates(model.rxns)),trimWarnings); +0235 EM='The following metabolite IDs are duplicates:'; +0236 dispEM(EM,throwErrors,model.mets(duplicates(model.mets)),trimWarnings); +0237 EM='The following compartment IDs are duplicates:'; +0238 dispEM(EM,throwErrors,model.comps(duplicates(model.comps)),trimWarnings); +0239 if isfield(model,'genes') +0240 EM='The following genes are duplicates:'; +0241 dispEM(EM,throwErrors,model.genes(duplicates(model.genes)),trimWarnings); +0242 end +0243 metInComp=strcat(model.metNames,'[',model.comps(model.metComps),']'); +0244 EM='The following metabolites already exist in the same compartment:'; +0245 dispEM(EM,throwErrors,metInComp(duplicates(metInComp)),trimWarnings); +0246 +0247 %Elements never used (print only as warnings +0248 EM='The following reactions are empty (no involved metabolites):'; +0249 dispEM(EM,false,model.rxns(~any(model.S,1)),trimWarnings); +0250 EM='The following metabolites are never used in a reaction:'; +0251 dispEM(EM,false,model.mets(~any(model.S,2)),trimWarnings); +0252 if isfield(model,'genes') +0253 EM='The following genes are not associated to a reaction:'; +0254 dispEM(EM,false,model.genes(~any(model.rxnGeneMat,1)),trimWarnings); +0255 end +0256 I=true(numel(model.comps),1); +0257 I(model.metComps)=false; +0258 EM='The following compartments contain no metabolites:'; +0259 dispEM(EM,false,model.comps(I),trimWarnings); +0260 +0261 %Contradicting bounds +0262 EM='The following reactions have contradicting bounds:'; +0263 dispEM(EM,throwErrors,model.rxns(model.lb>model.ub),trimWarnings); +0264 EM='The following reactions have bounds contradicting their reversibility:'; +0265 dispEM(EM,throwErrors,model.rxns(model.lb<0 & model.rev==0),trimWarnings); 0266 -0267 %Mapping of compartments -0268 if isfield(model,'compOutside') -0269 EM='The following compartments are in "compOutside" but not in "comps":'; -0270 dispEM(EM,throwErrors,setdiff(model.compOutside,[{''};model.comps]),trimWarnings); -0271 end -0272 -0273 %Met names which start with number -0274 I=false(numel(model.metNames),1); -0275 for i=1:numel(model.metNames) -0276 index=strfind(model.metNames{i},' '); -0277 if any(index) -0278 if any(str2double(model.metNames{i}(1:index(1)-1))) -0279 I(i)=true; -0280 end -0281 end -0282 end -0283 EM='The following metabolite IDs begin with a number directly followed by space:'; -0284 dispEM(EM,throwErrors,model.mets(I),trimWarnings); -0285 -0286 %Non-parseable composition -0287 if isfield(model,'metFormulas') -0288 [~, ~, exitFlag]=parseFormulas(model.metFormulas,true,false); -0289 EM='The composition for the following metabolites could not be parsed:'; -0290 dispEM(EM,false,model.mets(exitFlag==-1),trimWarnings); -0291 end -0292 -0293 %Check if there are metabolites with different names but the same MIRIAM -0294 %codes -0295 if isfield(model,'metMiriams') -0296 miriams=containers.Map(); -0297 for i=1:numel(model.mets) -0298 if ~isempty(model.metMiriams{i}) -0299 %Loop through and add for each miriam -0300 for j=1:numel(model.metMiriams{i}.name) -0301 %Get existing metabolite indexes -0302 current=strcat(model.metMiriams{i}.name{j},'/',model.metMiriams{i}.value{j}); -0303 if isKey(miriams,current) -0304 existing=miriams(current); -0305 else -0306 existing=[]; -0307 end -0308 miriams(current)=[existing;i]; -0309 end -0310 end -0311 end -0312 -0313 %Get all keys -0314 allMiriams=keys(miriams); -0315 -0316 hasMultiple=false(numel(allMiriams),1); -0317 for i=1:numel(allMiriams) -0318 if numel(miriams(allMiriams{i}))>1 -0319 %Check if they all have the same name -0320 if numel(unique(model.metNames(miriams(allMiriams{i}))))>1 -0321 if ~regexp(allMiriams{i},'^sbo\/SBO:') % SBO terms are expected to be multiple -0322 hasMultiple(i)=true; -0323 end -0324 end -0325 end -0326 end +0267 %Multiple or no objective functions not allowed in SBML L3V1 FBCv2 +0268 if numel(find(model.c))>1 +0269 EM='Multiple objective functions found. This might be intended, but results in FBCv2 non-compliant SBML file when exported'; +0270 dispEM(EM,false,model.rxns(find(model.c)),trimWarnings); +0271 elseif ~any(model.c) +0272 EM='No objective function found. This might be intended, but results in FBCv2 non-compliant SBML file when exported'; +0273 dispEM(EM,false); +0274 end +0275 +0276 EM='The following reactions have contradicting bounds:'; +0277 dispEM(EM,throwErrors,model.rxns(model.lb>model.ub),trimWarnings); +0278 +0279 %Mapping of compartments +0280 if isfield(model,'compOutside') +0281 EM='The following compartments are in "compOutside" but not in "comps":'; +0282 dispEM(EM,throwErrors,setdiff(model.compOutside,[{''};model.comps]),trimWarnings); +0283 end +0284 +0285 %Met names which start with number +0286 I=false(numel(model.metNames),1); +0287 for i=1:numel(model.metNames) +0288 index=strfind(model.metNames{i},' '); +0289 if any(index) +0290 if any(str2double(model.metNames{i}(1:index(1)-1))) +0291 I(i)=true; +0292 end +0293 end +0294 end +0295 EM='The following metabolite IDs begin with a number directly followed by space:'; +0296 dispEM(EM,throwErrors,model.mets(I),trimWarnings); +0297 +0298 %Non-parseable composition +0299 if isfield(model,'metFormulas') +0300 [~, ~, exitFlag]=parseFormulas(model.metFormulas,true,false); +0301 EM='The composition for the following metabolites could not be parsed:'; +0302 dispEM(EM,false,model.mets(exitFlag==-1),trimWarnings); +0303 end +0304 +0305 %Check if there are metabolites with different names but the same MIRIAM +0306 %codes +0307 if isfield(model,'metMiriams') +0308 miriams=containers.Map(); +0309 for i=1:numel(model.mets) +0310 if ~isempty(model.metMiriams{i}) +0311 %Loop through and add for each miriam +0312 for j=1:numel(model.metMiriams{i}.name) +0313 %Get existing metabolite indexes +0314 current=strcat(model.metMiriams{i}.name{j},'/',model.metMiriams{i}.value{j}); +0315 if isKey(miriams,current) +0316 existing=miriams(current); +0317 else +0318 existing=[]; +0319 end +0320 miriams(current)=[existing;i]; +0321 end +0322 end +0323 end +0324 +0325 %Get all keys +0326 allMiriams=keys(miriams); 0327 -0328 %Print output -0329 EM='The following MIRIAM strings are associated to more than one unique metabolite name:'; -0330 dispEM(EM,false,allMiriams(hasMultiple),trimWarnings); -0331 end -0332 -0333 %Check if there are metabolites with different names but the same InChI -0334 %codes -0335 if isfield(model,'inchis') -0336 inchis=containers.Map(); -0337 for i=1:numel(model.mets) -0338 if ~isempty(model.inchis{i}) -0339 %Get existing metabolite indexes -0340 if isKey(inchis,model.inchis{i}) -0341 existing=inchis(model.inchis{i}); -0342 else -0343 existing=[]; -0344 end -0345 inchis(model.inchis{i})=[existing;i]; -0346 end -0347 end -0348 -0349 %Get all keys -0350 allInchis=keys(inchis); -0351 -0352 hasMultiple=false(numel(allInchis),1); -0353 for i=1:numel(allInchis) -0354 if numel(inchis(allInchis{i}))>1 -0355 %Check if they all have the same name -0356 if numel(unique(model.metNames(inchis(allInchis{i}))))>1 -0357 hasMultiple(i)=true; -0358 end -0359 end -0360 end -0361 -0362 %Print output -0363 EM='The following InChI strings are associated to more than one unique metabolite name:'; -0364 dispEM(EM,false,allInchis(hasMultiple),trimWarnings); -0365 end -0366 end -0367 -0368 function I=duplicates(strings) -0369 I=false(numel(strings),1); -0370 [J, K]=unique(strings); -0371 if numel(J)~=numel(strings) -0372 L=1:numel(strings); -0373 L(K)=[]; -0374 I(L)=true; -0375 end -0376 end +0328 hasMultiple=false(numel(allMiriams),1); +0329 for i=1:numel(allMiriams) +0330 if numel(miriams(allMiriams{i}))>1 +0331 %Check if they all have the same name +0332 if numel(unique(model.metNames(miriams(allMiriams{i}))))>1 +0333 if ~regexp(allMiriams{i},'^sbo\/SBO:') % SBO terms are expected to be multiple +0334 hasMultiple(i)=true; +0335 end +0336 end +0337 end +0338 end +0339 +0340 %Print output +0341 EM='The following MIRIAM strings are associated to more than one unique metabolite name:'; +0342 dispEM(EM,false,allMiriams(hasMultiple),trimWarnings); +0343 end +0344 +0345 %Check if there are metabolites with different names but the same InChI +0346 %codes +0347 if isfield(model,'inchis') +0348 inchis=containers.Map(); +0349 for i=1:numel(model.mets) +0350 if ~isempty(model.inchis{i}) +0351 %Get existing metabolite indexes +0352 if isKey(inchis,model.inchis{i}) +0353 existing=inchis(model.inchis{i}); +0354 else +0355 existing=[]; +0356 end +0357 inchis(model.inchis{i})=[existing;i]; +0358 end +0359 end +0360 +0361 %Get all keys +0362 allInchis=keys(inchis); +0363 +0364 hasMultiple=false(numel(allInchis),1); +0365 for i=1:numel(allInchis) +0366 if numel(inchis(allInchis{i}))>1 +0367 %Check if they all have the same name +0368 if numel(unique(model.metNames(inchis(allInchis{i}))))>1 +0369 hasMultiple(i)=true; +0370 end +0371 end +0372 end +0373 +0374 %Print output +0375 EM='The following InChI strings are associated to more than one unique metabolite name:'; +0376 dispEM(EM,false,allInchis(hasMultiple),trimWarnings); +0377 end +0378 +0379 % %Check if there are metabolites with different names but the same SMILES +0380 % if isfield(model,'metSmiles') +0381 % metSmiles=containers.Map(); +0382 % for i=1:numel(model.mets) +0383 % if ~isempty(model.metSmiles{i}) +0384 % %Get existing metabolite indexes +0385 % if isKey(metSmiles,model.metSmiles{i}) +0386 % existing=metSmiles(model.metSmiles{i}); +0387 % else +0388 % existing=[]; +0389 % end +0390 % metSmiles(model.metSmiles{i})=[existing;i]; +0391 % end +0392 % end +0393 % +0394 % %Get all keys +0395 % allmetSmiles=keys(metSmiles); +0396 % +0397 % hasMultiple=false(numel(metSmiles),1); +0398 % for i=1:numel(metSmiles) +0399 % if numel(metSmiles(metSmiles{i}))>1 +0400 % %Check if they all have the same name +0401 % if numel(unique(model.metNames(metSmiles(allmetSmiles{i}))))>1 +0402 % hasMultiple(i)=true; +0403 % end +0404 % end +0405 % end +0406 % +0407 % %Print output +0408 % EM='The following metSmiles strings are associated to more than one unique metabolite name:'; +0409 % dispEM(EM,false,allmetSmiles(hasMultiple),trimWarnings); +0410 % end +0411 end +0412 +0413 function I=duplicates(strings) +0414 I=false(numel(strings),1); +0415 [J, K]=unique(strings); +0416 if numel(J)~=numel(strings) +0417 L=1:numel(strings); +0418 L(K)=[]; +0419 I(L)=true; +0420 end +0421 end
Generated by m2html © 2005
\ No newline at end of file diff --git a/doc/core/convertToIrrev.html b/doc/core/convertToIrrev.html index 806244aa..124797db 100644 --- a/doc/core/convertToIrrev.html +++ b/doc/core/convertToIrrev.html @@ -158,22 +158,25 @@

SOURCE CODE ^if isfield(irrevModel,'rxnConfidenceScores') 0097 irrevModel.rxnConfidenceScores=[irrevModel.rxnConfidenceScores;irrevModel.rxnConfidenceScores(revIndexes)]; 0098 end -0099 if isfield(irrevModel,'rxnReferences') -0100 irrevModel.rxnReferences=[irrevModel.rxnReferences;irrevModel.rxnReferences(revIndexes)]; +0099 if isfield(irrevModel,'rxnDeltaG') +0100 irrevModel.rxnDeltaG=[irrevModel.rxnDeltaG;-irrevModel.rxnDeltaG(revIndexes)]; % Invert dG for reversed rxns 0101 end -0102 end -0103 % Additional output -0104 if nargout>1 -0105 irrev2rev = [transpose(1:numOrigRxns);revIndexes]; -0106 rev2irrev = num2cell(transpose(1:numOrigRxns)); -0107 newIdxs = [revIndexes transpose(1:numRevRxns)]; -0108 for i=1:numRevRxns -0109 rev2irrev{revIndexes(i)} = newIdxs(i,:); -0110 end -0111 matchRev = zeros(numel(irrev2rev),1); -0112 matchRev(revIndexes) = (1:numRevRxns)+numOrigRxns; -0113 end -0114 end +0102 if isfield(irrevModel,'rxnReferences') +0103 irrevModel.rxnReferences=[irrevModel.rxnReferences;irrevModel.rxnReferences(revIndexes)]; +0104 end +0105 end +0106 % Additional output +0107 if nargout>1 +0108 irrev2rev = [transpose(1:numOrigRxns);revIndexes]; +0109 rev2irrev = num2cell(transpose(1:numOrigRxns)); +0110 newIdxs = [revIndexes transpose(1:numRevRxns)]; +0111 for i=1:numRevRxns +0112 rev2irrev{revIndexes(i)} = newIdxs(i,:); +0113 end +0114 matchRev = zeros(numel(irrev2rev),1); +0115 matchRev(revIndexes) = (1:numRevRxns)+numOrigRxns; +0116 end +0117 end
Generated by m2html © 2005
\ No newline at end of file diff --git a/doc/core/expandModel.html b/doc/core/expandModel.html index b09ed7d9..d6a7dc18 100644 --- a/doc/core/expandModel.html +++ b/doc/core/expandModel.html @@ -135,75 +135,78 @@

SOURCE CODE ^if isfield(model,'rxnConfidenceScores') 0072 model.rxnConfidenceScores=[model.rxnConfidenceScores;model.rxnConfidenceScores(cpyIndices)]; 0073 end -0074 -0075 %now expand the more complex fields - will be filled in later -0076 model.rxns=[model.rxns;cell(toAdd,1)]; -0077 model.grRules=[model.grRules;cell(toAdd,1)]; -0078 model.rxnGeneMat=[model.rxnGeneMat;sparse(toAdd,size(model.rxnGeneMat,2))]; -0079 -0080 %Loop throught those reactions and fill in the expanded data -0081 nextIndex = prevNumRxns + 1; -0082 for i=1:prevNumRxns -0083 if (numOrs(i) > 0) -0084 %Check that it doesn't contain nested 'and' and 'or' relations and -0085 %print a warning if it does -0086 if ~isempty(strfind(model.grRules{i},' and ')) -0087 rxnToCheck{end+1,1}=model.rxns{i}; -0088 end -0089 -0090 %Get rid of all '(' and ')' since I'm not looking at complex stuff -0091 %anyways -0092 geneString=model.grRules{i}; -0093 geneString=strrep(geneString,'(',''); -0094 geneString=strrep(geneString,')',''); -0095 geneString=strrep(geneString,' or ',';'); -0096 -0097 %Split the string into gene names -0098 geneNames=regexp(geneString,';','split'); +0074 if isfield(model,'rxnDeltaG') +0075 model.rxnDeltaG=[model.rxnDeltaG;model.rxnDeltaG(cpyIndices)]; +0076 end +0077 +0078 %now expand the more complex fields - will be filled in later +0079 model.rxns=[model.rxns;cell(toAdd,1)]; +0080 model.grRules=[model.grRules;cell(toAdd,1)]; +0081 model.rxnGeneMat=[model.rxnGeneMat;sparse(toAdd,size(model.rxnGeneMat,2))]; +0082 +0083 %Loop throught those reactions and fill in the expanded data +0084 nextIndex = prevNumRxns + 1; +0085 for i=1:prevNumRxns +0086 if (numOrs(i) > 0) +0087 %Check that it doesn't contain nested 'and' and 'or' relations and +0088 %print a warning if it does +0089 if ~isempty(strfind(model.grRules{i},' and ')) +0090 rxnToCheck{end+1,1}=model.rxns{i}; +0091 end +0092 +0093 %Get rid of all '(' and ')' since I'm not looking at complex stuff +0094 %anyways +0095 geneString=model.grRules{i}; +0096 geneString=strrep(geneString,'(',''); +0097 geneString=strrep(geneString,')',''); +0098 geneString=strrep(geneString,' or ',';'); 0099 -0100 %Update the reaction to only use the first gene -0101 model.grRules{i}=['(' geneNames{1} ')']; -0102 %Find the gene in the gene list If ' and ' relationship, first -0103 %split the genes -0104 model.rxnGeneMat(i,:)=0; -0105 if ~isempty(strfind(geneNames(1),' and ')) -0106 andGenes=regexp(geneNames{1},' and ','split'); -0107 model.rxnGeneMat(i,ismember(model.genes,andGenes)) = 1; -0108 else -0109 [~, index]=ismember(geneNames(1),model.genes); -0110 model.rxnGeneMat(i,index)=1; -0111 end -0112 -0113 %Insert the reactions at the end of the model and without -0114 %allocating space. This is not nice, but ok for now -0115 for j=2:numel(geneNames) -0116 ind = nextIndex+j-2; -0117 model.rxns{ind}=[model.rxns{i} '_EXP_' num2str(j)]; -0118 -0119 model.grRules{ind}=['(' geneNames{j} ')']; -0120 -0121 if ~isempty(strfind(geneNames(j),' and ')) -0122 andGenes=regexp(geneNames{j},' and ','split'); -0123 model.rxnGeneMat(ind,ismember(model.genes,andGenes)) = 1; -0124 else -0125 model.rxnGeneMat(ind,ismember(model.genes,geneNames(j))) = 1; -0126 end -0127 end -0128 model.rxns{i}=[model.rxns{i}, '_EXP_1']; -0129 nextIndex = nextIndex + numOrs(i); -0130 end -0131 end -0132 newModel=model; -0133 else -0134 %There are no reactions to expand, return the model as is +0100 %Split the string into gene names +0101 geneNames=regexp(geneString,';','split'); +0102 +0103 %Update the reaction to only use the first gene +0104 model.grRules{i}=['(' geneNames{1} ')']; +0105 %Find the gene in the gene list If ' and ' relationship, first +0106 %split the genes +0107 model.rxnGeneMat(i,:)=0; +0108 if ~isempty(strfind(geneNames(1),' and ')) +0109 andGenes=regexp(geneNames{1},' and ','split'); +0110 model.rxnGeneMat(i,ismember(model.genes,andGenes)) = 1; +0111 else +0112 [~, index]=ismember(geneNames(1),model.genes); +0113 model.rxnGeneMat(i,index)=1; +0114 end +0115 +0116 %Insert the reactions at the end of the model and without +0117 %allocating space. This is not nice, but ok for now +0118 for j=2:numel(geneNames) +0119 ind = nextIndex+j-2; +0120 model.rxns{ind}=[model.rxns{i} '_EXP_' num2str(j)]; +0121 +0122 model.grRules{ind}=['(' geneNames{j} ')']; +0123 +0124 if ~isempty(strfind(geneNames(j),' and ')) +0125 andGenes=regexp(geneNames{j},' and ','split'); +0126 model.rxnGeneMat(ind,ismember(model.genes,andGenes)) = 1; +0127 else +0128 model.rxnGeneMat(ind,ismember(model.genes,geneNames(j))) = 1; +0129 end +0130 end +0131 model.rxns{i}=[model.rxns{i}, '_EXP_1']; +0132 nextIndex = nextIndex + numOrs(i); +0133 end +0134 end 0135 newModel=model; -0136 end -0137 -0138 %Fix grRules and reconstruct rxnGeneMat -0139 [grRules,rxnGeneMat] = standardizeGrRules(newModel,true); -0140 newModel.grRules = grRules; -0141 newModel.rxnGeneMat = rxnGeneMat; -0142 end +0136 else +0137 %There are no reactions to expand, return the model as is +0138 newModel=model; +0139 end +0140 +0141 %Fix grRules and reconstruct rxnGeneMat +0142 [grRules,rxnGeneMat] = standardizeGrRules(newModel,true); +0143 newModel.grRules = grRules; +0144 newModel.rxnGeneMat = rxnGeneMat; +0145 end
Generated by m2html © 2005
\ No newline at end of file diff --git a/doc/core/mergeModels.html b/doc/core/mergeModels.html index 84a1fe8b..1d2b818a 100644 --- a/doc/core/mergeModels.html +++ b/doc/core/mergeModels.html @@ -238,393 +238,419 @@

SOURCE CODE ^end 0179 end -0180 -0181 if isfield(models{i},'rxnComps') -0182 if isfield(model,'rxnComps') -0183 model.rxnComps=[model.rxnComps;models{i}.rxnComps]; +0180 +0181 if isfield(models{i},'rxnDeltaG') +0182 if isfield(model,'rxnDeltaG') +0183 model.rxnDeltaG=[model.rxnDeltaG;models{i}.rxnDeltaG]; 0184 else -0185 model.rxnComps=[ones(numel(model.rxns)-numel(models{i}.rxns),1);models{i}.rxnComps]; -0186 fprintf('NOTE: One of the models does not contain compartment information for its reactions. All reactions in that model has been assigned to the first compartment\n'); -0187 end -0188 else -0189 if isfield(model,'rxnComps') -0190 model.rxnComps=[model.rxnComps;ones(numel(models{i}.rxns),1)]; -0191 fprintf('NOTE: One of the models does not contain compartment information for its reactions. All reactions in that model has been assigned to the first compartment\n'); -0192 end -0193 end -0194 -0195 if isfield(models{i},'rxnScores') -0196 if isfield(model,'rxnScores') -0197 model.rxnScores=[model.rxnScores;models{i}.rxnScores]; -0198 else -0199 emptyRS=zeros(numel(model.rxns)-numel(models{i}.rxns),1); -0200 model.rxnScores=[emptyRS;models{i}.rxnScores]; -0201 end -0202 else -0203 if isfield(model,'rxnScores') -0204 emptyRS=zeros(numel(models{i}.rxns),1); -0205 model.rxnScores=[model.rxnScores;emptyRS]; -0206 end -0207 end -0208 -0209 if isfield(models{i},'pwys') -0210 if isfield(model,'pwys') -0211 model.pwys=[model.pwys;models{i}.pwys]; -0212 else -0213 model.pwys=[cell(numel(model.rxns)-numel(models{i}.rxns),1);models{i}.pwys]; -0214 end -0215 else -0216 if isfield(model,'pwys') -0217 model.pwys=[model.pwys;cell(numel(models{i}.rxns),1)]; +0185 model.rxnDeltaG=[NaN(numel(model.rxns)-numel(models{i}.rxns),1);models{i}.rxnDeltaG]; +0186 end +0187 else +0188 if isfield(model,'rxnDeltaG') +0189 model.rxnDeltaG=[model.rxnDeltaG;NaN(numel(models{i}.rxns),1)]; +0190 end +0191 end +0192 +0193 if isfield(models{i},'rxnComps') +0194 if isfield(model,'rxnComps') +0195 model.rxnComps=[model.rxnComps;models{i}.rxnComps]; +0196 else +0197 model.rxnComps=[ones(numel(model.rxns)-numel(models{i}.rxns),1);models{i}.rxnComps]; +0198 fprintf('NOTE: One of the models does not contain compartment information for its reactions. All reactions in that model has been assigned to the first compartment\n'); +0199 end +0200 else +0201 if isfield(model,'rxnComps') +0202 model.rxnComps=[model.rxnComps;ones(numel(models{i}.rxns),1)]; +0203 fprintf('NOTE: One of the models does not contain compartment information for its reactions. All reactions in that model has been assigned to the first compartment\n'); +0204 end +0205 end +0206 +0207 if isfield(models{i},'rxnScores') +0208 if isfield(model,'rxnScores') +0209 model.rxnScores=[model.rxnScores;models{i}.rxnScores]; +0210 else +0211 emptyRS=zeros(numel(model.rxns)-numel(models{i}.rxns),1); +0212 model.rxnScores=[emptyRS;models{i}.rxnScores]; +0213 end +0214 else +0215 if isfield(model,'rxnScores') +0216 emptyRS=zeros(numel(models{i}.rxns),1); +0217 model.rxnScores=[model.rxnScores;emptyRS]; 0218 end 0219 end -0220 -0221 if strcmpi(metParam,'metNames') -0222 %Get the new metabolites from matching the models. Metabolites are said -0223 %to be the same if they share name and compartment id. This means that -0224 %metabolite IDs are not taken into account. -0225 -0226 oldMetComps=model.comps(model.metComps); -0227 oldMets=strcat(model.metNames,'[',oldMetComps,']'); -0228 %This is because it makes a '[]' string if no new metabolites -0229 if ~isempty(models{i}.metNames) -0230 newMetComps=models{i}.comps(models{i}.metComps); -0231 newMets=strcat(models{i}.metNames,'[',newMetComps,']'); -0232 else -0233 newMets={}; -0234 newMetComps={}; -0235 end -0236 tf=ismember(newMets,oldMets); -0237 metsToAdd=find(~tf); -0238 -0239 end -0240 -0241 if strcmpi(metParam,'mets') -0242 %Get the new metabolites from matching the models. Metabolites are matched by metabolite ID (model.mets). -0243 -0244 oldMetComps=model.comps(model.metComps); -0245 oldMets=model.mets; -0246 -0247 if ~isempty(models{i}.mets) -0248 newMetComps=models{i}.comps(models{i}.metComps); -0249 newMets=models{i}.mets; -0250 else -0251 newMets={}; -0252 newMetComps={}; -0253 end -0254 tf=ismember(newMets,oldMets); -0255 metsToAdd=find(~tf); -0256 -0257 end +0220 +0221 if isfield(models{i},'pwys') +0222 if isfield(model,'pwys') +0223 model.pwys=[model.pwys;models{i}.pwys]; +0224 else +0225 model.pwys=[cell(numel(model.rxns)-numel(models{i}.rxns),1);models{i}.pwys]; +0226 end +0227 else +0228 if isfield(model,'pwys') +0229 model.pwys=[model.pwys;cell(numel(models{i}.rxns),1)]; +0230 end +0231 end +0232 +0233 if strcmpi(metParam,'metNames') +0234 %Get the new metabolites from matching the models. Metabolites are said +0235 %to be the same if they share name and compartment id. This means that +0236 %metabolite IDs are not taken into account. +0237 +0238 oldMetComps=model.comps(model.metComps); +0239 oldMets=strcat(model.metNames,'[',oldMetComps,']'); +0240 %This is because it makes a '[]' string if no new metabolites +0241 if ~isempty(models{i}.metNames) +0242 newMetComps=models{i}.comps(models{i}.metComps); +0243 newMets=strcat(models{i}.metNames,'[',newMetComps,']'); +0244 else +0245 newMets={}; +0246 newMetComps={}; +0247 end +0248 tf=ismember(newMets,oldMets); +0249 metsToAdd=find(~tf); +0250 +0251 end +0252 +0253 if strcmpi(metParam,'mets') +0254 %Get the new metabolites from matching the models. Metabolites are matched by metabolite ID (model.mets). +0255 +0256 oldMetComps=model.comps(model.metComps); +0257 oldMets=model.mets; 0258 -0259 %First add the new metabolites Make sure that there are no conflicting -0260 %metabolite ids -0261 conflicting=ismember(models{i}.mets(metsToAdd),model.mets); -0262 -0263 conflicting=find(conflicting); -0264 -0265 if ~isempty(conflicting) -0266 printString=cell(numel(conflicting),1); -0267 for j=1:numel(conflicting) -0268 printString{j}=['Old: ' models{i}.mets{metsToAdd(conflicting(j))} ' New: ' models{i}.mets{metsToAdd(conflicting(j))} '_' models{i}.id]; -0269 models{i}.mets{metsToAdd(conflicting(j))}=[models{i}.mets{metsToAdd(conflicting(j))} '_' models{i}.id]; -0270 end -0271 if supressWarnings==false -0272 EM=['The following metabolite IDs in ' models{i}.id ' are already present in the model and were renamed:']; -0273 dispEM(EM,false,printString); -0274 end -0275 end +0259 if ~isempty(models{i}.mets) +0260 newMetComps=models{i}.comps(models{i}.metComps); +0261 newMets=models{i}.mets; +0262 else +0263 newMets={}; +0264 newMetComps={}; +0265 end +0266 tf=ismember(newMets,oldMets); +0267 metsToAdd=find(~tf); +0268 +0269 end +0270 +0271 %First add the new metabolites Make sure that there are no conflicting +0272 %metabolite ids +0273 conflicting=ismember(models{i}.mets(metsToAdd),model.mets); +0274 +0275 conflicting=find(conflicting); 0276 -0277 %Add static info on the metabolites -0278 metFrom=cell(numel(metsToAdd),1); -0279 metFrom(:)={models{i}.id}; -0280 model.metFrom=[model.metFrom;metFrom]; -0281 model.mets=[model.mets;models{i}.mets(metsToAdd)]; -0282 model.metNames=[model.metNames;models{i}.metNames(metsToAdd)]; -0283 model.b=[model.b;zeros(numel(metsToAdd),size(model.b,2))]; -0284 -0285 if isfield(model,'unconstrained') -0286 if isfield(models{i},'unconstrained') -0287 model.unconstrained=[model.unconstrained;models{i}.unconstrained(metsToAdd)]; -0288 else -0289 model.unconstrained=[model.unconstrained;zeros(numel(metsToAdd),1)]; -0290 end -0291 else -0292 if isfield(models{i},'unconstrained') -0293 model.unconstrained=[zeros(numel(model.mets),1);models{i}.unconstrained(metsToAdd)]; -0294 end -0295 end +0277 if ~isempty(conflicting) +0278 printString=cell(numel(conflicting),1); +0279 for j=1:numel(conflicting) +0280 printString{j}=['Old: ' models{i}.mets{metsToAdd(conflicting(j))} ' New: ' models{i}.mets{metsToAdd(conflicting(j))} '_' models{i}.id]; +0281 models{i}.mets{metsToAdd(conflicting(j))}=[models{i}.mets{metsToAdd(conflicting(j))} '_' models{i}.id]; +0282 end +0283 if supressWarnings==false +0284 EM=['The following metabolite IDs in ' models{i}.id ' are already present in the model and were renamed:']; +0285 dispEM(EM,false,printString); +0286 end +0287 end +0288 +0289 %Add static info on the metabolites +0290 metFrom=cell(numel(metsToAdd),1); +0291 metFrom(:)={models{i}.id}; +0292 model.metFrom=[model.metFrom;metFrom]; +0293 model.mets=[model.mets;models{i}.mets(metsToAdd)]; +0294 model.metNames=[model.metNames;models{i}.metNames(metsToAdd)]; +0295 model.b=[model.b;zeros(numel(metsToAdd),size(model.b,2))]; 0296 -0297 %Only add extra info on new metabolites since it's a little tricky to -0298 %chose what to keep otherwise. Should change in the future -0299 -0300 if ~isempty(metsToAdd) -0301 if isfield(models{i},'inchis') -0302 if isfield(model,'inchis') -0303 model.inchis=[model.inchis;models{i}.inchis(metsToAdd)]; -0304 else -0305 emptyInchi=cell(numel(model.mets)-numel(metsToAdd),1); -0306 emptyInchi(:)={''}; -0307 model.inchis=[emptyInchi;models{i}.inchis(metsToAdd)]; -0308 end -0309 else -0310 if isfield(model,'inchis') -0311 emptyInchi=cell(numel(metsToAdd),1); -0312 emptyInchi(:)={''}; -0313 model.inchis=[model.inchis;emptyInchi]; -0314 end -0315 end -0316 -0317 if isfield(models{i},'metSmiles') -0318 if isfield(model,'metSmiles') -0319 model.metSmiles=[model.metSmiles;models{i}.metSmiles(metsToAdd)]; -0320 else -0321 emptyInchi=cell(numel(model.mets)-numel(metsToAdd),1); -0322 emptyInchi(:)={''}; -0323 model.metSmiles=[emptyInchi;models{i}.metSmiles(metsToAdd)]; -0324 end -0325 else -0326 if isfield(model,'metSmiles') -0327 emptyInchi=cell(numel(metsToAdd),1); -0328 emptyInchi(:)={''}; -0329 model.metSmiles=[model.metSmiles;emptyInchi]; -0330 end -0331 end -0332 -0333 if isfield(models{i},'metFormulas') -0334 if isfield(model,'metFormulas') -0335 model.metFormulas=[model.metFormulas;models{i}.metFormulas(metsToAdd)]; -0336 else -0337 emptyMetFormulas=cell(numel(model.mets)-numel(metsToAdd),1); -0338 emptyMetFormulas(:)={''}; -0339 model.metFormulas=[emptyMetFormulas;models{i}.metFormulas(metsToAdd)]; -0340 end -0341 else -0342 if isfield(model,'metFormulas') -0343 emptyMetFormulas=cell(numel(metsToAdd),1); -0344 emptyMetFormulas(:)={''}; -0345 model.metFormulas=[model.metFormulas;emptyMetFormulas]; -0346 end -0347 end -0348 -0349 if isfield(models{i},'metCharges') -0350 if isfield(model,'metCharges') -0351 model.metCharges=[model.metCharges;models{i}.metCharges(metsToAdd)]; -0352 else -0353 emptyMetCharge=nan(numel(model.mets)-numel(metsToAdd),1); -0354 model.metCharges=[emptyMetCharge;models{i}.metCharges(metsToAdd)]; -0355 end -0356 else -0357 if isfield(model,'metCharges') -0358 emptyMetCharge=nan(numel(metsToAdd),1); -0359 model.metCharges=[model.metCharges;emptyMetCharge]; -0360 end -0361 end -0362 -0363 if isfield(models{i},'metMiriams') -0364 if isfield(model,'metMiriams') -0365 model.metMiriams=[model.metMiriams;models{i}.metMiriams(metsToAdd)]; -0366 else -0367 emptyMetMiriam=cell(numel(model.mets)-numel(metsToAdd),1); -0368 model.metMiriams=[emptyMetMiriam;models{i}.metMiriams(metsToAdd)]; -0369 end -0370 else -0371 if isfield(model,'metMiriams') -0372 emptyMetMiriam=cell(numel(metsToAdd),1); -0373 model.metMiriams=[model.metMiriams;emptyMetMiriam]; -0374 end -0375 end -0376 end -0377 -0378 %Add if there are any new compartments and add those. This can change -0379 %the order of compartments and the corresponding indexes in -0380 %model.metComps. -0381 -0382 %Find overlapping and new compartments -0383 [overlap, oldIDs]=ismember(models{i}.comps,model.comps); -0384 overlap=find(overlap); -0385 -0386 %Add the new compartments if any -0387 if numel(overlap)~=numel(models{i}.compNames) -0388 compIndexes=oldIDs==0; -0389 -0390 %Make sure that there are no conflicting compartment ids -0391 [~, conflicting]=ismember(models{i}.compNames(compIndexes),model.compNames); -0392 if any(conflicting) -0393 EM=['The following compartment IDs in ' models{i}.id ' are already present in the model but with another name. They have to be renamed']; -0394 dispEM(EM,true,model.comps(conflicting)); -0395 end -0396 -0397 %It's ok to add duplicate name, but not duplicate IDs -0398 model.compNames=[model.compNames; models{i}.compNames(compIndexes)]; -0399 model.comps=[model.comps; models{i}.comps(compIndexes)]; -0400 if isfield(model,'compOutside') -0401 if isfield(models{i},'compOutside') -0402 model.compOutside=[model.compOutside; models{i}.compOutside(compIndexes)]; -0403 else -0404 %This is if not all models have the field -0405 padding=cell(sum(compIndexes),1); -0406 padding(:)={''}; -0407 model.compOutside=[model.compOutside;padding]; -0408 end -0409 end -0410 if isfield(model,'compMiriams') -0411 if isfield(models{i},'compMiriams') -0412 model.compMiriams=[model.compMiriams; models{i}.compMiriams(compIndexes)]; -0413 else -0414 %This is if not all models have the field -0415 model.compMiriams=[model.compMiriams;cell(sum(compIndexes),1)]; -0416 end -0417 end -0418 end -0419 -0420 %Only add new comp info on the un-matched metabolites since the old -0421 %ones will be mapped to the existing list anyways -0422 [I, J]=ismember(newMetComps(metsToAdd),model.comps); -0423 %Just a check -0424 if ~all(I) -0425 EM='There was an unexpected error in matching compartments'; -0426 dispEM(EM); -0427 end -0428 model.metComps=[model.metComps;J]; -0429 -0430 %Create the new stoichiometric matrix -0431 model.S=[model.S;sparse(numel(metsToAdd),size(model.S,2))]; -0432 -0433 -0434 if strcmpi(metParam,'metNames') -0435 %Rematch metabolite names. Not the most clever way to do it maybe -0436 allMets=strcat(model.metNames,'[',model.comps(model.metComps),']'); -0437 [~, J]=ismember(newMets,allMets); -0438 end -0439 -0440 if strcmpi(metParam,'mets') -0441 %Rematch metabolite by IDs and add unique new metabolites -0442 allMets=model.mets; -0443 uniqueNewMets = setdiff(newMets,oldMets); -0444 allMets(end+1:end+numel(uniqueNewMets)) = uniqueNewMets; -0445 [~, J]=ismember(newMets,allMets); -0446 end -0447 -0448 %Update the stoichiometric matrix for the model to add -0449 newS=sparse(numel(model.mets),numel(models{i}.rxns)); -0450 newS(J,:)=models{i}.S; -0451 model.S=[model.S newS]; -0452 -0453 -0454 %Now add new genes -0455 if isfield(models{i},'genes') -0456 if ~isfield(model,'genes') -0457 %If there was no gene info before -0458 model.genes=models{i}.genes; -0459 model.rxnGeneMat=[sparse(numel(model.rxns),numel(models{i}.genes));models{i}.rxnGeneMat]; -0460 emptyGene=cell(numel(model.rxns),1); -0461 emptyGene(:)={''}; -0462 model.grRules=[emptyGene;models{i}.grRules]; -0463 model.geneFrom=cell(numel(models{i}.genes),1); -0464 model.geneFrom(:)={models{i}.id}; -0465 -0466 if isfield(models{i},'geneShortNames') -0467 model.geneShortNames=models{i}.geneShortNames; -0468 end -0469 -0470 if isfield(models{i},'geneMiriams') -0471 model.geneMiriams=models{i}.geneMiriams; -0472 end -0473 -0474 if isfield(models{i},'geneComps') -0475 model.geneComps=models{i}.geneComps; -0476 end -0477 else -0478 %If gene info should be merged -0479 a=ismember(models{i}.genes,model.genes); -0480 -0481 genesToAdd=find(~a); -0482 -0483 %Only add extra gene info on new genes. This might not be -0484 %correct and should be changed later... -0485 if ~isempty(genesToAdd) -0486 model.genes=[model.genes;models{i}.genes(genesToAdd)]; -0487 emptyGene=cell(numel(genesToAdd),1); -0488 emptyGene(:)={models{i}.id}; -0489 model.geneFrom=[model.geneFrom;emptyGene]; -0490 model.rxnGeneMat=[model.rxnGeneMat sparse(size(model.rxnGeneMat,1),numel(genesToAdd))]; -0491 -0492 if isfield(models{i},'geneShortNames') -0493 if isfield(model,'geneShortNames') -0494 model.geneShortNames=[model.geneShortNames;models{i}.geneShortNames(genesToAdd)]; -0495 else -0496 emptyGeneSN=cell(numel(model.genes)-numel(genesToAdd),1); -0497 emptyGeneSN(:)={''}; -0498 model.geneShortNames=[emptyGeneSN;models{i}.geneShortNames(genesToAdd)]; -0499 end -0500 else -0501 if isfield(model,'geneShortNames') -0502 emptyGeneSN=cell(numel(genesToAdd),1); -0503 emptyGeneSN(:)={''}; -0504 model.geneShortNames=[model.geneShortNames;emptyGeneSN]; -0505 end -0506 end -0507 -0508 if isfield(models{i},'geneMiriams') -0509 if isfield(model,'geneMiriams') -0510 model.geneMiriams=[model.geneMiriams;models{i}.geneMiriams(genesToAdd)]; -0511 else -0512 emptyGeneMir=cell(numel(model.genes)-numel(genesToAdd),1); -0513 model.geneMiriams=[emptyGeneMir;models{i}.geneMiriams(genesToAdd)]; -0514 end -0515 else -0516 if isfield(model,'geneMiriams') -0517 emptyGeneMir=cell(numel(genesToAdd),1); -0518 model.geneMiriams=[model.geneMiriams;emptyGeneMir]; -0519 end -0520 end -0521 -0522 if isfield(models{i},'geneComps') -0523 if isfield(model,'geneComps') -0524 model.geneComps=[model.geneComps;models{i}.geneComps(genesToAdd)]; -0525 else -0526 emptyGeneMir=ones(numel(model.genes)-numel(genesToAdd),1); -0527 model.geneComps=[emptyGeneMir;models{i}.geneComps(genesToAdd)]; -0528 EM='Adding genes with compartment information to a model without such information. All existing genes will be assigned to the first compartment'; -0529 dispEM(EM,false); -0530 end -0531 else -0532 if isfield(model,'geneComps') -0533 emptyGeneMir=ones(numel(genesToAdd),1); -0534 model.geneComps=[model.geneComps;emptyGeneMir]; -0535 EM='Adding genes with compartment information to a model without such information. All existing genes will be assigned to the first compartment'; -0536 dispEM(EM,false); -0537 end -0538 end -0539 end -0540 -0541 %Remap the genes from the new model. The same thing as with -0542 %mets; this is a wasteful way to do it but I don't care right -0543 %now -0544 [a, b]=ismember(models{i}.genes,model.genes); -0545 -0546 %Just a check -0547 if ~all(a) -0548 EM='There was an unexpected error in matching genes'; -0549 dispEM(EM); -0550 end -0551 model.grRules=[model.grRules;models{i}.grRules]; -0552 end -0553 else -0554 %Add empty gene associations -0555 if isfield(model,'genes') -0556 emptyGene=cell(numel(models{i}.rxns),1); -0557 emptyGene(:)={''}; -0558 model.grRules=[model.grRules;emptyGene]; -0559 end -0560 end -0561 end -0562 %Fix grRules and reconstruct rxnGeneMat -0563 [grRules,rxnGeneMat] = standardizeGrRules(model,true); -0564 model.grRules = grRules; -0565 model.rxnGeneMat = rxnGeneMat; -0566 end +0297 if isfield(model,'unconstrained') +0298 if isfield(models{i},'unconstrained') +0299 model.unconstrained=[model.unconstrained;models{i}.unconstrained(metsToAdd)]; +0300 else +0301 model.unconstrained=[model.unconstrained;zeros(numel(metsToAdd),1)]; +0302 end +0303 else +0304 if isfield(models{i},'unconstrained') +0305 model.unconstrained=[zeros(numel(model.mets),1);models{i}.unconstrained(metsToAdd)]; +0306 end +0307 end +0308 +0309 %Only add extra info on new metabolites since it's a little tricky to +0310 %chose what to keep otherwise. Should change in the future +0311 +0312 if ~isempty(metsToAdd) +0313 if isfield(models{i},'inchis') +0314 if isfield(model,'inchis') +0315 model.inchis=[model.inchis;models{i}.inchis(metsToAdd)]; +0316 else +0317 emptyInchi=cell(numel(model.mets)-numel(metsToAdd),1); +0318 emptyInchi(:)={''}; +0319 model.inchis=[emptyInchi;models{i}.inchis(metsToAdd)]; +0320 end +0321 else +0322 if isfield(model,'inchis') +0323 emptyInchi=cell(numel(metsToAdd),1); +0324 emptyInchi(:)={''}; +0325 model.inchis=[model.inchis;emptyInchi]; +0326 end +0327 end +0328 +0329 if isfield(models{i},'metSmiles') +0330 if isfield(model,'metSmiles') +0331 model.metSmiles=[model.metSmiles;models{i}.metSmiles(metsToAdd)]; +0332 else +0333 emptyInchi=cell(numel(model.mets)-numel(metsToAdd),1); +0334 emptyInchi(:)={''}; +0335 model.metSmiles=[emptyInchi;models{i}.metSmiles(metsToAdd)]; +0336 end +0337 else +0338 if isfield(model,'metSmiles') +0339 emptyInchi=cell(numel(metsToAdd),1); +0340 emptyInchi(:)={''}; +0341 model.metSmiles=[model.metSmiles;emptyInchi]; +0342 end +0343 end +0344 +0345 if isfield(models{i},'metFormulas') +0346 if isfield(model,'metFormulas') +0347 model.metFormulas=[model.metFormulas;models{i}.metFormulas(metsToAdd)]; +0348 else +0349 emptyMetFormulas=cell(numel(model.mets)-numel(metsToAdd),1); +0350 emptyMetFormulas(:)={''}; +0351 model.metFormulas=[emptyMetFormulas;models{i}.metFormulas(metsToAdd)]; +0352 end +0353 else +0354 if isfield(model,'metFormulas') +0355 emptyMetFormulas=cell(numel(metsToAdd),1); +0356 emptyMetFormulas(:)={''}; +0357 model.metFormulas=[model.metFormulas;emptyMetFormulas]; +0358 end +0359 end +0360 +0361 if isfield(models{i},'metCharges') +0362 if isfield(model,'metCharges') +0363 model.metCharges=[model.metCharges;models{i}.metCharges(metsToAdd)]; +0364 else +0365 emptyMetCharge=nan(numel(model.mets)-numel(metsToAdd),1); +0366 model.metCharges=[emptyMetCharge;models{i}.metCharges(metsToAdd)]; +0367 end +0368 else +0369 if isfield(model,'metCharges') +0370 emptyMetCharge=nan(numel(metsToAdd),1); +0371 model.metCharges=[model.metCharges;emptyMetCharge]; +0372 end +0373 end +0374 +0375 if isfield(models{i},'metDeltaG') +0376 if isfield(model,'metDeltaG') +0377 model.metDeltaG=[model.metDeltaG;models{i}.metDeltaG(metsToAdd)]; +0378 else +0379 emptyMetCharge=nan(numel(model.mets)-numel(metsToAdd),1); +0380 model.metDeltaG=[emptyMetCharge;models{i}.metDeltaG(metsToAdd)]; +0381 end +0382 else +0383 if isfield(model,'metDeltaG') +0384 emptyMetCharge=nan(numel(metsToAdd),1); +0385 model.metDeltaG=[model.metDeltaG;emptyMetCharge]; +0386 end +0387 end +0388 +0389 if isfield(models{i},'metMiriams') +0390 if isfield(model,'metMiriams') +0391 model.metMiriams=[model.metMiriams;models{i}.metMiriams(metsToAdd)]; +0392 else +0393 emptyMetMiriam=cell(numel(model.mets)-numel(metsToAdd),1); +0394 model.metMiriams=[emptyMetMiriam;models{i}.metMiriams(metsToAdd)]; +0395 end +0396 else +0397 if isfield(model,'metMiriams') +0398 emptyMetMiriam=cell(numel(metsToAdd),1); +0399 model.metMiriams=[model.metMiriams;emptyMetMiriam]; +0400 end +0401 end +0402 end +0403 +0404 %Add if there are any new compartments and add those. This can change +0405 %the order of compartments and the corresponding indexes in +0406 %model.metComps. +0407 +0408 %Find overlapping and new compartments +0409 [overlap, oldIDs]=ismember(models{i}.comps,model.comps); +0410 overlap=find(overlap); +0411 +0412 %Add the new compartments if any +0413 if numel(overlap)~=numel(models{i}.compNames) +0414 compIndexes=oldIDs==0; +0415 +0416 %Make sure that there are no conflicting compartment ids +0417 [~, conflicting]=ismember(models{i}.compNames(compIndexes),model.compNames); +0418 if any(conflicting) +0419 EM=['The following compartment IDs in ' models{i}.id ' are already present in the model but with another name. They have to be renamed']; +0420 dispEM(EM,true,model.comps(conflicting)); +0421 end +0422 +0423 %It's ok to add duplicate name, but not duplicate IDs +0424 model.compNames=[model.compNames; models{i}.compNames(compIndexes)]; +0425 model.comps=[model.comps; models{i}.comps(compIndexes)]; +0426 if isfield(model,'compOutside') +0427 if isfield(models{i},'compOutside') +0428 model.compOutside=[model.compOutside; models{i}.compOutside(compIndexes)]; +0429 else +0430 %This is if not all models have the field +0431 padding=cell(sum(compIndexes),1); +0432 padding(:)={''}; +0433 model.compOutside=[model.compOutside;padding]; +0434 end +0435 end +0436 if isfield(model,'compMiriams') +0437 if isfield(models{i},'compMiriams') +0438 model.compMiriams=[model.compMiriams; models{i}.compMiriams(compIndexes)]; +0439 else +0440 %This is if not all models have the field +0441 model.compMiriams=[model.compMiriams;cell(sum(compIndexes),1)]; +0442 end +0443 end +0444 end +0445 +0446 %Only add new comp info on the un-matched metabolites since the old +0447 %ones will be mapped to the existing list anyways +0448 [I, J]=ismember(newMetComps(metsToAdd),model.comps); +0449 %Just a check +0450 if ~all(I) +0451 EM='There was an unexpected error in matching compartments'; +0452 dispEM(EM); +0453 end +0454 model.metComps=[model.metComps;J]; +0455 +0456 %Create the new stoichiometric matrix +0457 model.S=[model.S;sparse(numel(metsToAdd),size(model.S,2))]; +0458 +0459 +0460 if strcmpi(metParam,'metNames') +0461 %Rematch metabolite names. Not the most clever way to do it maybe +0462 allMets=strcat(model.metNames,'[',model.comps(model.metComps),']'); +0463 [~, J]=ismember(newMets,allMets); +0464 end +0465 +0466 if strcmpi(metParam,'mets') +0467 %Rematch metabolite by IDs and add unique new metabolites +0468 allMets=model.mets; +0469 uniqueNewMets = setdiff(newMets,oldMets); +0470 allMets(end+1:end+numel(uniqueNewMets)) = uniqueNewMets; +0471 [~, J]=ismember(newMets,allMets); +0472 end +0473 +0474 %Update the stoichiometric matrix for the model to add +0475 newS=sparse(numel(model.mets),numel(models{i}.rxns)); +0476 newS(J,:)=models{i}.S; +0477 model.S=[model.S newS]; +0478 +0479 +0480 %Now add new genes +0481 if isfield(models{i},'genes') +0482 if ~isfield(model,'genes') +0483 %If there was no gene info before +0484 model.genes=models{i}.genes; +0485 model.rxnGeneMat=[sparse(numel(model.rxns),numel(models{i}.genes));models{i}.rxnGeneMat]; +0486 emptyGene=cell(numel(model.rxns),1); +0487 emptyGene(:)={''}; +0488 model.grRules=[emptyGene;models{i}.grRules]; +0489 model.geneFrom=cell(numel(models{i}.genes),1); +0490 model.geneFrom(:)={models{i}.id}; +0491 +0492 if isfield(models{i},'geneShortNames') +0493 model.geneShortNames=models{i}.geneShortNames; +0494 end +0495 +0496 if isfield(models{i},'geneMiriams') +0497 model.geneMiriams=models{i}.geneMiriams; +0498 end +0499 +0500 if isfield(models{i},'geneComps') +0501 model.geneComps=models{i}.geneComps; +0502 end +0503 else +0504 %If gene info should be merged +0505 a=ismember(models{i}.genes,model.genes); +0506 +0507 genesToAdd=find(~a); +0508 +0509 %Only add extra gene info on new genes. This might not be +0510 %correct and should be changed later... +0511 if ~isempty(genesToAdd) +0512 model.genes=[model.genes;models{i}.genes(genesToAdd)]; +0513 emptyGene=cell(numel(genesToAdd),1); +0514 emptyGene(:)={models{i}.id}; +0515 model.geneFrom=[model.geneFrom;emptyGene]; +0516 model.rxnGeneMat=[model.rxnGeneMat sparse(size(model.rxnGeneMat,1),numel(genesToAdd))]; +0517 +0518 if isfield(models{i},'geneShortNames') +0519 if isfield(model,'geneShortNames') +0520 model.geneShortNames=[model.geneShortNames;models{i}.geneShortNames(genesToAdd)]; +0521 else +0522 emptyGeneSN=cell(numel(model.genes)-numel(genesToAdd),1); +0523 emptyGeneSN(:)={''}; +0524 model.geneShortNames=[emptyGeneSN;models{i}.geneShortNames(genesToAdd)]; +0525 end +0526 else +0527 if isfield(model,'geneShortNames') +0528 emptyGeneSN=cell(numel(genesToAdd),1); +0529 emptyGeneSN(:)={''}; +0530 model.geneShortNames=[model.geneShortNames;emptyGeneSN]; +0531 end +0532 end +0533 +0534 if isfield(models{i},'geneMiriams') +0535 if isfield(model,'geneMiriams') +0536 model.geneMiriams=[model.geneMiriams;models{i}.geneMiriams(genesToAdd)]; +0537 else +0538 emptyGeneMir=cell(numel(model.genes)-numel(genesToAdd),1); +0539 model.geneMiriams=[emptyGeneMir;models{i}.geneMiriams(genesToAdd)]; +0540 end +0541 else +0542 if isfield(model,'geneMiriams') +0543 emptyGeneMir=cell(numel(genesToAdd),1); +0544 model.geneMiriams=[model.geneMiriams;emptyGeneMir]; +0545 end +0546 end +0547 +0548 if isfield(models{i},'geneComps') +0549 if isfield(model,'geneComps') +0550 model.geneComps=[model.geneComps;models{i}.geneComps(genesToAdd)]; +0551 else +0552 emptyGeneMir=ones(numel(model.genes)-numel(genesToAdd),1); +0553 model.geneComps=[emptyGeneMir;models{i}.geneComps(genesToAdd)]; +0554 EM='Adding genes with compartment information to a model without such information. All existing genes will be assigned to the first compartment'; +0555 dispEM(EM,false); +0556 end +0557 else +0558 if isfield(model,'geneComps') +0559 emptyGeneMir=ones(numel(genesToAdd),1); +0560 model.geneComps=[model.geneComps;emptyGeneMir]; +0561 EM='Adding genes with compartment information to a model without such information. All existing genes will be assigned to the first compartment'; +0562 dispEM(EM,false); +0563 end +0564 end +0565 end +0566 +0567 %Remap the genes from the new model. The same thing as with +0568 %mets; this is a wasteful way to do it but I don't care right +0569 %now +0570 [a, b]=ismember(models{i}.genes,model.genes); +0571 +0572 %Just a check +0573 if ~all(a) +0574 EM='There was an unexpected error in matching genes'; +0575 dispEM(EM); +0576 end +0577 model.grRules=[model.grRules;models{i}.grRules]; +0578 end +0579 else +0580 %Add empty gene associations +0581 if isfield(model,'genes') +0582 emptyGene=cell(numel(models{i}.rxns),1); +0583 emptyGene(:)={''}; +0584 model.grRules=[model.grRules;emptyGene]; +0585 end +0586 end +0587 end +0588 %Fix grRules and reconstruct rxnGeneMat +0589 [grRules,rxnGeneMat] = standardizeGrRules(model,true); +0590 model.grRules = grRules; +0591 model.rxnGeneMat = rxnGeneMat; +0592 end
Generated by m2html © 2005
\ No newline at end of file diff --git a/doc/core/permuteModel.html b/doc/core/permuteModel.html index 01c6b93a..f9ef17da 100644 --- a/doc/core/permuteModel.html +++ b/doc/core/permuteModel.html @@ -133,87 +133,93 @@

SOURCE CODE ^if isfield(newModel,'rxnConfidenceScores') 0077 newModel.rxnConfidenceScores=newModel.rxnConfidenceScores(indexes); 0078 end -0079 case 'mets' -0080 if isfield(newModel,'mets') -0081 newModel.mets=newModel.mets(indexes); -0082 end -0083 if isfield(newModel,'metNames') -0084 newModel.metNames=newModel.metNames(indexes); +0079 if isfield(newModel,'rxnDeltaG') +0080 newModel.rxnDeltaG=newModel.rxnDeltaG(indexes); +0081 end +0082 case 'mets' +0083 if isfield(newModel,'mets') +0084 newModel.mets=newModel.mets(indexes); 0085 end -0086 if isfield(newModel,'b') -0087 newModel.b=newModel.b(indexes,:); +0086 if isfield(newModel,'metNames') +0087 newModel.metNames=newModel.metNames(indexes); 0088 end -0089 if isfield(newModel,'metComps') -0090 newModel.metComps=newModel.metComps(indexes); +0089 if isfield(newModel,'b') +0090 newModel.b=newModel.b(indexes,:); 0091 end -0092 if isfield(newModel,'S') -0093 newModel.S=newModel.S(indexes,:); +0092 if isfield(newModel,'metComps') +0093 newModel.metComps=newModel.metComps(indexes); 0094 end -0095 if isfield(newModel,'unconstrained') -0096 newModel.unconstrained=newModel.unconstrained(indexes); +0095 if isfield(newModel,'S') +0096 newModel.S=newModel.S(indexes,:); 0097 end -0098 if isfield(newModel,'metMiriams') -0099 newModel.metMiriams=newModel.metMiriams(indexes,:); +0098 if isfield(newModel,'unconstrained') +0099 newModel.unconstrained=newModel.unconstrained(indexes); 0100 end -0101 if isfield(newModel,'inchis') -0102 newModel.inchis=newModel.inchis(indexes); +0101 if isfield(newModel,'metMiriams') +0102 newModel.metMiriams=newModel.metMiriams(indexes,:); 0103 end -0104 if isfield(newModel,'metSmiles') -0105 newModel.metSmiles=newModel.metSmiles(indexes); +0104 if isfield(newModel,'inchis') +0105 newModel.inchis=newModel.inchis(indexes); 0106 end -0107 if isfield(newModel,'metFormulas') -0108 newModel.metFormulas=newModel.metFormulas(indexes); +0107 if isfield(newModel,'metSmiles') +0108 newModel.metSmiles=newModel.metSmiles(indexes); 0109 end -0110 if isfield(newModel,'metFrom') -0111 newModel.metFrom=newModel.metFrom(indexes); +0110 if isfield(newModel,'metFormulas') +0111 newModel.metFormulas=newModel.metFormulas(indexes); 0112 end -0113 if isfield(newModel,'metCharges') -0114 newModel.metCharges=newModel.metCharges(indexes); +0113 if isfield(newModel,'metFrom') +0114 newModel.metFrom=newModel.metFrom(indexes); 0115 end -0116 case 'genes' -0117 if isfield(newModel,'genes') -0118 newModel.genes=newModel.genes(indexes); -0119 end -0120 if isfield(newModel,'geneComps') -0121 newModel.geneComps=newModel.geneComps(indexes); -0122 end -0123 if isfield(newModel,'geneMiriams') -0124 newModel.geneMiriams=newModel.geneMiriams(indexes); +0116 if isfield(newModel,'metCharges') +0117 newModel.metCharges=newModel.metCharges(indexes); +0118 end +0119 if isfield(newModel,'metDeltaG') +0120 newModel.metDeltaG=newModel.metDeltaG(indexes); +0121 end +0122 case 'genes' +0123 if isfield(newModel,'genes') +0124 newModel.genes=newModel.genes(indexes); 0125 end -0126 if isfield(newModel,'geneShortNames') -0127 newModel.geneShortNames=newModel.geneShortNames(indexes); +0126 if isfield(newModel,'geneComps') +0127 newModel.geneComps=newModel.geneComps(indexes); 0128 end -0129 if isfield(newModel,'rxnGeneMat') -0130 newModel.rxnGeneMat=newModel.rxnGeneMat(:,indexes); +0129 if isfield(newModel,'geneMiriams') +0130 newModel.geneMiriams=newModel.geneMiriams(indexes); 0131 end -0132 case 'comps' -0133 if isfield(newModel,'comps') -0134 newModel.comps=newModel.comps(indexes); -0135 end -0136 if isfield(newModel,'compNames') -0137 newModel.compNames=newModel.compNames(indexes); -0138 end -0139 if isfield(newModel,'compOutside') -0140 newModel.compOutside=newModel.compOutside(indexes); +0132 if isfield(newModel,'geneShortNames') +0133 newModel.geneShortNames=newModel.geneShortNames(indexes); +0134 end +0135 if isfield(newModel,'rxnGeneMat') +0136 newModel.rxnGeneMat=newModel.rxnGeneMat(:,indexes); +0137 end +0138 case 'comps' +0139 if isfield(newModel,'comps') +0140 newModel.comps=newModel.comps(indexes); 0141 end -0142 if isfield(newModel,'compMiriams') -0143 newModel.compMiriams=newModel.compMiriams(indexes); +0142 if isfield(newModel,'compNames') +0143 newModel.compNames=newModel.compNames(indexes); 0144 end -0145 [~,J]=sort(indexes); % The *index* of compartment is used in next fields -0146 if isfield(newModel,'metComps') -0147 [toreplace, bywhat] = ismember(newModel.metComps,1:length(J)); -0148 newModel.metComps(toreplace) = J(bywhat(toreplace)); -0149 end -0150 if isfield(model,'rxnComps') -0151 [toreplace, bywhat] = ismember(model.rxnComps,1:length(J)); -0152 model.rxnComps(toreplace) = J(bywhat(toreplace)); -0153 end -0154 if isfield(model,'geneComps') -0155 [toreplace, bywhat] = ismember(model.geneComps,1:length(J)); -0156 model.geneComps(toreplace) = J(bywhat(toreplace)); -0157 end -0158 end -0159 end +0145 if isfield(newModel,'compOutside') +0146 newModel.compOutside=newModel.compOutside(indexes); +0147 end +0148 if isfield(newModel,'compMiriams') +0149 newModel.compMiriams=newModel.compMiriams(indexes); +0150 end +0151 [~,J]=sort(indexes); % The *index* of compartment is used in next fields +0152 if isfield(newModel,'metComps') +0153 [toreplace, bywhat] = ismember(newModel.metComps,1:length(J)); +0154 newModel.metComps(toreplace) = J(bywhat(toreplace)); +0155 end +0156 if isfield(model,'rxnComps') +0157 [toreplace, bywhat] = ismember(model.rxnComps,1:length(J)); +0158 model.rxnComps(toreplace) = J(bywhat(toreplace)); +0159 end +0160 if isfield(model,'geneComps') +0161 [toreplace, bywhat] = ismember(model.geneComps,1:length(J)); +0162 model.geneComps(toreplace) = J(bywhat(toreplace)); +0163 end +0164 end +0165 end
Generated by m2html © 2005
\ No newline at end of file diff --git a/doc/core/predictLocalization.html b/doc/core/predictLocalization.html index 7df8b32e..10cb61f7 100644 --- a/doc/core/predictLocalization.html +++ b/doc/core/predictLocalization.html @@ -757,344 +757,353 @@

SOURCE CODE ^if isfield(outModel,'rxnConfidenceScores') 0653 outModel.rxnConfidenceScores=[outModel.rxnConfidenceScores;outModel.rxnConfidenceScores(nER+1:nER+nRxns)]; 0654 end -0655 outModel.mets=[outModel.mets;strcat(outModel.mets(nEM+1:nEM+nMets),'_',GSS.compartments{i+1})]; -0656 outModel.metNames=[outModel.metNames;outModel.metNames(nEM+1:nEM+nMets)]; -0657 outModel.b=[outModel.b;outModel.b(nEM+1:nEM+nMets,:)]; -0658 I=ones(nMets,1)*nStartComps+i; -0659 outModel.metComps=[outModel.metComps;I]; -0660 if isfield(outModel,'inchis') -0661 outModel.inchis=[outModel.inchis;outModel.inchis(nEM+1:nEM+nMets)]; -0662 end -0663 if isfield(outModel,'metSmiles') -0664 outModel.metSmiles=[outModel.metSmiles;outModel.metSmiles(nEM+1:nEM+nMets)]; +0655 if isfield(outModel,'rxnDeltaG') +0656 outModel.rxnDeltaG=[outModel.rxnDeltaG;outModel.rxnDeltaG(nER+1:nER+nRxns)]; +0657 end +0658 outModel.mets=[outModel.mets;strcat(outModel.mets(nEM+1:nEM+nMets),'_',GSS.compartments{i+1})]; +0659 outModel.metNames=[outModel.metNames;outModel.metNames(nEM+1:nEM+nMets)]; +0660 outModel.b=[outModel.b;outModel.b(nEM+1:nEM+nMets,:)]; +0661 I=ones(nMets,1)*nStartComps+i; +0662 outModel.metComps=[outModel.metComps;I]; +0663 if isfield(outModel,'inchis') +0664 outModel.inchis=[outModel.inchis;outModel.inchis(nEM+1:nEM+nMets)]; 0665 end -0666 if isfield(outModel,'unconstrained') -0667 outModel.unconstrained=[outModel.unconstrained;outModel.unconstrained(nEM+1:nEM+nMets)]; +0666 if isfield(outModel,'metSmiles') +0667 outModel.metSmiles=[outModel.metSmiles;outModel.metSmiles(nEM+1:nEM+nMets)]; 0668 end -0669 if isfield(outModel,'metMiriams') -0670 outModel.metMiriams=[outModel.metMiriams;outModel.metMiriams(nEM+1:nEM+nMets)]; +0669 if isfield(outModel,'unconstrained') +0670 outModel.unconstrained=[outModel.unconstrained;outModel.unconstrained(nEM+1:nEM+nMets)]; 0671 end -0672 if isfield(outModel,'metFormulas') -0673 outModel.metFormulas=[outModel.metFormulas;outModel.metFormulas(nEM+1:nEM+nMets)]; +0672 if isfield(outModel,'metMiriams') +0673 outModel.metMiriams=[outModel.metMiriams;outModel.metMiriams(nEM+1:nEM+nMets)]; 0674 end -0675 if isfield(outModel,'metFrom') -0676 outModel.metFrom=[outModel.metFrom;outModel.metFrom(nEM+1:nEM+nMets)]; +0675 if isfield(outModel,'metFormulas') +0676 outModel.metFormulas=[outModel.metFormulas;outModel.metFormulas(nEM+1:nEM+nMets)]; 0677 end -0678 if isfield(outModel,'metCharges') -0679 outModel.metCharges=[outModel.metCharges;outModel.metCharges(nEM+1:nEM+nMets)]; +0678 if isfield(outModel,'metFrom') +0679 outModel.metFrom=[outModel.metFrom;outModel.metFrom(nEM+1:nEM+nMets)]; 0680 end -0681 end -0682 -0683 %Add the transport reactions -0684 transS=bestS(:,numel(outModel.rxns)+1:end); -0685 J=sum(transS)>0; %Active rxns -0686 -0687 %Transport reactions are written in a different way compared to a "real" -0688 %stoichimetric matrix. This is to fix that -0689 transS(transS~=0)=1; -0690 transS(1:nEM+nMets,:)=transS(1:nEM+nMets,:)*-1; -0691 I=find(sum(transS>0,2)); -0692 nTransRxns=numel(I); -0693 outModel.S=[outModel.S transS(:,J)]; -0694 filler=ones(nTransRxns,1); -0695 outModel.lb=[outModel.lb;filler*-1000]; -0696 outModel.ub=[outModel.ub;filler*1000]; -0697 outModel.rev=[outModel.rev;filler]; -0698 outModel.c=[outModel.c;filler*0]; -0699 outModel.rxnGeneMat=[outModel.rxnGeneMat;sparse(nTransRxns,numel(outModel.genes))]; -0700 -0701 for i=1:numel(I) -0702 outModel.rxns=[outModel.rxns;strcat('transport',num2str(i))]; -0703 outModel.rxnNames=[outModel.rxnNames;['Transport of ',outModel.metNames{I(i)}]]; -0704 if isfield(outModel,'grRules') -0705 outModel.grRules=[outModel.grRules;{''}]; -0706 end -0707 if isfield(outModel,'rxnMiriams') -0708 outModel.rxnMiriams=[outModel.rxnMiriams;{[]}]; -0709 end -0710 if isfield(outModel,'subSystems') -0711 outModel.subSystems=[outModel.subSystems;{{'Inferred transport reactions'}}]; +0681 if isfield(outModel,'metCharges') +0682 outModel.metCharges=[outModel.metCharges;outModel.metCharges(nEM+1:nEM+nMets)]; +0683 end +0684 if isfield(outModel,'metDeltaG') +0685 outModel.metDeltaG=[outModel.metDeltaG;outModel.metDeltaG(nEM+1:nEM+nMets)]; +0686 end +0687 end +0688 +0689 %Add the transport reactions +0690 transS=bestS(:,numel(outModel.rxns)+1:end); +0691 J=sum(transS)>0; %Active rxns +0692 +0693 %Transport reactions are written in a different way compared to a "real" +0694 %stoichimetric matrix. This is to fix that +0695 transS(transS~=0)=1; +0696 transS(1:nEM+nMets,:)=transS(1:nEM+nMets,:)*-1; +0697 I=find(sum(transS>0,2)); +0698 nTransRxns=numel(I); +0699 outModel.S=[outModel.S transS(:,J)]; +0700 filler=ones(nTransRxns,1); +0701 outModel.lb=[outModel.lb;filler*-1000]; +0702 outModel.ub=[outModel.ub;filler*1000]; +0703 outModel.rev=[outModel.rev;filler]; +0704 outModel.c=[outModel.c;filler*0]; +0705 outModel.rxnGeneMat=[outModel.rxnGeneMat;sparse(nTransRxns,numel(outModel.genes))]; +0706 +0707 for i=1:numel(I) +0708 outModel.rxns=[outModel.rxns;strcat('transport',num2str(i))]; +0709 outModel.rxnNames=[outModel.rxnNames;['Transport of ',outModel.metNames{I(i)}]]; +0710 if isfield(outModel,'grRules') +0711 outModel.grRules=[outModel.grRules;{''}]; 0712 end -0713 if isfield(outModel,'eccodes') -0714 outModel.eccodes=[outModel.eccodes;{''}]; +0713 if isfield(outModel,'rxnMiriams') +0714 outModel.rxnMiriams=[outModel.rxnMiriams;{[]}]; 0715 end -0716 if isfield(outModel,'rxnFrom') -0717 outModel.rxnFrom=[outModel.rxnFrom;{''}]; +0716 if isfield(outModel,'subSystems') +0717 outModel.subSystems=[outModel.subSystems;{{'Inferred transport reactions'}}]; 0718 end -0719 if isfield(outModel,'rxnNotes') -0720 outModel.rxnNotes=[outModel.rxnNotes;{''}]; +0719 if isfield(outModel,'eccodes') +0720 outModel.eccodes=[outModel.eccodes;{''}]; 0721 end -0722 if isfield(outModel,'rxnReferences') -0723 outModel.rxnReferences=[outModel.rxnReferences;{''}]; +0722 if isfield(outModel,'rxnFrom') +0723 outModel.rxnFrom=[outModel.rxnFrom;{''}]; 0724 end -0725 if isfield(outModel,'rxnConfidenceScores') -0726 outModel.rxnConfidenceScores=[outModel.rxnConfidenceScores;NaN]; +0725 if isfield(outModel,'rxnNotes') +0726 outModel.rxnNotes=[outModel.rxnNotes;{''}]; 0727 end -0728 end -0729 -0730 %Then remove all reactions and metabolites that aren't used in the final -0731 %solution from the optimization -0732 [~, J]=find(bestS(:,1:nER+nComps*nRxns)); -0733 K=true(numel(outModel.rxns),1); -0734 K(J)=false; -0735 K(end-nTransRxns+1:end)=false; -0736 outModel=removeReactions(outModel,K,true); -0737 -0738 %Remove all fake genes -0739 I=strncmp('&&FAKE&&',outModel.genes,8); -0740 outModel.genes(I)=[]; -0741 if isfield(outModel,'geneMiriams') -0742 outModel.geneMiriams(I)=[]; -0743 end -0744 if isfield(outModel,'geneShortNames') -0745 outModel.geneShortNames(I)=[]; -0746 end -0747 outModel.rxnGeneMat(:,I)=[]; -0748 -0749 %Fix grRules and reconstruct rxnGeneMat -0750 [grRules,rxnGeneMat] = standardizeGrRules(outModel,true); -0751 outModel.grRules = grRules; -0752 outModel.rxnGeneMat = rxnGeneMat; -0753 end -0754 -0755 %Moves a gene and all associated reactions from one compartment to another -0756 function [S, g2c]=moveGene(S,model,g2c,geneToMove,toComp,nRxns,nMets) -0757 %Find the current compartment and update to the new one -0758 currentComp=find(g2c(geneToMove,:)); -0759 g2c(geneToMove,:)=false; -0760 g2c(geneToMove,toComp)=true; -0761 -0762 %Find the reactions in the original model that the gene controls -0763 [I, ~]=find(model.rxnGeneMat(:,geneToMove)); -0764 -0765 %Calculate their current positions in the S matrix -0766 oldRxns=I+(currentComp-1)*nRxns; -0767 -0768 %And their new positions -0769 newRxns=I+(toComp-1)*nRxns; +0728 if isfield(outModel,'rxnReferences') +0729 outModel.rxnReferences=[outModel.rxnReferences;{''}]; +0730 end +0731 if isfield(outModel,'rxnConfidenceScores') +0732 outModel.rxnConfidenceScores=[outModel.rxnConfidenceScores;NaN]; +0733 end +0734 if isfield(outModel,'rxnDeltaG') +0735 outModel.rxnDeltaG=[outModel.rxnDeltaG;NaN]; +0736 end +0737 end +0738 +0739 %Then remove all reactions and metabolites that aren't used in the final +0740 %solution from the optimization +0741 [~, J]=find(bestS(:,1:nER+nComps*nRxns)); +0742 K=true(numel(outModel.rxns),1); +0743 K(J)=false; +0744 K(end-nTransRxns+1:end)=false; +0745 outModel=removeReactions(outModel,K,true); +0746 +0747 %Remove all fake genes +0748 I=strncmp('&&FAKE&&',outModel.genes,8); +0749 outModel.genes(I)=[]; +0750 if isfield(outModel,'geneMiriams') +0751 outModel.geneMiriams(I)=[]; +0752 end +0753 if isfield(outModel,'geneShortNames') +0754 outModel.geneShortNames(I)=[]; +0755 end +0756 outModel.rxnGeneMat(:,I)=[]; +0757 +0758 %Fix grRules and reconstruct rxnGeneMat +0759 [grRules,rxnGeneMat] = standardizeGrRules(outModel,true); +0760 outModel.grRules = grRules; +0761 outModel.rxnGeneMat = rxnGeneMat; +0762 end +0763 +0764 %Moves a gene and all associated reactions from one compartment to another +0765 function [S, g2c]=moveGene(S,model,g2c,geneToMove,toComp,nRxns,nMets) +0766 %Find the current compartment and update to the new one +0767 currentComp=find(g2c(geneToMove,:)); +0768 g2c(geneToMove,:)=false; +0769 g2c(geneToMove,toComp)=true; 0770 -0771 %The metabolite ids also have to be changed in order to match the new -0772 %compartment -0773 metChange=nMets*(toComp-currentComp); -0774 -0775 %Update the reactions -0776 [I, J, K]=find(S(:,oldRxns)); -0777 I=I+metChange; -0778 -0779 %Move the reactions -0780 S(:,oldRxns)=0; -0781 S(sub2ind(size(S),I,newRxns(J)))=K; -0782 end +0771 %Find the reactions in the original model that the gene controls +0772 [I, ~]=find(model.rxnGeneMat(:,geneToMove)); +0773 +0774 %Calculate their current positions in the S matrix +0775 oldRxns=I+(currentComp-1)*nRxns; +0776 +0777 %And their new positions +0778 newRxns=I+(toComp-1)*nRxns; +0779 +0780 %The metabolite ids also have to be changed in order to match the new +0781 %compartment +0782 metChange=nMets*(toComp-currentComp); 0783 -0784 %Finds which metabolites are unconnected, in the sense that they are never -0785 %a product or only a product in a reversible reaction where one reactant is -0786 %only a product in the opposite direction of that reaction. This function -0787 %ignores exchange metabolites. Returns a vector of metabolite indexes. -0788 %metsToCheck is an array of metabolite indexes to check for connectivity. -0789 %If not supplied then all metabolites are checked -0790 function unconnected=findUnconnected(S,nEM,metsToCheck) -0791 if nargin>2 -0792 %Do this by deleting everything from the network that is not in -0793 %metsToCheck and that is not exchange metabolites -0794 I=false(size(S,1),1); -0795 I(1:nEM)=true; -0796 I(metsToCheck)=true; -0797 S=S(I,:); -0798 end -0799 -0800 em=false(size(S,1),1); -0801 em(1:nEM)=true; -0802 -0803 %Construct a matrix in which the reversible reactions are inverted -0804 I=sum(S>2,1) | sum(S>2,1); -0805 revS=S; -0806 revS(:,I)=revS(:,I)*-1; -0807 -0808 %First calculate the ones that are ok -0809 %Produced in 2 rxns, is exchange, is not used at all, is produced in -0810 %non-reversible, involved in more than 1 reversible reactions -0811 connected=sum(S>0,2)>1 | em | sum(S~=0,2)==0 | sum(S(:,~I)>0,2)>0 | sum(S(:,I)~=0,2)>1; -0812 -0813 %Then get the ones that are unconnected because they are never produced -0814 unconnected=sum(S>0 | revS>0,2)==0 & connected==false; -0815 -0816 %Then get the ones that are potentially unconnected -0817 maybeUnconnected=~connected & ~unconnected; -0818 %maybeUnconnected=find(maybeUnconnectedS); -0819 -0820 %The metabolites in maybeUnconnected are involved in one reversible -0821 %reaction and not produced in any other reaction. This means that the -0822 %reactions which have at least one met in maybeUnconnected as reactant and -0823 %one as product are unconnected. The metabolites in maybeUnconnected that -0824 %are present in those reactions are then dead ends -0825 deadRxns=any(S(maybeUnconnected,:)>0) & any(S(maybeUnconnected,:)<0); -0826 -0827 %Get the mets involved in any of those reactions -0828 problematic=any(S(:,deadRxns)~=0,2); -0829 -0830 %If any of these are in the maybeUnconnected list then the metabolite is -0831 %unconnected -0832 unconnected(problematic & maybeUnconnected)=true; -0833 -0834 %Map back to metsToCheck -0835 if nargin>2 -0836 unconnected=metsToCheck(unconnected(nEM+1:end)); -0837 else -0838 unconnected=find(unconnected); -0839 end -0840 end -0841 -0842 %Given a set of unconnected metabolites, this function tries to move each -0843 %gene that could connect any of them, calculates the number of newly -0844 %connected metabolites minus the number of newly disconnected metabolites. -0845 %As some metabolites are very connected, only 25 genes are checked. Genes -0846 %that have a low score in their current compartment are more likely to be -0847 %moved -0848 function [geneIndex, moveTo, deltaConnected, deltaScore]=selectGenes(S,nEM,nMets,nER,nRxns,model,unconnected,g2c,GSS) -0849 %If moveTo is 0 then the gene cannot connect any of the metabolites -0850 moveTo=zeros(numel(model.genes),1); -0851 deltaConnected=zeros(numel(model.genes),1); -0852 -0853 %First get where the metabolites are now -0854 nComps=size(g2c,2); -0855 comps=ceil((unconnected-nEM)/((size(S,1)-nEM)/nComps)); -0856 -0857 %Find the corresponding metabolite indexes if they all were in the default -0858 %compartment -0859 dcIndexes=unique(unconnected-(comps-1)*nMets); -0860 -0861 %Then find them if they were in any other compartment -0862 allIndexes=dcIndexes; -0863 for i=1:nComps-1 -0864 allIndexes=[allIndexes;dcIndexes+nMets*i]; -0865 end -0866 -0867 %Also check which reversible reactions that could be used -0868 I=sum(S>2,1) | sum(S>2,1); -0869 revS=S; -0870 revS(:,I)=revS(:,I)*-1; -0871 -0872 %Find all reactions that could make any of the unconnected metabolites in -0873 %some other compartment -0874 newMets=setdiff(allIndexes,unconnected); -0875 [~, potential]=find(S(newMets,:)>0 | revS(newMets,:)>0); -0876 potential(potential<=nER | potential>nER+nRxns*nComps)=[]; %No exchange rxns or transport rxns -0877 -0878 %Map J to the real metabolic reactions in model -0879 rxnComps=ceil((potential-nER)/(nRxns)); +0784 %Update the reactions +0785 [I, J, K]=find(S(:,oldRxns)); +0786 I=I+metChange; +0787 +0788 %Move the reactions +0789 S(:,oldRxns)=0; +0790 S(sub2ind(size(S),I,newRxns(J)))=K; +0791 end +0792 +0793 %Finds which metabolites are unconnected, in the sense that they are never +0794 %a product or only a product in a reversible reaction where one reactant is +0795 %only a product in the opposite direction of that reaction. This function +0796 %ignores exchange metabolites. Returns a vector of metabolite indexes. +0797 %metsToCheck is an array of metabolite indexes to check for connectivity. +0798 %If not supplied then all metabolites are checked +0799 function unconnected=findUnconnected(S,nEM,metsToCheck) +0800 if nargin>2 +0801 %Do this by deleting everything from the network that is not in +0802 %metsToCheck and that is not exchange metabolites +0803 I=false(size(S,1),1); +0804 I(1:nEM)=true; +0805 I(metsToCheck)=true; +0806 S=S(I,:); +0807 end +0808 +0809 em=false(size(S,1),1); +0810 em(1:nEM)=true; +0811 +0812 %Construct a matrix in which the reversible reactions are inverted +0813 I=sum(S>2,1) | sum(S>2,1); +0814 revS=S; +0815 revS(:,I)=revS(:,I)*-1; +0816 +0817 %First calculate the ones that are ok +0818 %Produced in 2 rxns, is exchange, is not used at all, is produced in +0819 %non-reversible, involved in more than 1 reversible reactions +0820 connected=sum(S>0,2)>1 | em | sum(S~=0,2)==0 | sum(S(:,~I)>0,2)>0 | sum(S(:,I)~=0,2)>1; +0821 +0822 %Then get the ones that are unconnected because they are never produced +0823 unconnected=sum(S>0 | revS>0,2)==0 & connected==false; +0824 +0825 %Then get the ones that are potentially unconnected +0826 maybeUnconnected=~connected & ~unconnected; +0827 %maybeUnconnected=find(maybeUnconnectedS); +0828 +0829 %The metabolites in maybeUnconnected are involved in one reversible +0830 %reaction and not produced in any other reaction. This means that the +0831 %reactions which have at least one met in maybeUnconnected as reactant and +0832 %one as product are unconnected. The metabolites in maybeUnconnected that +0833 %are present in those reactions are then dead ends +0834 deadRxns=any(S(maybeUnconnected,:)>0) & any(S(maybeUnconnected,:)<0); +0835 +0836 %Get the mets involved in any of those reactions +0837 problematic=any(S(:,deadRxns)~=0,2); +0838 +0839 %If any of these are in the maybeUnconnected list then the metabolite is +0840 %unconnected +0841 unconnected(problematic & maybeUnconnected)=true; +0842 +0843 %Map back to metsToCheck +0844 if nargin>2 +0845 unconnected=metsToCheck(unconnected(nEM+1:end)); +0846 else +0847 unconnected=find(unconnected); +0848 end +0849 end +0850 +0851 %Given a set of unconnected metabolites, this function tries to move each +0852 %gene that could connect any of them, calculates the number of newly +0853 %connected metabolites minus the number of newly disconnected metabolites. +0854 %As some metabolites are very connected, only 25 genes are checked. Genes +0855 %that have a low score in their current compartment are more likely to be +0856 %moved +0857 function [geneIndex, moveTo, deltaConnected, deltaScore]=selectGenes(S,nEM,nMets,nER,nRxns,model,unconnected,g2c,GSS) +0858 %If moveTo is 0 then the gene cannot connect any of the metabolites +0859 moveTo=zeros(numel(model.genes),1); +0860 deltaConnected=zeros(numel(model.genes),1); +0861 +0862 %First get where the metabolites are now +0863 nComps=size(g2c,2); +0864 comps=ceil((unconnected-nEM)/((size(S,1)-nEM)/nComps)); +0865 +0866 %Find the corresponding metabolite indexes if they all were in the default +0867 %compartment +0868 dcIndexes=unique(unconnected-(comps-1)*nMets); +0869 +0870 %Then find them if they were in any other compartment +0871 allIndexes=dcIndexes; +0872 for i=1:nComps-1 +0873 allIndexes=[allIndexes;dcIndexes+nMets*i]; +0874 end +0875 +0876 %Also check which reversible reactions that could be used +0877 I=sum(S>2,1) | sum(S>2,1); +0878 revS=S; +0879 revS(:,I)=revS(:,I)*-1; 0880 -0881 %Find the corresponding reaction indexes if they all were in the default -0882 %compartment -0883 dcRxnIndexes=potential-(rxnComps-1)*nRxns; -0884 -0885 %Get the genes for those reactions -0886 genes=find(sum(model.rxnGeneMat(dcRxnIndexes,:)>0,1)); -0887 -0888 %For some cases there can be very many reactions to connect something. This -0889 %is in particular true in the beginning of the optimization if, say, ATP is -0890 %unconnected. Therefore limit the number of genes to be checked to 25. -0891 %Weigh so that genes with bad scores in their current compartment are more -0892 %likely to be moved. +0881 %Find all reactions that could make any of the unconnected metabolites in +0882 %some other compartment +0883 newMets=setdiff(allIndexes,unconnected); +0884 [~, potential]=find(S(newMets,:)>0 | revS(newMets,:)>0); +0885 potential(potential<=nER | potential>nER+nRxns*nComps)=[]; %No exchange rxns or transport rxns +0886 +0887 %Map J to the real metabolic reactions in model +0888 rxnComps=ceil((potential-nER)/(nRxns)); +0889 +0890 %Find the corresponding reaction indexes if they all were in the default +0891 %compartment +0892 dcRxnIndexes=potential-(rxnComps-1)*nRxns; 0893 -0894 %Get scores for these genes -0895 [~, J]=find(g2c(genes,:)); +0894 %Get the genes for those reactions +0895 genes=find(sum(model.rxnGeneMat(dcRxnIndexes,:)>0,1)); 0896 -0897 %Add a small weight so that genes in their best compartment could be moved -0898 %as well -0899 geneScores=GSS.scores(sub2ind(size(g2c),genes(:),J)); -0900 modGeneScores=1.1-geneScores; -0901 if numel(genes)>25 -0902 rGenes=genes(randsample(numel(genes),min(numel(genes),25),true,modGeneScores)); -0903 -0904 %The sampling with weights could give duplicates -0905 rGenes=unique(rGenes); -0906 -0907 %Reorder the geneScores to match -0908 [~, I]=ismember(rGenes,genes); -0909 geneScores=geneScores(I); -0910 genes=rGenes; -0911 end -0912 for i=1:numel(genes) -0913 %Since one gene is moved at a time, only metabolites involved in any of -0914 %the reactions for that gene can become unconnected. This helps to -0915 %speed up the algorithm. First get all involved reactions in the -0916 %default compartment -0917 rxns=find(model.rxnGeneMat(:,genes(i))); -0918 -0919 %Then get their mets -0920 mets=find(sum(model.S(:,rxns)~=0,2)>0); -0921 -0922 %Then get their indexes in all compartments -0923 allIndexes=mets; -0924 for j=1:nComps-1 -0925 allIndexes=[allIndexes;mets+nMets*j]; -0926 end +0897 %For some cases there can be very many reactions to connect something. This +0898 %is in particular true in the beginning of the optimization if, say, ATP is +0899 %unconnected. Therefore limit the number of genes to be checked to 25. +0900 %Weigh so that genes with bad scores in their current compartment are more +0901 %likely to be moved. +0902 +0903 %Get scores for these genes +0904 [~, J]=find(g2c(genes,:)); +0905 +0906 %Add a small weight so that genes in their best compartment could be moved +0907 %as well +0908 geneScores=GSS.scores(sub2ind(size(g2c),genes(:),J)); +0909 modGeneScores=1.1-geneScores; +0910 if numel(genes)>25 +0911 rGenes=genes(randsample(numel(genes),min(numel(genes),25),true,modGeneScores)); +0912 +0913 %The sampling with weights could give duplicates +0914 rGenes=unique(rGenes); +0915 +0916 %Reorder the geneScores to match +0917 [~, I]=ismember(rGenes,genes); +0918 geneScores=geneScores(I); +0919 genes=rGenes; +0920 end +0921 for i=1:numel(genes) +0922 %Since one gene is moved at a time, only metabolites involved in any of +0923 %the reactions for that gene can become unconnected. This helps to +0924 %speed up the algorithm. First get all involved reactions in the +0925 %default compartment +0926 rxns=find(model.rxnGeneMat(:,genes(i))); 0927 -0928 %Check which of the unconnected metabolites that these reactions -0929 %correspond to. This could have been done earlier, but it is fast. The -0930 %reversibility check is skipped because it is unlikely to be an issue -0931 %here. Worst case is that the gene is tested once to much -0932 [I, ~]=find(model.S(:,rxns)); -0933 moveToComps=unique(comps(ismember(dcIndexes,I))); -0934 -0935 %Try to move the gene to each of the compartments -0936 bestMove=-inf; -0937 bestComp=[]; -0938 for j=1:numel(moveToComps) -0939 newS=moveGene(S,model,g2c,genes(i),moveToComps(j),nRxns,nMets); -0940 -0941 %Check how many metabolites that are unconnected after moving the -0942 %gene -0943 dConnected=numel(unconnected)-numel(findUnconnected(newS,nEM,[allIndexes;unconnected])); -0944 if dConnected>bestMove -0945 bestMove=dConnected; -0946 bestComp=moveToComps(j); -0947 end -0948 end -0949 -0950 %Add the difference in connectivity and where the genes should be moved -0951 moveTo(genes(i))=bestComp; -0952 deltaConnected(genes(i))=bestMove; -0953 end -0954 -0955 %Finish up -0956 geneIndex=genes(:); -0957 moveTo=moveTo(geneIndex); -0958 deltaConnected=deltaConnected(geneIndex); -0959 deltaScore=GSS.scores(sub2ind(size(g2c),geneIndex(:),moveTo))-geneScores; -0960 end -0961 -0962 %Small function to add a transport reactions between two metabolites. -0963 %Transport reactions are written as having a coefficient 2.0 for both -0964 %reactant and product. This is not a "real" reaction, but since all normal -0965 %reactions have coefficient -1/1 or -10/10 it is a compact way of writing -0966 %it -0967 function S=addTransport(S,nRxns,nER,nMets,nEM,nComps,metA,metB) -0968 mets=[metA;metB]; -0969 %Find the current compartments for the metabolites -0970 comps=ceil((mets-nEM)/((size(S,1)-nEM)/nComps)); -0971 -0972 if sum(comps==1)~=1 -0973 EM='Tried to create a transport reaction from a non-default compartment'; -0974 dispEM(EM); -0975 end -0976 -0977 %Calculate the reaction index -0978 rIndex=(nER+nRxns*nComps)+mets(comps~=1)-nEM-nMets; -0979 -0980 S(mets,rIndex)=2; -0981 end -0982 -0983 %Scores a network based on the localization of the genes and the number of -0984 %transporter reactions used -0985 function [score, geneScore, transportCost]=scoreModel(S,g2c,GSS,transportCost) -0986 [I, J]=find(g2c); -0987 geneScore=sum(GSS.scores(sub2ind(size(g2c),I,J))); -0988 [I, ~]=find(S==2); -0989 I=unique(I); -0990 transportCost=sum(transportCost(I)); -0991 score=geneScore-transportCost; -0992 end +0928 %Then get their mets +0929 mets=find(sum(model.S(:,rxns)~=0,2)>0); +0930 +0931 %Then get their indexes in all compartments +0932 allIndexes=mets; +0933 for j=1:nComps-1 +0934 allIndexes=[allIndexes;mets+nMets*j]; +0935 end +0936 +0937 %Check which of the unconnected metabolites that these reactions +0938 %correspond to. This could have been done earlier, but it is fast. The +0939 %reversibility check is skipped because it is unlikely to be an issue +0940 %here. Worst case is that the gene is tested once to much +0941 [I, ~]=find(model.S(:,rxns)); +0942 moveToComps=unique(comps(ismember(dcIndexes,I))); +0943 +0944 %Try to move the gene to each of the compartments +0945 bestMove=-inf; +0946 bestComp=[]; +0947 for j=1:numel(moveToComps) +0948 newS=moveGene(S,model,g2c,genes(i),moveToComps(j),nRxns,nMets); +0949 +0950 %Check how many metabolites that are unconnected after moving the +0951 %gene +0952 dConnected=numel(unconnected)-numel(findUnconnected(newS,nEM,[allIndexes;unconnected])); +0953 if dConnected>bestMove +0954 bestMove=dConnected; +0955 bestComp=moveToComps(j); +0956 end +0957 end +0958 +0959 %Add the difference in connectivity and where the genes should be moved +0960 moveTo(genes(i))=bestComp; +0961 deltaConnected(genes(i))=bestMove; +0962 end +0963 +0964 %Finish up +0965 geneIndex=genes(:); +0966 moveTo=moveTo(geneIndex); +0967 deltaConnected=deltaConnected(geneIndex); +0968 deltaScore=GSS.scores(sub2ind(size(g2c),geneIndex(:),moveTo))-geneScores; +0969 end +0970 +0971 %Small function to add a transport reactions between two metabolites. +0972 %Transport reactions are written as having a coefficient 2.0 for both +0973 %reactant and product. This is not a "real" reaction, but since all normal +0974 %reactions have coefficient -1/1 or -10/10 it is a compact way of writing +0975 %it +0976 function S=addTransport(S,nRxns,nER,nMets,nEM,nComps,metA,metB) +0977 mets=[metA;metB]; +0978 %Find the current compartments for the metabolites +0979 comps=ceil((mets-nEM)/((size(S,1)-nEM)/nComps)); +0980 +0981 if sum(comps==1)~=1 +0982 EM='Tried to create a transport reaction from a non-default compartment'; +0983 dispEM(EM); +0984 end +0985 +0986 %Calculate the reaction index +0987 rIndex=(nER+nRxns*nComps)+mets(comps~=1)-nEM-nMets; +0988 +0989 S(mets,rIndex)=2; +0990 end +0991 +0992 %Scores a network based on the localization of the genes and the number of +0993 %transporter reactions used +0994 function [score, geneScore, transportCost]=scoreModel(S,g2c,GSS,transportCost) +0995 [I, J]=find(g2c); +0996 geneScore=sum(GSS.scores(sub2ind(size(g2c),I,J))); +0997 [I, ~]=find(S==2); +0998 I=unique(I); +0999 transportCost=sum(transportCost(I)); +1000 score=geneScore-transportCost; +1001 end
Generated by m2html © 2005
\ No newline at end of file diff --git a/doc/core/removeMets.html b/doc/core/removeMets.html index 10b9120d..0bfbc8c3 100644 --- a/doc/core/removeMets.html +++ b/doc/core/removeMets.html @@ -158,35 +158,38 @@

SOURCE CODE ^if isfield(reducedModel,'metCharges') 0093 reducedModel.metCharges(indexesToDelete)=[]; 0094 end -0095 end -0096 -0097 %Remove unused reactions -0098 if removeUnusedRxns==true -0099 %Get unused reactions -0100 [~, a]=find(reducedModel.S); -0101 rxnsToRemove=1:numel(reducedModel.rxns); -0102 rxnsToRemove(a)=[]; -0103 reducedModel=removeReactions(reducedModel,rxnsToRemove,false,removeUnusedGenes); -0104 end -0105 -0106 %Remove unused compartments -0107 if removeUnusedComps==true -0108 oldComps=reducedModel.comps; -0109 I=ismember(1:numel(oldComps),reducedModel.metComps); -0110 if ~all(I) -0111 reducedModel.comps(~I)=[]; -0112 reducedModel.compNames(~I)=[]; -0113 if isfield(reducedModel,'compOutside') -0114 reducedModel.compOutside(~I)=[]; -0115 end -0116 if isfield(reducedModel,'compMiriams') -0117 reducedModel.compMiriams(~I)=[]; +0095 if isfield(reducedModel,'metDeltaG') +0096 reducedModel.metDeltaG(indexesToDelete)=[]; +0097 end +0098 end +0099 +0100 %Remove unused reactions +0101 if removeUnusedRxns==true +0102 %Get unused reactions +0103 [~, a]=find(reducedModel.S); +0104 rxnsToRemove=1:numel(reducedModel.rxns); +0105 rxnsToRemove(a)=[]; +0106 reducedModel=removeReactions(reducedModel,rxnsToRemove,false,removeUnusedGenes); +0107 end +0108 +0109 %Remove unused compartments +0110 if removeUnusedComps==true +0111 oldComps=reducedModel.comps; +0112 I=ismember(1:numel(oldComps),reducedModel.metComps); +0113 if ~all(I) +0114 reducedModel.comps(~I)=[]; +0115 reducedModel.compNames(~I)=[]; +0116 if isfield(reducedModel,'compOutside') +0117 reducedModel.compOutside(~I)=[]; 0118 end -0119 [~, J]=ismember(oldComps(reducedModel.metComps),reducedModel.comps); -0120 reducedModel.metComps=J; -0121 end -0122 end -0123 end +0119 if isfield(reducedModel,'compMiriams') +0120 reducedModel.compMiriams(~I)=[]; +0121 end +0122 [~, J]=ismember(oldComps(reducedModel.metComps),reducedModel.comps); +0123 reducedModel.metComps=J; +0124 end +0125 end +0126 end
Generated by m2html © 2005
\ No newline at end of file diff --git a/doc/core/removeReactions.html b/doc/core/removeReactions.html index 3e0f817c..d9dc6f79 100644 --- a/doc/core/removeReactions.html +++ b/doc/core/removeReactions.html @@ -154,54 +154,57 @@

SOURCE CODE ^if isfield(reducedModel,'rxnConfidenceScores') 0094 reducedModel.rxnConfidenceScores(indexesToDelete,:)=[]; 0095 end -0096 if isfield(reducedModel,'pwys') -0097 reducedModel.pwys(indexesToDelete,:)=[]; +0096 if isfield(reducedModel,'rxnDeltaG') +0097 reducedModel.rxnDeltaG(indexesToDelete,:)=[]; 0098 end -0099 if isfield(reducedModel,'spontaneous') -0100 reducedModel.spontaneous(indexesToDelete)=[]; +0099 if isfield(reducedModel,'pwys') +0100 reducedModel.pwys(indexesToDelete,:)=[]; 0101 end -0102 end -0103 -0104 %Remove unused metabolites -0105 if removeUnusedMets==true -0106 if isfield(reducedModel,'S') -0107 [usedMets, ~]=find(reducedModel.S); -0108 unUsedMets=true(numel(reducedModel.mets),1); -0109 unUsedMets(usedMets)=false; -0110 reducedModel=removeMets(reducedModel,unUsedMets,false,false,false,removeUnusedComps); -0111 end -0112 end -0113 -0114 %Remove unused genes -0115 if removeUnusedGenes==true && isfield(reducedModel,'rxnGeneMat') -0116 %Find all genes that are not used -0117 [~, b]=find(reducedModel.rxnGeneMat); -0118 toKeep=false(numel(reducedModel.genes),1); -0119 toKeep(b)=true; -0120 -0121 reducedModel.genes=reducedModel.genes(toKeep); -0122 reducedModel.rxnGeneMat=reducedModel.rxnGeneMat(:,toKeep); +0102 if isfield(reducedModel,'spontaneous') +0103 reducedModel.spontaneous(indexesToDelete)=[]; +0104 end +0105 end +0106 +0107 %Remove unused metabolites +0108 if removeUnusedMets==true +0109 if isfield(reducedModel,'S') +0110 [usedMets, ~]=find(reducedModel.S); +0111 unUsedMets=true(numel(reducedModel.mets),1); +0112 unUsedMets(usedMets)=false; +0113 reducedModel=removeMets(reducedModel,unUsedMets,false,false,false,removeUnusedComps); +0114 end +0115 end +0116 +0117 %Remove unused genes +0118 if removeUnusedGenes==true && isfield(reducedModel,'rxnGeneMat') +0119 %Find all genes that are not used +0120 [~, b]=find(reducedModel.rxnGeneMat); +0121 toKeep=false(numel(reducedModel.genes),1); +0122 toKeep(b)=true; 0123 -0124 if isfield(reducedModel,'geneShortNames') -0125 reducedModel.geneShortNames=reducedModel.geneShortNames(toKeep); -0126 end -0127 -0128 if isfield(reducedModel,'geneMiriams') -0129 reducedModel.geneMiriams=reducedModel.geneMiriams(toKeep); -0130 end -0131 -0132 if isfield(reducedModel,'geneFrom') -0133 reducedModel.geneFrom=reducedModel.geneFrom(toKeep); -0134 end -0135 -0136 if isfield(reducedModel,'geneComps') -0137 reducedModel.geneComps=reducedModel.geneComps(toKeep); -0138 end -0139 end -0140 else -0141 reducedModel=model; -0142 end -0143 end +0124 reducedModel.genes=reducedModel.genes(toKeep); +0125 reducedModel.rxnGeneMat=reducedModel.rxnGeneMat(:,toKeep); +0126 +0127 if isfield(reducedModel,'geneShortNames') +0128 reducedModel.geneShortNames=reducedModel.geneShortNames(toKeep); +0129 end +0130 +0131 if isfield(reducedModel,'geneMiriams') +0132 reducedModel.geneMiriams=reducedModel.geneMiriams(toKeep); +0133 end +0134 +0135 if isfield(reducedModel,'geneFrom') +0136 reducedModel.geneFrom=reducedModel.geneFrom(toKeep); +0137 end +0138 +0139 if isfield(reducedModel,'geneComps') +0140 reducedModel.geneComps=reducedModel.geneComps(toKeep); +0141 end +0142 end +0143 else +0144 reducedModel=model; +0145 end +0146 end
Generated by m2html © 2005
\ No newline at end of file diff --git a/doc/core/replaceMets.html b/doc/core/replaceMets.html index 8ffb877c..88c9d607 100644 --- a/doc/core/replaceMets.html +++ b/doc/core/replaceMets.html @@ -112,66 +112,72 @@

SOURCE CODE ^if isfield(model,'metCharges') 0053 model.metCharges(metIdx) = model.metCharges(repIdx(1)); 0054 end -0055 if isfield(model,'inchis') -0056 model.inchis(metIdx) = model.inchis(repIdx(1)); +0055 if isfield(model,'metDeltaG') +0056 model.metDeltaG(metIdx) = model.metDeltaG(repIdx(1)); 0057 end -0058 if isfield(model,'metSmiles') -0059 model.metSmiles(metIdx) = model.metSmiles(repIdx(1)); +0058 if isfield(model,'inchis') +0059 model.inchis(metIdx) = model.inchis(repIdx(1)); 0060 end -0061 % Run through replacement metabolites and their compartments. If any of the -0062 % to-be-replaced metabolites is already present (checked by -0063 % metaboliteName[compartment], then the replacement metabolite is kept and -0064 % the to-be-replace metabolite ID deleted. -0065 -0066 % Build list of metaboliteName[compartment] -0067 metCompsN =cellstr(num2str(model.metComps)); -0068 map = containers.Map(cellstr(num2str(transpose(1:length(model.comps)))),model.comps); -0069 metCompsN = map.values(metCompsN); -0070 metCompsN = strcat(lower(model.metNames),'[',metCompsN,']'); -0071 -0072 idxDelete=[]; -0073 for i = 1:length(repIdx) -0074 metCompsNidx=find(strcmp(metCompsN(repIdx(i)), metCompsN)); -0075 if length(metCompsNidx)>1 -0076 for j = 2:length(metCompsNidx) -0077 model.S(metCompsNidx(1),:) = model.S(metCompsNidx(1),:) + model.S(metCompsNidx(j),:); -0078 idxDelete=[idxDelete; metCompsNidx(j)]; % Make list of metabolite IDs to delete -0079 end -0080 end -0081 end -0082 -0083 if ~isempty(idxDelete) -0084 model.S(idxDelete,:) =[]; -0085 model.mets(idxDelete) = []; -0086 model.metNames(idxDelete) = []; -0087 model.metComps(idxDelete) = []; -0088 model.b(idxDelete) = []; -0089 if isfield(model,'metFormulas') -0090 model.metFormulas(idxDelete) = []; -0091 end -0092 if isfield(model,'unconstrained') -0093 model.unconstrained(idxDelete) = []; +0061 if isfield(model,'metSmiles') +0062 model.metSmiles(metIdx) = model.metSmiles(repIdx(1)); +0063 end +0064 % Run through replacement metabolites and their compartments. If any of the +0065 % to-be-replaced metabolites is already present (checked by +0066 % metaboliteName[compartment], then the replacement metabolite is kept and +0067 % the to-be-replace metabolite ID deleted. +0068 +0069 % Build list of metaboliteName[compartment] +0070 metCompsN =cellstr(num2str(model.metComps)); +0071 map = containers.Map(cellstr(num2str(transpose(1:length(model.comps)))),model.comps); +0072 metCompsN = map.values(metCompsN); +0073 metCompsN = strcat(lower(model.metNames),'[',metCompsN,']'); +0074 +0075 idxDelete=[]; +0076 for i = 1:length(repIdx) +0077 metCompsNidx=find(strcmp(metCompsN(repIdx(i)), metCompsN)); +0078 if length(metCompsNidx)>1 +0079 for j = 2:length(metCompsNidx) +0080 model.S(metCompsNidx(1),:) = model.S(metCompsNidx(1),:) + model.S(metCompsNidx(j),:); +0081 idxDelete=[idxDelete; metCompsNidx(j)]; % Make list of metabolite IDs to delete +0082 end +0083 end +0084 end +0085 +0086 if ~isempty(idxDelete) +0087 model.S(idxDelete,:) =[]; +0088 model.mets(idxDelete) = []; +0089 model.metNames(idxDelete) = []; +0090 model.metComps(idxDelete) = []; +0091 model.b(idxDelete) = []; +0092 if isfield(model,'metFormulas') +0093 model.metFormulas(idxDelete) = []; 0094 end -0095 if isfield(model,'metMiriams') -0096 model.metMiriams(idxDelete) = []; +0095 if isfield(model,'unconstrained') +0096 model.unconstrained(idxDelete) = []; 0097 end -0098 if isfield(model,'metCharges') -0099 model.metCharges(idxDelete) = []; +0098 if isfield(model,'metMiriams') +0099 model.metMiriams(idxDelete) = []; 0100 end -0101 if isfield(model,'inchis') -0102 model.inchis(idxDelete) = []; +0101 if isfield(model,'metCharges') +0102 model.metCharges(idxDelete) = []; 0103 end -0104 if isfield(model,'metSmiles') -0105 model.metSmiles(idxDelete) = []; +0104 if isfield(model,'metDeltaG') +0105 model.metDeltaG(idxDelete) = []; 0106 end -0107 if isfield(model,'metFrom') -0108 model.metFrom(idxDelete) = []; +0107 if isfield(model,'inchis') +0108 model.inchis(idxDelete) = []; 0109 end -0110 end -0111 -0112 % This could now have created duplicate reactions. Contract model. -0113 model=contractModel(model); -0114 end +0110 if isfield(model,'metSmiles') +0111 model.metSmiles(idxDelete) = []; +0112 end +0113 if isfield(model,'metFrom') +0114 model.metFrom(idxDelete) = []; +0115 end +0116 end +0117 +0118 % This could now have created duplicate reactions. Contract model. +0119 model=contractModel(model); +0120 end
Generated by m2html © 2005
\ No newline at end of file diff --git a/doc/io/closeModel.html b/doc/io/closeModel.html index c3f38bdb..1775063b 100644 --- a/doc/io/closeModel.html +++ b/doc/io/closeModel.html @@ -95,18 +95,21 @@

SOURCE CODE ^if isfield(closedModel,'metCharges') 0044 closedModel.metCharges(numel(closedModel.metCharges)+1)=closedModel.metCharges(find(closedModel.S(:,i))); 0045 end; -0046 closedModel.unconstrained(numel(closedModel.unconstrained)+1)=1; -0047 closedModel.b(numel(closedModel.b)+1)=0; -0048 closedModel.S=[closedModel.S;sparse(1,size(closedModel.S,2))]; -0049 if sum(closedModel.S(:,i))==1 -0050 closedModel.S(numel(closedModel.mets),i)=-1; -0051 else -0052 closedModel.S(numel(closedModel.mets),i)=1; -0053 end; -0054 end; -0055 end; -0056 -0057 end +0046 if isfield(closedModel,'metDeltaG') +0047 closedModel.metDeltaG(numel(closedModel.metDeltaG)+1)=closedModel.metDeltaG(find(closedModel.S(:,i))); +0048 end; +0049 closedModel.unconstrained(numel(closedModel.unconstrained)+1)=1; +0050 closedModel.b(numel(closedModel.b)+1)=0; +0051 closedModel.S=[closedModel.S;sparse(1,size(closedModel.S,2))]; +0052 if sum(closedModel.S(:,i))==1 +0053 closedModel.S(numel(closedModel.mets),i)=-1; +0054 else +0055 closedModel.S(numel(closedModel.mets),i)=1; +0056 end; +0057 end; +0058 end; +0059 +0060 end
Generated by m2html © 2005
\ No newline at end of file diff --git a/doc/io/readYAMLmodel.html b/doc/io/readYAMLmodel.html index 2914b6d9..fa37a6ab 100644 --- a/doc/io/readYAMLmodel.html +++ b/doc/io/readYAMLmodel.html @@ -137,191 +137,191 @@

SOURCE CODE ^'subSystems',cell(0,0);... 0081 'eccodes',cell(0,0);... 0082 'rxnMiriams',cell(0,0);... -0083 'rxnNotes',cell(0,0);... -0084 'rxnReferences',cell(0,0);... -0085 'rxnConfidenceScores',cell(0,0);... -0086 'metComps',cell(0,0);... %Changed to double in the end. -0087 'inchis',cell(0,0);... -0088 'metSmiles',cell(0,0);... -0089 'metFormulas',cell(0,0);... -0090 'metMiriams',cell(0,0);... -0091 'metCharges',cell(0,0);... %Changed to double in the end. -0092 'metNotes',cell(0,0);... -0093 'comps',cell(0,0);... -0094 'compNames',cell(0,0);... -0095 'compOutside',cell(0,0);... -0096 'geneComps',cell(0,0);... %Changed to double in the end. -0097 'geneMiriams',cell(0,0);... -0098 'geneShortNames',cell(0,0);... -0099 'unconstrained',cell(0,0);... %Changed to double in the end. -0100 'metFrom',cell(0,0);... -0101 'rxnFrom',cell(0,0)}; -0102 for i=1:size(modelFields,1) -0103 model.(modelFields{i,1})=modelFields{i,2}; -0104 end -0105 -0106 % If GECKO model -0107 if any(contains(line_key,'geckoLight')) -0108 isGECKO=true; -0109 ecFields = {'geckoLight', false;... -0110 'rxns', {};... -0111 'kcat', {};... -0112 'source', cell(0,0);... -0113 'notes', cell(0,0);... -0114 'eccodes', cell(0,0);... -0115 'genes', cell(0,0);... -0116 'enzymes', cell(0,0);... -0117 'mw', cell(0,0);... -0118 'sequence', cell(0,0);... -0119 'concs', cell(0,0);... -0120 'rxnEnzMat', []}; -0121 for i=1:size(ecFields,1) -0122 model.ec.(ecFields{i,1})=ecFields{i,2}; -0123 end -0124 ecGecko=cell(25000,2); ecGeckoNo=1; -0125 enzStoich=cell(100000,3); enzStoichNo=1; -0126 else -0127 isGECKO=false; -0128 end -0129 -0130 section = 0; -0131 metMiriams=cell(25000,3); metMirNo=1; -0132 rxnMiriams=cell(25000,3); rxnMirNo=1; -0133 geneMiriams=cell(25000,3); genMirNo=1; -0134 subSystems=cell(25000,2); subSysNo=1; -0135 eccodes=cell(25000,2); ecCodeNo=1; -0136 equations=cell(100000,3); equatiNo=1; -0137 % metMiriams=cell(0,3); metMirNo=1; -0138 % rxnMiriams=cell(0,3); rxnMirNo=1; -0139 % geneMiriams=cell(0,3); genMirNo=1; -0140 % subSystems=cell(0,2); subSysNo=1; -0141 % eccodes=cell(0,2); ecCodeNo=1; -0142 -0143 for i=1:numel(line_key) -0144 tline_raw = line_raw{i}; -0145 tline_key = line_key{i}; -0146 tline_value = line_value{i}; -0147 % import different sections -0148 switch tline_raw -0149 case '- metaData:' -0150 section = 1; -0151 if verbose -0152 fprintf('\t%d\n', section); -0153 end -0154 continue % Go to next line -0155 case '- metabolites:' -0156 section = 2; -0157 if verbose -0158 fprintf('\t%d\n', section); -0159 end -0160 pos=0; -0161 continue -0162 case '- reactions:' -0163 section = 3; -0164 if verbose -0165 fprintf('\t%d\n', section); -0166 end -0167 pos=0; -0168 continue -0169 case '- genes:' -0170 section = 4; -0171 if verbose -0172 fprintf('\t%d\n', section); -0173 end -0174 pos=0; -0175 continue -0176 case '- compartments: !!omap' -0177 section = 5; -0178 if verbose -0179 fprintf('\t%d\n', section); -0180 end -0181 pos=0; -0182 continue -0183 case '- ec-rxns:' -0184 section = 6; -0185 if verbose -0186 fprintf('\t%d\n', section); -0187 end -0188 pos=0; -0189 continue -0190 case '- ec-enzymes:' -0191 section = 7; -0192 if verbose -0193 fprintf('\t%d\n', section); -0194 end -0195 pos=0; -0196 continue -0197 end -0198 -0199 % skip over empty keys -0200 if isempty(tline_raw) || (isempty(tline_key) && contains(tline_raw,'!!omap')) -0201 continue; -0202 end -0203 -0204 % import metaData -0205 if section == 1 -0206 switch tline_key -0207 case {'short_name','id'} %short_name used by human-GEM -0208 model.id = tline_value; -0209 case 'name' -0210 model.name = tline_value; -0211 case 'full_name' %used by human-GEM -0212 model.description = tline_value; -0213 case 'version' -0214 model.version = tline_value; -0215 case 'date' -0216 model.date = tline_value; -0217 case 'taxonomy' -0218 model.annotation.taxonomy = tline_value; -0219 case {'description','note'} %description used by human-GEM -0220 model.annotation.note = tline_value; -0221 case 'github' -0222 model.annotation.sourceUrl = tline_value; -0223 case 'givenName' -0224 model.annotation.givenName = tline_value; -0225 case 'familyName' -0226 model.annotation.familyName = tline_value; -0227 case 'authors' -0228 model.annotation.authorList = tline_value; -0229 case 'email' -0230 model.annotation.email = tline_value; -0231 case 'organization' -0232 model.annotation.organization = tline_value; -0233 case 'geckoLight' -0234 if strcmp(tline_value,'true') -0235 model.ec.geckoLight = true; -0236 end -0237 end; continue -0238 end -0239 -0240 % import metabolites: -0241 if section == 2 -0242 switch tline_key -0243 case 'id' -0244 pos = pos + 1; -0245 model = readFieldValue(model, 'mets', tline_value,pos); +0083 'rxnDeltaG',{};... %Changed to double in the end. +0084 'rxnNotes',cell(0,0);... +0085 'rxnReferences',cell(0,0);... +0086 'rxnConfidenceScores',cell(0,0);... +0087 'metComps',cell(0,0);... %Changed to double in the end. +0088 'inchis',cell(0,0);... +0089 'metSmiles',cell(0,0);... +0090 'metFormulas',cell(0,0);... +0091 'metMiriams',cell(0,0);... +0092 'metDeltaG',{};... %Changed to double in the end. +0093 'metCharges',cell(0,0);... %Changed to double in the end. +0094 'metNotes',cell(0,0);... +0095 'comps',cell(0,0);... +0096 'compNames',cell(0,0);... +0097 'compOutside',cell(0,0);... +0098 'geneComps',cell(0,0);... %Changed to double in the end. +0099 'geneMiriams',cell(0,0);... +0100 'geneShortNames',cell(0,0);... +0101 'unconstrained',cell(0,0);... %Changed to double in the end. +0102 'metFrom',cell(0,0);... +0103 'rxnFrom',cell(0,0)}; +0104 for i=1:size(modelFields,1) +0105 model.(modelFields{i,1})=modelFields{i,2}; +0106 end +0107 +0108 % If GECKO model +0109 if any(contains(line_key,'geckoLight')) +0110 isGECKO=true; +0111 ecFields = {'geckoLight', false;... +0112 'rxns', {};... +0113 'kcat', {};... +0114 'source', cell(0,0);... +0115 'notes', cell(0,0);... +0116 'eccodes', cell(0,0);... +0117 'genes', cell(0,0);... +0118 'enzymes', cell(0,0);... +0119 'mw', cell(0,0);... +0120 'sequence', cell(0,0);... +0121 'concs', cell(0,0);... +0122 'rxnEnzMat', []}; +0123 for i=1:size(ecFields,1) +0124 model.ec.(ecFields{i,1})=ecFields{i,2}; +0125 end +0126 ecGecko=cell(25000,2); ecGeckoNo=1; +0127 enzStoich=cell(100000,3); enzStoichNo=1; +0128 else +0129 isGECKO=false; +0130 end +0131 +0132 section = 0; +0133 metMiriams=cell(100000,3); metMirNo=1; +0134 rxnMiriams=cell(100000,3); rxnMirNo=1; +0135 geneMiriams=cell(100000,3); genMirNo=1; +0136 subSystems=cell(100000,2); subSysNo=1; +0137 eccodes=cell(100000,2); ecCodeNo=1; +0138 equations=cell(100000,3); equatiNo=1; +0139 +0140 for i=1:numel(line_key) +0141 tline_raw = line_raw{i}; +0142 tline_key = line_key{i}; +0143 tline_value = line_value{i}; +0144 % import different sections +0145 switch tline_raw +0146 case '- metaData:' +0147 section = 1; +0148 if verbose +0149 fprintf('\t%d\n', section); +0150 end +0151 continue % Go to next line +0152 case '- metabolites:' +0153 section = 2; +0154 if verbose +0155 fprintf('\t%d\n', section); +0156 end +0157 pos=0; +0158 continue +0159 case '- reactions:' +0160 section = 3; +0161 if verbose +0162 fprintf('\t%d\n', section); +0163 end +0164 pos=0; +0165 continue +0166 case '- genes:' +0167 section = 4; +0168 if verbose +0169 fprintf('\t%d\n', section); +0170 end +0171 pos=0; +0172 continue +0173 case '- compartments: !!omap' +0174 section = 5; +0175 if verbose +0176 fprintf('\t%d\n', section); +0177 end +0178 pos=0; +0179 continue +0180 case '- ec-rxns:' +0181 section = 6; +0182 if verbose +0183 fprintf('\t%d\n', section); +0184 end +0185 pos=0; +0186 continue +0187 case '- ec-enzymes:' +0188 section = 7; +0189 if verbose +0190 fprintf('\t%d\n', section); +0191 end +0192 pos=0; +0193 continue +0194 end +0195 +0196 % skip over empty keys +0197 if isempty(tline_raw) || (isempty(tline_key) && contains(tline_raw,'!!omap')) +0198 continue; +0199 end +0200 +0201 % import metaData +0202 if section == 1 +0203 switch tline_key +0204 case {'short_name','id'} %short_name used by human-GEM +0205 model.id = tline_value; +0206 case 'name' +0207 model.name = tline_value; +0208 case 'full_name' %used by human-GEM +0209 model.description = tline_value; +0210 case 'version' +0211 model.version = tline_value; +0212 case 'date' +0213 model.date = tline_value; +0214 case 'taxonomy' +0215 model.annotation.taxonomy = tline_value; +0216 case {'description','note'} %description used by human-GEM +0217 model.annotation.note = tline_value; +0218 case 'github' +0219 model.annotation.sourceUrl = tline_value; +0220 case 'givenName' +0221 model.annotation.givenName = tline_value; +0222 case 'familyName' +0223 model.annotation.familyName = tline_value; +0224 case 'authors' +0225 model.annotation.authorList = tline_value; +0226 case 'email' +0227 model.annotation.email = tline_value; +0228 case 'organization' +0229 model.annotation.organization = tline_value; +0230 case 'geckoLight' +0231 if strcmp(tline_value,'true') +0232 model.ec.geckoLight = true; +0233 end +0234 end; continue +0235 end +0236 +0237 % import metabolites: +0238 if section == 2 +0239 switch tline_key +0240 case 'id' +0241 pos = pos + 1; +0242 model = readFieldValue(model, 'mets', tline_value,pos); +0243 readList=''; miriamKey=''; +0244 case 'name' +0245 model = readFieldValue(model, 'metNames', tline_value, pos); 0246 readList=''; miriamKey=''; -0247 case 'name' -0248 model = readFieldValue(model, 'metNames', tline_value, pos); +0247 case 'compartment' +0248 model = readFieldValue(model, 'metComps', tline_value, pos); 0249 readList=''; miriamKey=''; -0250 case 'compartment' -0251 model = readFieldValue(model, 'metComps', tline_value, pos); +0250 case 'formula' +0251 model = readFieldValue(model, 'metFormulas', tline_value, pos); 0252 readList=''; miriamKey=''; -0253 case 'formula' -0254 model = readFieldValue(model, 'metFormulas', tline_value, pos); +0253 case 'charge' +0254 model = readFieldValue(model, 'metCharges', tline_value, pos); 0255 readList=''; miriamKey=''; -0256 case 'charge' -0257 model = readFieldValue(model, 'metCharges', tline_value, pos); +0256 case 'notes' +0257 model = readFieldValue(model, 'metNotes', tline_value, pos); 0258 readList=''; miriamKey=''; -0259 case 'notes' -0260 model = readFieldValue(model, 'metNotes', tline_value, pos); +0259 case 'inchis' +0260 model = readFieldValue(model, 'inchis', tline_value, pos); 0261 readList=''; miriamKey=''; -0262 case 'inchis' -0263 model = readFieldValue(model, 'inchis', tline_value, pos); -0264 readList=''; miriamKey=''; -0265 case 'smiles' -0266 model = readFieldValue(model, 'metSmiles', tline_value, pos); -0267 readList=''; miriamKey=''; +0262 case 'smiles' +0263 model = readFieldValue(model, 'metSmiles', tline_value, pos); +0264 readList=''; miriamKey=''; +0265 case 'deltaG' +0266 model = readFieldValue(model, 'metDeltaG', tline_value, pos); +0267 readList=''; miriamKey=''; 0268 case 'metFrom' 0269 model = readFieldValue(model, 'metFrom', tline_value, pos); 0270 readList=''; miriamKey=''; @@ -366,363 +366,371 @@

SOURCE CODE ^case 'rxnFrom' 0310 model = readFieldValue(model, 'rxnFrom', tline_value, pos); 0311 readList=''; miriamKey=''; -0312 case 'objective_coefficient' -0313 model.c(pos,1) = 1; -0314 readList=''; miriamKey=''; -0315 case 'references' -0316 model = readFieldValue(model, 'rxnReferences', tline_value, pos); +0312 case 'deltaG' +0313 model = readFieldValue(model, 'rxnDeltaG', tline_value, pos); +0314 readList=''; miriamKey=''; +0315 case 'objective_coefficient' +0316 model.c(pos,1) = 1; 0317 readList=''; miriamKey=''; -0318 case 'confidence_score' -0319 model = readFieldValue(model, 'rxnConfidenceScores', tline_value, pos); +0318 case 'references' +0319 model = readFieldValue(model, 'rxnReferences', tline_value, pos); 0320 readList=''; miriamKey=''; -0321 case 'eccodes' -0322 if isempty(tline_value) -0323 readList = 'eccodes'; -0324 else -0325 eccodes(ecCodeNo,1:2)={pos,tline_value}; -0326 ecCodeNo=ecCodeNo+1; -0327 end -0328 case 'subsystem' -0329 if isempty(tline_value) -0330 readList = 'subsystem'; -0331 else -0332 subSystems(subSysNo,1:2)={pos,tline_value}; -0333 subSysNo=subSysNo+1; -0334 end -0335 case 'metabolites' -0336 readList = 'equation'; -0337 case 'annotation' -0338 readList = 'annotation'; -0339 -0340 otherwise -0341 switch readList -0342 case 'eccodes' -0343 eccodes(ecCodeNo,1:2)={pos,regexprep(tline_value,'^ +- "?(.*)"?$','$1')}; -0344 ecCodeNo=ecCodeNo+1; -0345 case 'subsystem' -0346 subSystems(subSysNo,1:2)={pos,regexprep(tline_value,'^ +- "?(.*)"?$','$1')}; -0347 subSysNo=subSysNo+1; -0348 case 'annotation' -0349 [rxnMiriams, miriamKey,rxnMirNo] = gatherAnnotation(pos,rxnMiriams,tline_key,tline_value,miriamKey,rxnMirNo); -0350 rxnMirNo=rxnMirNo+1; -0351 case 'equation' -0352 coeff = sscanf(tline_value,'%f'); -0353 equations(equatiNo,1:3)={pos,tline_key,coeff}; -0354 equatiNo=equatiNo+1; -0355 otherwise -0356 error(['Unknown entry in yaml file: ' tline_raw]) -0357 end -0358 end; continue -0359 end -0360 -0361 % import genes: -0362 if section == 4 -0363 switch tline_key -0364 case 'id' -0365 pos = pos + 1; -0366 model = readFieldValue(model, 'genes', tline_value, pos); -0367 readList = ''; -0368 miriamKey = ''; -0369 case 'name' -0370 model = readFieldValue(model, 'geneShortNames', tline_value, pos); -0371 case 'annotation' -0372 readList = 'annotation'; -0373 otherwise -0374 switch readList -0375 case 'annotation' -0376 [geneMiriams, miriamKey] = gatherAnnotation(pos,geneMiriams,tline_key,tline_value,miriamKey,genMirNo); -0377 genMirNo = genMirNo + 1; -0378 otherwise -0379 error(['Unknown entry in yaml file: ' tline_raw]) -0380 end -0381 end; continue -0382 end -0383 -0384 % import compartments: -0385 if section == 5 -0386 model.comps(end+1,1) = {tline_key}; -0387 model.compNames(end+1,1) = {tline_value}; -0388 end -0389 -0390 % import ec reaction info -0391 if section == 6 -0392 switch tline_key -0393 case 'id' -0394 pos = pos + 1; -0395 model.ec = readFieldValue(model.ec, 'rxns', tline_value, pos); -0396 readList=''; -0397 case 'kcat' -0398 model.ec = readFieldValue(model.ec, 'kcat', tline_value, pos); +0321 case 'confidence_score' +0322 model = readFieldValue(model, 'rxnConfidenceScores', tline_value, pos); +0323 readList=''; miriamKey=''; +0324 case 'eccodes' +0325 if isempty(tline_value) +0326 readList = 'eccodes'; +0327 else +0328 eccodes(ecCodeNo,1:2)={pos,tline_value}; +0329 ecCodeNo=ecCodeNo+1; +0330 end +0331 case 'subsystem' +0332 if isempty(tline_value) +0333 readList = 'subsystem'; +0334 else +0335 subSystems(subSysNo,1:2)={pos,tline_value}; +0336 subSysNo=subSysNo+1; +0337 end +0338 case 'metabolites' +0339 readList = 'equation'; +0340 case 'annotation' +0341 readList = 'annotation'; +0342 +0343 otherwise +0344 switch readList +0345 case 'eccodes' +0346 eccodes(ecCodeNo,1:2)={pos,regexprep(tline_value,'^ +- "?(.*)"?$','$1')}; +0347 ecCodeNo=ecCodeNo+1; +0348 case 'subsystem' +0349 subSystems(subSysNo,1:2)={pos,regexprep(tline_value,'^ +- "?(.*)"?$','$1')}; +0350 subSysNo=subSysNo+1; +0351 case 'annotation' +0352 [rxnMiriams, miriamKey,rxnMirNo] = gatherAnnotation(pos,rxnMiriams,tline_key,tline_value,miriamKey,rxnMirNo); +0353 rxnMirNo=rxnMirNo+1; +0354 case 'equation' +0355 coeff = sscanf(tline_value,'%f'); +0356 equations(equatiNo,1:3)={pos,tline_key,coeff}; +0357 equatiNo=equatiNo+1; +0358 otherwise +0359 error(['Unknown entry in yaml file: ' tline_raw]) +0360 end +0361 end; continue +0362 end +0363 +0364 % import genes: +0365 if section == 4 +0366 switch tline_key +0367 case 'id' +0368 pos = pos + 1; +0369 model = readFieldValue(model, 'genes', tline_value, pos); +0370 readList = ''; +0371 miriamKey = ''; +0372 case 'name' +0373 model = readFieldValue(model, 'geneShortNames', tline_value, pos); +0374 case 'annotation' +0375 readList = 'annotation'; +0376 otherwise +0377 switch readList +0378 case 'annotation' +0379 [geneMiriams, miriamKey] = gatherAnnotation(pos,geneMiriams,tline_key,tline_value,miriamKey,genMirNo); +0380 genMirNo = genMirNo + 1; +0381 otherwise +0382 error(['Unknown entry in yaml file: ' tline_raw]) +0383 end +0384 end; continue +0385 end +0386 +0387 % import compartments: +0388 if section == 5 +0389 model.comps(end+1,1) = {tline_key}; +0390 model.compNames(end+1,1) = {tline_value}; +0391 end +0392 +0393 % import ec reaction info +0394 if section == 6 +0395 switch tline_key +0396 case 'id' +0397 pos = pos + 1; +0398 model.ec = readFieldValue(model.ec, 'rxns', tline_value, pos); 0399 readList=''; -0400 case 'source' -0401 model.ec = readFieldValue(model.ec, 'source', tline_value, pos); +0400 case 'kcat' +0401 model.ec = readFieldValue(model.ec, 'kcat', tline_value, pos); 0402 readList=''; -0403 case 'notes' -0404 model.ec = readFieldValue(model.ec, 'notes', tline_value, pos); +0403 case 'source' +0404 model.ec = readFieldValue(model.ec, 'source', tline_value, pos); 0405 readList=''; -0406 case 'eccodes' -0407 if isempty(tline_value) -0408 readList = 'eccodes'; -0409 else -0410 ecGecko(ecGeckoNo,1:2)={pos,tline_value}; -0411 ecGeckoNo=ecGeckoNo+1; -0412 end -0413 case 'enzymes' -0414 readList = 'enzStoich'; -0415 otherwise -0416 switch readList -0417 case 'eccodes' -0418 ecGecko(ecGeckoNo,1:2)={pos,regexprep(tline_value,'^ +- "?(.*)"?$','$1')}; -0419 ecGeckoNo=ecGeckoNo+1; -0420 case 'enzStoich' -0421 coeff = sscanf(tline_value,'%f'); -0422 enzStoich(enzStoichNo,1:3)={pos,tline_key,coeff}; -0423 enzStoichNo=enzStoichNo+1; -0424 otherwise -0425 error(['Unknown entry in yaml file: ' tline_raw]) -0426 end -0427 end; continue -0428 end -0429 -0430 % import ec enzyme info -0431 if section == 7 -0432 switch tline_key -0433 case 'genes' -0434 pos = pos + 1; -0435 model.ec = readFieldValue(model.ec, 'genes', tline_value, pos); -0436 case 'enzymes' -0437 model.ec = readFieldValue(model.ec, 'enzymes', tline_value, pos); -0438 case 'mw' -0439 model.ec = readFieldValue(model.ec, 'mw', tline_value, pos); -0440 case 'sequence' -0441 model.ec = readFieldValue(model.ec, 'sequence', tline_value, pos); -0442 case 'concs' -0443 model.ec = readFieldValue(model.ec, 'concs', tline_value, pos); -0444 otherwise -0445 error(['Unknown entry in yaml file: ' tline_raw]) -0446 end; continue -0447 end -0448 end -0449 -0450 %Parse annotations -0451 if ~isempty(metMiriams) -0452 locs = cell2mat(metMiriams(:,1)); -0453 for i=unique(locs)' -0454 model.metMiriams{i,1}.name=metMiriams(locs==i,2); -0455 model.metMiriams{i,1}.value=metMiriams(locs==i,3); -0456 end -0457 end -0458 if ~isempty(rxnMiriams) -0459 locs = cell2mat(rxnMiriams(:,1)); -0460 for i=unique(locs)' -0461 model.rxnMiriams{i,1}.name=rxnMiriams(locs==i,2); -0462 model.rxnMiriams{i,1}.value=rxnMiriams(locs==i,3); -0463 end -0464 end -0465 if ~isempty(geneMiriams) -0466 locs = cell2mat(geneMiriams(:,1)); -0467 for i=unique(locs)' -0468 model.geneMiriams{i,1}.name=geneMiriams(locs==i,2); -0469 model.geneMiriams{i,1}.value=geneMiriams(locs==i,3); -0470 end -0471 end -0472 -0473 %Parse subSystems -0474 if ~isempty(subSystems) -0475 locs = cell2mat(subSystems(:,1)); -0476 for i=unique(locs)' -0477 model.subSystems{i,1}=subSystems(locs==i,2); -0478 end -0479 end -0480 -0481 %Parse ec-codes -0482 if ~isempty(eccodes) -0483 locs = cell2mat(eccodes(:,1)); -0484 for i=unique(locs)' -0485 eccodesCat=strjoin(eccodes(locs==i,2),';'); -0486 model.eccodes{i,1}=eccodesCat; -0487 end -0488 emptyEc=cellfun(@isempty,model.eccodes); -0489 model.eccodes(emptyEc)={''}; -0490 end -0491 -0492 % follow-up data processing -0493 if verbose -0494 fprintf('\nimporting completed\nfollow-up processing...'); -0495 end -0496 [~, model.metComps] = ismember(model.metComps, model.comps); -0497 [~, model.geneComps] = ismember(model.geneComps, model.comps); -0498 [~, model.rxnComps] = ismember(model.rxnComps, model.comps); -0499 -0500 % Fill S-matrix -0501 rxnIdx = cellfun(@isempty, equations(:,1)); -0502 equations(rxnIdx,:) = ''; -0503 rxnIdx = cell2mat(equations(:,1)); -0504 [~,metIdx] = ismember(equations(:,2),model.mets); -0505 coeffs = cell2mat(equations(:,3)); -0506 model.S=sparse(max(metIdx),max(rxnIdx)); -0507 linearIndices = sub2ind([max(metIdx), max(rxnIdx)],metIdx,rxnIdx); -0508 model.S(linearIndices) = coeffs; -0509 -0510 % Convert strings to numeric -0511 model.metCharges = str2double(model.metCharges); -0512 model.lb = str2double(model.lb); -0513 model.ub = str2double(model.ub); -0514 model.rxnConfidenceScores = str2double(model.rxnConfidenceScores); -0515 model.b = zeros(length(model.mets),1); -0516 -0517 % Fill some other fields -0518 model.annotation.defaultLB = min(model.lb); -0519 model.annotation.defaultUB = max(model.ub); -0520 if numel(model.lb)<numel(model.rxns) %No LB reported = min -0521 model.lb(end+1:numel(model.rxns)-numel(model.lb),1) = double(model.annotation.defaultLB); -0522 end -0523 if numel(model.ub)<numel(model.rxns) %No UB reported = max -0524 model.ub(end+1:numel(model.rxns)-numel(model.ub),1) = double(model.annotation.defaultUB); -0525 end -0526 if ~all(cellfun(@isempty,model.rev)) -0527 model.rev = str2double(model.rev); -0528 else -0529 model.rev = []; +0406 case 'notes' +0407 model.ec = readFieldValue(model.ec, 'notes', tline_value, pos); +0408 readList=''; +0409 case 'eccodes' +0410 if isempty(tline_value) +0411 readList = 'eccodes'; +0412 else +0413 ecGecko(ecGeckoNo,1:2)={pos,tline_value}; +0414 ecGeckoNo=ecGeckoNo+1; +0415 end +0416 case 'enzymes' +0417 readList = 'enzStoich'; +0418 otherwise +0419 switch readList +0420 case 'eccodes' +0421 ecGecko(ecGeckoNo,1:2)={pos,regexprep(tline_value,'^ +- "?(.*)"?$','$1')}; +0422 ecGeckoNo=ecGeckoNo+1; +0423 case 'enzStoich' +0424 coeff = sscanf(tline_value,'%f'); +0425 enzStoich(enzStoichNo,1:3)={pos,tline_key,coeff}; +0426 enzStoichNo=enzStoichNo+1; +0427 otherwise +0428 error(['Unknown entry in yaml file: ' tline_raw]) +0429 end +0430 end; continue +0431 end +0432 +0433 % import ec enzyme info +0434 if section == 7 +0435 switch tline_key +0436 case 'genes' +0437 pos = pos + 1; +0438 model.ec = readFieldValue(model.ec, 'genes', tline_value, pos); +0439 case 'enzymes' +0440 model.ec = readFieldValue(model.ec, 'enzymes', tline_value, pos); +0441 case 'mw' +0442 model.ec = readFieldValue(model.ec, 'mw', tline_value, pos); +0443 case 'sequence' +0444 model.ec = readFieldValue(model.ec, 'sequence', tline_value, pos); +0445 case 'concs' +0446 model.ec = readFieldValue(model.ec, 'concs', tline_value, pos); +0447 otherwise +0448 error(['Unknown entry in yaml file: ' tline_raw]) +0449 end; continue +0450 end +0451 end +0452 +0453 %Parse annotations +0454 if ~isempty(metMiriams) +0455 locs = cell2mat(metMiriams(:,1)); +0456 for i=unique(locs)' +0457 model.metMiriams{i,1}.name=metMiriams(locs==i,2); +0458 model.metMiriams{i,1}.value=metMiriams(locs==i,3); +0459 end +0460 end +0461 if ~isempty(rxnMiriams) +0462 locs = cell2mat(rxnMiriams(:,1)); +0463 for i=unique(locs)' +0464 model.rxnMiriams{i,1}.name=rxnMiriams(locs==i,2); +0465 model.rxnMiriams{i,1}.value=rxnMiriams(locs==i,3); +0466 end +0467 end +0468 if ~isempty(geneMiriams) +0469 locs = cell2mat(geneMiriams(:,1)); +0470 for i=unique(locs)' +0471 model.geneMiriams{i,1}.name=geneMiriams(locs==i,2); +0472 model.geneMiriams{i,1}.value=geneMiriams(locs==i,3); +0473 end +0474 end +0475 +0476 %Parse subSystems +0477 if ~isempty(subSystems) +0478 locs = cell2mat(subSystems(:,1)); +0479 for i=unique(locs)' +0480 model.subSystems{i,1}=subSystems(locs==i,2); +0481 end +0482 end +0483 +0484 %Parse ec-codes +0485 if ~isempty(eccodes) +0486 locs = cell2mat(eccodes(:,1)); +0487 for i=unique(locs)' +0488 eccodesCat=strjoin(eccodes(locs==i,2),';'); +0489 model.eccodes{i,1}=eccodesCat; +0490 end +0491 emptyEc=cellfun(@isempty,model.eccodes); +0492 model.eccodes(emptyEc)={''}; +0493 end +0494 +0495 % follow-up data processing +0496 if verbose +0497 fprintf('\nimporting completed\nfollow-up processing...'); +0498 end +0499 [~, model.metComps] = ismember(model.metComps, model.comps); +0500 [~, model.geneComps] = ismember(model.geneComps, model.comps); +0501 [~, model.rxnComps] = ismember(model.rxnComps, model.comps); +0502 +0503 % Fill S-matrix +0504 rxnIdx = cellfun(@isempty, equations(:,1)); +0505 equations(rxnIdx,:) = ''; +0506 rxnIdx = cell2mat(equations(:,1)); +0507 [~,metIdx] = ismember(equations(:,2),model.mets); +0508 coeffs = cell2mat(equations(:,3)); +0509 model.S=sparse(max(metIdx),max(rxnIdx)); +0510 linearIndices = sub2ind([max(metIdx), max(rxnIdx)],metIdx,rxnIdx); +0511 model.S(linearIndices) = coeffs; +0512 +0513 % Convert strings to numeric +0514 model.metCharges = str2double(model.metCharges); +0515 model.lb = str2double(model.lb); +0516 model.ub = str2double(model.ub); +0517 model.rxnConfidenceScores = str2double(model.rxnConfidenceScores); +0518 model.b = zeros(length(model.mets),1); +0519 model.metDeltaG = str2double(model.metDeltaG); +0520 model.rxnDeltaG = str2double(model.rxnDeltaG); +0521 +0522 % Fill some other fields +0523 model.annotation.defaultLB = min(model.lb); +0524 model.annotation.defaultUB = max(model.ub); +0525 if numel(model.lb)<numel(model.rxns) %No LB reported = min +0526 model.lb(end+1:numel(model.rxns)-numel(model.lb),1) = double(model.annotation.defaultLB); +0527 end +0528 if numel(model.ub)<numel(model.rxns) %No UB reported = max +0529 model.ub(end+1:numel(model.rxns)-numel(model.ub),1) = double(model.annotation.defaultUB); 0530 end -0531 if numel(model.rev)<numel(model.rxns) %No rev reported, assume from LB and UB -0532 model.rev(end+1:numel(model.rxns)-numel(model.rev),1) = double(model.lb<0 & model.ub>0); -0533 end -0534 -0535 % Remove empty fields, otherwise fill to correct length -0536 % Reactions -0537 for i={'rxnNames','grRules','eccodes','rxnNotes','rxnReferences',... -0538 'rxnFrom','subSystems','rxnMiriams'} % Empty strings -0539 model = emptyOrFill(model,i{1},{''},'rxns'); -0540 end -0541 for i={'c'} % Zeros -0542 model = emptyOrFill(model,i{1},0,'rxns'); -0543 end -0544 for i={'rxnConfidenceScores'} % NaNs -0545 model = emptyOrFill(model,i{1},NaN,'rxns'); -0546 end -0547 for i={'rxnComps'} % Ones, assume first compartment -0548 model = emptyOrFill(model,i{1},1,'rxns'); -0549 end -0550 % Metabolites -0551 for i={'metNames','inchis','metFormulas','metMiriams','metFrom','metSmiles','metNotes'} % Empty strings -0552 model = emptyOrFill(model,i{1},{''},'mets'); -0553 end -0554 for i={'metCharges','unconstrained'} % Zeros -0555 model = emptyOrFill(model,i{1},0,'mets'); -0556 end -0557 for i={'metComps'} % Ones, assume first compartment -0558 model = emptyOrFill(model,i{1},1,'mets'); -0559 end -0560 % Genes -0561 for i={'geneMiriams','geneShortNames'} % Empty strings -0562 model = emptyOrFill(model,i{1},{''},'genes'); -0563 end -0564 for i={'geneComps'} % Ones, assume first compartment -0565 model = emptyOrFill(model,i{1},1,'genes'); -0566 end -0567 % Comps -0568 for i={'compNames'} % Empty strings -0569 model = emptyOrFill(model,i{1},{''},'comps'); -0570 end -0571 for i={'compOutside'} % First comp -0572 model = emptyOrFill(model,i{1},model.comps{1},'comps'); -0573 end -0574 % Single fields are kept, even if empty -0575 % for i={'description','name','version','date','annotation'} -0576 % if isempty(model.(i{1})) -0577 % model = rmfield(model,i{1}); -0578 % end -0579 % end -0580 -0581 % Make rxnGeneMat fields and map to the existing model.genes field -0582 [genes, rxnGeneMat] = getGenesFromGrRules(model.grRules); -0583 model.rxnGeneMat = sparse(numel(model.rxns),numel(model.genes)); -0584 [~,geneOrder] = ismember(genes,model.genes); -0585 if any(geneOrder == 0) -0586 error(['The grRules includes the following gene(s), that are not in '... -0587 'the list of model genes: ', genes{~geneOrder}]) -0588 end -0589 model.rxnGeneMat(:,geneOrder) = rxnGeneMat; -0590 -0591 % Finalize GECKO model -0592 if isGECKO -0593 % Fill in empty fields and empty entries -0594 for i={'kcat','source','notes','eccodes'} % Even keep empty -0595 model.ec = emptyOrFill(model.ec,i{1},{''},'rxns',true); -0596 end -0597 for i={'enzymes','mw','sequence'} -0598 model.ec = emptyOrFill(model.ec,i{1},{''},'genes',true); -0599 end -0600 model.ec = emptyOrFill(model.ec,'concs',{'NaN'},'genes',true); -0601 model.ec = emptyOrFill(model.ec,'kcat',{'0'},'genes',true); -0602 % Change string to double -0603 for i={'kcat','mw','concs'} -0604 if isfield(model.ec,i{1}) -0605 model.ec.(i{1}) = str2double(model.ec.(i{1})); -0606 end +0531 if ~all(cellfun(@isempty,model.rev)) +0532 model.rev = str2double(model.rev); +0533 else +0534 model.rev = []; +0535 end +0536 if numel(model.rev)<numel(model.rxns) %No rev reported, assume from LB and UB +0537 model.rev(end+1:numel(model.rxns)-numel(model.rev),1) = double(model.lb<0 & model.ub>0); +0538 end +0539 +0540 % Remove empty fields, otherwise fill to correct length +0541 % Reactions +0542 for i={'rxnNames','grRules','eccodes','rxnNotes','rxnReferences',... +0543 'rxnFrom','subSystems','rxnMiriams'} % Empty strings +0544 model = emptyOrFill(model,i{1},{''},'rxns'); +0545 end +0546 for i={'c'} % Zeros +0547 model = emptyOrFill(model,i{1},0,'rxns'); +0548 end +0549 for i={'rxnConfidenceScores','rxnDeltaG'} % NaNs +0550 model = emptyOrFill(model,i{1},NaN,'rxns'); +0551 end +0552 for i={'rxnComps'} % Ones, assume first compartment +0553 model = emptyOrFill(model,i{1},1,'rxns'); +0554 end +0555 % Metabolites +0556 for i={'metNames','inchis','metFormulas','metMiriams','metFrom','metSmiles','metNotes'} % Empty strings +0557 model = emptyOrFill(model,i{1},{''},'mets'); +0558 end +0559 for i={'metCharges','unconstrained'} % Zeros +0560 model = emptyOrFill(model,i{1},0,'mets'); +0561 end +0562 for i={'metDeltaG'} % % NaNs +0563 model = emptyOrFill(model,i{1},NaN,'mets'); +0564 end +0565 for i={'metComps'} % Ones, assume first compartment +0566 model = emptyOrFill(model,i{1},1,'mets'); +0567 end +0568 % Genes +0569 for i={'geneMiriams','geneShortNames'} % Empty strings +0570 model = emptyOrFill(model,i{1},{''},'genes'); +0571 end +0572 for i={'geneComps'} % Ones, assume first compartment +0573 model = emptyOrFill(model,i{1},1,'genes'); +0574 end +0575 % Comps +0576 for i={'compNames'} % Empty strings +0577 model = emptyOrFill(model,i{1},{''},'comps'); +0578 end +0579 for i={'compOutside'} % First comp +0580 model = emptyOrFill(model,i{1},model.comps{1},'comps'); +0581 end +0582 % Single fields are kept, even if empty +0583 % for i={'description','name','version','date','annotation'} +0584 % if isempty(model.(i{1})) +0585 % model = rmfield(model,i{1}); +0586 % end +0587 % end +0588 +0589 % Make rxnGeneMat fields and map to the existing model.genes field +0590 [genes, rxnGeneMat] = getGenesFromGrRules(model.grRules); +0591 model.rxnGeneMat = sparse(numel(model.rxns),numel(model.genes)); +0592 [~,geneOrder] = ismember(genes,model.genes); +0593 if any(geneOrder == 0) +0594 error(['The grRules includes the following gene(s), that are not in '... +0595 'the list of model genes: ', genes{~geneOrder}]) +0596 end +0597 model.rxnGeneMat(:,geneOrder) = rxnGeneMat; +0598 +0599 % Finalize GECKO model +0600 if isGECKO +0601 % Fill in empty fields and empty entries +0602 for i={'kcat','source','notes','eccodes'} % Even keep empty +0603 model.ec = emptyOrFill(model.ec,i{1},{''},'rxns',true); +0604 end +0605 for i={'enzymes','mw','sequence'} +0606 model.ec = emptyOrFill(model.ec,i{1},{''},'genes',true); 0607 end -0608 % Fill rxnEnzMat -0609 rxnIdx = cellfun(@isempty, enzStoich(:,1)); -0610 enzStoich(rxnIdx,:) = ''; -0611 rxnIdx = cell2mat(enzStoich(:,1)); -0612 [~,enzIdx] = ismember(enzStoich(:,2),model.ec.enzymes); -0613 coeffs = cell2mat(enzStoich(:,3)); -0614 model.ec.rxnEnzMat = zeros(max(rxnIdx), max(enzIdx)); -0615 linearIndices = sub2ind([max(rxnIdx), max(enzIdx)], rxnIdx, enzIdx); -0616 model.ec.rxnEnzMat(linearIndices) = coeffs; -0617 %Parse ec-codes -0618 if ~isempty(ecGecko) -0619 locs = cell2mat(ecGecko(:,1)); -0620 for i=unique(locs)' -0621 ecGeckoCat=strjoin(ecGecko(locs==i,2),';'); -0622 model.ec.eccodes{i,1}=ecGeckoCat; -0623 end -0624 emptyEc=cellfun(@isempty,model.ec.eccodes); -0625 model.ec.eccodes(emptyEc)={''}; -0626 end -0627 end -0628 -0629 if verbose -0630 fprintf(' Done!\n'); -0631 end -0632 end -0633 -0634 function model = emptyOrFill(model,field,emptyEntry,type,keepEmpty) -0635 if nargin<5 -0636 keepEmpty=false; -0637 end -0638 if isnumeric(emptyEntry) -0639 emptyCells=isempty(model.(field)); -0640 else -0641 emptyCells=cellfun(@isempty,model.(field)); -0642 end -0643 if all(emptyCells) && ~keepEmpty -0644 model = rmfield(model, field); -0645 elseif numel(model.(field))<numel(model.(type)) -0646 model.(field)(end+1:numel(model.(type)),1)=emptyEntry; -0647 end -0648 end -0649 -0650 function model = readFieldValue(model, fieldName, value, pos) -0651 if numel(model.(fieldName))<pos-1 -0652 model.(fieldName)(end+1:pos,1) = {''}; -0653 end -0654 model.(fieldName)(pos,1) = {value}; +0608 model.ec = emptyOrFill(model.ec,'concs',{'NaN'},'genes',true); +0609 model.ec = emptyOrFill(model.ec,'kcat',{'0'},'genes',true); +0610 % Change string to double +0611 for i={'kcat','mw','concs'} +0612 if isfield(model.ec,i{1}) +0613 model.ec.(i{1}) = str2double(model.ec.(i{1})); +0614 end +0615 end +0616 % Fill rxnEnzMat +0617 rxnIdx = cellfun(@isempty, enzStoich(:,1)); +0618 enzStoich(rxnIdx,:) = ''; +0619 rxnIdx = cell2mat(enzStoich(:,1)); +0620 [~,enzIdx] = ismember(enzStoich(:,2),model.ec.enzymes); +0621 coeffs = cell2mat(enzStoich(:,3)); +0622 model.ec.rxnEnzMat = zeros(max(rxnIdx), max(enzIdx)); +0623 linearIndices = sub2ind([max(rxnIdx), max(enzIdx)], rxnIdx, enzIdx); +0624 model.ec.rxnEnzMat(linearIndices) = coeffs; +0625 %Parse ec-codes +0626 if ~isempty(ecGecko) +0627 locs = cell2mat(ecGecko(:,1)); +0628 for i=unique(locs)' +0629 ecGeckoCat=strjoin(ecGecko(locs==i,2),';'); +0630 model.ec.eccodes{i,1}=ecGeckoCat; +0631 end +0632 emptyEc=cellfun(@isempty,model.ec.eccodes); +0633 model.ec.eccodes(emptyEc)={''}; +0634 end +0635 end +0636 +0637 if verbose +0638 fprintf(' Done!\n'); +0639 end +0640 end +0641 +0642 function model = emptyOrFill(model,field,emptyEntry,type,keepEmpty) +0643 if nargin<5 +0644 keepEmpty=false; +0645 end +0646 if isnumeric(emptyEntry) +0647 emptyCells=isempty(model.(field)); +0648 else +0649 emptyCells=cellfun(@isempty,model.(field)); +0650 end +0651 if all(emptyCells) && ~keepEmpty +0652 model = rmfield(model, field); +0653 elseif numel(model.(field))<numel(model.(type)) +0654 model.(field)(end+1:numel(model.(type)),1)=emptyEntry; 0655 end -0656 -0657 function [miriams, miriamKey,entryNumber] = gatherAnnotation(pos,miriams,key,value,miriamKey,entryNumber) -0658 if isempty(key) -0659 key=miriamKey; -0660 else -0661 miriamKey=key; -0662 end -0663 if ~isempty(value) -0664 miriams(entryNumber,1:3) = {pos, key, strip(value)}; -0665 else -0666 entryNumber = entryNumber - 1; -0667 end -0668 end +0656 end +0657 +0658 function model = readFieldValue(model, fieldName, value, pos) +0659 if numel(model.(fieldName))<pos-1 +0660 model.(fieldName)(end+1:pos,1) = {''}; +0661 end +0662 model.(fieldName)(pos,1) = {value}; +0663 end +0664 +0665 function [miriams, miriamKey,entryNumber] = gatherAnnotation(pos,miriams,key,value,miriamKey,entryNumber) +0666 if isempty(key) +0667 key=miriamKey; +0668 else +0669 miriamKey=key; +0670 end +0671 if ~isempty(value) +0672 miriams(entryNumber,1:3) = {pos, key, strip(value)}; +0673 else +0674 entryNumber = entryNumber - 1; +0675 end +0676 end
Generated by m2html © 2005
\ No newline at end of file diff --git a/doc/io/writeYAMLmodel.html b/doc/io/writeYAMLmodel.html index 39b01959..6bba192c 100644 --- a/doc/io/writeYAMLmodel.html +++ b/doc/io/writeYAMLmodel.html @@ -135,284 +135,286 @@

SOURCE CODE ^writeField(model, fid, 'inchis', 'txt', i, ' - inchis', preserveQuotes) 0077 writeField(model, fid, 'metSmiles', 'txt', i, ' - smiles', preserveQuotes) 0078 writeField(model, fid, 'metMiriams', 'txt', i, ' - annotation', preserveQuotes) -0079 writeField(model, fid, 'metNotes', 'txt', i, ' - notes', preserveQuotes) -0080 writeField(model, fid, 'metFrom', 'txt', i, ' - metFrom', preserveQuotes) -0081 end -0082 -0083 %Reactions: -0084 fprintf(fid,'- reactions:\n'); -0085 for i = 1:length(model.rxns) -0086 fprintf(fid,' - !!omap\n'); -0087 writeField(model, fid, 'rxns', 'txt', i, ' - id', preserveQuotes) -0088 writeField(model, fid, 'rxnNames', 'txt', i, ' - name', preserveQuotes) -0089 writeField(model, fid, 'S', 'txt', i, ' - metabolites', preserveQuotes) -0090 writeField(model, fid, 'lb', 'num', i, ' - lower_bound', preserveQuotes) -0091 writeField(model, fid, 'ub', 'num', i, ' - upper_bound', preserveQuotes) -0092 writeField(model, fid, 'grRules', 'txt', i, ' - gene_reaction_rule', preserveQuotes) -0093 writeField(model, fid, 'rxnFrom', 'txt', i, ' - rxnFrom', preserveQuotes) -0094 if model.c(i)~=0 -0095 writeField(model, fid, 'c', 'num', i, ' - objective_coefficient', preserveQuotes) -0096 end -0097 writeField(model, fid, 'eccodes', 'txt', i, ' - eccodes', preserveQuotes) -0098 writeField(model, fid, 'rxnReferences', 'txt', i, ' - references', preserveQuotes) -0099 writeField(model, fid, 'subSystems', 'txt', i, ' - subsystem', preserveQuotes) -0100 writeField(model, fid, 'rxnMiriams', 'txt', i, ' - annotation', preserveQuotes) -0101 writeField(model, fid, 'rxnConfidenceScores', 'num', i, ' - confidence_score', preserveQuotes) -0102 writeField(model, fid, 'rxnNotes', 'txt', i, ' - rxnNotes', preserveQuotes) -0103 end -0104 -0105 %Genes: -0106 fprintf(fid,'- genes:\n'); -0107 for i = 1:length(model.genes) -0108 fprintf(fid,' - !!omap\n'); -0109 writeField(model, fid, 'genes', 'txt', i, ' - id', preserveQuotes) -0110 writeField(model, fid, 'geneShortNames', 'txt', i, ' - name', preserveQuotes) -0111 writeField(model, fid, 'geneMiriams', 'txt', i, ' - annotation', preserveQuotes) -0112 end -0113 -0114 %Compartments: -0115 fprintf(fid,'- compartments: !!omap\n'); -0116 for i = 1:length(model.comps) -0117 writeField(model, fid, 'compNames', 'txt', i, ['- ' model.comps{i}], preserveQuotes) -0118 writeField(model, fid, 'compMiriams', 'txt', i, '- annotation', preserveQuotes) -0119 end -0120 -0121 -0122 %EC-model: -0123 if isfield(model,'ec') -0124 fprintf(fid,'- ec-rxns:\n'); -0125 for i = 1:length(model.ec.rxns) -0126 fprintf(fid,' - !!omap\n'); -0127 writeField(model.ec, fid, 'rxns', 'txt', i, '- id', preserveQuotes) -0128 writeField(model.ec, fid, 'kcat', 'num', i, '- kcat', preserveQuotes) -0129 writeField(model.ec, fid, 'source', 'txt', i, '- source', preserveQuotes) -0130 writeField(model.ec, fid, 'notes', 'txt', i, '- notes', preserveQuotes) -0131 writeField(model.ec, fid, 'eccodes', 'txt', i, '- eccodes', preserveQuotes) -0132 writeField(model.ec, fid, 'rxnEnzMat', 'txt', i, '- enzymes', preserveQuotes) -0133 end -0134 -0135 fprintf(fid,'- ec-enzymes:\n'); -0136 for i = 1:length(model.ec.genes) -0137 fprintf(fid,' - !!omap\n'); -0138 writeField(model.ec, fid, 'genes', 'txt', i, '- genes', preserveQuotes) -0139 writeField(model.ec, fid, 'enzymes', 'txt', i, '- enzymes', preserveQuotes) -0140 writeField(model.ec, fid, 'mw', 'num', i, '- mw', preserveQuotes) -0141 writeField(model.ec, fid, 'sequence', 'txt', i, '- sequence', preserveQuotes) -0142 writeField(model.ec, fid, 'concs', 'num', i, '- concs', preserveQuotes) -0143 end -0144 end -0145 -0146 %Close file: -0147 fclose(fid); -0148 -0149 end +0079 writeField(model, fid, 'metDeltaG', 'num', i, ' - deltaG', preserveQuotes) +0080 writeField(model, fid, 'metNotes', 'txt', i, ' - notes', preserveQuotes) +0081 writeField(model, fid, 'metFrom', 'txt', i, ' - metFrom', preserveQuotes) +0082 end +0083 +0084 %Reactions: +0085 fprintf(fid,'- reactions:\n'); +0086 for i = 1:length(model.rxns) +0087 fprintf(fid,' - !!omap\n'); +0088 writeField(model, fid, 'rxns', 'txt', i, ' - id', preserveQuotes) +0089 writeField(model, fid, 'rxnNames', 'txt', i, ' - name', preserveQuotes) +0090 writeField(model, fid, 'S', 'txt', i, ' - metabolites', preserveQuotes) +0091 writeField(model, fid, 'lb', 'num', i, ' - lower_bound', preserveQuotes) +0092 writeField(model, fid, 'ub', 'num', i, ' - upper_bound', preserveQuotes) +0093 writeField(model, fid, 'grRules', 'txt', i, ' - gene_reaction_rule', preserveQuotes) +0094 writeField(model, fid, 'rxnFrom', 'txt', i, ' - rxnFrom', preserveQuotes) +0095 if model.c(i)~=0 +0096 writeField(model, fid, 'c', 'num', i, ' - objective_coefficient', preserveQuotes) +0097 end +0098 writeField(model, fid, 'eccodes', 'txt', i, ' - eccodes', preserveQuotes) +0099 writeField(model, fid, 'rxnReferences', 'txt', i, ' - references', preserveQuotes) +0100 writeField(model, fid, 'subSystems', 'txt', i, ' - subsystem', preserveQuotes) +0101 writeField(model, fid, 'rxnMiriams', 'txt', i, ' - annotation', preserveQuotes) +0102 writeField(model, fid, 'rxnDeltaG', 'num', i, ' - deltaG', preserveQuotes) +0103 writeField(model, fid, 'rxnConfidenceScores', 'num', i, ' - confidence_score', preserveQuotes) +0104 writeField(model, fid, 'rxnNotes', 'txt', i, ' - rxnNotes', preserveQuotes) +0105 end +0106 +0107 %Genes: +0108 fprintf(fid,'- genes:\n'); +0109 for i = 1:length(model.genes) +0110 fprintf(fid,' - !!omap\n'); +0111 writeField(model, fid, 'genes', 'txt', i, ' - id', preserveQuotes) +0112 writeField(model, fid, 'geneShortNames', 'txt', i, ' - name', preserveQuotes) +0113 writeField(model, fid, 'geneMiriams', 'txt', i, ' - annotation', preserveQuotes) +0114 end +0115 +0116 %Compartments: +0117 fprintf(fid,'- compartments: !!omap\n'); +0118 for i = 1:length(model.comps) +0119 writeField(model, fid, 'compNames', 'txt', i, ['- ' model.comps{i}], preserveQuotes) +0120 writeField(model, fid, 'compMiriams', 'txt', i, '- annotation', preserveQuotes) +0121 end +0122 +0123 +0124 %EC-model: +0125 if isfield(model,'ec') +0126 fprintf(fid,'- ec-rxns:\n'); +0127 for i = 1:length(model.ec.rxns) +0128 fprintf(fid,' - !!omap\n'); +0129 writeField(model.ec, fid, 'rxns', 'txt', i, '- id', preserveQuotes) +0130 writeField(model.ec, fid, 'kcat', 'num', i, '- kcat', preserveQuotes) +0131 writeField(model.ec, fid, 'source', 'txt', i, '- source', preserveQuotes) +0132 writeField(model.ec, fid, 'notes', 'txt', i, '- notes', preserveQuotes) +0133 writeField(model.ec, fid, 'eccodes', 'txt', i, '- eccodes', preserveQuotes) +0134 writeField(model.ec, fid, 'rxnEnzMat', 'txt', i, '- enzymes', preserveQuotes) +0135 end +0136 +0137 fprintf(fid,'- ec-enzymes:\n'); +0138 for i = 1:length(model.ec.genes) +0139 fprintf(fid,' - !!omap\n'); +0140 writeField(model.ec, fid, 'genes', 'txt', i, '- genes', preserveQuotes) +0141 writeField(model.ec, fid, 'enzymes', 'txt', i, '- enzymes', preserveQuotes) +0142 writeField(model.ec, fid, 'mw', 'num', i, '- mw', preserveQuotes) +0143 writeField(model.ec, fid, 'sequence', 'txt', i, '- sequence', preserveQuotes) +0144 writeField(model.ec, fid, 'concs', 'num', i, '- concs', preserveQuotes) +0145 end +0146 end +0147 +0148 %Close file: +0149 fclose(fid); 0150 -0151 function writeField(model,fid,fieldName,type,pos,name,preserveQuotes) -0152 %Writes a new line in the yaml file if the field exists and the field is -0153 %not empty at the correspoinding position. It's recursive for some fields -0154 %(metMiriams, rxnMiriams, and S) -0155 -0156 if isfield(model,fieldName) -0157 if strcmp(fieldName,'metComps') -0158 %metComps: write full name -0159 fieldName = 'comps'; -0160 pos = model.metComps(pos); -0161 end -0162 -0163 field = model.(fieldName); +0151 end +0152 +0153 function writeField(model,fid,fieldName,type,pos,name,preserveQuotes) +0154 %Writes a new line in the yaml file if the field exists and the field is +0155 %not empty at the correspoinding position. It's recursive for some fields +0156 %(metMiriams, rxnMiriams, and S) +0157 +0158 if isfield(model,fieldName) +0159 if strcmp(fieldName,'metComps') +0160 %metComps: write full name +0161 fieldName = 'comps'; +0162 pos = model.metComps(pos); +0163 end 0164 -0165 if strcmp(fieldName,'metMiriams') -0166 if ~isempty(model.metMiriams{pos}) -0167 fprintf(fid,' %s: !!omap\n',name); -0168 for i=1:size(model.newMetMiriams,2) -0169 %'i' represents the different miriam names, e.g. -0170 %kegg.compound or chebi -0171 if ~isempty(model.newMetMiriams{pos,i}) -0172 %As during the following writeField call the value of -0173 %'i' would be lost, it is temporarily concatenated to -0174 %'name' parameter, which will be edited later -0175 writeField(model, fid, 'newMetMiriams', 'txt', pos, [' - ' model.newMetMiriamNames{i} '_' sprintf('%d',i)], preserveQuotes) -0176 end -0177 end -0178 end -0179 -0180 elseif strcmp(fieldName,'rxnMiriams') -0181 if ~isempty(model.rxnMiriams{pos}) -0182 fprintf(fid,' %s: !!omap\n',name); -0183 for i=1:size(model.newRxnMiriams,2) -0184 if ~isempty(model.newRxnMiriams{pos,i}) -0185 writeField(model, fid, 'newRxnMiriams', 'txt', pos, [' - ' model.newRxnMiriamNames{i} '_' sprintf('%d',i)], preserveQuotes) -0186 end -0187 end -0188 end -0189 -0190 elseif strcmp(fieldName,'geneMiriams') -0191 if ~isempty(model.geneMiriams{pos}) -0192 fprintf(fid,' %s: !!omap\n',name); -0193 for i=1:size(model.newGeneMiriams,2) -0194 if ~isempty(model.newGeneMiriams{pos,i}) -0195 writeField(model, fid, 'newGeneMiriams', 'txt', pos, [' - ' model.newGeneMiriamNames{i} '_' sprintf('%d',i)], preserveQuotes) -0196 end -0197 end -0198 end -0199 -0200 elseif strcmp(fieldName,'compMiriams') -0201 if ~isempty(model.compMiriams{pos}) -0202 fprintf(fid,' %s: !!omap\n',name); -0203 for i=1:size(model.newCompMiriams,2) -0204 if ~isempty(model.newCompMiriams{pos,i}) -0205 writeField(model, fid, 'newCompMiriams', 'txt', pos, [' - ' model.newCompMiriamNames{i} '_' sprintf('%d',i)], preserveQuotes) -0206 end -0207 end -0208 end -0209 -0210 elseif strcmp(fieldName,'S') -0211 %S: create header & write each metabolite in a new line -0212 fprintf(fid,' %s: !!omap\n',name); -0213 if sum(field(:,pos) ~= 0) > 0 -0214 model.mets = model.mets(field(:,pos) ~= 0); -0215 model.coeffs = field(field(:,pos) ~= 0,pos); -0216 %Sort metabolites: -0217 [model.mets,order] = sort(model.mets); -0218 model.coeffs = model.coeffs(order); -0219 for i = 1:length(model.mets) -0220 writeField(model, fid, 'coeffs', 'num', i, [' - ' model.mets{i}], preserveQuotes) -0221 end -0222 end -0223 -0224 elseif strcmp(fieldName,'rxnEnzMat') -0225 %S: create header & write each enzyme in a new line -0226 fprintf(fid,' %s: !!omap\n',name); -0227 if sum(field(pos,:) ~= 0) > 0 -0228 model.enzymes = model.enzymes(field(pos,:) ~= 0); -0229 model.coeffs = field(pos,field(pos,:) ~= 0); -0230 %Sort metabolites: -0231 [model.enzymes,order] = sort(model.enzymes); -0232 model.coeffs = model.coeffs(order); -0233 for i = 1:length(model.enzymes) -0234 writeField(model, fid, 'coeffs', 'num', i, [' - ' model.enzymes{i}], preserveQuotes) -0235 end -0236 end -0237 -0238 elseif sum(strcmp({'subSystems','newMetMiriams','newRxnMiriams','newGeneMiriams','newCompMiriams','eccodes'},fieldName)) > 0 -0239 %eccodes/rxnNotes: if 1 write in 1 line, if more create header and list -0240 if strcmp(fieldName,'subSystems') -0241 list = field{pos}; %subSystems already comes in a cell array -0242 elseif strcmp(fieldName,'newMetMiriams') -0243 index = str2double(regexprep(name,'^.+_','')); -0244 name = regexprep(name,'_\d+$',''); -0245 list = strsplit(model.newMetMiriams{pos,index},'; '); -0246 elseif strcmp(fieldName,'newRxnMiriams') -0247 index = str2double(regexprep(name,'^.+_','')); -0248 name = regexprep(name,'_\d+$',''); -0249 list = strsplit(model.newRxnMiriams{pos,index},'; '); -0250 elseif strcmp(fieldName,'newGeneMiriams') -0251 index = str2double(regexprep(name,'^.+_','')); -0252 name = regexprep(name,'_\d+$',''); -0253 list = strsplit(model.newGeneMiriams{pos,index},'; '); -0254 elseif strcmp(fieldName,'newCompMiriams') -0255 index = str2double(regexprep(name,'^.+_','')); -0256 name = regexprep(name,'_\d+$',''); -0257 list = strsplit(model.newCompMiriams{pos,index},'; '); -0258 elseif ~isempty(field{pos}) -0259 list = strrep(field{pos},' ',''); -0260 list = strsplit(list,';'); -0261 else -0262 list = ''; -0263 end -0264 list=strip(list); -0265 -0266 if length(list) == 1 && ~strcmp(list{1},'') && ~strcmp(fieldName,'subSystems') -0267 if preserveQuotes -0268 list = ['"' list{1} '"']; -0269 end -0270 fprintf(fid,' %s: %s\n',name,list); -0271 elseif length(list) > 1 || strcmp(fieldName,'subSystems') -0272 if preserveQuotes -0273 for j=1:numel(list) -0274 list{j} = ['"' list{j} '"']; -0275 end -0276 end -0277 fprintf(fid,' %s:\n',name); -0278 for i = 1:length(list) -0279 fprintf(fid,'%s - %s\n',regexprep(name,'(^\s*).*','$1'),list{i}); -0280 end -0281 end -0282 -0283 elseif sum(pos) > 0 -0284 %All other fields: -0285 if strcmp(type,'txt') -0286 value = field{pos}; -0287 if preserveQuotes && ~isempty(value) -0288 value = ['"',value,'"']; -0289 end -0290 elseif strcmp(type,'num') -0291 if isnan(field(pos)) -0292 value = []; -0293 else -0294 value = sprintf('%.15g',full(field(pos))); -0295 end -0296 end -0297 if ~isempty(value) -0298 fprintf(fid,' %s: %s\n',name,value); -0299 end -0300 end -0301 end -0302 end -0303 -0304 function writeMetadata(model,fid) -0305 % Writes model metadata to the yaml file. This information will eventually -0306 % be extracted entirely from the model, but for now, many of the entries -0307 % are hard-coded defaults for HumanGEM. -0308 -0309 fprintf(fid, '- metaData:\n'); -0310 fprintf(fid, ' id: "%s"\n', model.id); -0311 fprintf(fid, ' name: "%s"\n',model.name); -0312 if isfield(model,'version') -0313 fprintf(fid, ' version: "%s"\n',model.version); -0314 end -0315 fprintf(fid, ' date: "%s"\n',datestr(now,29)); % 29=YYYY-MM-DD -0316 if isfield(model,'annotation') -0317 if isfield(model.annotation,'defaultLB') -0318 fprintf(fid, ' defaultLB: "%g"\n', model.annotation.defaultLB); -0319 end -0320 if isfield(model.annotation,'defaultUB') -0321 fprintf(fid, ' defaultUB: "%g"\n', model.annotation.defaultUB); -0322 end -0323 if isfield(model.annotation,'givenName') -0324 fprintf(fid, ' givenName: "%s"\n', model.annotation.givenName); -0325 end -0326 if isfield(model.annotation,'familyName') -0327 fprintf(fid, ' familyName: "%s"\n', model.annotation.familyName); -0328 end -0329 if isfield(model.annotation,'authors') -0330 fprintf(fid, ' authors: "%s"\n', model.annotation.authors); -0331 end -0332 if isfield(model.annotation,'email') -0333 fprintf(fid, ' email: "%s"\n', model.annotation.email); -0334 end -0335 if isfield(model.annotation,'organization') -0336 fprintf(fid, ' organization: "%s"\n',model.annotation.organization); -0337 end -0338 if isfield(model.annotation,'taxonomy') -0339 fprintf(fid, ' taxonomy: "%s"\n', model.annotation.taxonomy); -0340 end -0341 if isfield(model.annotation,'note') -0342 fprintf(fid, ' note: "%s"\n', model.annotation.note); -0343 end -0344 if isfield(model.annotation,'sourceUrl') -0345 fprintf(fid, ' sourceUrl: "%s"\n', model.annotation.sourceUrl); -0346 end -0347 end -0348 if isfield(model,'ec') -0349 if model.ec.geckoLight -0350 geckoLight = 'true'; -0351 else -0352 geckoLight = 'false'; -0353 end -0354 fprintf(fid,' geckoLight: "%s"\n',geckoLight); -0355 end -0356 end +0165 field = model.(fieldName); +0166 +0167 if strcmp(fieldName,'metMiriams') +0168 if ~isempty(model.metMiriams{pos}) +0169 fprintf(fid,' %s: !!omap\n',name); +0170 for i=1:size(model.newMetMiriams,2) +0171 %'i' represents the different miriam names, e.g. +0172 %kegg.compound or chebi +0173 if ~isempty(model.newMetMiriams{pos,i}) +0174 %As during the following writeField call the value of +0175 %'i' would be lost, it is temporarily concatenated to +0176 %'name' parameter, which will be edited later +0177 writeField(model, fid, 'newMetMiriams', 'txt', pos, [' - ' model.newMetMiriamNames{i} '_' sprintf('%d',i)], preserveQuotes) +0178 end +0179 end +0180 end +0181 +0182 elseif strcmp(fieldName,'rxnMiriams') +0183 if ~isempty(model.rxnMiriams{pos}) +0184 fprintf(fid,' %s: !!omap\n',name); +0185 for i=1:size(model.newRxnMiriams,2) +0186 if ~isempty(model.newRxnMiriams{pos,i}) +0187 writeField(model, fid, 'newRxnMiriams', 'txt', pos, [' - ' model.newRxnMiriamNames{i} '_' sprintf('%d',i)], preserveQuotes) +0188 end +0189 end +0190 end +0191 +0192 elseif strcmp(fieldName,'geneMiriams') +0193 if ~isempty(model.geneMiriams{pos}) +0194 fprintf(fid,' %s: !!omap\n',name); +0195 for i=1:size(model.newGeneMiriams,2) +0196 if ~isempty(model.newGeneMiriams{pos,i}) +0197 writeField(model, fid, 'newGeneMiriams', 'txt', pos, [' - ' model.newGeneMiriamNames{i} '_' sprintf('%d',i)], preserveQuotes) +0198 end +0199 end +0200 end +0201 +0202 elseif strcmp(fieldName,'compMiriams') +0203 if ~isempty(model.compMiriams{pos}) +0204 fprintf(fid,' %s: !!omap\n',name); +0205 for i=1:size(model.newCompMiriams,2) +0206 if ~isempty(model.newCompMiriams{pos,i}) +0207 writeField(model, fid, 'newCompMiriams', 'txt', pos, [' - ' model.newCompMiriamNames{i} '_' sprintf('%d',i)], preserveQuotes) +0208 end +0209 end +0210 end +0211 +0212 elseif strcmp(fieldName,'S') +0213 %S: create header & write each metabolite in a new line +0214 fprintf(fid,' %s: !!omap\n',name); +0215 if sum(field(:,pos) ~= 0) > 0 +0216 model.mets = model.mets(field(:,pos) ~= 0); +0217 model.coeffs = field(field(:,pos) ~= 0,pos); +0218 %Sort metabolites: +0219 [model.mets,order] = sort(model.mets); +0220 model.coeffs = model.coeffs(order); +0221 for i = 1:length(model.mets) +0222 writeField(model, fid, 'coeffs', 'num', i, [' - ' model.mets{i}], preserveQuotes) +0223 end +0224 end +0225 +0226 elseif strcmp(fieldName,'rxnEnzMat') +0227 %S: create header & write each enzyme in a new line +0228 fprintf(fid,' %s: !!omap\n',name); +0229 if sum(field(pos,:) ~= 0) > 0 +0230 model.enzymes = model.enzymes(field(pos,:) ~= 0); +0231 model.coeffs = field(pos,field(pos,:) ~= 0); +0232 %Sort metabolites: +0233 [model.enzymes,order] = sort(model.enzymes); +0234 model.coeffs = model.coeffs(order); +0235 for i = 1:length(model.enzymes) +0236 writeField(model, fid, 'coeffs', 'num', i, [' - ' model.enzymes{i}], preserveQuotes) +0237 end +0238 end +0239 +0240 elseif sum(strcmp({'subSystems','newMetMiriams','newRxnMiriams','newGeneMiriams','newCompMiriams','eccodes'},fieldName)) > 0 +0241 %eccodes/rxnNotes: if 1 write in 1 line, if more create header and list +0242 if strcmp(fieldName,'subSystems') +0243 list = field{pos}; %subSystems already comes in a cell array +0244 elseif strcmp(fieldName,'newMetMiriams') +0245 index = str2double(regexprep(name,'^.+_','')); +0246 name = regexprep(name,'_\d+$',''); +0247 list = strsplit(model.newMetMiriams{pos,index},'; '); +0248 elseif strcmp(fieldName,'newRxnMiriams') +0249 index = str2double(regexprep(name,'^.+_','')); +0250 name = regexprep(name,'_\d+$',''); +0251 list = strsplit(model.newRxnMiriams{pos,index},'; '); +0252 elseif strcmp(fieldName,'newGeneMiriams') +0253 index = str2double(regexprep(name,'^.+_','')); +0254 name = regexprep(name,'_\d+$',''); +0255 list = strsplit(model.newGeneMiriams{pos,index},'; '); +0256 elseif strcmp(fieldName,'newCompMiriams') +0257 index = str2double(regexprep(name,'^.+_','')); +0258 name = regexprep(name,'_\d+$',''); +0259 list = strsplit(model.newCompMiriams{pos,index},'; '); +0260 elseif ~isempty(field{pos}) +0261 list = strrep(field{pos},' ',''); +0262 list = strsplit(list,';'); +0263 else +0264 list = ''; +0265 end +0266 list=strip(list); +0267 +0268 if length(list) == 1 && ~strcmp(list{1},'') && ~strcmp(fieldName,'subSystems') +0269 if preserveQuotes +0270 list = ['"' list{1} '"']; +0271 end +0272 fprintf(fid,' %s: %s\n',name,list); +0273 elseif length(list) > 1 || strcmp(fieldName,'subSystems') +0274 if preserveQuotes +0275 for j=1:numel(list) +0276 list{j} = ['"' list{j} '"']; +0277 end +0278 end +0279 fprintf(fid,' %s:\n',name); +0280 for i = 1:length(list) +0281 fprintf(fid,'%s - %s\n',regexprep(name,'(^\s*).*','$1'),list{i}); +0282 end +0283 end +0284 +0285 elseif sum(pos) > 0 +0286 %All other fields: +0287 if strcmp(type,'txt') +0288 value = field{pos}; +0289 if preserveQuotes && ~isempty(value) +0290 value = ['"',value,'"']; +0291 end +0292 elseif strcmp(type,'num') +0293 if isnan(field(pos)) +0294 value = []; +0295 else +0296 value = sprintf('%.15g',full(field(pos))); +0297 end +0298 end +0299 if ~isempty(value) +0300 fprintf(fid,' %s: %s\n',name,value); +0301 end +0302 end +0303 end +0304 end +0305 +0306 function writeMetadata(model,fid) +0307 % Writes model metadata to the yaml file. This information will eventually +0308 % be extracted entirely from the model, but for now, many of the entries +0309 % are hard-coded defaults for HumanGEM. +0310 +0311 fprintf(fid, '- metaData:\n'); +0312 fprintf(fid, ' id: "%s"\n', model.id); +0313 fprintf(fid, ' name: "%s"\n',model.name); +0314 if isfield(model,'version') +0315 fprintf(fid, ' version: "%s"\n',model.version); +0316 end +0317 fprintf(fid, ' date: "%s"\n',datestr(now,29)); % 29=YYYY-MM-DD +0318 if isfield(model,'annotation') +0319 if isfield(model.annotation,'defaultLB') +0320 fprintf(fid, ' defaultLB: "%g"\n', model.annotation.defaultLB); +0321 end +0322 if isfield(model.annotation,'defaultUB') +0323 fprintf(fid, ' defaultUB: "%g"\n', model.annotation.defaultUB); +0324 end +0325 if isfield(model.annotation,'givenName') +0326 fprintf(fid, ' givenName: "%s"\n', model.annotation.givenName); +0327 end +0328 if isfield(model.annotation,'familyName') +0329 fprintf(fid, ' familyName: "%s"\n', model.annotation.familyName); +0330 end +0331 if isfield(model.annotation,'authors') +0332 fprintf(fid, ' authors: "%s"\n', model.annotation.authors); +0333 end +0334 if isfield(model.annotation,'email') +0335 fprintf(fid, ' email: "%s"\n', model.annotation.email); +0336 end +0337 if isfield(model.annotation,'organization') +0338 fprintf(fid, ' organization: "%s"\n',model.annotation.organization); +0339 end +0340 if isfield(model.annotation,'taxonomy') +0341 fprintf(fid, ' taxonomy: "%s"\n', model.annotation.taxonomy); +0342 end +0343 if isfield(model.annotation,'note') +0344 fprintf(fid, ' note: "%s"\n', model.annotation.note); +0345 end +0346 if isfield(model.annotation,'sourceUrl') +0347 fprintf(fid, ' sourceUrl: "%s"\n', model.annotation.sourceUrl); +0348 end +0349 end +0350 if isfield(model,'ec') +0351 if model.ec.geckoLight +0352 geckoLight = 'true'; +0353 else +0354 geckoLight = 'false'; +0355 end +0356 fprintf(fid,' geckoLight: "%s"\n',geckoLight); +0357 end +0358 end
Generated by m2html © 2005
\ No newline at end of file diff --git a/doc/struct_conversion/ravenCobraWrapper.html b/doc/struct_conversion/ravenCobraWrapper.html index 9e0a938b..7bc8b282 100644 --- a/doc/struct_conversion/ravenCobraWrapper.html +++ b/doc/struct_conversion/ravenCobraWrapper.html @@ -147,7 +147,7 @@

SOURCE CODE ^end 0076 newModel.rxns=model.rxns; -0077 optFields = {'rxnNames','subSystems','rxnNotes',... +0077 optFields = {'rxnNames','subSystems','rxnNotes','metDeltaG','rxnDeltaG',... 0078 'metFormulas','comps','compNames','metCharges','genes',... 0079 'rxnConfidenceScores','rxnGeneMat','metNotes','rev'}; 0080 for i=1:length(optFields) diff --git a/io/closeModel.m b/io/closeModel.m index 26e1d9f2..196250c5 100755 --- a/io/closeModel.m +++ b/io/closeModel.m @@ -43,6 +43,9 @@ if isfield(closedModel,'metCharges') closedModel.metCharges(numel(closedModel.metCharges)+1)=closedModel.metCharges(find(closedModel.S(:,i))); end; + if isfield(closedModel,'metDeltaG') + closedModel.metDeltaG(numel(closedModel.metDeltaG)+1)=closedModel.metDeltaG(find(closedModel.S(:,i))); + end; closedModel.unconstrained(numel(closedModel.unconstrained)+1)=1; closedModel.b(numel(closedModel.b)+1)=0; closedModel.S=[closedModel.S;sparse(1,size(closedModel.S,2))]; diff --git a/io/readYAMLmodel.m b/io/readYAMLmodel.m index a32df0ff..b489622d 100644 --- a/io/readYAMLmodel.m +++ b/io/readYAMLmodel.m @@ -80,6 +80,7 @@ 'subSystems',cell(0,0);... 'eccodes',cell(0,0);... 'rxnMiriams',cell(0,0);... + 'rxnDeltaG',{};... %Changed to double in the end. 'rxnNotes',cell(0,0);... 'rxnReferences',cell(0,0);... 'rxnConfidenceScores',cell(0,0);... @@ -88,6 +89,7 @@ 'metSmiles',cell(0,0);... 'metFormulas',cell(0,0);... 'metMiriams',cell(0,0);... + 'metDeltaG',{};... %Changed to double in the end. 'metCharges',cell(0,0);... %Changed to double in the end. 'metNotes',cell(0,0);... 'comps',cell(0,0);... @@ -128,17 +130,12 @@ end section = 0; -metMiriams=cell(25000,3); metMirNo=1; -rxnMiriams=cell(25000,3); rxnMirNo=1; -geneMiriams=cell(25000,3); genMirNo=1; -subSystems=cell(25000,2); subSysNo=1; -eccodes=cell(25000,2); ecCodeNo=1; +metMiriams=cell(100000,3); metMirNo=1; +rxnMiriams=cell(100000,3); rxnMirNo=1; +geneMiriams=cell(100000,3); genMirNo=1; +subSystems=cell(100000,2); subSysNo=1; +eccodes=cell(100000,2); ecCodeNo=1; equations=cell(100000,3); equatiNo=1; -% metMiriams=cell(0,3); metMirNo=1; -% rxnMiriams=cell(0,3); rxnMirNo=1; -% geneMiriams=cell(0,3); genMirNo=1; -% subSystems=cell(0,2); subSysNo=1; -% eccodes=cell(0,2); ecCodeNo=1; for i=1:numel(line_key) tline_raw = line_raw{i}; @@ -264,7 +261,10 @@ readList=''; miriamKey=''; case 'smiles' model = readFieldValue(model, 'metSmiles', tline_value, pos); - readList=''; miriamKey=''; + readList=''; miriamKey=''; + case 'deltaG' + model = readFieldValue(model, 'metDeltaG', tline_value, pos); + readList=''; miriamKey=''; case 'metFrom' model = readFieldValue(model, 'metFrom', tline_value, pos); readList=''; miriamKey=''; @@ -309,6 +309,9 @@ case 'rxnFrom' model = readFieldValue(model, 'rxnFrom', tline_value, pos); readList=''; miriamKey=''; + case 'deltaG' + model = readFieldValue(model, 'rxnDeltaG', tline_value, pos); + readList=''; miriamKey=''; case 'objective_coefficient' model.c(pos,1) = 1; readList=''; miriamKey=''; @@ -513,6 +516,8 @@ model.ub = str2double(model.ub); model.rxnConfidenceScores = str2double(model.rxnConfidenceScores); model.b = zeros(length(model.mets),1); +model.metDeltaG = str2double(model.metDeltaG); +model.rxnDeltaG = str2double(model.rxnDeltaG); % Fill some other fields model.annotation.defaultLB = min(model.lb); @@ -541,7 +546,7 @@ for i={'c'} % Zeros model = emptyOrFill(model,i{1},0,'rxns'); end -for i={'rxnConfidenceScores'} % NaNs +for i={'rxnConfidenceScores','rxnDeltaG'} % NaNs model = emptyOrFill(model,i{1},NaN,'rxns'); end for i={'rxnComps'} % Ones, assume first compartment @@ -554,6 +559,9 @@ for i={'metCharges','unconstrained'} % Zeros model = emptyOrFill(model,i{1},0,'mets'); end +for i={'metDeltaG'} % % NaNs + model = emptyOrFill(model,i{1},NaN,'mets'); + end for i={'metComps'} % Ones, assume first compartment model = emptyOrFill(model,i{1},1,'mets'); end diff --git a/io/writeYAMLmodel.m b/io/writeYAMLmodel.m index e50eb4eb..730f5123 100644 --- a/io/writeYAMLmodel.m +++ b/io/writeYAMLmodel.m @@ -76,6 +76,7 @@ function writeYAMLmodel(model,fileName,preserveQuotes,sortIds) writeField(model, fid, 'inchis', 'txt', i, ' - inchis', preserveQuotes) writeField(model, fid, 'metSmiles', 'txt', i, ' - smiles', preserveQuotes) writeField(model, fid, 'metMiriams', 'txt', i, ' - annotation', preserveQuotes) + writeField(model, fid, 'metDeltaG', 'num', i, ' - deltaG', preserveQuotes) writeField(model, fid, 'metNotes', 'txt', i, ' - notes', preserveQuotes) writeField(model, fid, 'metFrom', 'txt', i, ' - metFrom', preserveQuotes) end @@ -98,6 +99,7 @@ function writeYAMLmodel(model,fileName,preserveQuotes,sortIds) writeField(model, fid, 'rxnReferences', 'txt', i, ' - references', preserveQuotes) writeField(model, fid, 'subSystems', 'txt', i, ' - subsystem', preserveQuotes) writeField(model, fid, 'rxnMiriams', 'txt', i, ' - annotation', preserveQuotes) + writeField(model, fid, 'rxnDeltaG', 'num', i, ' - deltaG', preserveQuotes) writeField(model, fid, 'rxnConfidenceScores', 'num', i, ' - confidence_score', preserveQuotes) writeField(model, fid, 'rxnNotes', 'txt', i, ' - rxnNotes', preserveQuotes) end diff --git a/readme/RAVEN_structure_fields.csv b/readme/RAVEN_structure_fields.csv index 5cdec11c..f471abf7 100644 --- a/readme/RAVEN_structure_fields.csv +++ b/readme/RAVEN_structure_fields.csv @@ -41,6 +41,7 @@ rxnMiriams;;Struct;Structure with MIRIAM information about the reactions;Non-man rxnNotes;;Column Cell Array of Strings;Notes for each reaction;Non-mandatory field;Was added during manual curation; rxnReferences;;Column Cell Array of Strings;Non-PubMed references for each reaction;Non-mandatory field;Agren et al 2013;Non-Pubmed references should be written here. PubMed references should be included in rxnMiriams instead rxnConfidenceScores;;Column Vector of Doubles;Confidence scores for each reaction (5 - best, 1 - worst);Non-mandatory field;3; +rxnDeltaG;;Column Vector of Doubles;Gibbs free energy under biochemical standard conditions;Non-mandatory field;-24;In kJ/mol. Unknown Gibbs free energies must be set as NaN genes;;Column Cell Array of Strings;List of all genes;Non-mandatory field;; geneComps;;Column Cell Array of Strings;Compartments for genes;Non-mandatory field;1;This information is required for SBML Level 1-2, not for SBML Level 3 geneMiriams;;Struct;Structure with MIRIAM information about the genes;Non-mandatory field;;If there are multiple miriams, 'name' indexes must match 'value' indexes @@ -54,6 +55,7 @@ metFormulas;;Column Cell Array of Strings;Chemical formulas for metabolites;Non- metMiriams;;Struct;Structure with MIRIAM information about the metabolites;Non-mandatory field;;If there are multiple miriams, 'name' indexes must match 'value' indexes ;name;Column Cell Array of Strings;The name of MIRIAM prefix;Non-mandatory field;kegg.compound; ;value;Column Cell Array of Strings;The ID for particular MIRIAM entry;Non-mandatory field;C00267; -metCharges;;Column Vector of Doubles;Charge information for metabolites;Non-mandatory field;0;The charge values for metabolites with charge unknown must be set as NaNs +metCharges;;Column Vector of Doubles;Charge information for metabolites;Non-mandatory field;0;Unknown charges must be set as NaN +metDeltaG;;Column Vector of Doubles;Gibbs free energy of formation under biochemical standard conditions;Non-mandatory field;-5;In kJ/mol. Unknown Gibbs free energies must be set as NaN unconstrained;;Column Vector of Doubles;Binary vector, positive for exchange (boundary) metabolites;Non-mandatory field;0;This field is removed if boundary metabolites are deleted during the model import rxnFrom;;Column Cell Array of Strings;The name of template model from which particular reaction was taken;Non-mandatory field for internal use, not exported anywhere;iTO977;This field is needed during the models merging procedure diff --git a/struct_conversion/orderRavenFields.csv b/struct_conversion/orderRavenFields.csv index 4b2a54e3..1ddfc6ef 100644 --- a/struct_conversion/orderRavenFields.csv +++ b/struct_conversion/orderRavenFields.csv @@ -25,6 +25,7 @@ rxnMiriams rxnNotes rxnReferences rxnConfidenceScores +rxnDeltaG genes geneComps geneMiriams @@ -36,5 +37,8 @@ metFormulas metMiriams metCharges metSmiles +metDeltaG unconstrained +geneFrom +metFrom rxnFrom diff --git a/struct_conversion/ravenCobraWrapper.m b/struct_conversion/ravenCobraWrapper.m index 196c6d67..a9c8583c 100755 --- a/struct_conversion/ravenCobraWrapper.m +++ b/struct_conversion/ravenCobraWrapper.m @@ -74,7 +74,7 @@ newModel.c=zeros(numel(model.rxns),1); end newModel.rxns=model.rxns; -optFields = {'rxnNames','subSystems','rxnNotes',... +optFields = {'rxnNames','subSystems','rxnNotes','metDeltaG','rxnDeltaG',... 'metFormulas','comps','compNames','metCharges','genes',... 'rxnConfidenceScores','rxnGeneMat','metNotes','rev'}; for i=1:length(optFields)