diff --git a/INIT/runINIT.m b/INIT/runINIT.m index ca064f50..f20fd586 100644 --- a/INIT/runINIT.m +++ b/INIT/runINIT.m @@ -1,4 +1,4 @@ -function [outModel, deletedRxns, metProduction, fValue]=runINIT(model,rxnScores,presentMets,essentialRxns,prodWeight,allowExcretion,noRevLoops) +function [outModel, deletedRxns, metProduction, fValue]=runINIT(model,rxnScores,presentMets,essentialRxns,prodWeight,allowExcretion,noRevLoops,params) % runINIT % Generates a model using the INIT algorithm, based on proteomics and/or % transcriptomics and/or metabolomics and/or metabolic tasks. This is the @@ -38,6 +38,7 @@ % problem significantly more computationally intensive to % solve (two more integer constraints per reversible reaction) % (optional, default false) +% params parameter structure for use by optimizeProb % % outModel the resulting model structure % deletedRxns reactions which were deleted by the algorithm diff --git a/core/FSEOF.m b/core/FSEOF.m index 585abf1f..e60740ce 100755 --- a/core/FSEOF.m +++ b/core/FSEOF.m @@ -119,7 +119,12 @@ A2=char(model.rxns(num)); %enzyme ID A3=char(model.rxnNames(num)); %enzyme Name if isfield(model,'subSystems') && ~isempty(model.subSystems{num}); - A4=char(strjoin(model.subSystems{num,1},';')); %Subsystems + if ~any(cellfun(@(x) iscell(x), model.subSystems)); + subSys = cellfun(@(x) {x}, model.subSystems, 'uni', 0); + else + subSys = model.subSystems; + end + A4=char(strjoin(subSys{num},';')); %Subsystems else A4=''; end diff --git a/core/addExchangeRxns.m b/core/addExchangeRxns.m index 31df9b80..831e888b 100755 --- a/core/addExchangeRxns.m +++ b/core/addExchangeRxns.m @@ -63,8 +63,8 @@ end if isfield(model,'subSystems') fillerSub = filler; - if iscell(model.subSystems(1,1)) - fillerSub = repmat({fillerSub},numel(J),1); + if any(cellfun(@(x) iscell(x), model.subSystems)) + fillerSub(:)={{''}}; end model.subSystems=[model.subSystems;fillerSub]; end diff --git a/core/addRxns.m b/core/addRxns.m index 8efcd5e2..3ce890c6 100755 --- a/core/addRxns.m +++ b/core/addRxns.m @@ -227,10 +227,12 @@ nOldRxns=numel(model.rxns); filler=cell(nRxns,1); filler(:)={''}; -cellfiller=cellfun(@(x) cell(0,0),filler,'UniformOutput',false); +cellfiller=cell(nRxns,1); +cellfiller(:)={{''}}; largeFiller=cell(nOldRxns,1); largeFiller(:)={''}; -celllargefiller=cellfun(@(x) cell(0,0),largeFiller,'UniformOutput',false); +largeCellFiller=cell(nOldRxns,1); +largeCellFiller(:)={{''}}; %***Add everything to the model except for the equations. if numel(rxnsToAdd.equations)~=nRxns @@ -350,28 +352,45 @@ end if isfield(rxnsToAdd,'subSystems') + % Has to be cell array if ischar(rxnsToAdd.subSystems) - rxnsToAdd.subSystems = {{rxnsToAdd.subSystems}}; + rxnsToAdd.subSystems = {rxnsToAdd.subSystems}; + end + % If all nested cells are 1x1, then unnest + if all(cellfun(@(x) iscell(x) && isscalar(x), rxnsToAdd.subSystems)) + rxnsToAdd.subSystems = transpose([rxnsToAdd.subSystems{:}]); + end + % Cell array should now be as simple as possible. Check if it is nested + subSysRxnsNested = any(cellfun(@(x) iscell(x), rxnsToAdd.subSystems)); + if isfield(newModel,'subSystems') + subSysModelNested = any(cellfun(@(x) iscell(x), newModel.subSystems)); else - for i=1:numel(rxnsToAdd.subSystems) - if ischar(rxnsToAdd.subSystems{i}) - rxnsToAdd.subSystems{i}=rxnsToAdd.subSystems(i); - end + subSysModelNested = subSysRxnsNested; + if subSysRxnsNested + newModel.subSystems=largeCellFiller; + else + newModel.subSystems=largeFiller; end end + if subSysRxnsNested && ~subSysModelNested + % Make all existing subSystems nested + newModel.subSystems = cellfun(@(x) {x}, newModel.subSystems, 'uni', 0); + elseif ~subSysRxnsNested && subSysModelNested + rxnsToAdd.subSystems = cellfun(@(x) {x}, rxnsToAdd.subSystems, 'uni', 0); + end if numel(rxnsToAdd.subSystems)~=nRxns EM='rxnsToAdd.subSystems must have the same number of elements as rxnsToAdd.rxns'; dispEM(EM); end - %Fill with standard if it doesn't exist - if ~isfield(newModel,'subSystems') - newModel.subSystems=celllargefiller; - end newModel.subSystems=[newModel.subSystems;rxnsToAdd.subSystems(:)]; else - %Fill with standard if it doesn't exist + %Fill with standard if it does not exist if isfield(newModel,'subSystems') - newModel.subSystems=[newModel.subSystems;cellfiller]; + if any(cellfun(@(x) iscell(x), newModel.subSystems)) + newModel.subSystems=[newModel.subSystems;cellfiller]; + else + newModel.subSystems=[newModel.subSystems;filler]; + end end end if isfield(rxnsToAdd,'rxnMiriams') diff --git a/core/addTransport.m b/core/addTransport.m index 160f9fd2..4b88f022 100755 --- a/core/addTransport.m +++ b/core/addTransport.m @@ -134,11 +134,15 @@ model.eccodes=[model.eccodes;filler]; end if isfield(model,'subSystems') - ssFiller=filler; + isNested = any(cellfun(@(x) iscell(x), model.subSystems)); + ssFiller = filler; if isRev==1 - ssFiller(:)={{['Transport between ' fromComp ' and ' toComps{i}]}}; + ssFiller(:) = {['Transport between ' fromComp ' and ' toComps{i}]}; else - ssFiller(:)={{['Transport from ' fromComp ' to ' toComps{i}]}}; + ssFiller(:) = {['Transport from ' fromComp ' to ' toComps{i}]}; + end + if isNested + ssFiller = cellfun(@(x) {x}, ssFiller, 'uni', 0); end model.subSystems=[model.subSystems;ssFiller]; end diff --git a/core/checkModelStruct.m b/core/checkModelStruct.m index 3fb1e15f..eb9f8e6d 100755 --- a/core/checkModelStruct.m +++ b/core/checkModelStruct.m @@ -175,11 +175,11 @@ function checkModelStruct(model,throwErrors,trimWarnings) end end if isfield(model,'subSystems') - for i=1:numel(model.subSystems) - if ~iscell(model.subSystems{i,1}) - EM='The "subSystems" field must be a cell array'; + isNested = any(cellfun(@(x) iscell(x), model.subSystems)); + isCellStr = any(cellfun(@(x) ischar(x), model.subSystems)); + if ~xor(isNested,isCellStr) + EM='The "subSystems" field must be a cell array of chars, *or* a cell array of cell arrays of chars'; dispEM(EM,throwErrors); - end end end if isfield(model,'eccodes') diff --git a/core/compareMultipleModels.m b/core/compareMultipleModels.m index bb34169f..596d0957 100755 --- a/core/compareMultipleModels.m +++ b/core/compareMultipleModels.m @@ -92,16 +92,6 @@ fprintf('*** Done \n\n') -%% Flatten models' subSystems field -% Convert from cell array of cells to cell array of strings -% NOTE: this function currently only recognizes one subSystem per reaction; -% additional subSystems will be ignored! -for i = 1:numel(models) - cells = cellfun(@iscell,models{i}.subSystems); - models{i}.subSystems(cells) = cellfun(@(s) s{1}, models{i}.subSystems(cells), 'UniformOutput', false); -end - - %% Compare models structure & function based on high-dimensional methods % Compare number of reactions in each subsystem in each model using a heatmap field = 'subSystems'; @@ -110,6 +100,16 @@ fprintf('\nWARNING: At least one model does not contain the field "subSystems". \n') fprintf(' Skipping subsystem comparison. \n\n') else + %% Flatten model subSystems field + % Convert from cell array of cells to cell array of strings + % NOTE: this function currently only recognizes one subSystem per reaction; + % additional subSystems will be ignored! + for i = 1:numel(models) + if any(cellfun(@(x) iscell(x), models{i}.subSystems)); + cells = cellfun(@iscell,models{i}.subSystems); + models{i}.subSystems(cells) = cellfun(@(s) s{1}, models{i}.subSystems(cells), 'UniformOutput', false); + end + end [id,compMat] = compareModelField(models,field); compStruct.subsystems.ID = id; compStruct.subsystems.matrix = compMat; diff --git a/core/findRAVENroot.m b/core/findRAVENroot.m index 10c28ce4..17e4b878 100755 --- a/core/findRAVENroot.m +++ b/core/findRAVENroot.m @@ -1,23 +1,27 @@ function [ravenPath, prevDir] = findRAVENroot() % findRAVENroot -% Finds the root of the RAVEN directory, by searching for the path to +% Finds the root of the RAVEN directory, first by by searching for the path to % RAVEN2.png. Can also record the current directory, in case a function will % use the ravenPath to navigate to a precise folder, and it should return to % the previous directory afterwards. See e.g. optimizeProb calling glpk. ST=dbstack('-completenames'); prevDir = pwd(); -ravenPath = ST(strcmp({ST.name},'findRAVENroot')).file; -rootFound = 0; -while rootFound == 0 - isRoot = isfile(fullfile(ravenPath,'RAVEN2.png')); - if isRoot - rootFound = 1; - else - ravenPathOld = ravenPath; - ravenPath = fileparts(ravenPath); - if strcmp(ravenPathOld,ravenPath) - error('Cannot find the RAVEN root directory. Make sure you have not removed the RAVEN2.png file from your RAVEN installation.') +if ispref('RAVEN','ravenPath') + ravenPath = getpref('RAVEN','ravenPath'); +else + ravenPath = ST(strcmp({ST.name},'findRAVENroot')).file; + rootFound = 0; + while rootFound == 0 + isRoot = isfile(fullfile(ravenPath,'RAVEN2.png')); + if isRoot + rootFound = 1; + else + ravenPathOld = ravenPath; + ravenPath = fileparts(ravenPath); + if strcmp(ravenPathOld,ravenPath) + error('Cannot find the RAVEN root directory. Make sure you have not removed the RAVEN2.png file from your RAVEN installation.') + end end end end \ No newline at end of file diff --git a/core/fitTasks.m b/core/fitTasks.m index 992c3762..f823d459 100755 --- a/core/fitTasks.m +++ b/core/fitTasks.m @@ -34,7 +34,7 @@ % the result. % % Usage: [outModel, addedRxns]=fitTasks(model,refModel,inputFile,printOutput,... -% rxnScores,taskStructure,params) +% rxnScores,taskStructure) if nargin<4 printOutput=true; @@ -48,9 +48,6 @@ if nargin<6 taskStructure=[]; end -if nargin<7 - params=[]; -end if isempty(taskStructure) && ~isfile(inputFile) error('Task file %s cannot be found',string(inputFile)); @@ -268,7 +265,7 @@ try [~, ~, newRxns, newModel, exitFlag]=fillGaps(tModel,refModel,false,true,supressWarnings,rxnScores); if exitFlag==-2 - EM=['"[' taskStructure(i).id '] ' taskStructure(i).description '" was aborted before reaching optimality. Consider increasing params.maxTime\n']; + EM=['"[' taskStructure(i).id '] ' taskStructure(i).description '" was aborted before reaching optimality.\n']; dispEM(EM,false); end catch diff --git a/core/mergeModels.m b/core/mergeModels.m index cf45dd7a..d7ef3669 100755 --- a/core/mergeModels.m +++ b/core/mergeModels.m @@ -82,6 +82,11 @@ model=rmfield(model,'equations'); end +for i=1:numel(models) + if isfield(models{i},'subSystems') + models{i}.subSystems = cellfun(@(x) {x}, models{i}.subSystems, 'uni', 0); + end +end for i=2:numel(models) %Add the model id to the rxn id id it already exists in the model (id %have to be unique) This is because it makes a '[]' string if no new @@ -283,7 +288,6 @@ if strcmpi(metParam,'mets') %Get the new metabolites from matching the models. Metabolites are matched by metabolite ID (model.mets). - oldMetComps=model.comps(model.metComps); oldMets=model.mets; if ~isempty(models{i}.mets) @@ -613,7 +617,7 @@ end %Remap the genes from the new model. The same thing as with - %mets; this is a wasteful way to do it but I don't care right + %mets; this is a wasteful way to do it but I do not care right %now a = ismember(models{i}.genes,model.genes); @@ -637,4 +641,10 @@ [grRules,rxnGeneMat] = standardizeGrRules(model,true); model.grRules = grRules; model.rxnGeneMat = rxnGeneMat; +%Flatten subSystems if possible +if isfield(model,'subSystems') + if all(cellfun(@(x) iscell(x) && isscalar(x), model.subSystems)) + model.subSystems = transpose([model.subSystems{:}]); + end +end end diff --git a/core/predictLocalization.m b/core/predictLocalization.m index a2b5a550..1908caa6 100755 --- a/core/predictLocalization.m +++ b/core/predictLocalization.m @@ -726,7 +726,11 @@ outModel.rxnMiriams=[outModel.rxnMiriams;{[]}]; end if isfield(outModel,'subSystems') - outModel.subSystems=[outModel.subSystems;{{'Inferred transport reactions'}}]; + if any(cellfun(@(x) iscell(x), outModel.subSystems)) + outModel.subSystems=[outModel.subSystems;{{'Inferred transport reactions'}}]; + else + outModel.subSystems=[outModel.subSystems;{'Inferred transport reactions'}]; + end end if isfield(outModel,'eccodes') outModel.eccodes=[outModel.eccodes;{''}]; diff --git a/core/sortModel.m b/core/sortModel.m index 8d329fbc..7dc00d7e 100755 --- a/core/sortModel.m +++ b/core/sortModel.m @@ -65,6 +65,9 @@ subsystemsUnique=''; subsystemsConcatenated=''; for i=1:numel(model.subSystems) + if ~iscell(model.subSystems{i}) + model.subSystems{i} = {model.subSystems{i}}; + end subsystemsConcatenated{i,1}=strjoin(model.subSystems{i,1},';'); if ~isempty(model.subSystems{i,1}) for j=1:numel(model.subSystems{i,1}) diff --git a/doc/INIT/getINITModel.html b/doc/INIT/getINITModel.html index 739882c2..d0913510 100644 --- a/doc/INIT/getINITModel.html +++ b/doc/INIT/getINITModel.html @@ -133,7 +133,7 @@

DESCRIPTION ^CROSS-REFERENCE INFORMATION ^

This function calls: +
  • runINIT runINIT
  • This function is called by: @@ -446,7 +446,7 @@

    SOURCE CODE ^%carry flux in one direction. Runs without the constraints on reversibility 0301 %and with all output allowed. This is to reduce the complexity of the 0302 %problem. -0303 [~, deletedRxnsInINIT, metProduction]=runINIT(simplifyModel(cModel),rxnScores,metabolomicsData,essentialRxnsForTasks,0,true,false,params); +0303 [~, deletedRxnsInINIT, metProduction]=runINIT(simplifyModel(cModel),rxnScores,metabolomicsData,essentialRxnsForTasks,0,true,false,params); 0304 initModel=removeReactions(cModel,deletedRxnsInINIT,true,true); 0305 if printReport==true 0306 printScores(initModel,'INIT model statistics',hpaData,arrayData,tissue,celltype); diff --git a/doc/INIT/runINIT.html b/doc/INIT/runINIT.html index e4003c24..15cbb20d 100644 --- a/doc/INIT/runINIT.html +++ b/doc/INIT/runINIT.html @@ -24,7 +24,7 @@

    PURPOSE ^runINIT

    SYNOPSIS ^

    -
    function [outModel, deletedRxns, metProduction, fValue]=runINIT(model,rxnScores,presentMets,essentialRxns,prodWeight,allowExcretion,noRevLoops)
    +
    function [outModel, deletedRxns, metProduction, fValue]=runINIT(model,rxnScores,presentMets,essentialRxns,prodWeight,allowExcretion,noRevLoops,params)

    DESCRIPTION ^

     runINIT
    @@ -66,6 +66,7 @@ 

    DESCRIPTION ^CROSS-REFERENCE INFORMATION ^
 
 
 <h2><a name=SOURCE CODE ^

    -
    0001 function [outModel, deletedRxns, metProduction, fValue]=runINIT(model,rxnScores,presentMets,essentialRxns,prodWeight,allowExcretion,noRevLoops)
    +
    0001 function [outModel, deletedRxns, metProduction, fValue]=runINIT(model,rxnScores,presentMets,essentialRxns,prodWeight,allowExcretion,noRevLoops,params)
     0002 % runINIT
     0003 %    Generates a model using the INIT algorithm, based on proteomics and/or
     0004 %   transcriptomics and/or metabolomics and/or metabolic tasks. This is the
    @@ -141,303 +142,304 @@ 

    SOURCE CODE ^% problem significantly more computationally intensive to 0039 % solve (two more integer constraints per reversible reaction) 0040 % (optional, default false) -0041 % -0042 % outModel the resulting model structure -0043 % deletedRxns reactions which were deleted by the algorithm -0044 % metProduction array that indicates which of the -0045 % metabolites in presentMets that could be -0046 % produced -0047 % -2: metabolite name not found in model -0048 % -1: metabolite found, but it could not be produced -0049 % 1: metabolite could be produced -0050 % fValue objective value (sum of (the negative of) -0051 % reaction scores for the included reactions and -0052 % prodWeight*number of produced metabolites) -0053 % -0054 % This function is the actual implementation of the algorithm. See -0055 % getINITModel for a higher-level function for model reconstruction. See -0056 % PLoS Comput Biol. 2012;8(5):e1002518 for details regarding the -0057 % implementation. -0058 % -0059 % Usage: [outModel deletedRxns metProduction fValue]=runINIT(model,... -0060 % rxnScores,presentMets,essentialRxns,prodWeight,allowExcretion,... -0061 % noRevLoops,params) -0062 -0063 if nargin<2 -0064 rxnScores=zeros(numel(model.rxns),1); -0065 end -0066 if isempty(rxnScores) -0067 rxnScores=zeros(numel(model.rxns),1); -0068 end -0069 if nargin<3 || isempty(presentMets) -0070 presentMets={}; -0071 else -0072 presentMets=convertCharArray(presentMets); -0073 end -0074 if nargin<4 || isempty(essentialRxns) -0075 essentialRxns={}; -0076 else -0077 essentialRxns=convertCharArray(essentialRxns); -0078 end -0079 if nargin<5 || isempty(prodWeight) -0080 prodWeight=0.5; -0081 end -0082 if nargin<6 -0083 allowExcretion=false; -0084 end -0085 if nargin<7 -0086 noRevLoops=false; -0087 end -0088 if nargin<8 -0089 params=[]; -0090 end -0091 -0092 if numel(presentMets)~=numel(unique(presentMets)) -0093 EM='Duplicate metabolite names in presentMets'; -0094 dispEM(EM); -0095 end -0096 -0097 %Default is that the metabolites cannot be produced -0098 if ~isempty(presentMets) -0099 metProduction=ones(numel(presentMets),1)*-2; -0100 presentMets=upper(presentMets); -0101 pmIndexes=find(ismember(presentMets,upper(model.metNames))); -0102 metProduction(pmIndexes)=-1; %Then set that they are at least found -0103 else -0104 metProduction=[]; -0105 pmIndexes=[]; -0106 end -0107 -0108 %The model should be in the reversible format and all relevant exchange -0109 %reactions should be open -0110 if isfield(model,'unconstrained') -0111 EM='Exchange metabolites are still present in the model. Use simplifyModel if this is not intended'; -0112 dispEM(EM,false); -0113 end -0114 -0115 %The irreversible reactions that are essential must have a flux and are -0116 %therefore not optimized for using MILP, which reduces the problem size. -0117 %However, reversible reactions must have a flux in one direction, so they -0118 %have to stay in the problem. The essentiality constraint on reversible -0119 %reactions is implemented in the same manner as for reversible reactions -0120 %when noRevLoops==true, but with the additional constraint that C ub=-1. -0121 %This forces one of the directions to be active. -0122 revRxns=find(model.rev~=0); -0123 essentialReversible=find(ismember(model.rxns(revRxns),essentialRxns)); -0124 essentialRxns=intersect(essentialRxns,model.rxns(model.rev==0)); -0125 -0126 %Convert the model to irreversible -0127 irrevModel=convertToIrrev(model); -0128 rxnScores=[rxnScores;rxnScores(model.rev==1)]; -0129 %These are used if noRevLoops is true -0130 if noRevLoops==true -0131 forwardIndexes=find(model.rev~=0); -0132 backwardIndexes=(numel(model.rxns)+1:numel(irrevModel.rxns))'; -0133 else -0134 %Then they should only be used for essential reversible reactions -0135 forwardIndexes=revRxns(essentialReversible); -0136 backwardIndexes=essentialReversible+numel(model.rxns); -0137 end -0138 -0139 %Get the indexes of the essential reactions and remove them from the -0140 %scoring vector -0141 essentialIndex=find(ismember(irrevModel.rxns,essentialRxns)); -0142 rxnScores(essentialIndex)=[]; -0143 -0144 %Go through each of the presentMets (if they exist) and modify the S matrix -0145 %so that each reaction which produces any of them also produces a -0146 %corresponding fake metabolite and the opposite in the reverse direction. -0147 -0148 %This is to deal with the fact that there is no compartment info regarding -0149 %the presentMets. This modifies the irrevModel structure, but that is fine -0150 %since it's the model structure that is returned. -0151 if any(pmIndexes) -0152 irrevModel.metNames=upper(irrevModel.metNames); -0153 metsToAdd.mets=strcat({'FAKEFORPM'},num2str(pmIndexes)); -0154 metsToAdd.metNames=metsToAdd.mets; -0155 metsToAdd.compartments=irrevModel.comps{1}; -0156 -0157 %There is no constraints on the metabolites yet, since maybe not all of -0158 %them could be produced -0159 irrevModel=addMets(irrevModel,metsToAdd); -0160 end -0161 -0162 %Modify the matrix -0163 for i=1:numel(pmIndexes) -0164 %Get the matching mets -0165 I=ismember(irrevModel.metNames,presentMets(pmIndexes(i))); -0166 -0167 %Find the reactions where any of them are used. -0168 [~, K, L]=find(irrevModel.S(I,:)); -0169 -0170 %This ugly loop is to avoid problems if a metabolite occurs several -0171 %times in one reaction -0172 KK=unique(K); -0173 LL=zeros(numel(KK),1); -0174 for j=1:numel(KK) -0175 LL(j)=sum(L(K==KK(j))); -0176 end -0177 irrevModel.S(numel(irrevModel.mets)-numel(pmIndexes)+i,KK)=LL; -0178 end -0179 -0180 %Some nice to have numbers -0181 nMets=numel(irrevModel.mets); -0182 nRxns=numel(irrevModel.rxns); -0183 nEssential=numel(essentialIndex); -0184 nNonEssential=nRxns-nEssential; -0185 nonEssentialIndex=setdiff(1:nRxns,essentialIndex); -0186 S=irrevModel.S; -0187 -0188 %Add so that each non-essential reaction produces one unit of a fake -0189 %metabolite -0190 temp=sparse(1:nRxns,1:nRxns,1); -0191 temp(essentialIndex,:)=[]; -0192 S=[S;temp]; -0193 -0194 %Add another set of reactions (will be binary) which also produce these -0195 %fake metabolites, but with a stoichiometry of 1000 -0196 temp=sparse(1:nNonEssential,1:nNonEssential,1000); -0197 temp=[sparse(nMets,nNonEssential);temp]; -0198 S=[S temp]; -0199 -0200 %Add reactions for net-production of (real) metabolites -0201 if prodWeight~=0 -0202 temp=[speye(nMets-numel(pmIndexes))*-1;sparse(nNonEssential+numel(pmIndexes),nMets-numel(pmIndexes))]; -0203 S=[S temp]; -0204 %To keep the number of reactions added like this -0205 nNetProd=nMets-numel(pmIndexes); -0206 else -0207 nNetProd=0; -0208 end -0209 -0210 %Add constraints so that reversible reactions can only be used in one -0211 %direction. This is done by adding the fake metabolites A, B, C for each -0212 %reversible reaction in the following manner -0213 % forward: A + .. => ... backwards: B + ... => ... int1: C => 1000 A int2: -0214 % C => 1000 B A ub=999.9 B ub=999.9 C lb=-1 int1 and int2 are binary -0215 if any(forwardIndexes) -0216 nRevBounds=numel(forwardIndexes); -0217 -0218 %Add the A metabolites for the forward reactions and the B metabolites -0219 %for the reverse reactions -0220 I=speye(numel(irrevModel.rxns))*-1; -0221 temp=[I(forwardIndexes,:);I(backwardIndexes,:)]; -0222 -0223 %Padding -0224 temp=[temp sparse(size(temp,1),size(S,2)-numel(irrevModel.rxns))]; -0225 -0226 %Add the int1 & int2 reactions that produce A and B -0227 temp=[temp speye(nRevBounds*2)*1000]; -0228 -0229 %And add that they also consume C -0230 temp=[temp;[sparse(nRevBounds,size(S,2)) speye(nRevBounds)*-1 speye(nRevBounds)*-1]]; -0231 -0232 %Add the new reactions and metabolites -0233 S=[S sparse(size(S,1),nRevBounds*2)]; -0234 S=[S;temp]; -0235 else -0236 nRevBounds=0; -0237 end -0238 -0239 %Add so that the essential reactions must have a small flux and that the -0240 %binary ones (and net-production reactions) may have zero flux. The integer -0241 %reactions for reversible reactions have [0 1] -0242 prob.blx=[irrevModel.lb;zeros(nNonEssential+nNetProd+nRevBounds*2,1)]; -0243 prob.blx(essentialIndex)=max(0.1,prob.blx(essentialIndex)); -0244 -0245 %Add so that the binary ones and net-production reactions can have at the -0246 %most flux 1.0 -0247 prob.bux=[irrevModel.ub;ones(nNonEssential+nNetProd+nRevBounds*2,1)]; -0248 -0249 %Add that the fake metabolites must be produced in a small amount and that -0250 %the A and B metabolites for reversible reactions can be [0 999.9] and C -0251 %metabolites [-1 0] -0252 prob.blc=[irrevModel.b(:,1);ones(nNonEssential,1);zeros(nRevBounds*2,1);ones(nRevBounds,1)*-1]; -0253 -0254 %Add that normal metabolites can be freely excreted if -0255 %allowExcretion==true, and that the fake ones can be excreted 1000 units at -0256 %most. C metabolites for essential reversible reactions should have an -0257 %upper bound of -1. If noRevLoops is false, then add this constraint for -0258 %all the reactions instead. -0259 if noRevLoops==true -0260 revUB=zeros(nRevBounds,1); -0261 revUB(essentialReversible)=-1; -0262 else -0263 revUB=ones(nRevBounds,1)*-1; -0264 end -0265 if allowExcretion==true -0266 metUB=inf(nMets,1); -0267 else -0268 metUB=irrevModel.b(:,min(size(irrevModel.b,2),2)); -0269 end -0270 prob.buc=[metUB;ones(nNonEssential,1)*1000;ones(nRevBounds*2,1)*999.9;revUB]; -0271 -0272 %Add objective coefficients for the binary reactions. The negative is used -0273 %since we're minimizing. The negative is taken for the prodWeight as well, -0274 %in order to be consistent with the syntax that positive scores are good -0275 prob.c=[zeros(nRxns,1);rxnScores;ones(nNetProd,1)*prodWeight*-1;zeros(nRevBounds*2,1)]; -0276 prob.a=S; -0277 -0278 % adapt problem structure for cobra-style solver -0279 prob.c=[prob.c;zeros(size(prob.a,1),1)]; -0280 prob.A=[prob.a -speye(size(prob.a,1))]; -0281 prob.b=zeros(size(prob.a,1), 1); -0282 prob.ub=[prob.bux; prob.buc]; -0283 prob.osense=1; -0284 prob.csense=char(zeros(1,size(prob.a,1))); -0285 prob.csense(:)='E'; -0286 -0287 %We still don't know which of the presentMets that can be produced. Go -0288 %through them, force production, and see if the problem can be solved -0289 for i=1:numel(pmIndexes) -0290 prob.blc(numel(irrevModel.mets)-numel(pmIndexes)+i)=1; -0291 prob.lb=[prob.blx; prob.blc]; -0292 res=optimizeProb(prob,params); -0293 isFeasible=checkSolution(res); -0294 if ~isFeasible -0295 %Reset the constraint again -0296 prob.blc(numel(irrevModel.mets)-numel(pmIndexes)+i)=0; -0297 else -0298 %Metabolite produced -0299 metProduction(pmIndexes(i))=1; -0300 end -0301 end -0302 prob.lb=[prob.blx; prob.blc]; -0303 -0304 %Add that the binary reactions may only take integer values. -0305 prob.vartype = repmat('C', 1, size(prob.A, 2)); -0306 allInt=[(nRxns+1):(nRxns+nNonEssential) size(S,2)-nRevBounds*2+1:size(S,2)]; -0307 prob.vartype(allInt) = 'B'; -0308 -0309 % solve problem -0310 res=optimizeProb(prob,params); -0311 -0312 %Problem should not be infeasible, but it is possible that the time limit -0313 %was reached before finding any solutions. -0314 if ~checkSolution(res) -0315 if strcmp(res.origStat, 'TIME_LIMIT') -0316 EM='Time limit reached without finding a solution. Try increasing the TimeLimit parameter.'; -0317 else -0318 EM='The problem is infeasible'; -0319 end -0320 dispEM(EM); -0321 end -0322 -0323 fValue=res.obj; -0324 -0325 %Get all reactions used in the irreversible model -0326 usedRxns=(nonEssentialIndex(res.full(nRxns+1:nRxns+nNonEssential)<0.1))'; -0327 -0328 %Map to reversible model IDs -0329 usedRxns=[usedRxns(usedRxns<=numel(model.rxns));revRxns(usedRxns(usedRxns>numel(model.rxns))-numel(model.rxns))]; -0330 -0331 %Then get the ones that are not used in either direction or is essential -0332 I=true(numel(model.rxns),1); -0333 I(usedRxns)=false; -0334 I(essentialIndex)=false; -0335 deletedRxns=model.rxns(I); -0336 outModel=removeReactions(model,I,true,true); -0337 end

    +0041 % params parameter structure for use by optimizeProb +0042 % +0043 % outModel the resulting model structure +0044 % deletedRxns reactions which were deleted by the algorithm +0045 % metProduction array that indicates which of the +0046 % metabolites in presentMets that could be +0047 % produced +0048 % -2: metabolite name not found in model +0049 % -1: metabolite found, but it could not be produced +0050 % 1: metabolite could be produced +0051 % fValue objective value (sum of (the negative of) +0052 % reaction scores for the included reactions and +0053 % prodWeight*number of produced metabolites) +0054 % +0055 % This function is the actual implementation of the algorithm. See +0056 % getINITModel for a higher-level function for model reconstruction. See +0057 % PLoS Comput Biol. 2012;8(5):e1002518 for details regarding the +0058 % implementation. +0059 % +0060 % Usage: [outModel deletedRxns metProduction fValue]=runINIT(model,... +0061 % rxnScores,presentMets,essentialRxns,prodWeight,allowExcretion,... +0062 % noRevLoops,params) +0063 +0064 if nargin<2 +0065 rxnScores=zeros(numel(model.rxns),1); +0066 end +0067 if isempty(rxnScores) +0068 rxnScores=zeros(numel(model.rxns),1); +0069 end +0070 if nargin<3 || isempty(presentMets) +0071 presentMets={}; +0072 else +0073 presentMets=convertCharArray(presentMets); +0074 end +0075 if nargin<4 || isempty(essentialRxns) +0076 essentialRxns={}; +0077 else +0078 essentialRxns=convertCharArray(essentialRxns); +0079 end +0080 if nargin<5 || isempty(prodWeight) +0081 prodWeight=0.5; +0082 end +0083 if nargin<6 +0084 allowExcretion=false; +0085 end +0086 if nargin<7 +0087 noRevLoops=false; +0088 end +0089 if nargin<8 +0090 params=[]; +0091 end +0092 +0093 if numel(presentMets)~=numel(unique(presentMets)) +0094 EM='Duplicate metabolite names in presentMets'; +0095 dispEM(EM); +0096 end +0097 +0098 %Default is that the metabolites cannot be produced +0099 if ~isempty(presentMets) +0100 metProduction=ones(numel(presentMets),1)*-2; +0101 presentMets=upper(presentMets); +0102 pmIndexes=find(ismember(presentMets,upper(model.metNames))); +0103 metProduction(pmIndexes)=-1; %Then set that they are at least found +0104 else +0105 metProduction=[]; +0106 pmIndexes=[]; +0107 end +0108 +0109 %The model should be in the reversible format and all relevant exchange +0110 %reactions should be open +0111 if isfield(model,'unconstrained') +0112 EM='Exchange metabolites are still present in the model. Use simplifyModel if this is not intended'; +0113 dispEM(EM,false); +0114 end +0115 +0116 %The irreversible reactions that are essential must have a flux and are +0117 %therefore not optimized for using MILP, which reduces the problem size. +0118 %However, reversible reactions must have a flux in one direction, so they +0119 %have to stay in the problem. The essentiality constraint on reversible +0120 %reactions is implemented in the same manner as for reversible reactions +0121 %when noRevLoops==true, but with the additional constraint that C ub=-1. +0122 %This forces one of the directions to be active. +0123 revRxns=find(model.rev~=0); +0124 essentialReversible=find(ismember(model.rxns(revRxns),essentialRxns)); +0125 essentialRxns=intersect(essentialRxns,model.rxns(model.rev==0)); +0126 +0127 %Convert the model to irreversible +0128 irrevModel=convertToIrrev(model); +0129 rxnScores=[rxnScores;rxnScores(model.rev==1)]; +0130 %These are used if noRevLoops is true +0131 if noRevLoops==true +0132 forwardIndexes=find(model.rev~=0); +0133 backwardIndexes=(numel(model.rxns)+1:numel(irrevModel.rxns))'; +0134 else +0135 %Then they should only be used for essential reversible reactions +0136 forwardIndexes=revRxns(essentialReversible); +0137 backwardIndexes=essentialReversible+numel(model.rxns); +0138 end +0139 +0140 %Get the indexes of the essential reactions and remove them from the +0141 %scoring vector +0142 essentialIndex=find(ismember(irrevModel.rxns,essentialRxns)); +0143 rxnScores(essentialIndex)=[]; +0144 +0145 %Go through each of the presentMets (if they exist) and modify the S matrix +0146 %so that each reaction which produces any of them also produces a +0147 %corresponding fake metabolite and the opposite in the reverse direction. +0148 +0149 %This is to deal with the fact that there is no compartment info regarding +0150 %the presentMets. This modifies the irrevModel structure, but that is fine +0151 %since it's the model structure that is returned. +0152 if any(pmIndexes) +0153 irrevModel.metNames=upper(irrevModel.metNames); +0154 metsToAdd.mets=strcat({'FAKEFORPM'},num2str(pmIndexes)); +0155 metsToAdd.metNames=metsToAdd.mets; +0156 metsToAdd.compartments=irrevModel.comps{1}; +0157 +0158 %There is no constraints on the metabolites yet, since maybe not all of +0159 %them could be produced +0160 irrevModel=addMets(irrevModel,metsToAdd); +0161 end +0162 +0163 %Modify the matrix +0164 for i=1:numel(pmIndexes) +0165 %Get the matching mets +0166 I=ismember(irrevModel.metNames,presentMets(pmIndexes(i))); +0167 +0168 %Find the reactions where any of them are used. +0169 [~, K, L]=find(irrevModel.S(I,:)); +0170 +0171 %This ugly loop is to avoid problems if a metabolite occurs several +0172 %times in one reaction +0173 KK=unique(K); +0174 LL=zeros(numel(KK),1); +0175 for j=1:numel(KK) +0176 LL(j)=sum(L(K==KK(j))); +0177 end +0178 irrevModel.S(numel(irrevModel.mets)-numel(pmIndexes)+i,KK)=LL; +0179 end +0180 +0181 %Some nice to have numbers +0182 nMets=numel(irrevModel.mets); +0183 nRxns=numel(irrevModel.rxns); +0184 nEssential=numel(essentialIndex); +0185 nNonEssential=nRxns-nEssential; +0186 nonEssentialIndex=setdiff(1:nRxns,essentialIndex); +0187 S=irrevModel.S; +0188 +0189 %Add so that each non-essential reaction produces one unit of a fake +0190 %metabolite +0191 temp=sparse(1:nRxns,1:nRxns,1); +0192 temp(essentialIndex,:)=[]; +0193 S=[S;temp]; +0194 +0195 %Add another set of reactions (will be binary) which also produce these +0196 %fake metabolites, but with a stoichiometry of 1000 +0197 temp=sparse(1:nNonEssential,1:nNonEssential,1000); +0198 temp=[sparse(nMets,nNonEssential);temp]; +0199 S=[S temp]; +0200 +0201 %Add reactions for net-production of (real) metabolites +0202 if prodWeight~=0 +0203 temp=[speye(nMets-numel(pmIndexes))*-1;sparse(nNonEssential+numel(pmIndexes),nMets-numel(pmIndexes))]; +0204 S=[S temp]; +0205 %To keep the number of reactions added like this +0206 nNetProd=nMets-numel(pmIndexes); +0207 else +0208 nNetProd=0; +0209 end +0210 +0211 %Add constraints so that reversible reactions can only be used in one +0212 %direction. This is done by adding the fake metabolites A, B, C for each +0213 %reversible reaction in the following manner +0214 % forward: A + .. => ... backwards: B + ... => ... int1: C => 1000 A int2: +0215 % C => 1000 B A ub=999.9 B ub=999.9 C lb=-1 int1 and int2 are binary +0216 if any(forwardIndexes) +0217 nRevBounds=numel(forwardIndexes); +0218 +0219 %Add the A metabolites for the forward reactions and the B metabolites +0220 %for the reverse reactions +0221 I=speye(numel(irrevModel.rxns))*-1; +0222 temp=[I(forwardIndexes,:);I(backwardIndexes,:)]; +0223 +0224 %Padding +0225 temp=[temp sparse(size(temp,1),size(S,2)-numel(irrevModel.rxns))]; +0226 +0227 %Add the int1 & int2 reactions that produce A and B +0228 temp=[temp speye(nRevBounds*2)*1000]; +0229 +0230 %And add that they also consume C +0231 temp=[temp;[sparse(nRevBounds,size(S,2)) speye(nRevBounds)*-1 speye(nRevBounds)*-1]]; +0232 +0233 %Add the new reactions and metabolites +0234 S=[S sparse(size(S,1),nRevBounds*2)]; +0235 S=[S;temp]; +0236 else +0237 nRevBounds=0; +0238 end +0239 +0240 %Add so that the essential reactions must have a small flux and that the +0241 %binary ones (and net-production reactions) may have zero flux. The integer +0242 %reactions for reversible reactions have [0 1] +0243 prob.blx=[irrevModel.lb;zeros(nNonEssential+nNetProd+nRevBounds*2,1)]; +0244 prob.blx(essentialIndex)=max(0.1,prob.blx(essentialIndex)); +0245 +0246 %Add so that the binary ones and net-production reactions can have at the +0247 %most flux 1.0 +0248 prob.bux=[irrevModel.ub;ones(nNonEssential+nNetProd+nRevBounds*2,1)]; +0249 +0250 %Add that the fake metabolites must be produced in a small amount and that +0251 %the A and B metabolites for reversible reactions can be [0 999.9] and C +0252 %metabolites [-1 0] +0253 prob.blc=[irrevModel.b(:,1);ones(nNonEssential,1);zeros(nRevBounds*2,1);ones(nRevBounds,1)*-1]; +0254 +0255 %Add that normal metabolites can be freely excreted if +0256 %allowExcretion==true, and that the fake ones can be excreted 1000 units at +0257 %most. C metabolites for essential reversible reactions should have an +0258 %upper bound of -1. If noRevLoops is false, then add this constraint for +0259 %all the reactions instead. +0260 if noRevLoops==true +0261 revUB=zeros(nRevBounds,1); +0262 revUB(essentialReversible)=-1; +0263 else +0264 revUB=ones(nRevBounds,1)*-1; +0265 end +0266 if allowExcretion==true +0267 metUB=inf(nMets,1); +0268 else +0269 metUB=irrevModel.b(:,min(size(irrevModel.b,2),2)); +0270 end +0271 prob.buc=[metUB;ones(nNonEssential,1)*1000;ones(nRevBounds*2,1)*999.9;revUB]; +0272 +0273 %Add objective coefficients for the binary reactions. The negative is used +0274 %since we're minimizing. The negative is taken for the prodWeight as well, +0275 %in order to be consistent with the syntax that positive scores are good +0276 prob.c=[zeros(nRxns,1);rxnScores;ones(nNetProd,1)*prodWeight*-1;zeros(nRevBounds*2,1)]; +0277 prob.a=S; +0278 +0279 % adapt problem structure for cobra-style solver +0280 prob.c=[prob.c;zeros(size(prob.a,1),1)]; +0281 prob.A=[prob.a -speye(size(prob.a,1))]; +0282 prob.b=zeros(size(prob.a,1), 1); +0283 prob.ub=[prob.bux; prob.buc]; +0284 prob.osense=1; +0285 prob.csense=char(zeros(1,size(prob.a,1))); +0286 prob.csense(:)='E'; +0287 +0288 %We still don't know which of the presentMets that can be produced. Go +0289 %through them, force production, and see if the problem can be solved +0290 for i=1:numel(pmIndexes) +0291 prob.blc(numel(irrevModel.mets)-numel(pmIndexes)+i)=1; +0292 prob.lb=[prob.blx; prob.blc]; +0293 res=optimizeProb(prob,params); +0294 isFeasible=checkSolution(res); +0295 if ~isFeasible +0296 %Reset the constraint again +0297 prob.blc(numel(irrevModel.mets)-numel(pmIndexes)+i)=0; +0298 else +0299 %Metabolite produced +0300 metProduction(pmIndexes(i))=1; +0301 end +0302 end +0303 prob.lb=[prob.blx; prob.blc]; +0304 +0305 %Add that the binary reactions may only take integer values. +0306 prob.vartype = repmat('C', 1, size(prob.A, 2)); +0307 allInt=[(nRxns+1):(nRxns+nNonEssential) size(S,2)-nRevBounds*2+1:size(S,2)]; +0308 prob.vartype(allInt) = 'B'; +0309 +0310 % solve problem +0311 res=optimizeProb(prob,params); +0312 +0313 %Problem should not be infeasible, but it is possible that the time limit +0314 %was reached before finding any solutions. +0315 if ~checkSolution(res) +0316 if strcmp(res.origStat, 'TIME_LIMIT') +0317 EM='Time limit reached without finding a solution. Try increasing the TimeLimit parameter.'; +0318 else +0319 EM='The problem is infeasible'; +0320 end +0321 dispEM(EM); +0322 end +0323 +0324 fValue=res.obj; +0325 +0326 %Get all reactions used in the irreversible model +0327 usedRxns=(nonEssentialIndex(res.full(nRxns+1:nRxns+nNonEssential)<0.1))'; +0328 +0329 %Map to reversible model IDs +0330 usedRxns=[usedRxns(usedRxns<=numel(model.rxns));revRxns(usedRxns(usedRxns>numel(model.rxns))-numel(model.rxns))]; +0331 +0332 %Then get the ones that are not used in either direction or is essential +0333 I=true(numel(model.rxns),1); +0334 I(usedRxns)=false; +0335 I(essentialIndex)=false; +0336 deletedRxns=model.rxns(I); +0337 outModel=removeReactions(model,I,true,true); +0338 end

    Generated by m2html © 2005
    \ No newline at end of file diff --git a/doc/core/FSEOF.html b/doc/core/FSEOF.html index 940f3278..af3e7a45 100644 --- a/doc/core/FSEOF.html +++ b/doc/core/FSEOF.html @@ -191,29 +191,34 @@

    SOURCE CODE ^%enzyme ID 0120 A3=char(model.rxnNames(num)); %enzyme Name 0121 if isfield(model,'subSystems') && ~isempty(model.subSystems{num}); -0122 A4=char(strjoin(model.subSystems{num,1},';')); %Subsystems -0123 else -0124 A4=''; -0125 end -0126 A5=num2str(model.rev(num)*rxnDirection(num,1)); %reaction Dirction -0127 A6=char(model.grRules(num)); %Gr Rule -0128 if output == 1 %Output to a file -0129 fprintf(fid,formatSpec,A0,A1,A2,A3,A4,A5,A6); -0130 else %Output screen -0131 fprintf(formatSpec,A0,A1,A2,A3,A4,A5,A6); -0132 end -0133 end -0134 end -0135 -0136 if output == 1 %Output to a file -0137 fclose(fid); -0138 end -0139 -0140 if nargout == 1 -0141 targets.logical=logical(fseof.target); -0142 targets.slope=abs(fseof.results(:,iterations)-fseof.results(:,1))/abs(targetMax-targetMax/iterations); %Slope calculation +0122 if ~any(cellfun(@(x) iscell(x), model.subSystems)); +0123 subSys = cellfun(@(x) {x}, model.subSystems, 'uni', 0); +0124 else +0125 subSys = model.subSystems; +0126 end +0127 A4=char(strjoin(subSys{num},';')); %Subsystems +0128 else +0129 A4=''; +0130 end +0131 A5=num2str(model.rev(num)*rxnDirection(num,1)); %reaction Dirction +0132 A6=char(model.grRules(num)); %Gr Rule +0133 if output == 1 %Output to a file +0134 fprintf(fid,formatSpec,A0,A1,A2,A3,A4,A5,A6); +0135 else %Output screen +0136 fprintf(formatSpec,A0,A1,A2,A3,A4,A5,A6); +0137 end +0138 end +0139 end +0140 +0141 if output == 1 %Output to a file +0142 fclose(fid); 0143 end -0144 end

    +0144 +0145 if nargout == 1 +0146 targets.logical=logical(fseof.target); +0147 targets.slope=abs(fseof.results(:,iterations)-fseof.results(:,1))/abs(targetMax-targetMax/iterations); %Slope calculation +0148 end +0149 end
    Generated by m2html © 2005
    \ No newline at end of file diff --git a/doc/core/addExchangeRxns.html b/doc/core/addExchangeRxns.html index 77045cdd..c1bdf99f 100644 --- a/doc/core/addExchangeRxns.html +++ b/doc/core/addExchangeRxns.html @@ -127,8 +127,8 @@

    SOURCE CODE ^end 0064 if isfield(model,'subSystems') 0065 fillerSub = filler; -0066 if iscell(model.subSystems(1,1)) -0067 fillerSub = repmat({fillerSub},numel(J),1); +0066 if any(cellfun(@(x) iscell(x), model.subSystems)) +0067 fillerSub(:)={{''}}; 0068 end 0069 model.subSystems=[model.subSystems;fillerSub]; 0070 end diff --git a/doc/core/addRxns.html b/doc/core/addRxns.html index e4ebe1c7..5a26576f 100644 --- a/doc/core/addRxns.html +++ b/doc/core/addRxns.html @@ -371,457 +371,476 @@

    SOURCE CODE ^''}; -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 ischar(rxnsToAdd.subSystems) -0354 rxnsToAdd.subSystems = {{rxnsToAdd.subSystems}}; -0355 else -0356 for i=1:numel(rxnsToAdd.subSystems) -0357 if ischar(rxnsToAdd.subSystems{i}) -0358 rxnsToAdd.subSystems{i}=rxnsToAdd.subSystems(i); -0359 end -0360 end -0361 end -0362 if numel(rxnsToAdd.subSystems)~=nRxns -0363 EM='rxnsToAdd.subSystems must have the same number of elements as rxnsToAdd.rxns'; -0364 dispEM(EM); -0365 end -0366 %Fill with standard if it doesn't exist -0367 if ~isfield(newModel,'subSystems') -0368 newModel.subSystems=celllargefiller; -0369 end -0370 newModel.subSystems=[newModel.subSystems;rxnsToAdd.subSystems(:)]; -0371 else -0372 %Fill with standard if it doesn't exist -0373 if isfield(newModel,'subSystems') -0374 newModel.subSystems=[newModel.subSystems;cellfiller]; -0375 end -0376 end -0377 if isfield(rxnsToAdd,'rxnMiriams') -0378 if numel(rxnsToAdd.rxnMiriams)~=nRxns -0379 EM='rxnsToAdd.rxnMiriams must have the same number of elements as rxnsToAdd.rxns'; -0380 dispEM(EM); -0381 end -0382 %Fill with standard if it doesn't exist -0383 if ~isfield(newModel,'rxnMiriams') -0384 newModel.rxnMiriams=cell(nOldRxns,1); -0385 end -0386 newModel.rxnMiriams=[newModel.rxnMiriams;rxnsToAdd.rxnMiriams(:)]; -0387 else -0388 %Fill with standard if it doesn't exist -0389 if isfield(newModel,'rxnMiriams') -0390 newModel.rxnMiriams=[newModel.rxnMiriams;cell(nRxns,1)]; -0391 end -0392 end -0393 if isfield(rxnsToAdd,'rxnComps') -0394 if numel(rxnsToAdd.rxnComps)~=nRxns -0395 EM='rxnsToAdd.rxnComps must have the same number of elements as rxnsToAdd.rxns'; -0396 dispEM(EM); -0397 end -0398 %Fill with standard if it doesn't exist -0399 if ~isfield(newModel,'rxnComps') -0400 newModel.rxnComps=ones(nOldRxns,1); -0401 EM='Adding reactions with compartment information to a model without such information. All existing reactions will be assigned to the first compartment'; -0402 dispEM(EM,false); -0403 end -0404 newModel.rxnComps=[newModel.rxnComps;rxnsToAdd.rxnComps(:)]; -0405 else -0406 %Fill with standard if it doesn't exist -0407 if isfield(newModel,'rxnComps') -0408 newModel.rxnComps=[newModel.rxnComps;ones(nRxns,1)]; -0409 %fprintf('NOTE: The added reactions will be assigned to the first -0410 %compartment\n'); -0411 end -0412 end -0413 if isfield(rxnsToAdd,'grRules') -0414 rxnsToAdd.grRules=convertCharArray(rxnsToAdd.grRules); -0415 if numel(rxnsToAdd.grRules)~=nRxns -0416 EM='rxnsToAdd.grRules must have the same number of elements as rxnsToAdd.rxns'; -0417 dispEM(EM); -0418 end -0419 %Fill with standard if it doesn't exist -0420 if ~isfield(newModel,'grRules') -0421 newModel.grRules=largeFiller; +0230 cellfiller=cell(nRxns,1); +0231 cellfiller(:)={{''}}; +0232 largeFiller=cell(nOldRxns,1); +0233 largeFiller(:)={''}; +0234 largeCellFiller=cell(nOldRxns,1); +0235 largeCellFiller(:)={{''}}; +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 % Has to be cell array +0356 if ischar(rxnsToAdd.subSystems) +0357 rxnsToAdd.subSystems = {rxnsToAdd.subSystems}; +0358 end +0359 % If all nested cells are 1x1, then unnest +0360 if all(cellfun(@(x) iscell(x) && isscalar(x), rxnsToAdd.subSystems)) +0361 rxnsToAdd.subSystems = transpose([rxnsToAdd.subSystems{:}]); +0362 end +0363 % Cell array should now be as simple as possible. Check if it is nested +0364 subSysRxnsNested = any(cellfun(@(x) iscell(x), rxnsToAdd.subSystems)); +0365 if isfield(newModel,'subSystems') +0366 subSysModelNested = any(cellfun(@(x) iscell(x), newModel.subSystems)); +0367 else +0368 subSysModelNested = subSysRxnsNested; +0369 if subSysRxnsNested +0370 newModel.subSystems=largeCellFiller; +0371 else +0372 newModel.subSystems=largeFiller; +0373 end +0374 end +0375 if subSysRxnsNested && ~subSysModelNested +0376 % Make all existing subSystems nested +0377 newModel.subSystems = cellfun(@(x) {x}, newModel.subSystems, 'uni', 0); +0378 elseif ~subSysRxnsNested && subSysModelNested +0379 rxnsToAdd.subSystems = cellfun(@(x) {x}, rxnsToAdd.subSystems, 'uni', 0); +0380 end +0381 if numel(rxnsToAdd.subSystems)~=nRxns +0382 EM='rxnsToAdd.subSystems must have the same number of elements as rxnsToAdd.rxns'; +0383 dispEM(EM); +0384 end +0385 newModel.subSystems=[newModel.subSystems;rxnsToAdd.subSystems(:)]; +0386 else +0387 %Fill with standard if it does not exist +0388 if isfield(newModel,'subSystems') +0389 if any(cellfun(@(x) iscell(x), newModel.subSystems)) +0390 newModel.subSystems=[newModel.subSystems;cellfiller]; +0391 else +0392 newModel.subSystems=[newModel.subSystems;filler]; +0393 end +0394 end +0395 end +0396 if isfield(rxnsToAdd,'rxnMiriams') +0397 if numel(rxnsToAdd.rxnMiriams)~=nRxns +0398 EM='rxnsToAdd.rxnMiriams must have the same number of elements as rxnsToAdd.rxns'; +0399 dispEM(EM); +0400 end +0401 %Fill with standard if it doesn't exist +0402 if ~isfield(newModel,'rxnMiriams') +0403 newModel.rxnMiriams=cell(nOldRxns,1); +0404 end +0405 newModel.rxnMiriams=[newModel.rxnMiriams;rxnsToAdd.rxnMiriams(:)]; +0406 else +0407 %Fill with standard if it doesn't exist +0408 if isfield(newModel,'rxnMiriams') +0409 newModel.rxnMiriams=[newModel.rxnMiriams;cell(nRxns,1)]; +0410 end +0411 end +0412 if isfield(rxnsToAdd,'rxnComps') +0413 if numel(rxnsToAdd.rxnComps)~=nRxns +0414 EM='rxnsToAdd.rxnComps 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,'rxnComps') +0419 newModel.rxnComps=ones(nOldRxns,1); +0420 EM='Adding reactions with compartment information to a model without such information. All existing reactions will be assigned to the first compartment'; +0421 dispEM(EM,false); 0422 end -0423 newModel.grRules=[newModel.grRules;rxnsToAdd.grRules(:)]; +0423 newModel.rxnComps=[newModel.rxnComps;rxnsToAdd.rxnComps(:)]; 0424 else 0425 %Fill with standard if it doesn't exist -0426 if isfield(newModel,'grRules') -0427 newModel.grRules=[newModel.grRules;filler]; -0428 end -0429 end -0430 -0431 if isfield(rxnsToAdd,'rxnFrom') -0432 rxnsToAdd.rxnFrom=convertCharArray(rxnsToAdd.rxnFrom); -0433 if numel(rxnsToAdd.rxnFrom)~=nRxns -0434 EM='rxnsToAdd.rxnFrom must have the same number of elements as rxnsToAdd.rxns'; -0435 dispEM(EM); -0436 end -0437 %Fill with standard if it doesn't exist -0438 if ~isfield(newModel,'rxnFrom') -0439 newModel.rxnFrom=largeFiller; -0440 end -0441 newModel.rxnFrom=[newModel.rxnFrom;rxnsToAdd.rxnFrom(:)]; -0442 else -0443 %Fill with standard if it doesn't exist -0444 if isfield(newModel,'rxnFrom') -0445 newModel.rxnFrom=[newModel.rxnFrom;filler]; -0446 end -0447 end -0448 -0449 if isfield(rxnsToAdd,'rxnNotes') -0450 rxnsToAdd.rxnNotes=convertCharArray(rxnsToAdd.rxnNotes); -0451 if numel(rxnsToAdd.rxnNotes)~=nRxns -0452 EM='rxnsToAdd.rxnNotes must have the same number of elements as rxnsToAdd.rxns'; -0453 dispEM(EM); -0454 end -0455 %Fill with standard if it doesn't exist -0456 if ~isfield(newModel,'rxnNotes') -0457 newModel.rxnNotes=largeFiller; -0458 end -0459 newModel.rxnNotes=[newModel.rxnNotes;rxnsToAdd.rxnNotes(:)]; -0460 else -0461 %Fill with standard if it doesn't exist -0462 if isfield(newModel,'rxnNotes') -0463 newModel.rxnNotes=[newModel.rxnNotes;filler]; -0464 end -0465 end -0466 -0467 if isfield(rxnsToAdd,'rxnReferences') -0468 rxnsToAdd.rxnReferences=convertCharArray(rxnsToAdd.rxnReferences); -0469 if numel(rxnsToAdd.rxnReferences)~=nRxns -0470 EM='rxnsToAdd.rxnReferences must have the same number of elements as rxnsToAdd.rxns'; -0471 dispEM(EM); -0472 end -0473 %Fill with standard if it doesn't exist -0474 if ~isfield(newModel,'rxnReferences') -0475 newModel.rxnReferences=largeFiller; -0476 end -0477 newModel.rxnReferences=[newModel.rxnReferences;rxnsToAdd.rxnReferences(:)]; -0478 else -0479 %Fill with standard if it doesn't exist -0480 if isfield(newModel,'rxnReferences') -0481 newModel.rxnReferences=[newModel.rxnReferences;filler]; -0482 end -0483 end -0484 -0485 if isfield(rxnsToAdd,'pwys') -0486 rxnsToAdd.pwys=convertCharArray(rxnsToAdd.pwys); -0487 if numel(rxnsToAdd.pwys)~=nRxns -0488 EM='rxnsToAdd.pwys must have the same number of elements as rxnsToAdd.rxns'; -0489 dispEM(EM); -0490 end -0491 %Fill with standard if it doesn't exist -0492 if ~isfield(newModel,'pwys') -0493 newModel.pwys=largeFiller; -0494 end -0495 newModel.pwys=[newModel.pwys;rxnsToAdd.pwys(:)]; -0496 else -0497 %Fill with standard if it doesn't exist -0498 if isfield(newModel,'pwys') -0499 newModel.pwys=[newModel.pwys;filler]; -0500 end -0501 end -0502 -0503 if isfield(rxnsToAdd,'rxnConfidenceScores') -0504 if numel(rxnsToAdd.rxnConfidenceScores)~=nRxns -0505 EM='rxnsToAdd.rxnConfidenceScores must have the same number of elements as rxnsToAdd.rxns'; -0506 dispEM(EM); -0507 end -0508 %Fill with standard if it doesn't exist -0509 if ~isfield(newModel,'rxnConfidenceScores') -0510 newModel.rxnConfidenceScores=NaN(nOldRxns,1); -0511 end -0512 newModel.rxnConfidenceScores=[newModel.rxnConfidenceScores;rxnsToAdd.rxnConfidenceScores(:)]; -0513 else -0514 %Fill with standard if it doesn't exist -0515 if isfield(newModel,'rxnConfidenceScores') -0516 newModel.rxnConfidenceScores=[newModel.rxnConfidenceScores;NaN(nRxns,1)]; -0517 end -0518 end -0519 -0520 if isfield(rxnsToAdd,'rxnDeltaG') -0521 if numel(rxnsToAdd.rxnDeltaG)~=nRxns -0522 EM='rxnsToAdd.rxnDeltaG must have the same number of elements as rxnsToAdd.rxns'; -0523 dispEM(EM); -0524 end -0525 %Fill with standard if it doesn't exist -0526 if ~isfield(newModel,'rxnDeltaG') -0527 newModel.rxnDeltaG=NaN(nOldRxns,1); -0528 end -0529 newModel.rxnDeltaG=[newModel.rxnDeltaG;rxnsToAdd.rxnDeltaG(:)]; -0530 else -0531 %Fill with standard if it doesn't exist -0532 if isfield(newModel,'rxnDeltaG') -0533 newModel.rxnDeltaG=[newModel.rxnDeltaG;NaN(nRxns,1)]; -0534 end -0535 end -0536 -0537 -0538 %***Start parsing the equations and adding the info to the S matrix The -0539 %mets are matched to model.mets -0540 if eqnType==1 -0541 [I, J]=ismember(mets,model.mets); -0542 if ~all(I) -0543 if allowNewMets==true || ischar(allowNewMets) -0544 %Add the new mets -0545 metsToAdd.mets=mets(~I); -0546 metsToAdd.metNames=metsToAdd.mets; -0547 metsToAdd.compartments=compartment; -0548 if ischar(allowNewMets) -0549 newModel=addMets(newModel,metsToAdd,true,allowNewMets); -0550 else -0551 newModel=addMets(newModel,metsToAdd,true); -0552 end -0553 else -0554 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?'; -0555 dispEM(EM); -0556 end -0557 end -0558 %Calculate the indexes of the metabolites and add the info -0559 metIndexes=J; -0560 metIndexes(~I)=numel(newModel.mets)-sum(~I)+1:numel(newModel.mets); -0561 end -0562 -0563 %Do some stuff that is the same for eqnType=2 and eqnType=3 -0564 if eqnType==2 || eqnType==3 -0565 %For later.. -0566 t2=strcat(model.metNames,'***',model.comps(model.metComps)); -0567 end -0568 -0569 %The mets are matched to model.metNames and assigned to "compartment" -0570 if eqnType==2 -0571 %%Check that the metabolite names aren't present in the same -0572 %%compartment. -0573 %Not the neatest way maybe.. -0574 t1=strcat(mets,'***',compartment); -0575 [I, J]=ismember(t1,t2); -0576 -0577 if ~all(I) -0578 if allowNewMets==true || ischar(allowNewMets) -0579 %Add the new mets -0580 metsToAdd.metNames=mets(~I); -0581 metsToAdd.compartments=compartment; -0582 if ischar(allowNewMets) -0583 newModel=addMets(newModel,metsToAdd,true,allowNewMets); -0584 else -0585 newModel=addMets(newModel,metsToAdd,true); -0586 end -0587 else -0588 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'; -0589 dispEM(EM); -0590 end -0591 end -0592 -0593 %Calculate the indexes of the metabolites -0594 metIndexes=J; -0595 metIndexes(~I)=numel(newModel.mets)-sum(~I)+1:numel(newModel.mets); -0596 end -0597 -0598 %The equations are on the form metNames[compName] -0599 if eqnType==3 -0600 %Parse the metabolite names -0601 metNames=cell(numel(mets),1); -0602 compartments=metNames; -0603 for i=1:numel(mets) -0604 starts=max(strfind(mets{i},'[')); -0605 ends=max(strfind(mets{i},']')); -0606 -0607 %Check that the formatting is correct -0608 if isempty(starts) || isempty(ends) || ends<numel(mets{i}) -0609 EM=['The metabolite ' mets{i} ' is not correctly formatted for eqnType=3']; -0610 dispEM(EM); -0611 end -0612 -0613 %Check that the compartment is correct -0614 compartments{i}=mets{i}(starts+1:ends-1); -0615 I=ismember(compartments(i),newModel.comps); -0616 if ~I -0617 EM=['The metabolite ' mets{i} ' has a compartment that is not in model.comps']; -0618 dispEM(EM); -0619 end -0620 metNames{i}=mets{i}(1:starts-1); -0621 end -0622 -0623 %Check if the metabolite exists already -0624 t1=strcat(metNames,'***',compartments); -0625 [I, J]=ismember(t1,t2); -0626 -0627 if ~all(I) -0628 if allowNewMets==true | ischar(allowNewMets) -0629 %Add the new mets -0630 metsToAdd.metNames=metNames(~I); -0631 metsToAdd.compartments=compartments(~I); -0632 if ischar(allowNewMets) -0633 newModel=addMets(newModel,metsToAdd,true,allowNewMets); -0634 else -0635 newModel=addMets(newModel,metsToAdd,true); -0636 end -0637 else -0638 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'; -0639 dispEM(EM); -0640 end -0641 end -0642 -0643 %Calculate the indexes of the metabolites -0644 metIndexes=J; -0645 metIndexes(~I)=numel(newModel.mets)-sum(~I)+1:numel(newModel.mets); -0646 end -0647 -0648 %Add the info to the stoichiometric matrix -0649 newModel.S=[newModel.S sparse(size(newModel.S,1),nRxns)]; -0650 -0651 for i=1:nRxns -0652 newModel.S(metIndexes,nOldRxns+i)=S(:,i); -0653 %Parse the grRules and check whether all genes in grRules appear in -0654 %genes -0655 if isfield(newModel,'grRules') -0656 rule=newModel.grRules{nOldRxns+i}; -0657 rule=strrep(rule,'(',''); -0658 rule=strrep(rule,')',''); -0659 rule=strrep(rule,' or ',' '); -0660 rule=strrep(rule,' and ',' '); -0661 genes=regexp(rule,' ','split'); -0662 [I, J]=ismember(genes,newModel.genes); -0663 if ~all(I) && any(rule) -0664 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']; -0665 dispEM(EM); -0666 end -0667 end -0668 end +0426 if isfield(newModel,'rxnComps') +0427 newModel.rxnComps=[newModel.rxnComps;ones(nRxns,1)]; +0428 %fprintf('NOTE: The added reactions will be assigned to the first +0429 %compartment\n'); +0430 end +0431 end +0432 if isfield(rxnsToAdd,'grRules') +0433 rxnsToAdd.grRules=convertCharArray(rxnsToAdd.grRules); +0434 if numel(rxnsToAdd.grRules)~=nRxns +0435 EM='rxnsToAdd.grRules must have the same number of elements as rxnsToAdd.rxns'; +0436 dispEM(EM); +0437 end +0438 %Fill with standard if it doesn't exist +0439 if ~isfield(newModel,'grRules') +0440 newModel.grRules=largeFiller; +0441 end +0442 newModel.grRules=[newModel.grRules;rxnsToAdd.grRules(:)]; +0443 else +0444 %Fill with standard if it doesn't exist +0445 if isfield(newModel,'grRules') +0446 newModel.grRules=[newModel.grRules;filler]; +0447 end +0448 end +0449 +0450 if isfield(rxnsToAdd,'rxnFrom') +0451 rxnsToAdd.rxnFrom=convertCharArray(rxnsToAdd.rxnFrom); +0452 if numel(rxnsToAdd.rxnFrom)~=nRxns +0453 EM='rxnsToAdd.rxnFrom must have the same number of elements as rxnsToAdd.rxns'; +0454 dispEM(EM); +0455 end +0456 %Fill with standard if it doesn't exist +0457 if ~isfield(newModel,'rxnFrom') +0458 newModel.rxnFrom=largeFiller; +0459 end +0460 newModel.rxnFrom=[newModel.rxnFrom;rxnsToAdd.rxnFrom(:)]; +0461 else +0462 %Fill with standard if it doesn't exist +0463 if isfield(newModel,'rxnFrom') +0464 newModel.rxnFrom=[newModel.rxnFrom;filler]; +0465 end +0466 end +0467 +0468 if isfield(rxnsToAdd,'rxnNotes') +0469 rxnsToAdd.rxnNotes=convertCharArray(rxnsToAdd.rxnNotes); +0470 if numel(rxnsToAdd.rxnNotes)~=nRxns +0471 EM='rxnsToAdd.rxnNotes must have the same number of elements as rxnsToAdd.rxns'; +0472 dispEM(EM); +0473 end +0474 %Fill with standard if it doesn't exist +0475 if ~isfield(newModel,'rxnNotes') +0476 newModel.rxnNotes=largeFiller; +0477 end +0478 newModel.rxnNotes=[newModel.rxnNotes;rxnsToAdd.rxnNotes(:)]; +0479 else +0480 %Fill with standard if it doesn't exist +0481 if isfield(newModel,'rxnNotes') +0482 newModel.rxnNotes=[newModel.rxnNotes;filler]; +0483 end +0484 end +0485 +0486 if isfield(rxnsToAdd,'rxnReferences') +0487 rxnsToAdd.rxnReferences=convertCharArray(rxnsToAdd.rxnReferences); +0488 if numel(rxnsToAdd.rxnReferences)~=nRxns +0489 EM='rxnsToAdd.rxnReferences must have the same number of elements as rxnsToAdd.rxns'; +0490 dispEM(EM); +0491 end +0492 %Fill with standard if it doesn't exist +0493 if ~isfield(newModel,'rxnReferences') +0494 newModel.rxnReferences=largeFiller; +0495 end +0496 newModel.rxnReferences=[newModel.rxnReferences;rxnsToAdd.rxnReferences(:)]; +0497 else +0498 %Fill with standard if it doesn't exist +0499 if isfield(newModel,'rxnReferences') +0500 newModel.rxnReferences=[newModel.rxnReferences;filler]; +0501 end +0502 end +0503 +0504 if isfield(rxnsToAdd,'pwys') +0505 rxnsToAdd.pwys=convertCharArray(rxnsToAdd.pwys); +0506 if numel(rxnsToAdd.pwys)~=nRxns +0507 EM='rxnsToAdd.pwys must have the same number of elements as rxnsToAdd.rxns'; +0508 dispEM(EM); +0509 end +0510 %Fill with standard if it doesn't exist +0511 if ~isfield(newModel,'pwys') +0512 newModel.pwys=largeFiller; +0513 end +0514 newModel.pwys=[newModel.pwys;rxnsToAdd.pwys(:)]; +0515 else +0516 %Fill with standard if it doesn't exist +0517 if isfield(newModel,'pwys') +0518 newModel.pwys=[newModel.pwys;filler]; +0519 end +0520 end +0521 +0522 if isfield(rxnsToAdd,'rxnConfidenceScores') +0523 if numel(rxnsToAdd.rxnConfidenceScores)~=nRxns +0524 EM='rxnsToAdd.rxnConfidenceScores must have the same number of elements as rxnsToAdd.rxns'; +0525 dispEM(EM); +0526 end +0527 %Fill with standard if it doesn't exist +0528 if ~isfield(newModel,'rxnConfidenceScores') +0529 newModel.rxnConfidenceScores=NaN(nOldRxns,1); +0530 end +0531 newModel.rxnConfidenceScores=[newModel.rxnConfidenceScores;rxnsToAdd.rxnConfidenceScores(:)]; +0532 else +0533 %Fill with standard if it doesn't exist +0534 if isfield(newModel,'rxnConfidenceScores') +0535 newModel.rxnConfidenceScores=[newModel.rxnConfidenceScores;NaN(nRxns,1)]; +0536 end +0537 end +0538 +0539 if isfield(rxnsToAdd,'rxnDeltaG') +0540 if numel(rxnsToAdd.rxnDeltaG)~=nRxns +0541 EM='rxnsToAdd.rxnDeltaG must have the same number of elements as rxnsToAdd.rxns'; +0542 dispEM(EM); +0543 end +0544 %Fill with standard if it doesn't exist +0545 if ~isfield(newModel,'rxnDeltaG') +0546 newModel.rxnDeltaG=NaN(nOldRxns,1); +0547 end +0548 newModel.rxnDeltaG=[newModel.rxnDeltaG;rxnsToAdd.rxnDeltaG(:)]; +0549 else +0550 %Fill with standard if it doesn't exist +0551 if isfield(newModel,'rxnDeltaG') +0552 newModel.rxnDeltaG=[newModel.rxnDeltaG;NaN(nRxns,1)]; +0553 end +0554 end +0555 +0556 +0557 %***Start parsing the equations and adding the info to the S matrix The +0558 %mets are matched to model.mets +0559 if eqnType==1 +0560 [I, J]=ismember(mets,model.mets); +0561 if ~all(I) +0562 if allowNewMets==true || ischar(allowNewMets) +0563 %Add the new mets +0564 metsToAdd.mets=mets(~I); +0565 metsToAdd.metNames=metsToAdd.mets; +0566 metsToAdd.compartments=compartment; +0567 if ischar(allowNewMets) +0568 newModel=addMets(newModel,metsToAdd,true,allowNewMets); +0569 else +0570 newModel=addMets(newModel,metsToAdd,true); +0571 end +0572 else +0573 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?'; +0574 dispEM(EM); +0575 end +0576 end +0577 %Calculate the indexes of the metabolites and add the info +0578 metIndexes=J; +0579 metIndexes(~I)=numel(newModel.mets)-sum(~I)+1:numel(newModel.mets); +0580 end +0581 +0582 %Do some stuff that is the same for eqnType=2 and eqnType=3 +0583 if eqnType==2 || eqnType==3 +0584 %For later.. +0585 t2=strcat(model.metNames,'***',model.comps(model.metComps)); +0586 end +0587 +0588 %The mets are matched to model.metNames and assigned to "compartment" +0589 if eqnType==2 +0590 %%Check that the metabolite names aren't present in the same +0591 %%compartment. +0592 %Not the neatest way maybe.. +0593 t1=strcat(mets,'***',compartment); +0594 [I, J]=ismember(t1,t2); +0595 +0596 if ~all(I) +0597 if allowNewMets==true || ischar(allowNewMets) +0598 %Add the new mets +0599 metsToAdd.metNames=mets(~I); +0600 metsToAdd.compartments=compartment; +0601 if ischar(allowNewMets) +0602 newModel=addMets(newModel,metsToAdd,true,allowNewMets); +0603 else +0604 newModel=addMets(newModel,metsToAdd,true); +0605 end +0606 else +0607 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'; +0608 dispEM(EM); +0609 end +0610 end +0611 +0612 %Calculate the indexes of the metabolites +0613 metIndexes=J; +0614 metIndexes(~I)=numel(newModel.mets)-sum(~I)+1:numel(newModel.mets); +0615 end +0616 +0617 %The equations are on the form metNames[compName] +0618 if eqnType==3 +0619 %Parse the metabolite names +0620 metNames=cell(numel(mets),1); +0621 compartments=metNames; +0622 for i=1:numel(mets) +0623 starts=max(strfind(mets{i},'[')); +0624 ends=max(strfind(mets{i},']')); +0625 +0626 %Check that the formatting is correct +0627 if isempty(starts) || isempty(ends) || ends<numel(mets{i}) +0628 EM=['The metabolite ' mets{i} ' is not correctly formatted for eqnType=3']; +0629 dispEM(EM); +0630 end +0631 +0632 %Check that the compartment is correct +0633 compartments{i}=mets{i}(starts+1:ends-1); +0634 I=ismember(compartments(i),newModel.comps); +0635 if ~I +0636 EM=['The metabolite ' mets{i} ' has a compartment that is not in model.comps']; +0637 dispEM(EM); +0638 end +0639 metNames{i}=mets{i}(1:starts-1); +0640 end +0641 +0642 %Check if the metabolite exists already +0643 t1=strcat(metNames,'***',compartments); +0644 [I, J]=ismember(t1,t2); +0645 +0646 if ~all(I) +0647 if allowNewMets==true | ischar(allowNewMets) +0648 %Add the new mets +0649 metsToAdd.metNames=metNames(~I); +0650 metsToAdd.compartments=compartments(~I); +0651 if ischar(allowNewMets) +0652 newModel=addMets(newModel,metsToAdd,true,allowNewMets); +0653 else +0654 newModel=addMets(newModel,metsToAdd,true); +0655 end +0656 else +0657 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'; +0658 dispEM(EM); +0659 end +0660 end +0661 +0662 %Calculate the indexes of the metabolites +0663 metIndexes=J; +0664 metIndexes(~I)=numel(newModel.mets)-sum(~I)+1:numel(newModel.mets); +0665 end +0666 +0667 %Add the info to the stoichiometric matrix +0668 newModel.S=[newModel.S sparse(size(newModel.S,1),nRxns)]; 0669 -0670 %Make temporary minimal model structure with only new rxns, to parse to -0671 %standardizeGrRules -0672 newRxnsModel.genes=newModel.genes; -0673 newRxnsModel.grRules=newModel.grRules(length(model.rxns)+1:end); -0674 newRxnsModel.rxns=newModel.rxns(length(model.rxns)+1:end); -0675 -0676 %Fix grRules and reconstruct rxnGeneMat -0677 [grRules,rxnGeneMat] = standardizeGrRules(newRxnsModel,true); -0678 newModel.rxnGeneMat = [newModel.rxnGeneMat; rxnGeneMat]; -0679 newModel.grRules = [newModel.grRules(1:nOldRxns); grRules]; -0680 end +0670 for i=1:nRxns +0671 newModel.S(metIndexes,nOldRxns+i)=S(:,i); +0672 %Parse the grRules and check whether all genes in grRules appear in +0673 %genes +0674 if isfield(newModel,'grRules') +0675 rule=newModel.grRules{nOldRxns+i}; +0676 rule=strrep(rule,'(',''); +0677 rule=strrep(rule,')',''); +0678 rule=strrep(rule,' or ',' '); +0679 rule=strrep(rule,' and ',' '); +0680 genes=regexp(rule,' ','split'); +0681 [I, J]=ismember(genes,newModel.genes); +0682 if ~all(I) && any(rule) +0683 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']; +0684 dispEM(EM); +0685 end +0686 end +0687 end +0688 +0689 %Make temporary minimal model structure with only new rxns, to parse to +0690 %standardizeGrRules +0691 newRxnsModel.genes=newModel.genes; +0692 newRxnsModel.grRules=newModel.grRules(length(model.rxns)+1:end); +0693 newRxnsModel.rxns=newModel.rxns(length(model.rxns)+1:end); +0694 +0695 %Fix grRules and reconstruct rxnGeneMat +0696 [grRules,rxnGeneMat] = standardizeGrRules(newRxnsModel,true); +0697 newModel.rxnGeneMat = [newModel.rxnGeneMat; rxnGeneMat]; +0698 newModel.grRules = [newModel.grRules(1:nOldRxns); grRules]; +0699 end
    Generated by m2html © 2005
    \ No newline at end of file diff --git a/doc/core/addTransport.html b/doc/core/addTransport.html index 98b65338..21b58cbe 100644 --- a/doc/core/addTransport.html +++ b/doc/core/addTransport.html @@ -202,45 +202,49 @@

    SOURCE CODE ^end 0136 if isfield(model,'subSystems') -0137 ssFiller=filler; -0138 if isRev==1 -0139 ssFiller(:)={{['Transport between ' fromComp ' and ' toComps{i}]}}; -0140 else -0141 ssFiller(:)={{['Transport from ' fromComp ' to ' toComps{i}]}}; -0142 end -0143 model.subSystems=[model.subSystems;ssFiller]; -0144 end -0145 if isfield(model,'grRules') -0146 model.grRules=[model.grRules;filler]; -0147 end -0148 if isfield(model,'rxnFrom') -0149 model.rxnFrom=[model.rxnFrom;filler]; -0150 end -0151 if isfield(model,'rxnMiriams') -0152 model.rxnMiriams=[model.rxnMiriams;cell(nRxns,1)]; -0153 end -0154 if isfield(model,'rxnComps') -0155 model.rxnComps=[model.rxnComps;ones(nRxns,1)]; -0156 fprintf('NOTE: The added transport reactions will be added to the first compartment\n'); +0137 isNested = any(cellfun(@(x) iscell(x), model.subSystems)); +0138 ssFiller = filler; +0139 if isRev==1 +0140 ssFiller(:) = {['Transport between ' fromComp ' and ' toComps{i}]}; +0141 else +0142 ssFiller(:) = {['Transport from ' fromComp ' to ' toComps{i}]}; +0143 end +0144 if isNested +0145 ssFiller = cellfun(@(x) {x}, ssFiller, 'uni', 0); +0146 end +0147 model.subSystems=[model.subSystems;ssFiller]; +0148 end +0149 if isfield(model,'grRules') +0150 model.grRules=[model.grRules;filler]; +0151 end +0152 if isfield(model,'rxnFrom') +0153 model.rxnFrom=[model.rxnFrom;filler]; +0154 end +0155 if isfield(model,'rxnMiriams') +0156 model.rxnMiriams=[model.rxnMiriams;cell(nRxns,1)]; 0157 end -0158 if isfield(model,'rxnGeneMat') -0159 model.rxnGeneMat=[model.rxnGeneMat;sparse(nRxns,numel(model.genes))]; -0160 end -0161 if isfield(model,'rxnNotes') -0162 model.rxnNotes=[model.rxnNotes;filler]; -0163 end -0164 if isfield(model,'rxnReferences') -0165 model.rxnReferences=[model.rxnReferences;filler]; -0166 end -0167 if isfield(model,'rxnConfidenceScores') -0168 model.rxnConfidenceScores=[model.rxnConfidenceScores;ones(nRxns,1)]; -0169 end -0170 if isfield(model,'rxnDeltaG') -0171 model.rxnDeltaG=[model.rxnDeltaG;zeros(nRxns,1)]; -0172 end -0173 addedRxns = [addedRxns; addedRxnsID]; -0174 end -0175 end +0158 if isfield(model,'rxnComps') +0159 model.rxnComps=[model.rxnComps;ones(nRxns,1)]; +0160 fprintf('NOTE: The added transport reactions will be added to the first compartment\n'); +0161 end +0162 if isfield(model,'rxnGeneMat') +0163 model.rxnGeneMat=[model.rxnGeneMat;sparse(nRxns,numel(model.genes))]; +0164 end +0165 if isfield(model,'rxnNotes') +0166 model.rxnNotes=[model.rxnNotes;filler]; +0167 end +0168 if isfield(model,'rxnReferences') +0169 model.rxnReferences=[model.rxnReferences;filler]; +0170 end +0171 if isfield(model,'rxnConfidenceScores') +0172 model.rxnConfidenceScores=[model.rxnConfidenceScores;ones(nRxns,1)]; +0173 end +0174 if isfield(model,'rxnDeltaG') +0175 model.rxnDeltaG=[model.rxnDeltaG;zeros(nRxns,1)]; +0176 end +0177 addedRxns = [addedRxns; addedRxnsID]; +0178 end +0179 end
    Generated by m2html © 2005
    \ No newline at end of file diff --git a/doc/core/checkModelStruct.html b/doc/core/checkModelStruct.html index 920a7c8b..a25d6ed4 100644 --- a/doc/core/checkModelStruct.html +++ b/doc/core/checkModelStruct.html @@ -234,11 +234,11 @@

    SOURCE CODE ^end 0176 end 0177 if isfield(model,'subSystems') -0178 for i=1:numel(model.subSystems) -0179 if ~iscell(model.subSystems{i,1}) -0180 EM='The "subSystems" field must be a cell array'; -0181 dispEM(EM,throwErrors); -0182 end +0178 isNested = any(cellfun(@(x) iscell(x), model.subSystems)); +0179 isCellStr = any(cellfun(@(x) ischar(x), model.subSystems)); +0180 if ~xor(isNested,isCellStr) +0181 EM='The "subSystems" field must be a cell array of chars, *or* a cell array of cell arrays of chars'; +0182 dispEM(EM,throwErrors); 0183 end 0184 end 0185 if isfield(model,'eccodes') diff --git a/doc/core/compareMultipleModels.html b/doc/core/compareMultipleModels.html index d4b35e1c..9a36fa00 100644 --- a/doc/core/compareMultipleModels.html +++ b/doc/core/compareMultipleModels.html @@ -178,24 +178,24 @@

    SOURCE CODE ^'*** Done \n\n') 0093 0094 -0095 %% Flatten models' subSystems field -0096 % Convert from cell array of cells to cell array of strings -0097 % NOTE: this function currently only recognizes one subSystem per reaction; -0098 % additional subSystems will be ignored! -0099 for i = 1:numel(models) -0100 cells = cellfun(@iscell,models{i}.subSystems); -0101 models{i}.subSystems(cells) = cellfun(@(s) s{1}, models{i}.subSystems(cells), 'UniformOutput', false); -0102 end -0103 -0104 -0105 %% Compare models structure & function based on high-dimensional methods -0106 % Compare number of reactions in each subsystem in each model using a heatmap -0107 field = 'subSystems'; -0108 fprintf('\n Comparing subsystem utilization \n') -0109 if any(~cellfun(@(m) isfield(m,field),models)) -0110 fprintf('\nWARNING: At least one model does not contain the field "subSystems". \n') -0111 fprintf(' Skipping subsystem comparison. \n\n') -0112 else +0095 %% Compare models structure & function based on high-dimensional methods +0096 % Compare number of reactions in each subsystem in each model using a heatmap +0097 field = 'subSystems'; +0098 fprintf('\n Comparing subsystem utilization \n') +0099 if any(~cellfun(@(m) isfield(m,field),models)) +0100 fprintf('\nWARNING: At least one model does not contain the field "subSystems". \n') +0101 fprintf(' Skipping subsystem comparison. \n\n') +0102 else +0103 %% Flatten model subSystems field +0104 % Convert from cell array of cells to cell array of strings +0105 % NOTE: this function currently only recognizes one subSystem per reaction; +0106 % additional subSystems will be ignored! +0107 for i = 1:numel(models) +0108 if any(cellfun(@(x) iscell(x), models{i}.subSystems)); +0109 cells = cellfun(@iscell,models{i}.subSystems); +0110 models{i}.subSystems(cells) = cellfun(@(s) s{1}, models{i}.subSystems(cells), 'UniformOutput', false); +0111 end +0112 end 0113 [id,compMat] = compareModelField(models,field); 0114 compStruct.subsystems.ID = id; 0115 compStruct.subsystems.matrix = compMat; diff --git a/doc/core/findRAVENroot.html b/doc/core/findRAVENroot.html index a3a1cf38..df783a87 100644 --- a/doc/core/findRAVENroot.html +++ b/doc/core/findRAVENroot.html @@ -28,7 +28,7 @@

    SYNOPSIS ^DESCRIPTION ^

     findRAVENroot
    -   Finds the root of the RAVEN directory, by searching for the path to
    +   Finds the root of the RAVEN directory, first by  by searching for the path to
        RAVEN2.png. Can also record the current directory, in case a function will
        use the ravenPath to navigate to a precise folder, and it should return to
        the previous directory afterwards. See e.g. optimizeProb calling glpk.
    @@ -48,27 +48,31 @@

    CROSS-REFERENCE INFORMATION ^
 <h2><a name=SOURCE CODE ^

    0001 function [ravenPath, prevDir] = findRAVENroot()
     0002 % findRAVENroot
    -0003 %   Finds the root of the RAVEN directory, by searching for the path to
    +0003 %   Finds the root of the RAVEN directory, first by  by searching for the path to
     0004 %   RAVEN2.png. Can also record the current directory, in case a function will
     0005 %   use the ravenPath to navigate to a precise folder, and it should return to
     0006 %   the previous directory afterwards. See e.g. optimizeProb calling glpk.
     0007 
     0008 ST=dbstack('-completenames');
     0009 prevDir = pwd();
    -0010 ravenPath = ST(strcmp({ST.name},'findRAVENroot')).file;
    -0011 rootFound = 0;
    -0012 while rootFound == 0
    -0013     isRoot = isfile(fullfile(ravenPath,'RAVEN2.png'));
    -0014     if isRoot
    -0015         rootFound = 1;
    -0016     else
    -0017         ravenPathOld = ravenPath;
    -0018         ravenPath = fileparts(ravenPath);
    -0019         if strcmp(ravenPathOld,ravenPath)
    -0020             error('Cannot find the RAVEN root directory. Make sure you have not removed the RAVEN2.png file from your RAVEN installation.')
    -0021         end
    -0022     end
    -0023 end
    +0010 if ispref('RAVEN','ravenPath') +0011 ravenPath = getpref('RAVEN','ravenPath'); +0012 else +0013 ravenPath = ST(strcmp({ST.name},'findRAVENroot')).file; +0014 rootFound = 0; +0015 while rootFound == 0 +0016 isRoot = isfile(fullfile(ravenPath,'RAVEN2.png')); +0017 if isRoot +0018 rootFound = 1; +0019 else +0020 ravenPathOld = ravenPath; +0021 ravenPath = fileparts(ravenPath); +0022 if strcmp(ravenPathOld,ravenPath) +0023 error('Cannot find the RAVEN root directory. Make sure you have not removed the RAVEN2.png file from your RAVEN installation.') +0024 end +0025 end +0026 end +0027 end
    Generated by m2html © 2005
    \ No newline at end of file diff --git a/doc/core/fitTasks.html b/doc/core/fitTasks.html index 3a45616c..03cc8895 100644 --- a/doc/core/fitTasks.html +++ b/doc/core/fitTasks.html @@ -62,7 +62,7 @@

    DESCRIPTION ^CROSS-REFERENCE INFORMATION ^

    @@ -113,7 +113,7 @@

    SOURCE CODE ^% the result. 0035 % 0036 % Usage: [outModel, addedRxns]=fitTasks(model,refModel,inputFile,printOutput,... -0037 % rxnScores,taskStructure,params) +0037 % rxnScores,taskStructure) 0038 0039 if nargin<4 0040 printOutput=true; @@ -127,286 +127,283 @@

    SOURCE CODE ^if nargin<6 0049 taskStructure=[]; 0050 end -0051 if nargin<7 -0052 params=[]; -0053 end -0054 -0055 if isempty(taskStructure) && ~isfile(inputFile) -0056 error('Task file %s cannot be found',string(inputFile)); -0057 end -0058 -0059 if strcmpi(model.id,refModel.id) -0060 fprintf('NOTE: The model and reference model have the same IDs. The ID for the reference model was set to "refModel" in order to keep track of the origin of reactions.\n'); -0061 refModel.id='refModel'; -0062 end -0063 -0064 if any(rxnScores>=0) -0065 EM='Only negative values are allowed in rxnScores'; -0066 dispEM(EM); -0067 end -0068 -0069 %Prepare the input models a little -0070 model.b=zeros(numel(model.mets),2); -0071 modelMets=upper(strcat(model.metNames,'[',model.comps(model.metComps),']')); -0072 %This is the mets in the reference model. Used if the tasks involve -0073 %metabolites that doesn't exist in the model -0074 largeModelMets=upper(strcat(refModel.metNames,'[',refModel.comps(refModel.metComps),']')); -0075 -0076 if ~isfield(model,'unconstrained') -0077 EM='Exchange metabolites should normally not be removed from the model when using checkTasks. Inputs and outputs are defined in the task file instead. Use importModel(file,false) to import a model with exchange metabolites remaining'; -0078 dispEM(EM,false); -0079 end -0080 -0081 if isempty(taskStructure) -0082 taskStructure=parseTaskList(inputFile); -0083 end -0084 -0085 tModel=model; -0086 addedRxns=false(numel(refModel.rxns),numel(taskStructure)); -0087 supressWarnings=false; -0088 nAdded=0; -0089 for i=1:numel(taskStructure) -0090 if ~taskStructure(i).shouldFail -0091 %Set the inputs -0092 if ~isempty(taskStructure(i).inputs) -0093 [I, J]=ismember(upper(taskStructure(i).inputs),modelMets); -0094 K=ismember(upper(taskStructure(i).inputs),'ALLMETS'); -0095 L=~cellfun('isempty',strfind(upper(taskStructure(i).inputs),'ALLMETSIN')); -0096 %Check that all metabolites are either real metabolites or -0097 %ALLMETS/ALLMETSIN -0098 goodMets=I|K|L; -0099 if ~all(goodMets) -0100 %Not all of the inputs could be found in the small model. -0101 %Check if they exist in the large model -0102 [found, metMatch]=ismember(upper(taskStructure(i).inputs(~goodMets)),largeModelMets); -0103 if ~all(found) -0104 EM=['Could not find all inputs in "[' taskStructure(i).id '] ' taskStructure(i).description '" in either model']; -0105 disp(EM); -0106 else -0107 %Otherwise add them to the model -0108 met.metNames=refModel.metNames(metMatch); -0109 met.compartments=refModel.comps(refModel.metComps(metMatch)); -0110 -0111 %Add the metabolite both to the base model and the -0112 %model used in the current task -0113 model=addMets(model,met); -0114 tModel=addMets(tModel,met); -0115 modelMets=[modelMets;upper(taskStructure(i).inputs(~goodMets))]; -0116 end -0117 -0118 %By now the indexes might be getting a bit confusing, but -0119 %this is to update the indexes of the "real" metabolites to -0120 %point to the newly added ones -0121 I(~goodMets)=true; %All the bad ones are fixed at this stage -0122 J(~goodMets)=numel(modelMets)-numel(metMatch)+1:numel(modelMets); -0123 end -0124 if numel(J(I))~=numel(unique(J(I))) -0125 EM=['The constraints on some input(s) in "[' taskStructure(i).id '] ' taskStructure(i).description '" are defined more than one time']; -0126 dispEM(EM); -0127 end -0128 %If all metabolites should be added -0129 if any(K) -0130 %Check if ALLMETS is the first metabolite. Otherwise print -0131 %a warning since it will write over any other constraints -0132 %that are set -0133 if K(1)==0 -0134 EM=['ALLMETS is used as an input in "[' taskStructure(i).id '] ' taskStructure(i).description '" but it it not the first metabolite in the list. Constraints defined for the metabolites before it will be over-written']; -0135 dispEM(EM,false); -0136 end -0137 %Use the first match of ALLMETS. There should only be one, -0138 %but still.. -0139 tModel.b(:,1)=taskStructure(i).UBin(find(K,1))*-1; -0140 end -0141 %If metabolites in a specific compartment should be used -0142 if any(L) -0143 L=find(L); -0144 for j=1:numel(L) -0145 %The compartment defined -0146 compartment=upper(taskStructure(i).inputs{L(j)}(11:end-1)); -0147 %Check if it exists in the model -0148 C=find(ismember(upper(model.comps),compartment)); -0149 if any(C) -0150 %Match to metabolites -0151 tModel.b(model.metComps==C,1)=taskStructure(i).UBin(L(j))*-1; -0152 else -0153 EM=['The compartment defined for ALLMETSIN in "[' taskStructure(i).id '] ' taskStructure(i).description '" does not exist']; -0154 dispEM(EM); -0155 end -0156 end -0157 end -0158 %Then add the normal constraints -0159 if any(J(I)) -0160 tModel.b(J(I),1)=taskStructure(i).UBin(I)*-1; -0161 tModel.b(J(I),2)=taskStructure(i).LBin(I)*-1; -0162 end -0163 end -0164 %Set the outputs -0165 if ~isempty(taskStructure(i).outputs) -0166 [I, J]=ismember(upper(taskStructure(i).outputs),modelMets); -0167 K=ismember(upper(taskStructure(i).outputs),'ALLMETS'); -0168 L=~cellfun('isempty',strfind(upper(taskStructure(i).outputs),'ALLMETSIN')); -0169 %Check that all metabolites are either real metabolites or -0170 %ALLMETS/ALLMETSIN -0171 goodMets=I|K|L; -0172 if ~all(goodMets) -0173 %Not all of the outputs could be found in the small model. -0174 %Check if they exist in the large model -0175 [found, metMatch]=ismember(upper(taskStructure(i).outputs(~goodMets)),largeModelMets); -0176 if ~all(found) -0177 EM=['Could not find all outputs in "[' taskStructure(i).id '] ' taskStructure(i).description '" in either model']; -0178 dispEM(EM); -0179 else -0180 %Otherwise add them to the model -0181 met.metNames=refModel.metNames(metMatch); -0182 met.compartments=refModel.comps(refModel.metComps(metMatch)); -0183 -0184 %Add the metabolite both to the base model and the -0185 %model used in the current task -0186 model=addMets(model,met); -0187 tModel=addMets(tModel,met); -0188 modelMets=[modelMets;upper(taskStructure(i).outputs(~goodMets))]; -0189 end -0190 -0191 %By now the indexes might be getting a bit confusing, but -0192 %this is to update the indexes of the "real" metabolites to -0193 %point to the newly added ones -0194 I(~goodMets)=true; %All the bad ones are fixed at this stage -0195 J(~goodMets)=numel(modelMets)-numel(metMatch)+1:numel(modelMets); -0196 end -0197 if numel(J(I))~=numel(unique(J(I))) -0198 EM=['The constraints on some output(s) in "[' taskStructure(i).id '] ' taskStructure(i).description '" are defined more than one time']; -0199 dispEM(EM); -0200 end -0201 %If all metabolites should be added -0202 if any(K) -0203 %Check if ALLMETS is the first metabolite. Otherwise print -0204 %a warning since it will write over any other constraints -0205 %that are set -0206 if K(1)==0 -0207 EM=['ALLMETS is used as an output in "[' taskStructure(i).id '] ' taskStructure(i).description '" but it it not the first metabolite in the list. Constraints defined for the metabolites before it will be over-written']; -0208 dispEM(EM,false); -0209 end -0210 %Use the first match of ALLMETS. There should only be one, -0211 %but still.. -0212 tModel.b(:,2)=taskStructure(i).UBout(find(K,1)); -0213 end -0214 %If metabolites in a specific compartment should be used -0215 if any(L) -0216 L=find(L); -0217 for j=1:numel(L) -0218 %The compartment defined -0219 compartment=upper(taskStructure(i).outputs{L(j)}(11:end-1)); -0220 %Check if it exists in the model -0221 C=find(ismember(upper(model.comps),compartment)); -0222 if any(C) -0223 %Match to metabolites -0224 tModel.b(model.metComps==C,2)=taskStructure(i).UBout(L(j)); -0225 else -0226 EM=['The compartment defined for ALLMETSIN in "[' taskStructure(i).id '] ' taskStructure(i).description '" does not exist']; -0227 dispEM(EM); -0228 end -0229 end -0230 end -0231 %Then add the normal constraints -0232 if any(J(I)) -0233 %Verify that IN and OUT bounds are consistent. Cannot require -0234 %that a metabolite is simultaneously input AND output at some -0235 %nonzero flux. -0236 J = J(I); -0237 I = find(I); % otherwise indexing becomes confusing -0238 nonzero_LBin = tModel.b(J,2) < 0; -0239 nonzero_LBout = taskStructure(i).LBout(I) > 0; -0240 if any(nonzero_LBin & nonzero_LBout) -0241 EM=['The IN LB and OUT LB in "[' taskStructure(i).id '] ' taskStructure(i).description '" cannot be nonzero for the same metabolite']; -0242 dispEM(EM); -0243 end -0244 tModel.b(J(nonzero_LBout),1)=taskStructure(i).LBout(I(nonzero_LBout)); -0245 tModel.b(J,2)=taskStructure(i).UBout(I); -0246 end -0247 end -0248 -0249 %Add new rxns -0250 if ~isempty(taskStructure(i).equations) -0251 rxn.equations=taskStructure(i).equations; -0252 rxn.lb=taskStructure(i).LBequ; -0253 rxn.ub=taskStructure(i).UBequ; -0254 rxn.rxns=strcat({'TEMPORARY_'},num2str((1:numel(taskStructure(i).equations))')); -0255 tModel=addRxns(tModel,rxn,3); -0256 end -0257 %Add changed bounds -0258 if ~isempty(taskStructure(i).changed) -0259 tModel=setParam(tModel,'lb',taskStructure(i).changed,taskStructure(i).LBrxn); -0260 tModel=setParam(tModel,'ub',taskStructure(i).changed,taskStructure(i).UBrxn); -0261 end -0262 -0263 %Solve and print. Display a warning if the problem is not solveable -0264 sol=solveLP(tModel); -0265 if isempty(sol.x) -0266 %Only do gap-filling if it cannot be solved -0267 failed=false; -0268 try -0269 [~, ~, newRxns, newModel, exitFlag]=fillGaps(tModel,refModel,false,true,supressWarnings,rxnScores); -0270 if exitFlag==-2 -0271 EM=['"[' taskStructure(i).id '] ' taskStructure(i).description '" was aborted before reaching optimality. Consider increasing params.maxTime\n']; -0272 dispEM(EM,false); -0273 end -0274 catch -0275 EM=['"[' taskStructure(i).id '] ' taskStructure(i).description '" could not be performed for any set of reactions\n']; -0276 dispEM(EM,false); -0277 failed=true; -0278 end -0279 if failed==false -0280 if ~isempty(newRxns) -0281 nAdded=nAdded+numel(newRxns); -0282 -0283 %Add the reactions to the base model. It is not correct -0284 %to use newModel directly, as it may contain -0285 %reactions/constraints that are specific to this task -0286 model=mergeModels({model,removeReactions(newModel,setdiff(newModel.rxns,newRxns),true,true)},'metNames',true); -0287 -0288 %Keep track of the added reactions -0289 addedRxns(ismember(refModel.rxns,newRxns),i)=true; +0051 +0052 if isempty(taskStructure) && ~isfile(inputFile) +0053 error('Task file %s cannot be found',string(inputFile)); +0054 end +0055 +0056 if strcmpi(model.id,refModel.id) +0057 fprintf('NOTE: The model and reference model have the same IDs. The ID for the reference model was set to "refModel" in order to keep track of the origin of reactions.\n'); +0058 refModel.id='refModel'; +0059 end +0060 +0061 if any(rxnScores>=0) +0062 EM='Only negative values are allowed in rxnScores'; +0063 dispEM(EM); +0064 end +0065 +0066 %Prepare the input models a little +0067 model.b=zeros(numel(model.mets),2); +0068 modelMets=upper(strcat(model.metNames,'[',model.comps(model.metComps),']')); +0069 %This is the mets in the reference model. Used if the tasks involve +0070 %metabolites that doesn't exist in the model +0071 largeModelMets=upper(strcat(refModel.metNames,'[',refModel.comps(refModel.metComps),']')); +0072 +0073 if ~isfield(model,'unconstrained') +0074 EM='Exchange metabolites should normally not be removed from the model when using checkTasks. Inputs and outputs are defined in the task file instead. Use importModel(file,false) to import a model with exchange metabolites remaining'; +0075 dispEM(EM,false); +0076 end +0077 +0078 if isempty(taskStructure) +0079 taskStructure=parseTaskList(inputFile); +0080 end +0081 +0082 tModel=model; +0083 addedRxns=false(numel(refModel.rxns),numel(taskStructure)); +0084 supressWarnings=false; +0085 nAdded=0; +0086 for i=1:numel(taskStructure) +0087 if ~taskStructure(i).shouldFail +0088 %Set the inputs +0089 if ~isempty(taskStructure(i).inputs) +0090 [I, J]=ismember(upper(taskStructure(i).inputs),modelMets); +0091 K=ismember(upper(taskStructure(i).inputs),'ALLMETS'); +0092 L=~cellfun('isempty',strfind(upper(taskStructure(i).inputs),'ALLMETSIN')); +0093 %Check that all metabolites are either real metabolites or +0094 %ALLMETS/ALLMETSIN +0095 goodMets=I|K|L; +0096 if ~all(goodMets) +0097 %Not all of the inputs could be found in the small model. +0098 %Check if they exist in the large model +0099 [found, metMatch]=ismember(upper(taskStructure(i).inputs(~goodMets)),largeModelMets); +0100 if ~all(found) +0101 EM=['Could not find all inputs in "[' taskStructure(i).id '] ' taskStructure(i).description '" in either model']; +0102 disp(EM); +0103 else +0104 %Otherwise add them to the model +0105 met.metNames=refModel.metNames(metMatch); +0106 met.compartments=refModel.comps(refModel.metComps(metMatch)); +0107 +0108 %Add the metabolite both to the base model and the +0109 %model used in the current task +0110 model=addMets(model,met); +0111 tModel=addMets(tModel,met); +0112 modelMets=[modelMets;upper(taskStructure(i).inputs(~goodMets))]; +0113 end +0114 +0115 %By now the indexes might be getting a bit confusing, but +0116 %this is to update the indexes of the "real" metabolites to +0117 %point to the newly added ones +0118 I(~goodMets)=true; %All the bad ones are fixed at this stage +0119 J(~goodMets)=numel(modelMets)-numel(metMatch)+1:numel(modelMets); +0120 end +0121 if numel(J(I))~=numel(unique(J(I))) +0122 EM=['The constraints on some input(s) in "[' taskStructure(i).id '] ' taskStructure(i).description '" are defined more than one time']; +0123 dispEM(EM); +0124 end +0125 %If all metabolites should be added +0126 if any(K) +0127 %Check if ALLMETS is the first metabolite. Otherwise print +0128 %a warning since it will write over any other constraints +0129 %that are set +0130 if K(1)==0 +0131 EM=['ALLMETS is used as an input in "[' taskStructure(i).id '] ' taskStructure(i).description '" but it it not the first metabolite in the list. Constraints defined for the metabolites before it will be over-written']; +0132 dispEM(EM,false); +0133 end +0134 %Use the first match of ALLMETS. There should only be one, +0135 %but still.. +0136 tModel.b(:,1)=taskStructure(i).UBin(find(K,1))*-1; +0137 end +0138 %If metabolites in a specific compartment should be used +0139 if any(L) +0140 L=find(L); +0141 for j=1:numel(L) +0142 %The compartment defined +0143 compartment=upper(taskStructure(i).inputs{L(j)}(11:end-1)); +0144 %Check if it exists in the model +0145 C=find(ismember(upper(model.comps),compartment)); +0146 if any(C) +0147 %Match to metabolites +0148 tModel.b(model.metComps==C,1)=taskStructure(i).UBin(L(j))*-1; +0149 else +0150 EM=['The compartment defined for ALLMETSIN in "[' taskStructure(i).id '] ' taskStructure(i).description '" does not exist']; +0151 dispEM(EM); +0152 end +0153 end +0154 end +0155 %Then add the normal constraints +0156 if any(J(I)) +0157 tModel.b(J(I),1)=taskStructure(i).UBin(I)*-1; +0158 tModel.b(J(I),2)=taskStructure(i).LBin(I)*-1; +0159 end +0160 end +0161 %Set the outputs +0162 if ~isempty(taskStructure(i).outputs) +0163 [I, J]=ismember(upper(taskStructure(i).outputs),modelMets); +0164 K=ismember(upper(taskStructure(i).outputs),'ALLMETS'); +0165 L=~cellfun('isempty',strfind(upper(taskStructure(i).outputs),'ALLMETSIN')); +0166 %Check that all metabolites are either real metabolites or +0167 %ALLMETS/ALLMETSIN +0168 goodMets=I|K|L; +0169 if ~all(goodMets) +0170 %Not all of the outputs could be found in the small model. +0171 %Check if they exist in the large model +0172 [found, metMatch]=ismember(upper(taskStructure(i).outputs(~goodMets)),largeModelMets); +0173 if ~all(found) +0174 EM=['Could not find all outputs in "[' taskStructure(i).id '] ' taskStructure(i).description '" in either model']; +0175 dispEM(EM); +0176 else +0177 %Otherwise add them to the model +0178 met.metNames=refModel.metNames(metMatch); +0179 met.compartments=refModel.comps(refModel.metComps(metMatch)); +0180 +0181 %Add the metabolite both to the base model and the +0182 %model used in the current task +0183 model=addMets(model,met); +0184 tModel=addMets(tModel,met); +0185 modelMets=[modelMets;upper(taskStructure(i).outputs(~goodMets))]; +0186 end +0187 +0188 %By now the indexes might be getting a bit confusing, but +0189 %this is to update the indexes of the "real" metabolites to +0190 %point to the newly added ones +0191 I(~goodMets)=true; %All the bad ones are fixed at this stage +0192 J(~goodMets)=numel(modelMets)-numel(metMatch)+1:numel(modelMets); +0193 end +0194 if numel(J(I))~=numel(unique(J(I))) +0195 EM=['The constraints on some output(s) in "[' taskStructure(i).id '] ' taskStructure(i).description '" are defined more than one time']; +0196 dispEM(EM); +0197 end +0198 %If all metabolites should be added +0199 if any(K) +0200 %Check if ALLMETS is the first metabolite. Otherwise print +0201 %a warning since it will write over any other constraints +0202 %that are set +0203 if K(1)==0 +0204 EM=['ALLMETS is used as an output in "[' taskStructure(i).id '] ' taskStructure(i).description '" but it it not the first metabolite in the list. Constraints defined for the metabolites before it will be over-written']; +0205 dispEM(EM,false); +0206 end +0207 %Use the first match of ALLMETS. There should only be one, +0208 %but still.. +0209 tModel.b(:,2)=taskStructure(i).UBout(find(K,1)); +0210 end +0211 %If metabolites in a specific compartment should be used +0212 if any(L) +0213 L=find(L); +0214 for j=1:numel(L) +0215 %The compartment defined +0216 compartment=upper(taskStructure(i).outputs{L(j)}(11:end-1)); +0217 %Check if it exists in the model +0218 C=find(ismember(upper(model.comps),compartment)); +0219 if any(C) +0220 %Match to metabolites +0221 tModel.b(model.metComps==C,2)=taskStructure(i).UBout(L(j)); +0222 else +0223 EM=['The compartment defined for ALLMETSIN in "[' taskStructure(i).id '] ' taskStructure(i).description '" does not exist']; +0224 dispEM(EM); +0225 end +0226 end +0227 end +0228 %Then add the normal constraints +0229 if any(J(I)) +0230 %Verify that IN and OUT bounds are consistent. Cannot require +0231 %that a metabolite is simultaneously input AND output at some +0232 %nonzero flux. +0233 J = J(I); +0234 I = find(I); % otherwise indexing becomes confusing +0235 nonzero_LBin = tModel.b(J,2) < 0; +0236 nonzero_LBout = taskStructure(i).LBout(I) > 0; +0237 if any(nonzero_LBin & nonzero_LBout) +0238 EM=['The IN LB and OUT LB in "[' taskStructure(i).id '] ' taskStructure(i).description '" cannot be nonzero for the same metabolite']; +0239 dispEM(EM); +0240 end +0241 tModel.b(J(nonzero_LBout),1)=taskStructure(i).LBout(I(nonzero_LBout)); +0242 tModel.b(J,2)=taskStructure(i).UBout(I); +0243 end +0244 end +0245 +0246 %Add new rxns +0247 if ~isempty(taskStructure(i).equations) +0248 rxn.equations=taskStructure(i).equations; +0249 rxn.lb=taskStructure(i).LBequ; +0250 rxn.ub=taskStructure(i).UBequ; +0251 rxn.rxns=strcat({'TEMPORARY_'},num2str((1:numel(taskStructure(i).equations))')); +0252 tModel=addRxns(tModel,rxn,3); +0253 end +0254 %Add changed bounds +0255 if ~isempty(taskStructure(i).changed) +0256 tModel=setParam(tModel,'lb',taskStructure(i).changed,taskStructure(i).LBrxn); +0257 tModel=setParam(tModel,'ub',taskStructure(i).changed,taskStructure(i).UBrxn); +0258 end +0259 +0260 %Solve and print. Display a warning if the problem is not solveable +0261 sol=solveLP(tModel); +0262 if isempty(sol.x) +0263 %Only do gap-filling if it cannot be solved +0264 failed=false; +0265 try +0266 [~, ~, newRxns, newModel, exitFlag]=fillGaps(tModel,refModel,false,true,supressWarnings,rxnScores); +0267 if exitFlag==-2 +0268 EM=['"[' taskStructure(i).id '] ' taskStructure(i).description '" was aborted before reaching optimality.\n']; +0269 dispEM(EM,false); +0270 end +0271 catch +0272 EM=['"[' taskStructure(i).id '] ' taskStructure(i).description '" could not be performed for any set of reactions\n']; +0273 dispEM(EM,false); +0274 failed=true; +0275 end +0276 if failed==false +0277 if ~isempty(newRxns) +0278 nAdded=nAdded+numel(newRxns); +0279 +0280 %Add the reactions to the base model. It is not correct +0281 %to use newModel directly, as it may contain +0282 %reactions/constraints that are specific to this task +0283 model=mergeModels({model,removeReactions(newModel,setdiff(newModel.rxns,newRxns),true,true)},'metNames',true); +0284 +0285 %Keep track of the added reactions +0286 addedRxns(ismember(refModel.rxns,newRxns),i)=true; +0287 end +0288 if printOutput==true +0289 fprintf(['[' taskStructure(i).id '] ' taskStructure(i).description ': Added ' num2str(numel(newRxns)) ' reaction(s), ' num2str(nAdded) ' reactions added in total\n']); 0290 end -0291 if printOutput==true -0292 fprintf(['[' taskStructure(i).id '] ' taskStructure(i).description ': Added ' num2str(numel(newRxns)) ' reaction(s), ' num2str(nAdded) ' reactions added in total\n']); -0293 end -0294 end -0295 else -0296 if printOutput==true -0297 fprintf(['[' taskStructure(i).id '] ' taskStructure(i).description ': Added 0 reaction(s), ' num2str(nAdded) ' reactions added in total\n']); -0298 end -0299 end -0300 supressWarnings=true; -0301 -0302 %Print the output if chosen -0303 if taskStructure(i).printFluxes && printOutput -0304 if ~isempty(sol.x) -0305 sol=solveLP(tModel,1); -0306 printFluxes(tModel,sol.x,false,10^-5,[],'%rxnID (%eqn):%flux\n'); -0307 fprintf('\n'); -0308 else -0309 %If the problem wasn't solveable then the gap-filled model -0310 %should be used -0311 if failed==false -0312 sol=solveLP(newModel,1); -0313 printFluxes(newModel,sol.x,false,10^-5,[],'%rxnID (%eqn):%flux\n'); -0314 fprintf('\n'); -0315 end -0316 end -0317 end -0318 -0319 tModel=model; -0320 %Since new mets are added by merging the new reactions and not only -0321 %from the task sheet -0322 modelMets=upper(strcat(model.metNames,'[',model.comps(model.metComps),']')); -0323 else -0324 EM=['"[' taskStructure(i).id '] ' taskStructure(i).description '" is set as SHOULD FAIL. Such tasks cannot be modelled using this approach and the task is therefore ignored\n']; -0325 dispEM(EM,false); -0326 end -0327 end -0328 model.b(:,2) = []; % resume field b -0329 outModel=model; -0330 end +0291 end +0292 else +0293 if printOutput==true +0294 fprintf(['[' taskStructure(i).id '] ' taskStructure(i).description ': Added 0 reaction(s), ' num2str(nAdded) ' reactions added in total\n']); +0295 end +0296 end +0297 supressWarnings=true; +0298 +0299 %Print the output if chosen +0300 if taskStructure(i).printFluxes && printOutput +0301 if ~isempty(sol.x) +0302 sol=solveLP(tModel,1); +0303 printFluxes(tModel,sol.x,false,10^-5,[],'%rxnID (%eqn):%flux\n'); +0304 fprintf('\n'); +0305 else +0306 %If the problem wasn't solveable then the gap-filled model +0307 %should be used +0308 if failed==false +0309 sol=solveLP(newModel,1); +0310 printFluxes(newModel,sol.x,false,10^-5,[],'%rxnID (%eqn):%flux\n'); +0311 fprintf('\n'); +0312 end +0313 end +0314 end +0315 +0316 tModel=model; +0317 %Since new mets are added by merging the new reactions and not only +0318 %from the task sheet +0319 modelMets=upper(strcat(model.metNames,'[',model.comps(model.metComps),']')); +0320 else +0321 EM=['"[' taskStructure(i).id '] ' taskStructure(i).description '" is set as SHOULD FAIL. Such tasks cannot be modelled using this approach and the task is therefore ignored\n']; +0322 dispEM(EM,false); +0323 end +0324 end +0325 model.b(:,2) = []; % resume field b +0326 outModel=model; +0327 end
    Generated by m2html © 2005
    \ No newline at end of file diff --git a/doc/core/mergeModels.html b/doc/core/mergeModels.html index bdae72a3..b4315eb6 100644 --- a/doc/core/mergeModels.html +++ b/doc/core/mergeModels.html @@ -149,562 +149,572 @@

    SOURCE CODE ^'equations'); 0083 end 0084 -0085 for i=2:numel(models) -0086 %Add the model id to the rxn id id it already exists in the model (id -0087 %have to be unique) This is because it makes a '[]' string if no new -0088 %reactions -0089 if ~isempty(models{i}.rxns) -0090 I=ismember(models{i}.rxns,model.rxns); -0091 models{i}.rxns(I)=strcat(models{i}.rxns(I),['_' models{i}.id]); -0092 end -0093 -0094 %Make sure that there are no conflicting reaction ids -0095 [~, ~, conflicting]=intersect(model.rxns,models{i}.rxns); -0096 -0097 if ~isempty(conflicting) -0098 printString=cell(numel(conflicting),1); -0099 for j=1:numel(conflicting) -0100 printString{j}=['Old: ' models{i}.rxns{conflicting(j)} ' New: ' models{i}.rxns{conflicting(j)} '_' models{i}.id]; -0101 models{i}.rxns{conflicting(j)}=[models{i}.rxns{conflicting(j)} '_' models{i}.id]; -0102 end -0103 if supressWarnings==false -0104 EM=['The following reaction IDs in ' models{i}.id ' are already present in the model and were renamed:']; -0105 dispEM(EM,false,printString); -0106 fprintf('\n'); +0085 for i=1:numel(models) +0086 if isfield(models{i},'subSystems') +0087 models{i}.subSystems = cellfun(@(x) {x}, models{i}.subSystems, 'uni', 0); +0088 end +0089 end +0090 for i=2:numel(models) +0091 %Add the model id to the rxn id id it already exists in the model (id +0092 %have to be unique) This is because it makes a '[]' string if no new +0093 %reactions +0094 if ~isempty(models{i}.rxns) +0095 I=ismember(models{i}.rxns,model.rxns); +0096 models{i}.rxns(I)=strcat(models{i}.rxns(I),['_' models{i}.id]); +0097 end +0098 +0099 %Make sure that there are no conflicting reaction ids +0100 [~, ~, conflicting]=intersect(model.rxns,models{i}.rxns); +0101 +0102 if ~isempty(conflicting) +0103 printString=cell(numel(conflicting),1); +0104 for j=1:numel(conflicting) +0105 printString{j}=['Old: ' models{i}.rxns{conflicting(j)} ' New: ' models{i}.rxns{conflicting(j)} '_' models{i}.id]; +0106 models{i}.rxns{conflicting(j)}=[models{i}.rxns{conflicting(j)} '_' models{i}.id]; 0107 end -0108 end -0109 -0110 %Add all static stuff -0111 if any(hasRxnFrom) || (~copyToComps && ~any(hasRxnFrom)) -0112 model.rxnFrom = [model.rxnFrom; models{i}.rxnFrom]; +0108 if supressWarnings==false +0109 EM=['The following reaction IDs in ' models{i}.id ' are already present in the model and were renamed:']; +0110 dispEM(EM,false,printString); +0111 fprintf('\n'); +0112 end 0113 end -0114 model.rxns = [model.rxns; models{i}.rxns]; -0115 model.rxnNames = [model.rxnNames; models{i}.rxnNames]; -0116 model.lb = [model.lb; models{i}.lb]; -0117 model.ub = [model.ub; models{i}.ub]; -0118 model.c = [model.c; models{i}.c]; -0119 model.rev = [model.rev; models{i}.rev]; -0120 -0121 if isfield(models{i},'subSystems') -0122 if isfield(model,'subSystems') -0123 model.subSystems=[model.subSystems;models{i}.subSystems]; -0124 else -0125 emptySubSystem=cell(numel(model.rxns)-numel(models{i}.rxns),1); -0126 emptySubSystem(:)={''}; -0127 emptySubSystem=cellfun(@(x) cell(0,0),emptySubSystem,'UniformOutput',false); -0128 model.subSystems=[emptySubSystem;models{i}.subSystems]; -0129 end -0130 else -0131 if isfield(model,'subSystems') -0132 emptySubSystem=cell(numel(models{i}.rxns),1); -0133 emptySubSystem(:)={''}; -0134 emptySubSystem=cellfun(@(x) cell(0,0),emptySubSystem,'UniformOutput',false); -0135 model.subSystems=[model.subSystems;emptySubSystem]; -0136 end -0137 end -0138 -0139 if isfield(models{i},'eccodes') -0140 if isfield(model,'eccodes') -0141 model.eccodes=[model.eccodes;models{i}.eccodes]; -0142 else -0143 emptyEC=cell(numel(model.rxns)-numel(models{i}.rxns),1); -0144 emptyEC(:)={''}; -0145 model.eccodes=[emptyEC;models{i}.eccodes]; -0146 end -0147 else -0148 if isfield(model,'eccodes') -0149 emptyEC=cell(numel(models{i}.rxns),1); -0150 emptyEC(:)={''}; -0151 model.eccodes=[model.eccodes;emptyEC]; -0152 end -0153 end -0154 -0155 if isfield(models{i},'rxnMiriams') -0156 if isfield(model,'rxnMiriams') -0157 model.rxnMiriams=[model.rxnMiriams;models{i}.rxnMiriams]; -0158 else -0159 model.rxnMiriams=[cell(numel(model.rxns)-numel(models{i}.rxns),1);models{i}.rxnMiriams]; -0160 end -0161 else -0162 if isfield(model,'rxnMiriams') -0163 model.rxnMiriams=[model.rxnMiriams;cell(numel(models{i}.rxns),1)]; -0164 end -0165 end -0166 -0167 if isfield(models{i},'rxnNotes') -0168 if isfield(model,'rxnNotes') -0169 model.rxnNotes=[model.rxnNotes;models{i}.rxnNotes]; -0170 else -0171 emptyNotes=cell(numel(model.rxns)-numel(models{i}.rxns),1); -0172 emptyNotes(:)={''}; -0173 model.rxnNotes=[emptyNotes;models{i}.rxnNotes]; -0174 end -0175 else -0176 if isfield(model,'rxnNotes') -0177 emptyNotes=cell(numel(models{i}.rxns),1); -0178 emptyNotes(:)={''}; -0179 model.rxnNotes=[model.rxnNotes;emptyNotes]; -0180 end -0181 end -0182 -0183 if isfield(models{i},'rxnReferences') -0184 if isfield(model,'rxnReferences') -0185 model.rxnReferences=[model.rxnReferences;models{i}.rxnReferences]; -0186 else -0187 emptyReferences=cell(numel(model.rxns)-numel(models{i}.rxns),1); -0188 emptyReferences(:)={''}; -0189 model.rxnReferences=[emptyReferences;models{i}.rxnReferences]; -0190 end -0191 else -0192 if isfield(model,'rxnReferences') -0193 emptyReferences=cell(numel(models{i}.rxns),1); -0194 emptyReferences(:)={''}; -0195 model.rxnReferences=[model.rxnReferences;emptyReferences]; -0196 end -0197 end -0198 -0199 if isfield(models{i},'rxnConfidenceScores') -0200 if isfield(model,'rxnConfidenceScores') -0201 model.rxnConfidenceScores=[model.rxnConfidenceScores;models{i}.rxnConfidenceScores]; -0202 else -0203 model.rxnConfidenceScores=[NaN(numel(model.rxns)-numel(models{i}.rxns),1);models{i}.rxnConfidenceScores]; -0204 end -0205 else -0206 if isfield(model,'rxnConfidenceScores') -0207 model.rxnConfidenceScores=[model.rxnConfidenceScores;NaN(numel(models{i}.rxns),1)]; -0208 end -0209 end -0210 -0211 if isfield(models{i},'rxnDeltaG') -0212 if isfield(model,'rxnDeltaG') -0213 model.rxnDeltaG=[model.rxnDeltaG;models{i}.rxnDeltaG]; -0214 else -0215 model.rxnDeltaG=[NaN(numel(model.rxns)-numel(models{i}.rxns),1);models{i}.rxnDeltaG]; -0216 end -0217 else -0218 if isfield(model,'rxnDeltaG') -0219 model.rxnDeltaG=[model.rxnDeltaG;NaN(numel(models{i}.rxns),1)]; -0220 end -0221 end -0222 -0223 if isfield(models{i},'rxnComps') -0224 if isfield(model,'rxnComps') -0225 model.rxnComps=[model.rxnComps;models{i}.rxnComps]; -0226 else -0227 model.rxnComps=[ones(numel(model.rxns)-numel(models{i}.rxns),1);models{i}.rxnComps]; -0228 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'); -0229 end -0230 else -0231 if isfield(model,'rxnComps') -0232 model.rxnComps=[model.rxnComps;ones(numel(models{i}.rxns),1)]; +0114 +0115 %Add all static stuff +0116 if any(hasRxnFrom) || (~copyToComps && ~any(hasRxnFrom)) +0117 model.rxnFrom = [model.rxnFrom; models{i}.rxnFrom]; +0118 end +0119 model.rxns = [model.rxns; models{i}.rxns]; +0120 model.rxnNames = [model.rxnNames; models{i}.rxnNames]; +0121 model.lb = [model.lb; models{i}.lb]; +0122 model.ub = [model.ub; models{i}.ub]; +0123 model.c = [model.c; models{i}.c]; +0124 model.rev = [model.rev; models{i}.rev]; +0125 +0126 if isfield(models{i},'subSystems') +0127 if isfield(model,'subSystems') +0128 model.subSystems=[model.subSystems;models{i}.subSystems]; +0129 else +0130 emptySubSystem=cell(numel(model.rxns)-numel(models{i}.rxns),1); +0131 emptySubSystem(:)={''}; +0132 emptySubSystem=cellfun(@(x) cell(0,0),emptySubSystem,'UniformOutput',false); +0133 model.subSystems=[emptySubSystem;models{i}.subSystems]; +0134 end +0135 else +0136 if isfield(model,'subSystems') +0137 emptySubSystem=cell(numel(models{i}.rxns),1); +0138 emptySubSystem(:)={''}; +0139 emptySubSystem=cellfun(@(x) cell(0,0),emptySubSystem,'UniformOutput',false); +0140 model.subSystems=[model.subSystems;emptySubSystem]; +0141 end +0142 end +0143 +0144 if isfield(models{i},'eccodes') +0145 if isfield(model,'eccodes') +0146 model.eccodes=[model.eccodes;models{i}.eccodes]; +0147 else +0148 emptyEC=cell(numel(model.rxns)-numel(models{i}.rxns),1); +0149 emptyEC(:)={''}; +0150 model.eccodes=[emptyEC;models{i}.eccodes]; +0151 end +0152 else +0153 if isfield(model,'eccodes') +0154 emptyEC=cell(numel(models{i}.rxns),1); +0155 emptyEC(:)={''}; +0156 model.eccodes=[model.eccodes;emptyEC]; +0157 end +0158 end +0159 +0160 if isfield(models{i},'rxnMiriams') +0161 if isfield(model,'rxnMiriams') +0162 model.rxnMiriams=[model.rxnMiriams;models{i}.rxnMiriams]; +0163 else +0164 model.rxnMiriams=[cell(numel(model.rxns)-numel(models{i}.rxns),1);models{i}.rxnMiriams]; +0165 end +0166 else +0167 if isfield(model,'rxnMiriams') +0168 model.rxnMiriams=[model.rxnMiriams;cell(numel(models{i}.rxns),1)]; +0169 end +0170 end +0171 +0172 if isfield(models{i},'rxnNotes') +0173 if isfield(model,'rxnNotes') +0174 model.rxnNotes=[model.rxnNotes;models{i}.rxnNotes]; +0175 else +0176 emptyNotes=cell(numel(model.rxns)-numel(models{i}.rxns),1); +0177 emptyNotes(:)={''}; +0178 model.rxnNotes=[emptyNotes;models{i}.rxnNotes]; +0179 end +0180 else +0181 if isfield(model,'rxnNotes') +0182 emptyNotes=cell(numel(models{i}.rxns),1); +0183 emptyNotes(:)={''}; +0184 model.rxnNotes=[model.rxnNotes;emptyNotes]; +0185 end +0186 end +0187 +0188 if isfield(models{i},'rxnReferences') +0189 if isfield(model,'rxnReferences') +0190 model.rxnReferences=[model.rxnReferences;models{i}.rxnReferences]; +0191 else +0192 emptyReferences=cell(numel(model.rxns)-numel(models{i}.rxns),1); +0193 emptyReferences(:)={''}; +0194 model.rxnReferences=[emptyReferences;models{i}.rxnReferences]; +0195 end +0196 else +0197 if isfield(model,'rxnReferences') +0198 emptyReferences=cell(numel(models{i}.rxns),1); +0199 emptyReferences(:)={''}; +0200 model.rxnReferences=[model.rxnReferences;emptyReferences]; +0201 end +0202 end +0203 +0204 if isfield(models{i},'rxnConfidenceScores') +0205 if isfield(model,'rxnConfidenceScores') +0206 model.rxnConfidenceScores=[model.rxnConfidenceScores;models{i}.rxnConfidenceScores]; +0207 else +0208 model.rxnConfidenceScores=[NaN(numel(model.rxns)-numel(models{i}.rxns),1);models{i}.rxnConfidenceScores]; +0209 end +0210 else +0211 if isfield(model,'rxnConfidenceScores') +0212 model.rxnConfidenceScores=[model.rxnConfidenceScores;NaN(numel(models{i}.rxns),1)]; +0213 end +0214 end +0215 +0216 if isfield(models{i},'rxnDeltaG') +0217 if isfield(model,'rxnDeltaG') +0218 model.rxnDeltaG=[model.rxnDeltaG;models{i}.rxnDeltaG]; +0219 else +0220 model.rxnDeltaG=[NaN(numel(model.rxns)-numel(models{i}.rxns),1);models{i}.rxnDeltaG]; +0221 end +0222 else +0223 if isfield(model,'rxnDeltaG') +0224 model.rxnDeltaG=[model.rxnDeltaG;NaN(numel(models{i}.rxns),1)]; +0225 end +0226 end +0227 +0228 if isfield(models{i},'rxnComps') +0229 if isfield(model,'rxnComps') +0230 model.rxnComps=[model.rxnComps;models{i}.rxnComps]; +0231 else +0232 model.rxnComps=[ones(numel(model.rxns)-numel(models{i}.rxns),1);models{i}.rxnComps]; 0233 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'); 0234 end -0235 end -0236 -0237 if isfield(models{i},'rxnScores') -0238 if isfield(model,'rxnScores') -0239 model.rxnScores=[model.rxnScores;models{i}.rxnScores]; -0240 else -0241 emptyRS=zeros(numel(model.rxns)-numel(models{i}.rxns),1); -0242 model.rxnScores=[emptyRS;models{i}.rxnScores]; -0243 end -0244 else -0245 if isfield(model,'rxnScores') -0246 emptyRS=zeros(numel(models{i}.rxns),1); -0247 model.rxnScores=[model.rxnScores;emptyRS]; +0235 else +0236 if isfield(model,'rxnComps') +0237 model.rxnComps=[model.rxnComps;ones(numel(models{i}.rxns),1)]; +0238 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'); +0239 end +0240 end +0241 +0242 if isfield(models{i},'rxnScores') +0243 if isfield(model,'rxnScores') +0244 model.rxnScores=[model.rxnScores;models{i}.rxnScores]; +0245 else +0246 emptyRS=zeros(numel(model.rxns)-numel(models{i}.rxns),1); +0247 model.rxnScores=[emptyRS;models{i}.rxnScores]; 0248 end -0249 end -0250 -0251 if isfield(models{i},'pwys') -0252 if isfield(model,'pwys') -0253 model.pwys=[model.pwys;models{i}.pwys]; -0254 else -0255 model.pwys=[cell(numel(model.rxns)-numel(models{i}.rxns),1);models{i}.pwys]; -0256 end -0257 else -0258 if isfield(model,'pwys') -0259 model.pwys=[model.pwys;cell(numel(models{i}.rxns),1)]; -0260 end -0261 end -0262 -0263 if strcmpi(metParam,'metNames') -0264 %Get the new metabolites from matching the models. Metabolites are said -0265 %to be the same if they share name and compartment id. This means that -0266 %metabolite IDs are not taken into account. -0267 -0268 oldMetComps=model.comps(model.metComps); -0269 oldMets=strcat(model.metNames,'[',oldMetComps,']'); -0270 %This is because it makes a '[]' string if no new metabolites -0271 if ~isempty(models{i}.metNames) -0272 newMetComps=models{i}.comps(models{i}.metComps); -0273 newMets=strcat(models{i}.metNames,'[',newMetComps,']'); -0274 else -0275 newMets={}; -0276 newMetComps={}; -0277 end -0278 tf=ismember(newMets,oldMets); -0279 metsToAdd=find(~tf); -0280 -0281 end -0282 -0283 if strcmpi(metParam,'mets') -0284 %Get the new metabolites from matching the models. Metabolites are matched by metabolite ID (model.mets). +0249 else +0250 if isfield(model,'rxnScores') +0251 emptyRS=zeros(numel(models{i}.rxns),1); +0252 model.rxnScores=[model.rxnScores;emptyRS]; +0253 end +0254 end +0255 +0256 if isfield(models{i},'pwys') +0257 if isfield(model,'pwys') +0258 model.pwys=[model.pwys;models{i}.pwys]; +0259 else +0260 model.pwys=[cell(numel(model.rxns)-numel(models{i}.rxns),1);models{i}.pwys]; +0261 end +0262 else +0263 if isfield(model,'pwys') +0264 model.pwys=[model.pwys;cell(numel(models{i}.rxns),1)]; +0265 end +0266 end +0267 +0268 if strcmpi(metParam,'metNames') +0269 %Get the new metabolites from matching the models. Metabolites are said +0270 %to be the same if they share name and compartment id. This means that +0271 %metabolite IDs are not taken into account. +0272 +0273 oldMetComps=model.comps(model.metComps); +0274 oldMets=strcat(model.metNames,'[',oldMetComps,']'); +0275 %This is because it makes a '[]' string if no new metabolites +0276 if ~isempty(models{i}.metNames) +0277 newMetComps=models{i}.comps(models{i}.metComps); +0278 newMets=strcat(models{i}.metNames,'[',newMetComps,']'); +0279 else +0280 newMets={}; +0281 newMetComps={}; +0282 end +0283 tf=ismember(newMets,oldMets); +0284 metsToAdd=find(~tf); 0285 -0286 oldMetComps=model.comps(model.metComps); -0287 oldMets=model.mets; -0288 -0289 if ~isempty(models{i}.mets) -0290 newMetComps=models{i}.comps(models{i}.metComps); -0291 newMets=models{i}.mets; -0292 else -0293 newMets={}; -0294 newMetComps={}; -0295 end -0296 tf=ismember(newMets,oldMets); -0297 metsToAdd=find(~tf); -0298 -0299 end -0300 -0301 %First add the new metabolites Make sure that there are no conflicting -0302 %metabolite ids -0303 conflicting=ismember(models{i}.mets(metsToAdd),model.mets); +0286 end +0287 +0288 if strcmpi(metParam,'mets') +0289 %Get the new metabolites from matching the models. Metabolites are matched by metabolite ID (model.mets). +0290 +0291 oldMets=model.mets; +0292 +0293 if ~isempty(models{i}.mets) +0294 newMetComps=models{i}.comps(models{i}.metComps); +0295 newMets=models{i}.mets; +0296 else +0297 newMets={}; +0298 newMetComps={}; +0299 end +0300 tf=ismember(newMets,oldMets); +0301 metsToAdd=find(~tf); +0302 +0303 end 0304 -0305 conflicting=find(conflicting); -0306 -0307 if ~isempty(conflicting) -0308 printString=cell(numel(conflicting),1); -0309 for j=1:numel(conflicting) -0310 printString{j}=['Old: ' models{i}.mets{metsToAdd(conflicting(j))} ' New: ' models{i}.mets{metsToAdd(conflicting(j))} '_' models{i}.id]; -0311 models{i}.mets{metsToAdd(conflicting(j))}=[models{i}.mets{metsToAdd(conflicting(j))} '_' models{i}.id]; -0312 end -0313 if supressWarnings==false -0314 EM=['The following metabolite IDs in ' models{i}.id ' are already present in the model and were renamed:']; -0315 dispEM(EM,false,printString); +0305 %First add the new metabolites Make sure that there are no conflicting +0306 %metabolite ids +0307 conflicting=ismember(models{i}.mets(metsToAdd),model.mets); +0308 +0309 conflicting=find(conflicting); +0310 +0311 if ~isempty(conflicting) +0312 printString=cell(numel(conflicting),1); +0313 for j=1:numel(conflicting) +0314 printString{j}=['Old: ' models{i}.mets{metsToAdd(conflicting(j))} ' New: ' models{i}.mets{metsToAdd(conflicting(j))} '_' models{i}.id]; +0315 models{i}.mets{metsToAdd(conflicting(j))}=[models{i}.mets{metsToAdd(conflicting(j))} '_' models{i}.id]; 0316 end -0317 end -0318 -0319 %Add static info on the metabolites -0320 if any(hasMetFrom) -0321 model.metFrom = [model.metFrom; models{i}.metFrom(metsToAdd)]; -0322 end -0323 model.mets = [model.mets; models{i}.mets(metsToAdd)]; -0324 model.metNames = [model.metNames; models{i}.metNames(metsToAdd)]; -0325 model.b = [model.b; zeros(numel(metsToAdd),size(model.b,2))]; -0326 -0327 if isfield(model,'unconstrained') -0328 if isfield(models{i},'unconstrained') -0329 model.unconstrained=[model.unconstrained;models{i}.unconstrained(metsToAdd)]; -0330 else -0331 model.unconstrained=[model.unconstrained;zeros(numel(metsToAdd),1)]; -0332 end -0333 else -0334 if isfield(models{i},'unconstrained') -0335 model.unconstrained=[zeros(numel(model.mets),1);models{i}.unconstrained(metsToAdd)]; +0317 if supressWarnings==false +0318 EM=['The following metabolite IDs in ' models{i}.id ' are already present in the model and were renamed:']; +0319 dispEM(EM,false,printString); +0320 end +0321 end +0322 +0323 %Add static info on the metabolites +0324 if any(hasMetFrom) +0325 model.metFrom = [model.metFrom; models{i}.metFrom(metsToAdd)]; +0326 end +0327 model.mets = [model.mets; models{i}.mets(metsToAdd)]; +0328 model.metNames = [model.metNames; models{i}.metNames(metsToAdd)]; +0329 model.b = [model.b; zeros(numel(metsToAdd),size(model.b,2))]; +0330 +0331 if isfield(model,'unconstrained') +0332 if isfield(models{i},'unconstrained') +0333 model.unconstrained=[model.unconstrained;models{i}.unconstrained(metsToAdd)]; +0334 else +0335 model.unconstrained=[model.unconstrained;zeros(numel(metsToAdd),1)]; 0336 end -0337 end -0338 -0339 %Only add extra info on new metabolites since it's a little tricky to -0340 %chose what to keep otherwise. Should change in the future -0341 -0342 if ~isempty(metsToAdd) -0343 if isfield(models{i},'inchis') -0344 if isfield(model,'inchis') -0345 model.inchis=[model.inchis;models{i}.inchis(metsToAdd)]; -0346 else -0347 emptyInchi=cell(numel(model.mets)-numel(metsToAdd),1); -0348 emptyInchi(:)={''}; -0349 model.inchis=[emptyInchi;models{i}.inchis(metsToAdd)]; -0350 end -0351 else -0352 if isfield(model,'inchis') -0353 emptyInchi=cell(numel(metsToAdd),1); -0354 emptyInchi(:)={''}; -0355 model.inchis=[model.inchis;emptyInchi]; -0356 end -0357 end -0358 -0359 if isfield(models{i},'metSmiles') -0360 if isfield(model,'metSmiles') -0361 model.metSmiles=[model.metSmiles;models{i}.metSmiles(metsToAdd)]; -0362 else -0363 emptyInchi=cell(numel(model.mets)-numel(metsToAdd),1); -0364 emptyInchi(:)={''}; -0365 model.metSmiles=[emptyInchi;models{i}.metSmiles(metsToAdd)]; -0366 end -0367 else -0368 if isfield(model,'metSmiles') -0369 emptyInchi=cell(numel(metsToAdd),1); -0370 emptyInchi(:)={''}; -0371 model.metSmiles=[model.metSmiles;emptyInchi]; -0372 end -0373 end -0374 -0375 if isfield(models{i},'metFormulas') -0376 if isfield(model,'metFormulas') -0377 model.metFormulas=[model.metFormulas;models{i}.metFormulas(metsToAdd)]; -0378 else -0379 emptyMetFormulas=cell(numel(model.mets)-numel(metsToAdd),1); -0380 emptyMetFormulas(:)={''}; -0381 model.metFormulas=[emptyMetFormulas;models{i}.metFormulas(metsToAdd)]; -0382 end -0383 else -0384 if isfield(model,'metFormulas') -0385 emptyMetFormulas=cell(numel(metsToAdd),1); -0386 emptyMetFormulas(:)={''}; -0387 model.metFormulas=[model.metFormulas;emptyMetFormulas]; -0388 end -0389 end -0390 -0391 if isfield(models{i},'metCharges') -0392 if isfield(model,'metCharges') -0393 model.metCharges=[model.metCharges;models{i}.metCharges(metsToAdd)]; -0394 else -0395 emptyMetCharge=nan(numel(model.mets)-numel(metsToAdd),1); -0396 model.metCharges=[emptyMetCharge;models{i}.metCharges(metsToAdd)]; -0397 end -0398 else -0399 if isfield(model,'metCharges') -0400 emptyMetCharge=nan(numel(metsToAdd),1); -0401 model.metCharges=[model.metCharges;emptyMetCharge]; -0402 end -0403 end -0404 -0405 if isfield(models{i},'metDeltaG') -0406 if isfield(model,'metDeltaG') -0407 model.metDeltaG=[model.metDeltaG;models{i}.metDeltaG(metsToAdd)]; -0408 else -0409 emptyMetCharge=nan(numel(model.mets)-numel(metsToAdd),1); -0410 model.metDeltaG=[emptyMetCharge;models{i}.metDeltaG(metsToAdd)]; -0411 end -0412 else -0413 if isfield(model,'metDeltaG') -0414 emptyMetCharge=nan(numel(metsToAdd),1); -0415 model.metDeltaG=[model.metDeltaG;emptyMetCharge]; -0416 end -0417 end -0418 -0419 if isfield(models{i},'metMiriams') -0420 if isfield(model,'metMiriams') -0421 model.metMiriams=[model.metMiriams;models{i}.metMiriams(metsToAdd)]; -0422 else -0423 emptyMetMiriam=cell(numel(model.mets)-numel(metsToAdd),1); -0424 model.metMiriams=[emptyMetMiriam;models{i}.metMiriams(metsToAdd)]; -0425 end -0426 else -0427 if isfield(model,'metMiriams') -0428 emptyMetMiriam=cell(numel(metsToAdd),1); -0429 model.metMiriams=[model.metMiriams;emptyMetMiriam]; -0430 end -0431 end -0432 end -0433 -0434 %Add if there are any new compartments and add those. This can change -0435 %the order of compartments and the corresponding indexes in -0436 %model.metComps. +0337 else +0338 if isfield(models{i},'unconstrained') +0339 model.unconstrained=[zeros(numel(model.mets),1);models{i}.unconstrained(metsToAdd)]; +0340 end +0341 end +0342 +0343 %Only add extra info on new metabolites since it's a little tricky to +0344 %chose what to keep otherwise. Should change in the future +0345 +0346 if ~isempty(metsToAdd) +0347 if isfield(models{i},'inchis') +0348 if isfield(model,'inchis') +0349 model.inchis=[model.inchis;models{i}.inchis(metsToAdd)]; +0350 else +0351 emptyInchi=cell(numel(model.mets)-numel(metsToAdd),1); +0352 emptyInchi(:)={''}; +0353 model.inchis=[emptyInchi;models{i}.inchis(metsToAdd)]; +0354 end +0355 else +0356 if isfield(model,'inchis') +0357 emptyInchi=cell(numel(metsToAdd),1); +0358 emptyInchi(:)={''}; +0359 model.inchis=[model.inchis;emptyInchi]; +0360 end +0361 end +0362 +0363 if isfield(models{i},'metSmiles') +0364 if isfield(model,'metSmiles') +0365 model.metSmiles=[model.metSmiles;models{i}.metSmiles(metsToAdd)]; +0366 else +0367 emptyInchi=cell(numel(model.mets)-numel(metsToAdd),1); +0368 emptyInchi(:)={''}; +0369 model.metSmiles=[emptyInchi;models{i}.metSmiles(metsToAdd)]; +0370 end +0371 else +0372 if isfield(model,'metSmiles') +0373 emptyInchi=cell(numel(metsToAdd),1); +0374 emptyInchi(:)={''}; +0375 model.metSmiles=[model.metSmiles;emptyInchi]; +0376 end +0377 end +0378 +0379 if isfield(models{i},'metFormulas') +0380 if isfield(model,'metFormulas') +0381 model.metFormulas=[model.metFormulas;models{i}.metFormulas(metsToAdd)]; +0382 else +0383 emptyMetFormulas=cell(numel(model.mets)-numel(metsToAdd),1); +0384 emptyMetFormulas(:)={''}; +0385 model.metFormulas=[emptyMetFormulas;models{i}.metFormulas(metsToAdd)]; +0386 end +0387 else +0388 if isfield(model,'metFormulas') +0389 emptyMetFormulas=cell(numel(metsToAdd),1); +0390 emptyMetFormulas(:)={''}; +0391 model.metFormulas=[model.metFormulas;emptyMetFormulas]; +0392 end +0393 end +0394 +0395 if isfield(models{i},'metCharges') +0396 if isfield(model,'metCharges') +0397 model.metCharges=[model.metCharges;models{i}.metCharges(metsToAdd)]; +0398 else +0399 emptyMetCharge=nan(numel(model.mets)-numel(metsToAdd),1); +0400 model.metCharges=[emptyMetCharge;models{i}.metCharges(metsToAdd)]; +0401 end +0402 else +0403 if isfield(model,'metCharges') +0404 emptyMetCharge=nan(numel(metsToAdd),1); +0405 model.metCharges=[model.metCharges;emptyMetCharge]; +0406 end +0407 end +0408 +0409 if isfield(models{i},'metDeltaG') +0410 if isfield(model,'metDeltaG') +0411 model.metDeltaG=[model.metDeltaG;models{i}.metDeltaG(metsToAdd)]; +0412 else +0413 emptyMetCharge=nan(numel(model.mets)-numel(metsToAdd),1); +0414 model.metDeltaG=[emptyMetCharge;models{i}.metDeltaG(metsToAdd)]; +0415 end +0416 else +0417 if isfield(model,'metDeltaG') +0418 emptyMetCharge=nan(numel(metsToAdd),1); +0419 model.metDeltaG=[model.metDeltaG;emptyMetCharge]; +0420 end +0421 end +0422 +0423 if isfield(models{i},'metMiriams') +0424 if isfield(model,'metMiriams') +0425 model.metMiriams=[model.metMiriams;models{i}.metMiriams(metsToAdd)]; +0426 else +0427 emptyMetMiriam=cell(numel(model.mets)-numel(metsToAdd),1); +0428 model.metMiriams=[emptyMetMiriam;models{i}.metMiriams(metsToAdd)]; +0429 end +0430 else +0431 if isfield(model,'metMiriams') +0432 emptyMetMiriam=cell(numel(metsToAdd),1); +0433 model.metMiriams=[model.metMiriams;emptyMetMiriam]; +0434 end +0435 end +0436 end 0437 -0438 %Find overlapping and new compartments -0439 [overlap, oldIDs]=ismember(models{i}.comps,model.comps); -0440 overlap=find(overlap); +0438 %Add if there are any new compartments and add those. This can change +0439 %the order of compartments and the corresponding indexes in +0440 %model.metComps. 0441 -0442 %Add the new compartments if any -0443 if numel(overlap)~=numel(models{i}.compNames) -0444 compIndexes=oldIDs==0; -0445 -0446 %Make sure that there are no conflicting compartment ids -0447 [~, conflicting]=ismember(models{i}.compNames(compIndexes),model.compNames); -0448 if any(conflicting) -0449 EM=['The following compartment IDs in ' models{i}.id ' are already present in the model but with another name. They have to be renamed']; -0450 dispEM(EM,true,model.comps(conflicting)); -0451 end -0452 -0453 %It's ok to add duplicate name, but not duplicate IDs -0454 model.compNames=[model.compNames; models{i}.compNames(compIndexes)]; -0455 model.comps=[model.comps; models{i}.comps(compIndexes)]; -0456 if isfield(model,'compOutside') -0457 if isfield(models{i},'compOutside') -0458 model.compOutside=[model.compOutside; models{i}.compOutside(compIndexes)]; -0459 else -0460 %This is if not all models have the field -0461 padding=cell(sum(compIndexes),1); -0462 padding(:)={''}; -0463 model.compOutside=[model.compOutside;padding]; -0464 end -0465 end -0466 if isfield(model,'compMiriams') -0467 if isfield(models{i},'compMiriams') -0468 model.compMiriams=[model.compMiriams; models{i}.compMiriams(compIndexes)]; -0469 else -0470 %This is if not all models have the field -0471 model.compMiriams=[model.compMiriams;cell(sum(compIndexes),1)]; -0472 end -0473 end -0474 end -0475 -0476 %Only add new comp info on the un-matched metabolites since the old -0477 %ones will be mapped to the existing list anyways -0478 [I, J]=ismember(newMetComps(metsToAdd),model.comps); -0479 %Just a check -0480 if ~all(I) -0481 EM='There was an unexpected error in matching compartments'; -0482 dispEM(EM); -0483 end -0484 model.metComps=[model.metComps;J]; -0485 -0486 %Create the new stoichiometric matrix -0487 model.S=[model.S;sparse(numel(metsToAdd),size(model.S,2))]; -0488 -0489 -0490 if strcmpi(metParam,'metNames') -0491 %Rematch metabolite names. Not the most clever way to do it maybe -0492 allMets=strcat(model.metNames,'[',model.comps(model.metComps),']'); -0493 [~, J]=ismember(newMets,allMets); -0494 end -0495 -0496 if strcmpi(metParam,'mets') -0497 %Rematch metabolite by IDs and add unique new metabolites -0498 allMets=model.mets; -0499 uniqueNewMets = setdiff(newMets,oldMets); -0500 allMets(end+1:end+numel(uniqueNewMets)) = uniqueNewMets; -0501 [~, J]=ismember(newMets,allMets); -0502 end -0503 -0504 %Update the stoichiometric matrix for the model to add -0505 newS=sparse(numel(model.mets),numel(models{i}.rxns)); -0506 newS(J,:)=models{i}.S; -0507 model.S=[model.S newS]; -0508 -0509 -0510 %Now add new genes -0511 if isfield(models{i},'genes') -0512 if ~isfield(model,'genes') -0513 %If there was no gene info before -0514 model.genes = models{i}.genes; -0515 model.rxnGeneMat = [sparse(numel(model.rxns),numel(models{i}.genes));models{i}.rxnGeneMat]; -0516 emptyGene = repmat({''},numel(model.rxns),1); -0517 model.grRules = [emptyGene;models{i}.grRules]; -0518 if any(hasGeneFrom) -0519 model.geneFrom = models{i}.geneFrom; -0520 end -0521 -0522 if isfield(models{i},'geneShortNames') -0523 model.geneShortNames=models{i}.geneShortNames; +0442 %Find overlapping and new compartments +0443 [overlap, oldIDs]=ismember(models{i}.comps,model.comps); +0444 overlap=find(overlap); +0445 +0446 %Add the new compartments if any +0447 if numel(overlap)~=numel(models{i}.compNames) +0448 compIndexes=oldIDs==0; +0449 +0450 %Make sure that there are no conflicting compartment ids +0451 [~, conflicting]=ismember(models{i}.compNames(compIndexes),model.compNames); +0452 if any(conflicting) +0453 EM=['The following compartment IDs in ' models{i}.id ' are already present in the model but with another name. They have to be renamed']; +0454 dispEM(EM,true,model.comps(conflicting)); +0455 end +0456 +0457 %It's ok to add duplicate name, but not duplicate IDs +0458 model.compNames=[model.compNames; models{i}.compNames(compIndexes)]; +0459 model.comps=[model.comps; models{i}.comps(compIndexes)]; +0460 if isfield(model,'compOutside') +0461 if isfield(models{i},'compOutside') +0462 model.compOutside=[model.compOutside; models{i}.compOutside(compIndexes)]; +0463 else +0464 %This is if not all models have the field +0465 padding=cell(sum(compIndexes),1); +0466 padding(:)={''}; +0467 model.compOutside=[model.compOutside;padding]; +0468 end +0469 end +0470 if isfield(model,'compMiriams') +0471 if isfield(models{i},'compMiriams') +0472 model.compMiriams=[model.compMiriams; models{i}.compMiriams(compIndexes)]; +0473 else +0474 %This is if not all models have the field +0475 model.compMiriams=[model.compMiriams;cell(sum(compIndexes),1)]; +0476 end +0477 end +0478 end +0479 +0480 %Only add new comp info on the un-matched metabolites since the old +0481 %ones will be mapped to the existing list anyways +0482 [I, J]=ismember(newMetComps(metsToAdd),model.comps); +0483 %Just a check +0484 if ~all(I) +0485 EM='There was an unexpected error in matching compartments'; +0486 dispEM(EM); +0487 end +0488 model.metComps=[model.metComps;J]; +0489 +0490 %Create the new stoichiometric matrix +0491 model.S=[model.S;sparse(numel(metsToAdd),size(model.S,2))]; +0492 +0493 +0494 if strcmpi(metParam,'metNames') +0495 %Rematch metabolite names. Not the most clever way to do it maybe +0496 allMets=strcat(model.metNames,'[',model.comps(model.metComps),']'); +0497 [~, J]=ismember(newMets,allMets); +0498 end +0499 +0500 if strcmpi(metParam,'mets') +0501 %Rematch metabolite by IDs and add unique new metabolites +0502 allMets=model.mets; +0503 uniqueNewMets = setdiff(newMets,oldMets); +0504 allMets(end+1:end+numel(uniqueNewMets)) = uniqueNewMets; +0505 [~, J]=ismember(newMets,allMets); +0506 end +0507 +0508 %Update the stoichiometric matrix for the model to add +0509 newS=sparse(numel(model.mets),numel(models{i}.rxns)); +0510 newS(J,:)=models{i}.S; +0511 model.S=[model.S newS]; +0512 +0513 +0514 %Now add new genes +0515 if isfield(models{i},'genes') +0516 if ~isfield(model,'genes') +0517 %If there was no gene info before +0518 model.genes = models{i}.genes; +0519 model.rxnGeneMat = [sparse(numel(model.rxns),numel(models{i}.genes));models{i}.rxnGeneMat]; +0520 emptyGene = repmat({''},numel(model.rxns),1); +0521 model.grRules = [emptyGene;models{i}.grRules]; +0522 if any(hasGeneFrom) +0523 model.geneFrom = models{i}.geneFrom; 0524 end -0525 -0526 if isfield(models{i},'proteins') -0527 model.proteins=models{i}.proteins; +0525 +0526 if isfield(models{i},'geneShortNames') +0527 model.geneShortNames=models{i}.geneShortNames; 0528 end 0529 -0530 if isfield(models{i},'geneMiriams') -0531 model.geneMiriams=models{i}.geneMiriams; +0530 if isfield(models{i},'proteins') +0531 model.proteins=models{i}.proteins; 0532 end -0533 -0534 if isfield(models{i},'geneComps') -0535 model.geneComps=models{i}.geneComps; +0533 +0534 if isfield(models{i},'geneMiriams') +0535 model.geneMiriams=models{i}.geneMiriams; 0536 end -0537 else -0538 %If gene info should be merged -0539 a=ismember(models{i}.genes,model.genes); -0540 -0541 genesToAdd=find(~a); -0542 -0543 %Only add extra gene info on new genes. This might not be -0544 %correct and should be changed later... -0545 if ~isempty(genesToAdd) -0546 model.genes = [model.genes; models{i}.genes(genesToAdd)]; -0547 model.geneFrom = [model.geneFrom; models{i}.geneFrom(genesToAdd)]; -0548 model.rxnGeneMat = [model.rxnGeneMat sparse(size(model.rxnGeneMat,1),numel(genesToAdd))]; -0549 -0550 if isfield(models{i},'geneShortNames') -0551 if isfield(model,'geneShortNames') -0552 model.geneShortNames=[model.geneShortNames;models{i}.geneShortNames(genesToAdd)]; -0553 else -0554 emptyGeneSN=cell(numel(model.genes)-numel(genesToAdd),1); -0555 emptyGeneSN(:)={''}; -0556 model.geneShortNames=[emptyGeneSN;models{i}.geneShortNames(genesToAdd)]; -0557 end -0558 else -0559 if isfield(model,'geneShortNames') -0560 emptyGeneSN=cell(numel(genesToAdd),1); -0561 emptyGeneSN(:)={''}; -0562 model.geneShortNames=[model.geneShortNames;emptyGeneSN]; -0563 end -0564 end -0565 -0566 if isfield(models{i},'proteins') -0567 if isfield(model,'proteins') -0568 model.proteins=[model.proteins;models{i}.proteins(genesToAdd)]; -0569 else -0570 emptyGeneSN=cell(numel(model.genes)-numel(genesToAdd),1); -0571 emptyGeneSN(:)={''}; -0572 model.proteins=[emptyGeneSN;models{i}.proteins(genesToAdd)]; -0573 end -0574 else -0575 if isfield(model,'proteins') -0576 emptyGeneSN=cell(numel(genesToAdd),1); -0577 emptyGeneSN(:)={''}; -0578 model.proteins=[model.proteins;emptyGeneSN]; -0579 end -0580 end -0581 -0582 if isfield(models{i},'geneMiriams') -0583 if isfield(model,'geneMiriams') -0584 model.geneMiriams=[model.geneMiriams;models{i}.geneMiriams(genesToAdd)]; -0585 else -0586 emptyGeneMir=cell(numel(model.genes)-numel(genesToAdd),1); -0587 model.geneMiriams=[emptyGeneMir;models{i}.geneMiriams(genesToAdd)]; -0588 end -0589 else -0590 if isfield(model,'geneMiriams') -0591 emptyGeneMir=cell(numel(genesToAdd),1); -0592 model.geneMiriams=[model.geneMiriams;emptyGeneMir]; -0593 end -0594 end -0595 -0596 if isfield(models{i},'geneComps') -0597 if isfield(model,'geneComps') -0598 model.geneComps=[model.geneComps;models{i}.geneComps(genesToAdd)]; -0599 else -0600 emptyGeneMir=ones(numel(model.genes)-numel(genesToAdd),1); -0601 model.geneComps=[emptyGeneMir;models{i}.geneComps(genesToAdd)]; -0602 EM='Adding genes with compartment information to a model without such information. All existing genes will be assigned to the first compartment'; -0603 dispEM(EM,false); -0604 end -0605 else -0606 if isfield(model,'geneComps') -0607 emptyGeneMir=ones(numel(genesToAdd),1); -0608 model.geneComps=[model.geneComps;emptyGeneMir]; -0609 EM='Adding genes with compartment information to a model without such information. All existing genes will be assigned to the first compartment'; -0610 dispEM(EM,false); -0611 end -0612 end -0613 end -0614 -0615 %Remap the genes from the new model. The same thing as with -0616 %mets; this is a wasteful way to do it but I don't care right -0617 %now -0618 a = ismember(models{i}.genes,model.genes); -0619 -0620 %Just a check -0621 if ~all(a) -0622 EM='There was an unexpected error in matching genes'; -0623 dispEM(EM); -0624 end -0625 model.grRules=[model.grRules;models{i}.grRules]; -0626 end -0627 else -0628 %Add empty gene associations -0629 if isfield(model,'genes') -0630 emptyGene=cell(numel(models{i}.rxns),1); -0631 emptyGene(:)={''}; -0632 model.grRules=[model.grRules;emptyGene]; -0633 end -0634 end -0635 end -0636 %Fix grRules and reconstruct rxnGeneMat -0637 [grRules,rxnGeneMat] = standardizeGrRules(model,true); -0638 model.grRules = grRules; -0639 model.rxnGeneMat = rxnGeneMat; -0640 end +0537 +0538 if isfield(models{i},'geneComps') +0539 model.geneComps=models{i}.geneComps; +0540 end +0541 else +0542 %If gene info should be merged +0543 a=ismember(models{i}.genes,model.genes); +0544 +0545 genesToAdd=find(~a); +0546 +0547 %Only add extra gene info on new genes. This might not be +0548 %correct and should be changed later... +0549 if ~isempty(genesToAdd) +0550 model.genes = [model.genes; models{i}.genes(genesToAdd)]; +0551 model.geneFrom = [model.geneFrom; models{i}.geneFrom(genesToAdd)]; +0552 model.rxnGeneMat = [model.rxnGeneMat sparse(size(model.rxnGeneMat,1),numel(genesToAdd))]; +0553 +0554 if isfield(models{i},'geneShortNames') +0555 if isfield(model,'geneShortNames') +0556 model.geneShortNames=[model.geneShortNames;models{i}.geneShortNames(genesToAdd)]; +0557 else +0558 emptyGeneSN=cell(numel(model.genes)-numel(genesToAdd),1); +0559 emptyGeneSN(:)={''}; +0560 model.geneShortNames=[emptyGeneSN;models{i}.geneShortNames(genesToAdd)]; +0561 end +0562 else +0563 if isfield(model,'geneShortNames') +0564 emptyGeneSN=cell(numel(genesToAdd),1); +0565 emptyGeneSN(:)={''}; +0566 model.geneShortNames=[model.geneShortNames;emptyGeneSN]; +0567 end +0568 end +0569 +0570 if isfield(models{i},'proteins') +0571 if isfield(model,'proteins') +0572 model.proteins=[model.proteins;models{i}.proteins(genesToAdd)]; +0573 else +0574 emptyGeneSN=cell(numel(model.genes)-numel(genesToAdd),1); +0575 emptyGeneSN(:)={''}; +0576 model.proteins=[emptyGeneSN;models{i}.proteins(genesToAdd)]; +0577 end +0578 else +0579 if isfield(model,'proteins') +0580 emptyGeneSN=cell(numel(genesToAdd),1); +0581 emptyGeneSN(:)={''}; +0582 model.proteins=[model.proteins;emptyGeneSN]; +0583 end +0584 end +0585 +0586 if isfield(models{i},'geneMiriams') +0587 if isfield(model,'geneMiriams') +0588 model.geneMiriams=[model.geneMiriams;models{i}.geneMiriams(genesToAdd)]; +0589 else +0590 emptyGeneMir=cell(numel(model.genes)-numel(genesToAdd),1); +0591 model.geneMiriams=[emptyGeneMir;models{i}.geneMiriams(genesToAdd)]; +0592 end +0593 else +0594 if isfield(model,'geneMiriams') +0595 emptyGeneMir=cell(numel(genesToAdd),1); +0596 model.geneMiriams=[model.geneMiriams;emptyGeneMir]; +0597 end +0598 end +0599 +0600 if isfield(models{i},'geneComps') +0601 if isfield(model,'geneComps') +0602 model.geneComps=[model.geneComps;models{i}.geneComps(genesToAdd)]; +0603 else +0604 emptyGeneMir=ones(numel(model.genes)-numel(genesToAdd),1); +0605 model.geneComps=[emptyGeneMir;models{i}.geneComps(genesToAdd)]; +0606 EM='Adding genes with compartment information to a model without such information. All existing genes will be assigned to the first compartment'; +0607 dispEM(EM,false); +0608 end +0609 else +0610 if isfield(model,'geneComps') +0611 emptyGeneMir=ones(numel(genesToAdd),1); +0612 model.geneComps=[model.geneComps;emptyGeneMir]; +0613 EM='Adding genes with compartment information to a model without such information. All existing genes will be assigned to the first compartment'; +0614 dispEM(EM,false); +0615 end +0616 end +0617 end +0618 +0619 %Remap the genes from the new model. The same thing as with +0620 %mets; this is a wasteful way to do it but I do not care right +0621 %now +0622 a = ismember(models{i}.genes,model.genes); +0623 +0624 %Just a check +0625 if ~all(a) +0626 EM='There was an unexpected error in matching genes'; +0627 dispEM(EM); +0628 end +0629 model.grRules=[model.grRules;models{i}.grRules]; +0630 end +0631 else +0632 %Add empty gene associations +0633 if isfield(model,'genes') +0634 emptyGene=cell(numel(models{i}.rxns),1); +0635 emptyGene(:)={''}; +0636 model.grRules=[model.grRules;emptyGene]; +0637 end +0638 end +0639 end +0640 %Fix grRules and reconstruct rxnGeneMat +0641 [grRules,rxnGeneMat] = standardizeGrRules(model,true); +0642 model.grRules = grRules; +0643 model.rxnGeneMat = rxnGeneMat; +0644 %Flatten subSystems if possible +0645 if isfield(model,'subSystems') +0646 if all(cellfun(@(x) iscell(x) && isscalar(x), model.subSystems)) +0647 model.subSystems = transpose([model.subSystems{:}]); +0648 end +0649 end +0650 end
    Generated by m2html © 2005
    \ No newline at end of file diff --git a/doc/core/predictLocalization.html b/doc/core/predictLocalization.html index 317e1f4f..8b7b0ddf 100644 --- a/doc/core/predictLocalization.html +++ b/doc/core/predictLocalization.html @@ -831,413 +831,417 @@

    SOURCE CODE ^end 0728 if isfield(outModel,'subSystems') -0729 outModel.subSystems=[outModel.subSystems;{{'Inferred transport reactions'}}]; -0730 end -0731 if isfield(outModel,'eccodes') -0732 outModel.eccodes=[outModel.eccodes;{''}]; -0733 end -0734 if isfield(outModel,'rxnFrom') -0735 outModel.rxnFrom=[outModel.rxnFrom;{''}]; -0736 end -0737 if isfield(outModel,'rxnNotes') -0738 outModel.rxnNotes=[outModel.rxnNotes;{''}]; -0739 end -0740 if isfield(outModel,'rxnReferences') -0741 outModel.rxnReferences=[outModel.rxnReferences;{''}]; -0742 end -0743 if isfield(outModel,'rxnConfidenceScores') -0744 outModel.rxnConfidenceScores=[outModel.rxnConfidenceScores;NaN]; -0745 end -0746 if isfield(outModel,'rxnDeltaG') -0747 outModel.rxnDeltaG=[outModel.rxnDeltaG;NaN]; -0748 end -0749 end -0750 -0751 %Then remove all reactions and metabolites that aren't used in the final -0752 %solution from the optimization -0753 [~, J]=find(bestS(:,1:nER+nComps*nRxns)); -0754 K=true(numel(outModel.rxns),1); -0755 K(J)=false; -0756 K(end-nTransRxns+1:end)=false; -0757 outModel=removeReactions(outModel,K,true); -0758 -0759 %Remove all fake genes -0760 I=strncmp('&&FAKE&&',outModel.genes,8); -0761 outModel.genes(I)=[]; -0762 if isfield(outModel,'geneMiriams') -0763 outModel.geneMiriams(I)=[]; -0764 end -0765 if isfield(outModel,'geneShortNames') -0766 outModel.geneShortNames(I)=[]; -0767 end -0768 if isfield(outModel,'proteins') -0769 outModel.proteins(I)=[]; -0770 end -0771 outModel.rxnGeneMat(:,I)=[]; -0772 -0773 %Fix grRules and reconstruct rxnGeneMat -0774 [grRules,rxnGeneMat] = standardizeGrRules(outModel,true); -0775 outModel.grRules = grRules; -0776 outModel.rxnGeneMat = rxnGeneMat; -0777 end -0778 -0779 %Moves a gene and all associated reactions from one compartment to another -0780 function [S, g2c]=moveGene(S,model,g2c,geneToMove,toComp,nRxns,nMets) -0781 %Find the current compartment and update to the new one -0782 currentComp=find(g2c(geneToMove,:)); -0783 g2c(geneToMove,:)=false; -0784 g2c(geneToMove,toComp)=true; -0785 -0786 %Find the reactions in the original model that the gene controls -0787 [I, ~]=find(model.rxnGeneMat(:,geneToMove)); -0788 -0789 %Calculate their current positions in the S matrix -0790 oldRxns=I+(currentComp-1)*nRxns; -0791 -0792 %And their new positions -0793 newRxns=I+(toComp-1)*nRxns; -0794 -0795 %The metabolite ids also have to be changed in order to match the new -0796 %compartment -0797 metChange=nMets*(toComp-currentComp); +0729 if any(cellfun(@(x) iscell(x), outModel.subSystems)) +0730 outModel.subSystems=[outModel.subSystems;{{'Inferred transport reactions'}}]; +0731 else +0732 outModel.subSystems=[outModel.subSystems;{'Inferred transport reactions'}]; +0733 end +0734 end +0735 if isfield(outModel,'eccodes') +0736 outModel.eccodes=[outModel.eccodes;{''}]; +0737 end +0738 if isfield(outModel,'rxnFrom') +0739 outModel.rxnFrom=[outModel.rxnFrom;{''}]; +0740 end +0741 if isfield(outModel,'rxnNotes') +0742 outModel.rxnNotes=[outModel.rxnNotes;{''}]; +0743 end +0744 if isfield(outModel,'rxnReferences') +0745 outModel.rxnReferences=[outModel.rxnReferences;{''}]; +0746 end +0747 if isfield(outModel,'rxnConfidenceScores') +0748 outModel.rxnConfidenceScores=[outModel.rxnConfidenceScores;NaN]; +0749 end +0750 if isfield(outModel,'rxnDeltaG') +0751 outModel.rxnDeltaG=[outModel.rxnDeltaG;NaN]; +0752 end +0753 end +0754 +0755 %Then remove all reactions and metabolites that aren't used in the final +0756 %solution from the optimization +0757 [~, J]=find(bestS(:,1:nER+nComps*nRxns)); +0758 K=true(numel(outModel.rxns),1); +0759 K(J)=false; +0760 K(end-nTransRxns+1:end)=false; +0761 outModel=removeReactions(outModel,K,true); +0762 +0763 %Remove all fake genes +0764 I=strncmp('&&FAKE&&',outModel.genes,8); +0765 outModel.genes(I)=[]; +0766 if isfield(outModel,'geneMiriams') +0767 outModel.geneMiriams(I)=[]; +0768 end +0769 if isfield(outModel,'geneShortNames') +0770 outModel.geneShortNames(I)=[]; +0771 end +0772 if isfield(outModel,'proteins') +0773 outModel.proteins(I)=[]; +0774 end +0775 outModel.rxnGeneMat(:,I)=[]; +0776 +0777 %Fix grRules and reconstruct rxnGeneMat +0778 [grRules,rxnGeneMat] = standardizeGrRules(outModel,true); +0779 outModel.grRules = grRules; +0780 outModel.rxnGeneMat = rxnGeneMat; +0781 end +0782 +0783 %Moves a gene and all associated reactions from one compartment to another +0784 function [S, g2c]=moveGene(S,model,g2c,geneToMove,toComp,nRxns,nMets) +0785 %Find the current compartment and update to the new one +0786 currentComp=find(g2c(geneToMove,:)); +0787 g2c(geneToMove,:)=false; +0788 g2c(geneToMove,toComp)=true; +0789 +0790 %Find the reactions in the original model that the gene controls +0791 [I, ~]=find(model.rxnGeneMat(:,geneToMove)); +0792 +0793 %Calculate their current positions in the S matrix +0794 oldRxns=I+(currentComp-1)*nRxns; +0795 +0796 %And their new positions +0797 newRxns=I+(toComp-1)*nRxns; 0798 -0799 %Update the reactions -0800 [I, J, K]=find(S(:,oldRxns)); -0801 I=I+metChange; +0799 %The metabolite ids also have to be changed in order to match the new +0800 %compartment +0801 metChange=nMets*(toComp-currentComp); 0802 -0803 %Move the reactions -0804 S(:,oldRxns)=0; -0805 S(sub2ind(size(S),I,newRxns(J)))=K; -0806 end -0807 -0808 %Finds which metabolites are unconnected, in the sense that they are never -0809 %a product or only a product in a reversible reaction where one reactant is -0810 %only a product in the opposite direction of that reaction. This function -0811 %ignores exchange metabolites. Returns a vector of metabolite indexes. -0812 %metsToCheck is an array of metabolite indexes to check for connectivity. -0813 %If not supplied then all metabolites are checked -0814 function unconnected=findUnconnected(S,nEM,metsToCheck) -0815 if nargin>2 -0816 %Do this by deleting everything from the network that is not in -0817 %metsToCheck and that is not exchange metabolites -0818 I=false(size(S,1),1); -0819 I(1:nEM)=true; -0820 I(metsToCheck)=true; -0821 S=S(I,:); -0822 end -0823 -0824 em=false(size(S,1),1); -0825 em(1:nEM)=true; -0826 -0827 %Construct a matrix in which the reversible reactions are inverted -0828 I=sum(S>2,1) | sum(S>2,1); -0829 revS=S; -0830 revS(:,I)=revS(:,I)*-1; -0831 -0832 %First calculate the ones that are ok -0833 %Produced in 2 rxns, is exchange, is not used at all, is produced in -0834 %non-reversible, involved in more than 1 reversible reactions -0835 connected=sum(S>0,2)>1 | em | sum(S~=0,2)==0 | sum(S(:,~I)>0,2)>0 | sum(S(:,I)~=0,2)>1; -0836 -0837 %Then get the ones that are unconnected because they are never produced -0838 unconnected=sum(S>0 | revS>0,2)==0 & connected==false; -0839 -0840 %Then get the ones that are potentially unconnected -0841 maybeUnconnected=~connected & ~unconnected; -0842 %maybeUnconnected=find(maybeUnconnectedS); +0803 %Update the reactions +0804 [I, J, K]=find(S(:,oldRxns)); +0805 I=I+metChange; +0806 +0807 %Move the reactions +0808 S(:,oldRxns)=0; +0809 S(sub2ind(size(S),I,newRxns(J)))=K; +0810 end +0811 +0812 %Finds which metabolites are unconnected, in the sense that they are never +0813 %a product or only a product in a reversible reaction where one reactant is +0814 %only a product in the opposite direction of that reaction. This function +0815 %ignores exchange metabolites. Returns a vector of metabolite indexes. +0816 %metsToCheck is an array of metabolite indexes to check for connectivity. +0817 %If not supplied then all metabolites are checked +0818 function unconnected=findUnconnected(S,nEM,metsToCheck) +0819 if nargin>2 +0820 %Do this by deleting everything from the network that is not in +0821 %metsToCheck and that is not exchange metabolites +0822 I=false(size(S,1),1); +0823 I(1:nEM)=true; +0824 I(metsToCheck)=true; +0825 S=S(I,:); +0826 end +0827 +0828 em=false(size(S,1),1); +0829 em(1:nEM)=true; +0830 +0831 %Construct a matrix in which the reversible reactions are inverted +0832 I=sum(S>2,1) | sum(S>2,1); +0833 revS=S; +0834 revS(:,I)=revS(:,I)*-1; +0835 +0836 %First calculate the ones that are ok +0837 %Produced in 2 rxns, is exchange, is not used at all, is produced in +0838 %non-reversible, involved in more than 1 reversible reactions +0839 connected=sum(S>0,2)>1 | em | sum(S~=0,2)==0 | sum(S(:,~I)>0,2)>0 | sum(S(:,I)~=0,2)>1; +0840 +0841 %Then get the ones that are unconnected because they are never produced +0842 unconnected=sum(S>0 | revS>0,2)==0 & connected==false; 0843 -0844 %The metabolites in maybeUnconnected are involved in one reversible -0845 %reaction and not produced in any other reaction. This means that the -0846 %reactions which have at least one met in maybeUnconnected as reactant and -0847 %one as product are unconnected. The metabolites in maybeUnconnected that -0848 %are present in those reactions are then dead ends -0849 deadRxns=any(S(maybeUnconnected,:)>0) & any(S(maybeUnconnected,:)<0); -0850 -0851 %Get the mets involved in any of those reactions -0852 problematic=any(S(:,deadRxns)~=0,2); -0853 -0854 %If any of these are in the maybeUnconnected list then the metabolite is -0855 %unconnected -0856 unconnected(problematic & maybeUnconnected)=true; +0844 %Then get the ones that are potentially unconnected +0845 maybeUnconnected=~connected & ~unconnected; +0846 %maybeUnconnected=find(maybeUnconnectedS); +0847 +0848 %The metabolites in maybeUnconnected are involved in one reversible +0849 %reaction and not produced in any other reaction. This means that the +0850 %reactions which have at least one met in maybeUnconnected as reactant and +0851 %one as product are unconnected. The metabolites in maybeUnconnected that +0852 %are present in those reactions are then dead ends +0853 deadRxns=any(S(maybeUnconnected,:)>0) & any(S(maybeUnconnected,:)<0); +0854 +0855 %Get the mets involved in any of those reactions +0856 problematic=any(S(:,deadRxns)~=0,2); 0857 -0858 %Map back to metsToCheck -0859 if nargin>2 -0860 unconnected=metsToCheck(unconnected(nEM+1:end)); -0861 else -0862 unconnected=find(unconnected); -0863 end -0864 end -0865 -0866 %Given a set of unconnected metabolites, this function tries to move each -0867 %gene that could connect any of them, calculates the number of newly -0868 %connected metabolites minus the number of newly disconnected metabolites. -0869 %As some metabolites are very connected, only 25 genes are checked. Genes -0870 %that have a low score in their current compartment are more likely to be -0871 %moved -0872 function [geneIndex, moveTo, deltaConnected, deltaScore]=selectGenes(S,nEM,nMets,nER,nRxns,model,unconnected,g2c,GSS) -0873 %If moveTo is 0 then the gene cannot connect any of the metabolites -0874 moveTo=zeros(numel(model.genes),1); -0875 deltaConnected=zeros(numel(model.genes),1); -0876 -0877 %First get where the metabolites are now -0878 nComps=size(g2c,2); -0879 comps=ceil((unconnected-nEM)/((size(S,1)-nEM)/nComps)); +0858 %If any of these are in the maybeUnconnected list then the metabolite is +0859 %unconnected +0860 unconnected(problematic & maybeUnconnected)=true; +0861 +0862 %Map back to metsToCheck +0863 if nargin>2 +0864 unconnected=metsToCheck(unconnected(nEM+1:end)); +0865 else +0866 unconnected=find(unconnected); +0867 end +0868 end +0869 +0870 %Given a set of unconnected metabolites, this function tries to move each +0871 %gene that could connect any of them, calculates the number of newly +0872 %connected metabolites minus the number of newly disconnected metabolites. +0873 %As some metabolites are very connected, only 25 genes are checked. Genes +0874 %that have a low score in their current compartment are more likely to be +0875 %moved +0876 function [geneIndex, moveTo, deltaConnected, deltaScore]=selectGenes(S,nEM,nMets,nER,nRxns,model,unconnected,g2c,GSS) +0877 %If moveTo is 0 then the gene cannot connect any of the metabolites +0878 moveTo=zeros(numel(model.genes),1); +0879 deltaConnected=zeros(numel(model.genes),1); 0880 -0881 %Find the corresponding metabolite indexes if they all were in the default -0882 %compartment -0883 dcIndexes=unique(unconnected-(comps-1)*nMets); +0881 %First get where the metabolites are now +0882 nComps=size(g2c,2); +0883 comps=ceil((unconnected-nEM)/((size(S,1)-nEM)/nComps)); 0884 -0885 %Then find them if they were in any other compartment -0886 allIndexes=dcIndexes; -0887 for i=1:nComps-1 -0888 allIndexes=[allIndexes;dcIndexes+nMets*i]; -0889 end -0890 -0891 %Also check which reversible reactions that could be used -0892 I=sum(S>2,1) | sum(S>2,1); -0893 revS=S; -0894 revS(:,I)=revS(:,I)*-1; -0895 -0896 %Find all reactions that could make any of the unconnected metabolites in -0897 %some other compartment -0898 newMets=setdiff(allIndexes,unconnected); -0899 [~, potential]=find(S(newMets,:)>0 | revS(newMets,:)>0); -0900 potential(potential<=nER | potential>nER+nRxns*nComps)=[]; %No exchange rxns or transport rxns -0901 -0902 %Map J to the real metabolic reactions in model -0903 rxnComps=ceil((potential-nER)/(nRxns)); -0904 -0905 %Find the corresponding reaction indexes if they all were in the default -0906 %compartment -0907 dcRxnIndexes=potential-(rxnComps-1)*nRxns; +0885 %Find the corresponding metabolite indexes if they all were in the default +0886 %compartment +0887 dcIndexes=unique(unconnected-(comps-1)*nMets); +0888 +0889 %Then find them if they were in any other compartment +0890 allIndexes=dcIndexes; +0891 for i=1:nComps-1 +0892 allIndexes=[allIndexes;dcIndexes+nMets*i]; +0893 end +0894 +0895 %Also check which reversible reactions that could be used +0896 I=sum(S>2,1) | sum(S>2,1); +0897 revS=S; +0898 revS(:,I)=revS(:,I)*-1; +0899 +0900 %Find all reactions that could make any of the unconnected metabolites in +0901 %some other compartment +0902 newMets=setdiff(allIndexes,unconnected); +0903 [~, potential]=find(S(newMets,:)>0 | revS(newMets,:)>0); +0904 potential(potential<=nER | potential>nER+nRxns*nComps)=[]; %No exchange rxns or transport rxns +0905 +0906 %Map J to the real metabolic reactions in model +0907 rxnComps=ceil((potential-nER)/(nRxns)); 0908 -0909 %Get the genes for those reactions -0910 genes=find(sum(model.rxnGeneMat(dcRxnIndexes,:)>0,1)); -0911 -0912 %For some cases there can be very many reactions to connect something. This -0913 %is in particular true in the beginning of the optimization if, say, ATP is -0914 %unconnected. Therefore limit the number of genes to be checked to 25. -0915 %Weigh so that genes with bad scores in their current compartment are more -0916 %likely to be moved. -0917 -0918 %Get scores for these genes -0919 [~, J]=find(g2c(genes,:)); -0920 -0921 %Add a small weight so that genes in their best compartment could be moved -0922 %as well -0923 geneScores=GSS.scores(sub2ind(size(g2c),genes(:),J)); -0924 modGeneScores=1.1-geneScores; -0925 if numel(genes)>25 -0926 rGenes=genes(randsample(numel(genes),min(numel(genes),25),true,modGeneScores)); -0927 -0928 %The sampling with weights could give duplicates -0929 rGenes=unique(rGenes); -0930 -0931 %Reorder the geneScores to match -0932 [~, I]=ismember(rGenes,genes); -0933 geneScores=geneScores(I); -0934 genes=rGenes; -0935 end -0936 for i=1:numel(genes) -0937 %Since one gene is moved at a time, only metabolites involved in any of -0938 %the reactions for that gene can become unconnected. This helps to -0939 %speed up the algorithm. First get all involved reactions in the -0940 %default compartment -0941 rxns=find(model.rxnGeneMat(:,genes(i))); -0942 -0943 %Then get their mets -0944 mets=find(sum(model.S(:,rxns)~=0,2)>0); -0945 -0946 %Then get their indexes in all compartments -0947 allIndexes=mets; -0948 for j=1:nComps-1 -0949 allIndexes=[allIndexes;mets+nMets*j]; -0950 end -0951 -0952 %Check which of the unconnected metabolites that these reactions -0953 %correspond to. This could have been done earlier, but it is fast. The -0954 %reversibility check is skipped because it is unlikely to be an issue -0955 %here. Worst case is that the gene is tested once to much -0956 [I, ~]=find(model.S(:,rxns)); -0957 moveToComps=unique(comps(ismember(dcIndexes,I))); -0958 -0959 %Try to move the gene to each of the compartments -0960 bestMove=-inf; -0961 bestComp=[]; -0962 for j=1:numel(moveToComps) -0963 newS=moveGene(S,model,g2c,genes(i),moveToComps(j),nRxns,nMets); -0964 -0965 %Check how many metabolites that are unconnected after moving the -0966 %gene -0967 dConnected=numel(unconnected)-numel(findUnconnected(newS,nEM,[allIndexes;unconnected])); -0968 if dConnected>bestMove -0969 bestMove=dConnected; -0970 bestComp=moveToComps(j); -0971 end -0972 end -0973 -0974 %Add the difference in connectivity and where the genes should be moved -0975 moveTo(genes(i))=bestComp; -0976 deltaConnected(genes(i))=bestMove; -0977 end -0978 -0979 %Finish up -0980 geneIndex=genes(:); -0981 moveTo=moveTo(geneIndex); -0982 deltaConnected=deltaConnected(geneIndex); -0983 deltaScore=GSS.scores(sub2ind(size(g2c),geneIndex(:),moveTo))-geneScores; -0984 end -0985 -0986 %Small function to add a transport reactions between two metabolites. -0987 %Transport reactions are written as having a coefficient 2.0 for both -0988 %reactant and product. This is not a "real" reaction, but since all normal -0989 %reactions have coefficient -1/1 or -10/10 it is a compact way of writing -0990 %it -0991 function S=addTransport(S,nRxns,nER,nMets,nEM,nComps,metA,metB) -0992 mets=[metA;metB]; -0993 %Find the current compartments for the metabolites -0994 comps=ceil((mets-nEM)/((size(S,1)-nEM)/nComps)); -0995 -0996 if sum(comps==1)~=1 -0997 EM='Tried to create a transport reaction from a non-default compartment'; -0998 dispEM(EM); -0999 end -1000 -1001 %Calculate the reaction index -1002 rIndex=(nER+nRxns*nComps)+mets(comps~=1)-nEM-nMets; -1003 -1004 S(mets,rIndex)=2; -1005 end -1006 -1007 %Scores a network based on the localization of the genes and the number of -1008 %transporter reactions used -1009 function [score, geneScore, transportCost]=scoreModel(S,g2c,GSS,transportCost) -1010 [I, J]=find(g2c); -1011 geneScore=sum(GSS.scores(sub2ind(size(g2c),I,J))); -1012 [I, ~]=find(S==2); -1013 I=unique(I); -1014 transportCost=sum(transportCost(I)); -1015 score=geneScore-transportCost; -1016 end -1017 -1018 % To avoid dependency on stats toolbox, use this alternative implementation -1019 % of randsample, source: -1020 % https://github.com/gpeyre/numerical-tours/blob/dacee30081c04ef5f67b26b387ead85f2b193af9/matlab/toolbox_signal/randsample.m -1021 function y = randsample(n, k, replace, w) -1022 %RANDSAMPLE Random sample, with or without replacement. -1023 % Y = RANDSAMPLE(N,K) returns Y as a vector of K values sampled uniformly -1024 % at random, without replacement, from the integers 1:N. -1025 % -1026 % Y = RANDSAMPLE(POPULATION,K) returns K values sampled uniformly at -1027 % random, without replacement, from the values in the vector POPULATION. -1028 % -1029 % Y = RANDSAMPLE(...,REPLACE) returns a sample taken with replacement if -1030 % REPLACE is true, or without replacement if REPLACE is false (the default). -1031 % -1032 % Y = RANDSAMPLE(...,true,W) returns a weighted sample, using positive -1033 % weights W, taken with replacement. W is often a vector of probabilities. -1034 % This function does not support weighted sampling without replacement. +0909 %Find the corresponding reaction indexes if they all were in the default +0910 %compartment +0911 dcRxnIndexes=potential-(rxnComps-1)*nRxns; +0912 +0913 %Get the genes for those reactions +0914 genes=find(sum(model.rxnGeneMat(dcRxnIndexes,:)>0,1)); +0915 +0916 %For some cases there can be very many reactions to connect something. This +0917 %is in particular true in the beginning of the optimization if, say, ATP is +0918 %unconnected. Therefore limit the number of genes to be checked to 25. +0919 %Weigh so that genes with bad scores in their current compartment are more +0920 %likely to be moved. +0921 +0922 %Get scores for these genes +0923 [~, J]=find(g2c(genes,:)); +0924 +0925 %Add a small weight so that genes in their best compartment could be moved +0926 %as well +0927 geneScores=GSS.scores(sub2ind(size(g2c),genes(:),J)); +0928 modGeneScores=1.1-geneScores; +0929 if numel(genes)>25 +0930 rGenes=genes(randsample(numel(genes),min(numel(genes),25),true,modGeneScores)); +0931 +0932 %The sampling with weights could give duplicates +0933 rGenes=unique(rGenes); +0934 +0935 %Reorder the geneScores to match +0936 [~, I]=ismember(rGenes,genes); +0937 geneScores=geneScores(I); +0938 genes=rGenes; +0939 end +0940 for i=1:numel(genes) +0941 %Since one gene is moved at a time, only metabolites involved in any of +0942 %the reactions for that gene can become unconnected. This helps to +0943 %speed up the algorithm. First get all involved reactions in the +0944 %default compartment +0945 rxns=find(model.rxnGeneMat(:,genes(i))); +0946 +0947 %Then get their mets +0948 mets=find(sum(model.S(:,rxns)~=0,2)>0); +0949 +0950 %Then get their indexes in all compartments +0951 allIndexes=mets; +0952 for j=1:nComps-1 +0953 allIndexes=[allIndexes;mets+nMets*j]; +0954 end +0955 +0956 %Check which of the unconnected metabolites that these reactions +0957 %correspond to. This could have been done earlier, but it is fast. The +0958 %reversibility check is skipped because it is unlikely to be an issue +0959 %here. Worst case is that the gene is tested once to much +0960 [I, ~]=find(model.S(:,rxns)); +0961 moveToComps=unique(comps(ismember(dcIndexes,I))); +0962 +0963 %Try to move the gene to each of the compartments +0964 bestMove=-inf; +0965 bestComp=[]; +0966 for j=1:numel(moveToComps) +0967 newS=moveGene(S,model,g2c,genes(i),moveToComps(j),nRxns,nMets); +0968 +0969 %Check how many metabolites that are unconnected after moving the +0970 %gene +0971 dConnected=numel(unconnected)-numel(findUnconnected(newS,nEM,[allIndexes;unconnected])); +0972 if dConnected>bestMove +0973 bestMove=dConnected; +0974 bestComp=moveToComps(j); +0975 end +0976 end +0977 +0978 %Add the difference in connectivity and where the genes should be moved +0979 moveTo(genes(i))=bestComp; +0980 deltaConnected(genes(i))=bestMove; +0981 end +0982 +0983 %Finish up +0984 geneIndex=genes(:); +0985 moveTo=moveTo(geneIndex); +0986 deltaConnected=deltaConnected(geneIndex); +0987 deltaScore=GSS.scores(sub2ind(size(g2c),geneIndex(:),moveTo))-geneScores; +0988 end +0989 +0990 %Small function to add a transport reactions between two metabolites. +0991 %Transport reactions are written as having a coefficient 2.0 for both +0992 %reactant and product. This is not a "real" reaction, but since all normal +0993 %reactions have coefficient -1/1 or -10/10 it is a compact way of writing +0994 %it +0995 function S=addTransport(S,nRxns,nER,nMets,nEM,nComps,metA,metB) +0996 mets=[metA;metB]; +0997 %Find the current compartments for the metabolites +0998 comps=ceil((mets-nEM)/((size(S,1)-nEM)/nComps)); +0999 +1000 if sum(comps==1)~=1 +1001 EM='Tried to create a transport reaction from a non-default compartment'; +1002 dispEM(EM); +1003 end +1004 +1005 %Calculate the reaction index +1006 rIndex=(nER+nRxns*nComps)+mets(comps~=1)-nEM-nMets; +1007 +1008 S(mets,rIndex)=2; +1009 end +1010 +1011 %Scores a network based on the localization of the genes and the number of +1012 %transporter reactions used +1013 function [score, geneScore, transportCost]=scoreModel(S,g2c,GSS,transportCost) +1014 [I, J]=find(g2c); +1015 geneScore=sum(GSS.scores(sub2ind(size(g2c),I,J))); +1016 [I, ~]=find(S==2); +1017 I=unique(I); +1018 transportCost=sum(transportCost(I)); +1019 score=geneScore-transportCost; +1020 end +1021 +1022 % To avoid dependency on stats toolbox, use this alternative implementation +1023 % of randsample, source: +1024 % https://github.com/gpeyre/numerical-tours/blob/dacee30081c04ef5f67b26b387ead85f2b193af9/matlab/toolbox_signal/randsample.m +1025 function y = randsample(n, k, replace, w) +1026 %RANDSAMPLE Random sample, with or without replacement. +1027 % Y = RANDSAMPLE(N,K) returns Y as a vector of K values sampled uniformly +1028 % at random, without replacement, from the integers 1:N. +1029 % +1030 % Y = RANDSAMPLE(POPULATION,K) returns K values sampled uniformly at +1031 % random, without replacement, from the values in the vector POPULATION. +1032 % +1033 % Y = RANDSAMPLE(...,REPLACE) returns a sample taken with replacement if +1034 % REPLACE is true, or without replacement if REPLACE is false (the default). 1035 % -1036 % Example: Generate a random sequence of the characters ACGT, with -1037 % replacement, according to specified probabilities. -1038 % -1039 % R = randsample('ACGT',48,true,[0.15 0.35 0.35 0.15]) -1040 % -1041 % See also RAND, RANDPERM. -1042 -1043 % Copyright 1993-2008 The MathWorks, Inc. -1044 % $Revision: 1.1.4.3 $ $Date: 2008/12/01 08:09:34 $ -1045 -1046 if nargin < 2 -1047 error('stats:randsample:TooFewInputs','Requires two input arguments.'); -1048 elseif numel(n) == 1 -1049 population = []; -1050 else -1051 population = n; -1052 n = numel(population); -1053 if length(population)~=n -1054 error('stats:randsample:BadPopulation','POPULATION must be a vector.'); -1055 end -1056 end -1057 -1058 if nargin < 3 -1059 replace = false; +1036 % Y = RANDSAMPLE(...,true,W) returns a weighted sample, using positive +1037 % weights W, taken with replacement. W is often a vector of probabilities. +1038 % This function does not support weighted sampling without replacement. +1039 % +1040 % Example: Generate a random sequence of the characters ACGT, with +1041 % replacement, according to specified probabilities. +1042 % +1043 % R = randsample('ACGT',48,true,[0.15 0.35 0.35 0.15]) +1044 % +1045 % See also RAND, RANDPERM. +1046 +1047 % Copyright 1993-2008 The MathWorks, Inc. +1048 % $Revision: 1.1.4.3 $ $Date: 2008/12/01 08:09:34 $ +1049 +1050 if nargin < 2 +1051 error('stats:randsample:TooFewInputs','Requires two input arguments.'); +1052 elseif numel(n) == 1 +1053 population = []; +1054 else +1055 population = n; +1056 n = numel(population); +1057 if length(population)~=n +1058 error('stats:randsample:BadPopulation','POPULATION must be a vector.'); +1059 end 1060 end 1061 -1062 if nargin < 4 -1063 w = []; -1064 elseif ~isempty(w) -1065 if length(w) ~= n -1066 if isempty(population) -1067 error('stats:randsample:InputSizeMismatch',... -1068 'W must have length equal to N.'); -1069 else -1070 error('stats:randsample:InputSizeMismatch',... -1071 'W must have the same length as the population.'); -1072 end -1073 else -1074 p = w(:)' / sum(w); -1075 end -1076 end -1077 -1078 switch replace -1079 -1080 % Sample with replacement -1081 case {true, 'true', 1} -1082 if isempty(w) -1083 y = ceil(n .* rand(k,1)); -1084 else -1085 [dum, y] = histc(rand(k,1),[0 cumsum(p)]); -1086 end -1087 -1088 % Sample without replacement -1089 case {false, 'false', 0} -1090 if k > n -1091 if isempty(population) -1092 error('stats:randsample:SampleTooLarge',... -1093 'K must be less than or equal to N for sampling without replacement.'); -1094 else -1095 error('stats:randsample:SampleTooLarge',... -1096 'K must be less than or equal to the population size.'); -1097 end -1098 end -1099 -1100 if isempty(w) -1101 % If the sample is a sizeable fraction of the population, -1102 % just randomize the whole population (which involves a full -1103 % sort of n random values), and take the first k. -1104 if 4*k > n -1105 rp = randperm(n); -1106 y = rp(1:k); -1107 -1108 % If the sample is a small fraction of the population, a full sort -1109 % is wasteful. Repeatedly sample with replacement until there are -1110 % k unique values. -1111 else -1112 x = zeros(1,n); % flags -1113 sumx = 0; -1114 while sumx < k -1115 x(ceil(n * rand(1,k-sumx))) = 1; % sample w/replacement -1116 sumx = sum(x); % count how many unique elements so far -1117 end -1118 y = find(x > 0); -1119 y = y(randperm(k)); -1120 end -1121 else -1122 error('stats:randsample:NoWeighting',... -1123 'Weighted sampling without replacement is not supported.'); -1124 end -1125 otherwise -1126 error('stats:randsample:BadReplaceValue',... -1127 'REPLACE must be either true or false.'); -1128 end -1129 -1130 if ~isempty(population) -1131 y = population(y); -1132 else -1133 y = y(:); -1134 end -1135 end +1062 if nargin < 3 +1063 replace = false; +1064 end +1065 +1066 if nargin < 4 +1067 w = []; +1068 elseif ~isempty(w) +1069 if length(w) ~= n +1070 if isempty(population) +1071 error('stats:randsample:InputSizeMismatch',... +1072 'W must have length equal to N.'); +1073 else +1074 error('stats:randsample:InputSizeMismatch',... +1075 'W must have the same length as the population.'); +1076 end +1077 else +1078 p = w(:)' / sum(w); +1079 end +1080 end +1081 +1082 switch replace +1083 +1084 % Sample with replacement +1085 case {true, 'true', 1} +1086 if isempty(w) +1087 y = ceil(n .* rand(k,1)); +1088 else +1089 [dum, y] = histc(rand(k,1),[0 cumsum(p)]); +1090 end +1091 +1092 % Sample without replacement +1093 case {false, 'false', 0} +1094 if k > n +1095 if isempty(population) +1096 error('stats:randsample:SampleTooLarge',... +1097 'K must be less than or equal to N for sampling without replacement.'); +1098 else +1099 error('stats:randsample:SampleTooLarge',... +1100 'K must be less than or equal to the population size.'); +1101 end +1102 end +1103 +1104 if isempty(w) +1105 % If the sample is a sizeable fraction of the population, +1106 % just randomize the whole population (which involves a full +1107 % sort of n random values), and take the first k. +1108 if 4*k > n +1109 rp = randperm(n); +1110 y = rp(1:k); +1111 +1112 % If the sample is a small fraction of the population, a full sort +1113 % is wasteful. Repeatedly sample with replacement until there are +1114 % k unique values. +1115 else +1116 x = zeros(1,n); % flags +1117 sumx = 0; +1118 while sumx < k +1119 x(ceil(n * rand(1,k-sumx))) = 1; % sample w/replacement +1120 sumx = sum(x); % count how many unique elements so far +1121 end +1122 y = find(x > 0); +1123 y = y(randperm(k)); +1124 end +1125 else +1126 error('stats:randsample:NoWeighting',... +1127 'Weighted sampling without replacement is not supported.'); +1128 end +1129 otherwise +1130 error('stats:randsample:BadReplaceValue',... +1131 'REPLACE must be either true or false.'); +1132 end +1133 +1134 if ~isempty(population) +1135 y = population(y); +1136 else +1137 y = y(:); +1138 end +1139 end
    Generated by m2html © 2005
    \ No newline at end of file diff --git a/doc/core/sortModel.html b/doc/core/sortModel.html index 9033f9dc..b14269df 100644 --- a/doc/core/sortModel.html +++ b/doc/core/sortModel.html @@ -127,120 +127,123 @@

    SOURCE CODE ^''; 0066 subsystemsConcatenated=''; 0067 for i=1:numel(model.subSystems) -0068 subsystemsConcatenated{i,1}=strjoin(model.subSystems{i,1},';'); -0069 if ~isempty(model.subSystems{i,1}) -0070 for j=1:numel(model.subSystems{i,1}) -0071 subsystemsUnique{numel(subsystemsUnique)+1,1}=model.subSystems{i,1}{1,j}; -0072 end -0073 end -0074 end -0075 subsystemsUnique=unique(subsystemsUnique); -0076 for i=1:numel(subsystemsUnique) -0077 %Get all reactions for that subsystem -0078 rxns=find(~cellfun(@isempty,regexp(subsystemsConcatenated,subsystemsUnique(i)))); -0079 -0080 %Temporarily ignore large subsystems because of inefficient -0081 %implementation -0082 if numel(rxns)<2 || numel(rxns)>250 -0083 continue; -0084 end -0085 -0086 nRxns=numel(rxns); -0087 revRxns=rxns(model.rev(rxns)~=0); +0068 if ~iscell(model.subSystems{i}) +0069 model.subSystems{i} = {model.subSystems{i}}; +0070 end +0071 subsystemsConcatenated{i,1}=strjoin(model.subSystems{i,1},';'); +0072 if ~isempty(model.subSystems{i,1}) +0073 for j=1:numel(model.subSystems{i,1}) +0074 subsystemsUnique{numel(subsystemsUnique)+1,1}=model.subSystems{i,1}{1,j}; +0075 end +0076 end +0077 end +0078 subsystemsUnique=unique(subsystemsUnique); +0079 for i=1:numel(subsystemsUnique) +0080 %Get all reactions for that subsystem +0081 rxns=find(~cellfun(@isempty,regexp(subsystemsConcatenated,subsystemsUnique(i)))); +0082 +0083 %Temporarily ignore large subsystems because of inefficient +0084 %implementation +0085 if numel(rxns)<2 || numel(rxns)>250 +0086 continue; +0087 end 0088 -0089 %This variable will hold the current reversibility directions of -0090 %the reversible reactions. 1 means the same direction as in the -0091 %original model and -1 means the opposite direction. -0092 oldRev=ones(numel(revRxns),1); -0093 -0094 %The problem could probably be solved analytically but a simple -0095 %random method is implemented here instead. Two reactions are -0096 %chosen randomly and their positions are switched. A score is -0097 %calculated based on the number of metabolites that are produced -0098 %before they are consumed. If the perturbed model has a better or -0099 %equal score than the original the reaction order is switched. If -0100 %no increase in score has been seen after 1000*rxnsInSubsystem then -0101 %the optimization is terminated -0102 -0103 rxnOrder=1:nRxns; -0104 oldScore=-inf; -0105 counter=0; -0106 firstIter=true; -0107 while 1==1 -0108 counter=counter+1; -0109 if counter==100*nRxns -0110 break; -0111 end -0112 -0113 newRxnOrder=rxnOrder; -0114 rev=oldRev; +0089 nRxns=numel(rxns); +0090 revRxns=rxns(model.rev(rxns)~=0); +0091 +0092 %This variable will hold the current reversibility directions of +0093 %the reversible reactions. 1 means the same direction as in the +0094 %original model and -1 means the opposite direction. +0095 oldRev=ones(numel(revRxns),1); +0096 +0097 %The problem could probably be solved analytically but a simple +0098 %random method is implemented here instead. Two reactions are +0099 %chosen randomly and their positions are switched. A score is +0100 %calculated based on the number of metabolites that are produced +0101 %before they are consumed. If the perturbed model has a better or +0102 %equal score than the original the reaction order is switched. If +0103 %no increase in score has been seen after 1000*rxnsInSubsystem then +0104 %the optimization is terminated +0105 +0106 rxnOrder=1:nRxns; +0107 oldScore=-inf; +0108 counter=0; +0109 firstIter=true; +0110 while 1==1 +0111 counter=counter+1; +0112 if counter==100*nRxns +0113 break; +0114 end 0115 -0116 if firstIter==false -0117 y=randperm(nRxns,2); -0118 -0119 %Switch the order -0120 newRxnOrder(y(1))=rxnOrder(y(2)); -0121 newRxnOrder(y(2))=rxnOrder(y(1)); -0122 -0123 %With a 50% chance, also switch the reversibility of one of -0124 %the reactions -0125 if rand()>0.5 && numel(rev)>1 -0126 n=randperm(numel(rev),1); -0127 rev(n)=rev(n)*-1; -0128 end -0129 end -0130 firstIter=false; -0131 -0132 tempS=model.S; -0133 -0134 %Switch the directionalities -0135 for j=1:numel(rev) -0136 if rev(j)==-1 -0137 tempS(:,revRxns(j))=tempS(:,revRxns(j)).*-1; -0138 end -0139 end -0140 -0141 %Get the metabolites that are involved and when they are -0142 %produced/consumed -0143 s=tempS(:,newRxnOrder); -0144 -0145 %Remove mets that aren't used in both directions -0146 s=s(any(s,2),:); +0116 newRxnOrder=rxnOrder; +0117 rev=oldRev; +0118 +0119 if firstIter==false +0120 y=randperm(nRxns,2); +0121 +0122 %Switch the order +0123 newRxnOrder(y(1))=rxnOrder(y(2)); +0124 newRxnOrder(y(2))=rxnOrder(y(1)); +0125 +0126 %With a 50% chance, also switch the reversibility of one of +0127 %the reactions +0128 if rand()>0.5 && numel(rev)>1 +0129 n=randperm(numel(rev),1); +0130 rev(n)=rev(n)*-1; +0131 end +0132 end +0133 firstIter=false; +0134 +0135 tempS=model.S; +0136 +0137 %Switch the directionalities +0138 for j=1:numel(rev) +0139 if rev(j)==-1 +0140 tempS(:,revRxns(j))=tempS(:,revRxns(j)).*-1; +0141 end +0142 end +0143 +0144 %Get the metabolites that are involved and when they are +0145 %produced/consumed +0146 s=tempS(:,newRxnOrder); 0147 -0148 %Add so that all mets are produced and consumed in the end -0149 s=[s ones(size(s,1),1) ones(size(s,1),1)*-1]; +0148 %Remove mets that aren't used in both directions +0149 s=s(any(s,2),:); 0150 -0151 %For each metabolite, find the reaction where it's first -0152 %produced and the reaction where it's first consumed -0153 s1=s>0; -0154 r1=arrayfun(@(x) find(s1(x,:),1,'first'),1:size(s1,1)); -0155 s2=s<0; -0156 r2=arrayfun(@(x) find(s2(x,:),1,'first'),1:size(s2,1)); -0157 -0158 score=sum(r1<r2); -0159 -0160 if score>=oldScore -0161 if score>oldScore -0162 counter=0; -0163 end -0164 oldScore=score; -0165 oldRev=rev; -0166 rxnOrder=newRxnOrder; -0167 end -0168 end -0169 -0170 %Update the model for this subsystem -0171 for j=1:numel(oldRev) -0172 if oldRev(j)==-1 -0173 model.S(:,revRxns(j))=model.S(:,revRxns(j)).*-1; -0174 end -0175 end -0176 order=1:numel(model.rxns); -0177 order(rxns)=rxns(rxnOrder); -0178 model=permuteModel(model, order, 'rxns'); -0179 end -0180 end -0181 end +0151 %Add so that all mets are produced and consumed in the end +0152 s=[s ones(size(s,1),1) ones(size(s,1),1)*-1]; +0153 +0154 %For each metabolite, find the reaction where it's first +0155 %produced and the reaction where it's first consumed +0156 s1=s>0; +0157 r1=arrayfun(@(x) find(s1(x,:),1,'first'),1:size(s1,1)); +0158 s2=s<0; +0159 r2=arrayfun(@(x) find(s2(x,:),1,'first'),1:size(s2,1)); +0160 +0161 score=sum(r1<r2); +0162 +0163 if score>=oldScore +0164 if score>oldScore +0165 counter=0; +0166 end +0167 oldScore=score; +0168 oldRev=rev; +0169 rxnOrder=newRxnOrder; +0170 end +0171 end +0172 +0173 %Update the model for this subsystem +0174 for j=1:numel(oldRev) +0175 if oldRev(j)==-1 +0176 model.S(:,revRxns(j))=model.S(:,revRxns(j)).*-1; +0177 end +0178 end +0179 order=1:numel(model.rxns); +0180 order(rxns)=rxns(rxnOrder); +0181 model=permuteModel(model, order, 'rxns'); +0182 end +0183 end +0184 end
    Generated by m2html © 2005
    \ No newline at end of file diff --git a/doc/external/kegg/getKEGGModelForOrganism.html b/doc/external/kegg/getKEGGModelForOrganism.html index 1aeb3f42..283e89f7 100644 --- a/doc/external/kegg/getKEGGModelForOrganism.html +++ b/doc/external/kegg/getKEGGModelForOrganism.html @@ -1310,37 +1310,33 @@

    SOURCE CODE ^%Fix subsystems -1030 emptySubSystems=cellfun(@isempty, model.subSystems); -1031 model.subSystems(emptySubSystems)={{''}}; -1032 -1033 %Add the description to the reactions -1034 for i=1:numel(model.rxns) -1035 if ~isempty(model.rxnNotes{i}) -1036 model.rxnNotes(i)=strcat('Included by getKEGGModelForOrganism (using HMMs).',model.rxnNotes(i)); -1037 model.rxnNotes(i)=strrep(model.rxnNotes(i),'.','. '); -1038 else -1039 model.rxnNotes(i)={'Included by getKEGGModelForOrganism (using HMMs)'}; -1040 end +1029 %Add the description to the reactions +1030 for i=1:numel(model.rxns) +1031 if ~isempty(model.rxnNotes{i}) +1032 model.rxnNotes(i)=strcat('Included by getKEGGModelForOrganism (using HMMs).',model.rxnNotes(i)); +1033 model.rxnNotes(i)=strrep(model.rxnNotes(i),'.','. '); +1034 else +1035 model.rxnNotes(i)={'Included by getKEGGModelForOrganism (using HMMs)'}; +1036 end +1037 end +1038 %Remove the temp fasta file +1039 delete(fastaFile) +1040 fprintf('COMPLETE\n\n*** Model reconstruction complete ***\n'); 1041 end -1042 %Remove the temp fasta file -1043 delete(fastaFile) -1044 fprintf('COMPLETE\n\n*** Model reconstruction complete ***\n'); -1045 end -1046 -1047 function files=listFiles(directory) -1048 %Supporter function to list the files in a directory and return them as a -1049 %cell array -1050 temp=dir(directory); -1051 files=cell(numel(temp),1); -1052 for i=1:numel(temp) -1053 files{i}=temp(i,1).name; -1054 end -1055 files=strrep(files,'.fa',''); -1056 files=strrep(files,'.hmm',''); -1057 files=strrep(files,'.out',''); -1058 files=strrep(files,'.faw',''); -1059 end +1042 +1043 function files=listFiles(directory) +1044 %Supporter function to list the files in a directory and return them as a +1045 %cell array +1046 temp=dir(directory); +1047 files=cell(numel(temp),1); +1048 for i=1:numel(temp) +1049 files{i}=temp(i,1).name; +1050 end +1051 files=strrep(files,'.fa',''); +1052 files=strrep(files,'.hmm',''); +1053 files=strrep(files,'.out',''); +1054 files=strrep(files,'.faw',''); +1055 end
    Generated by m2html © 2005
    \ No newline at end of file diff --git a/doc/external/kegg/getRxnsFromKEGG.html b/doc/external/kegg/getRxnsFromKEGG.html index 603c3d76..f419f5d0 100644 --- a/doc/external/kegg/getRxnsFromKEGG.html +++ b/doc/external/kegg/getRxnsFromKEGG.html @@ -240,373 +240,381 @@

    SOURCE CODE ^if numel(tline)<12 0132 continue; 0133 end -0134 -0135 %Check if it's a new reaction -0136 if strcmp(tline(1:12),'ENTRY ') -0137 rxnCounter=rxnCounter+1; -0138 -0139 %Add empty strings where there should be such -0140 model.rxnNames{rxnCounter}=''; -0141 model.eccodes{rxnCounter}=''; -0142 %model.subSystems{rxnCounter}=''; %remain empty cell -0143 model.rxnNotes{rxnCounter}=''; -0144 equations{rxnCounter}=''; -0145 -0146 %Add reaction ID (always 6 characters) -0147 model.rxns{rxnCounter}=tline(13:18); -0148 orthology=false; -0149 pathway=false; -0150 module=false; -0151 -0152 %Add KEGG reaction ID miriam -0153 tempStruct=model.rxnMiriams{rxnCounter}; -0154 tempStruct.name{1,1}='kegg.reaction'; -0155 tempStruct.value{1,1}=tline(13:18); -0156 model.rxnMiriams{rxnCounter}=tempStruct; -0157 end -0158 -0159 %Add name -0160 if strcmp(tline(1:12),'NAME ') -0161 model.rxnNames{rxnCounter}=tline(13:end); +0134 % Skip other lines with unused information +0135 if strcmp(tline(1:5),'BRITE') +0136 pathway = false; +0137 continue; +0138 end +0139 +0140 %Check if it's a new reaction +0141 if strcmp(tline(1:12),'ENTRY ') +0142 rxnCounter=rxnCounter+1; +0143 +0144 %Add empty strings where there should be such +0145 model.rxnNames{rxnCounter}=''; +0146 model.eccodes{rxnCounter}=''; +0147 %model.subSystems{rxnCounter}={''}; %remain empty cell +0148 model.rxnNotes{rxnCounter}=''; +0149 equations{rxnCounter}=''; +0150 +0151 %Add reaction ID (always 6 characters) +0152 model.rxns{rxnCounter}=tline(13:18); +0153 orthology=false; +0154 pathway=false; +0155 module=false; +0156 +0157 %Add KEGG reaction ID miriam +0158 tempStruct=model.rxnMiriams{rxnCounter}; +0159 tempStruct.name{1,1}='kegg.reaction'; +0160 tempStruct.value{1,1}=tline(13:18); +0161 model.rxnMiriams{rxnCounter}=tempStruct; 0162 end 0163 -0164 %Add whether the comment includes "incomplete", "erroneous" or -0165 %"unclear" -0166 if strcmp(tline(1:12),'COMMENT ') -0167 %Read all text until '///', 'RPAIR', 'ENZYME', 'PATHWAY' or 'RCLASS' -0168 commentText=tline(13:end); -0169 while 1 -0170 tline = fgetl(fid); -0171 if ~strcmp(tline(1:3),'///') && ~strcmp(tline(1:3),'RPA') && ~strcmp(tline(1:3),'ENZ') && ~strcmp(tline(1:3),'PAT') && ~strcmp(tline(1:3),'RCL') -0172 commentText=[commentText ' ' strtrim(tline)]; -0173 else -0174 break; -0175 end -0176 end -0177 if any(regexpi(commentText,'SPONTANEOUS')) -0178 %It should start this way -0179 isSpontaneous(rxnCounter)=true; -0180 end -0181 if any(regexpi(commentText,'INCOMPLETE')) || any(regexpi(commentText,'ERRONEOUS')) || any(regexpi(commentText,'UNCLEAR')) -0182 isIncomplete(rxnCounter)=true; -0183 end -0184 if any(regexpi(commentText,'GENERAL REACTION')) -0185 %It should start this way -0186 isGeneral(rxnCounter)=true; -0187 end -0188 -0189 %Go to next iteration if it is '///' -0190 if numel(tline)<12 -0191 continue; +0164 %Add name +0165 if strcmp(tline(1:12),'NAME ') +0166 model.rxnNames{rxnCounter}=tline(13:end); +0167 end +0168 +0169 %Add whether the comment includes "incomplete", "erroneous" or +0170 %"unclear" +0171 if strcmp(tline(1:12),'COMMENT ') +0172 %Read all text until '///', 'RPAIR', 'ENZYME', 'PATHWAY' or 'RCLASS' +0173 commentText=tline(13:end); +0174 while 1 +0175 tline = fgetl(fid); +0176 if ~strcmp(tline(1:3),'///') && ~strcmp(tline(1:3),'RPA') && ~strcmp(tline(1:3),'ENZ') && ~strcmp(tline(1:3),'PAT') && ~strcmp(tline(1:3),'RCL') +0177 commentText=[commentText ' ' strtrim(tline)]; +0178 else +0179 break; +0180 end +0181 end +0182 if any(regexpi(commentText,'SPONTANEOUS')) +0183 %It should start this way +0184 isSpontaneous(rxnCounter)=true; +0185 end +0186 if any(regexpi(commentText,'INCOMPLETE')) || any(regexpi(commentText,'ERRONEOUS')) || any(regexpi(commentText,'UNCLEAR')) +0187 isIncomplete(rxnCounter)=true; +0188 end +0189 if any(regexpi(commentText,'GENERAL REACTION')) +0190 %It should start this way +0191 isGeneral(rxnCounter)=true; 0192 end -0193 end -0194 -0195 %Add ec-number -0196 if strcmp(tline(1:12),'ENZYME ') -0197 model.eccodes{rxnCounter}=tline(13:end); -0198 model.eccodes{rxnCounter}=deblank(model.eccodes{rxnCounter}); -0199 model.eccodes{rxnCounter}=regexprep(model.eccodes{rxnCounter},'\s+',';'); -0200 end -0201 if numel(tline)>8 -0202 if strcmp(tline(1:9),'REFERENCE') -0203 pathway=false; -0204 orthology=false; -0205 end -0206 end -0207 -0208 %Add module ids -0209 if numel(tline)>18 -0210 if strcmp(tline(1:12),'MODULE ') || module==true -0211 pathway=false; -0212 orthology=false; -0213 if isstruct(model.rxnMiriams{rxnCounter}) -0214 addToIndex=numel(model.rxnMiriams{rxnCounter}.name)+1; -0215 else -0216 addToIndex=1; -0217 end -0218 tempStruct=model.rxnMiriams{rxnCounter}; -0219 tempStruct.name{addToIndex,1}='kegg.module'; -0220 tempStruct.value{addToIndex,1}=tline(13:18); -0221 model.rxnMiriams{rxnCounter}=tempStruct; -0222 end -0223 end -0224 -0225 %Add RHEA id -0226 if numel(tline)>18 -0227 if strcmp(tline(1:18),'DBLINKS RHEA: ') -0228 pathway=false; -0229 orthology=false; -0230 module=false; -0231 if isstruct(model.rxnMiriams{rxnCounter}) -0232 addToIndex=numel(model.rxnMiriams{rxnCounter}.name)+1; -0233 else -0234 addToIndex=1; -0235 end -0236 tempStruct=model.rxnMiriams{rxnCounter}; -0237 tempStruct.name{addToIndex,1}='rhea'; -0238 tempStruct.value{addToIndex,1}=tline(19:end); -0239 model.rxnMiriams{rxnCounter}=tempStruct; -0240 end -0241 end -0242 -0243 %Add KO-ids -0244 if numel(tline)>16 -0245 if strcmp(tline(1:16),'ORTHOLOGY KO: ') || strcmp(tline(1:16),' KO: ') || strcmp(tline(1:12),'ORTHOLOGY ') || orthology==true -0246 pathway=false; -0247 module=false; -0248 %Check if KO has been added already (each reaction may -0249 %belong to several) -0250 if isstruct(model.rxnMiriams{rxnCounter}) -0251 addToIndex=numel(model.rxnMiriams{rxnCounter}.name)+1; -0252 else -0253 addToIndex=1; -0254 end -0255 -0256 tempStruct=model.rxnMiriams{rxnCounter}; -0257 tempStruct.name{addToIndex,1}='kegg.orthology'; -0258 if strcmp(tline(13:16),'KO:') -0259 %This is in the old version -0260 tempStruct.value{addToIndex,1}=tline(17:22); -0261 else -0262 %This means that it found one KO in the new format -0263 %and that subsequent lines might be other KOs -0264 orthology=true; -0265 tempStruct.value{addToIndex,1}=tline(13:18); -0266 end -0267 model.rxnMiriams{rxnCounter}=tempStruct; -0268 end -0269 end -0270 -0271 %Add pathways -0272 if numel(tline)>18 -0273 if strcmp(tline(1:18),'PATHWAY PATH: ') || strcmp(tline(1:18),' PATH: ') || strcmp(tline(1:12),'PATHWAY ') || pathway==true -0274 orthology=false; -0275 module=false; -0276 %Check if annotation has been added already -0277 if isstruct(model.rxnMiriams{rxnCounter}) -0278 addToIndex=numel(model.rxnMiriams{rxnCounter}.name)+1; -0279 else -0280 addToIndex=1; -0281 end -0282 -0283 tempStruct=model.rxnMiriams{rxnCounter}; -0284 tempStruct.name{addToIndex,1}='kegg.pathway'; -0285 %If it is the old version -0286 if strcmp(tline(14:17),'PATH:') -0287 tempStruct.value{addToIndex,1}=tline(19:25); -0288 else -0289 %If it is the new version -0290 tempStruct.value{addToIndex,1}=tline(13:19); -0291 pathway=true; -0292 end -0293 -0294 %Do not save global or overview pathways. The ids for -0295 %such pathways begin with rn011 or rn012 -0296 if ~strcmp('rn011',tempStruct.value{addToIndex,1}(1:5)) && ~strcmp('rn012',tempStruct.value{addToIndex,1}(1:5)) -0297 model.rxnMiriams{rxnCounter}=tempStruct; -0298 -0299 %Also save the subSystems names. For the old KEGG -0300 %format, only the first mentioned subsystem is -0301 %picked. Use the newer KEGG format to fetch all the -0302 %subsystems -0303 if strcmp(tline(14:17),'PATH:') -0304 %The old format -0305 model.subSystems{rxnCounter}=tline(28:end); -0306 else -0307 %The new format -0308 model.subSystems{rxnCounter,1}{1,numel(model.subSystems{rxnCounter,1})+1}=tline(22:end); -0309 end -0310 end -0311 end -0312 end -0313 end -0314 -0315 %Close the file -0316 fclose(fid); -0317 -0318 %This is done here since the the indexes won't match since some -0319 %reactions are removed along the way -0320 isIncomplete=model.rxns(isIncomplete); -0321 isGeneral=model.rxns(isGeneral); -0322 isSpontaneous=model.rxns(isSpontaneous); -0323 -0324 %If too much space was allocated, shrink the model -0325 model.rxns=model.rxns(1:rxnCounter); -0326 model.rxnNames=model.rxnNames(1:rxnCounter); -0327 model.eccodes=model.eccodes(1:rxnCounter); -0328 equations=equations(1:rxnCounter); -0329 model.rxnMiriams=model.rxnMiriams(1:rxnCounter); -0330 model.rxnNotes=model.rxnNotes(1:rxnCounter); -0331 model.subSystems=model.subSystems(1:rxnCounter); -0332 -0333 %Then load the equations from another file. This is because the -0334 %equations are easier to retrieve from there -0335 -0336 %The format is rxnID: equation The reactions should have been -0337 %loaded in the exact same order -0338 fid = fopen(fullfile(keggPath,'reaction.lst'), 'r'); -0339 -0340 %Loop through the file -0341 for i=1:rxnCounter -0342 %Get the next line -0343 tline = fgetl(fid); -0344 -0345 equations{i}=tline(9:end); -0346 end +0193 +0194 %Go to next iteration if it is '///' +0195 if numel(tline)<12 +0196 continue; +0197 end +0198 end +0199 +0200 %Add ec-number +0201 if strcmp(tline(1:12),'ENZYME ') +0202 model.eccodes{rxnCounter}=tline(13:end); +0203 model.eccodes{rxnCounter}=deblank(model.eccodes{rxnCounter}); +0204 model.eccodes{rxnCounter}=regexprep(model.eccodes{rxnCounter},'\s+',';'); +0205 end +0206 if numel(tline)>8 +0207 if strcmp(tline(1:9),'REFERENCE') +0208 pathway=false; +0209 orthology=false; +0210 end +0211 end +0212 +0213 %Add module ids +0214 if numel(tline)>18 +0215 if strcmp(tline(1:12),'MODULE ') || module==true +0216 pathway=false; +0217 orthology=false; +0218 if isstruct(model.rxnMiriams{rxnCounter}) +0219 addToIndex=numel(model.rxnMiriams{rxnCounter}.name)+1; +0220 else +0221 addToIndex=1; +0222 end +0223 tempStruct=model.rxnMiriams{rxnCounter}; +0224 tempStruct.name{addToIndex,1}='kegg.module'; +0225 tempStruct.value{addToIndex,1}=tline(13:18); +0226 model.rxnMiriams{rxnCounter}=tempStruct; +0227 end +0228 end +0229 +0230 %Add RHEA id +0231 if numel(tline)>18 +0232 if strcmp(tline(1:18),'DBLINKS RHEA: ') +0233 pathway=false; +0234 orthology=false; +0235 module=false; +0236 if isstruct(model.rxnMiriams{rxnCounter}) +0237 addToIndex=numel(model.rxnMiriams{rxnCounter}.name)+1; +0238 else +0239 addToIndex=1; +0240 end +0241 tempStruct=model.rxnMiriams{rxnCounter}; +0242 tempStruct.name{addToIndex,1}='rhea'; +0243 tempStruct.value{addToIndex,1}=tline(19:end); +0244 model.rxnMiriams{rxnCounter}=tempStruct; +0245 end +0246 end +0247 +0248 %Add KO-ids +0249 if numel(tline)>16 +0250 if strcmp(tline(1:16),'ORTHOLOGY KO: ') || strcmp(tline(1:16),' KO: ') || strcmp(tline(1:12),'ORTHOLOGY ') || orthology==true +0251 pathway=false; +0252 module=false; +0253 %Check if KO has been added already (each reaction may +0254 %belong to several) +0255 if isstruct(model.rxnMiriams{rxnCounter}) +0256 addToIndex=numel(model.rxnMiriams{rxnCounter}.name)+1; +0257 else +0258 addToIndex=1; +0259 end +0260 +0261 tempStruct=model.rxnMiriams{rxnCounter}; +0262 tempStruct.name{addToIndex,1}='kegg.orthology'; +0263 if strcmp(tline(13:16),'KO:') +0264 %This is in the old version +0265 tempStruct.value{addToIndex,1}=tline(17:22); +0266 else +0267 %This means that it found one KO in the new format +0268 %and that subsequent lines might be other KOs +0269 orthology=true; +0270 tempStruct.value{addToIndex,1}=tline(13:18); +0271 end +0272 model.rxnMiriams{rxnCounter}=tempStruct; +0273 end +0274 end +0275 +0276 %Add pathways +0277 if numel(tline)>18 +0278 if strcmp(tline(1:18),'PATHWAY PATH: ') || strcmp(tline(1:18),' PATH: ') || strcmp(tline(1:12),'PATHWAY ') || pathway==true +0279 orthology=false; +0280 module=false; +0281 %Check if annotation has been added already +0282 if isstruct(model.rxnMiriams{rxnCounter}) +0283 addToIndex=numel(model.rxnMiriams{rxnCounter}.name)+1; +0284 else +0285 addToIndex=1; +0286 end +0287 +0288 tempStruct=model.rxnMiriams{rxnCounter}; +0289 tempStruct.name{addToIndex,1}='kegg.pathway'; +0290 %If it is the old version +0291 if strcmp(tline(14:17),'PATH:') +0292 tempStruct.value{addToIndex,1}=tline(19:25); +0293 else +0294 %If it is the new version +0295 tempStruct.value{addToIndex,1}=tline(13:19); +0296 pathway=true; +0297 end +0298 +0299 %Do not save global or overview pathways. The ids for +0300 %such pathways begin with rn011 or rn012 +0301 if ~strcmp('rn011',tempStruct.value{addToIndex,1}(1:5)) && ~strcmp('rn012',tempStruct.value{addToIndex,1}(1:5)) +0302 model.rxnMiriams{rxnCounter}=tempStruct; +0303 +0304 %Also save the subSystems names. For the old KEGG +0305 %format, only the first mentioned subsystem is +0306 %picked. Use the newer KEGG format to fetch all the +0307 %subsystems +0308 if strcmp(tline(14:17),'PATH:') +0309 %The old format +0310 model.subSystems{rxnCounter}=tline(28:end); +0311 else +0312 %The new format +0313 model.subSystems{rxnCounter,1}{numel(model.subSystems{rxnCounter,1})+1,1}=tline(22:end); +0314 end +0315 end +0316 end +0317 end +0318 end +0319 +0320 %Close the file +0321 fclose(fid); +0322 +0323 %This is done here since the the indexes won't match since some +0324 %reactions are removed along the way +0325 isIncomplete=model.rxns(isIncomplete); +0326 isGeneral=model.rxns(isGeneral); +0327 isSpontaneous=model.rxns(isSpontaneous); +0328 +0329 %If too much space was allocated, shrink the model +0330 model.rxns=model.rxns(1:rxnCounter); +0331 model.rxnNames=model.rxnNames(1:rxnCounter); +0332 model.eccodes=model.eccodes(1:rxnCounter); +0333 equations=equations(1:rxnCounter); +0334 model.rxnMiriams=model.rxnMiriams(1:rxnCounter); +0335 model.rxnNotes=model.rxnNotes(1:rxnCounter); +0336 model.subSystems=model.subSystems(1:rxnCounter); +0337 +0338 emptySubSys = cellfun(@isempty,model.subSystems); +0339 model.subSystems(emptySubSys) = {{''}}; +0340 +0341 %Then load the equations from another file. This is because the +0342 %equations are easier to retrieve from there +0343 +0344 %The format is rxnID: equation The reactions should have been +0345 %loaded in the exact same order +0346 fid = fopen(fullfile(keggPath,'reaction.lst'), 'r'); 0347 -0348 %Close the file -0349 fclose(fid); -0350 -0351 %Several equations may have two whitespaces between the last -0352 %reactant and the reversible arrow sign. The number of whitespaces -0353 %is thus reduced to one -0354 equations = regexprep(equations,' <=>', ' <=>'); +0348 %Loop through the file +0349 for i=1:rxnCounter +0350 %Get the next line +0351 tline = fgetl(fid); +0352 +0353 equations{i}=tline(9:end); +0354 end 0355 -0356 %Construct the S matrix and list of metabolites -0357 [S, mets, badRxns]=constructS(equations); -0358 model.S=S; -0359 model.mets=mets; -0360 -0361 %There is some limited evidence for directionality in -0362 %reaction_mapformula.lst. The information there concerns how the -0363 %reactions are drawn in the KEGG maps. If a reaction is -0364 %irreversible in the same direction for all maps, then I consider -0365 %is irreversible, otherwise reversible. Also, not all reactions are -0366 %present in the maps, so not all will have directionality. They -0367 %will be considered to be reversible +0356 %Close the file +0357 fclose(fid); +0358 +0359 %Several equations may have two whitespaces between the last +0360 %reactant and the reversible arrow sign. The number of whitespaces +0361 %is thus reduced to one +0362 equations = regexprep(equations,' <=>', ' <=>'); +0363 +0364 %Construct the S matrix and list of metabolites +0365 [S, mets, badRxns]=constructS(equations); +0366 model.S=S; +0367 model.mets=mets; 0368 -0369 %The format is R00005: 00330: C01010 => C00011 Generate a -0370 %reversibility structure with the fields: *rxns: reaction ids -0371 %*product: one met id that is a product. This is because the -0372 %*reactions might be written in another direction compared to in -0373 % the reactions.lst file -0374 %*rev: 1 if reversible, otherwise 0 -0375 reversibility.rxns={}; -0376 reversibility.product={}; -0377 reversibility.rev=[]; -0378 -0379 fid = fopen(fullfile(keggPath,'reaction_mapformula.lst'), 'r'); -0380 while 1 -0381 %Get the next line -0382 tline = fgetl(fid); -0383 -0384 %Abort at end of file -0385 if ~ischar(tline) -0386 break; -0387 end -0388 -0389 rxn=tline(1:6); -0390 prod=tline(end-5:end); -0391 rev=any(strfind(tline,'<=>')); -0392 if isempty(reversibility.rxns) -0393 reversibility.rxns{1}=rxn; -0394 reversibility.product{1}=prod; -0395 reversibility.rev(1)=rev; -0396 elseif strcmp(reversibility.rxns(end),rxn) -0397 %Check if the reaction was added before. It's an ordered -0398 %list, so only check the last element If it's reversible in -0399 %the new reaction or reversible in the old reaction then -0400 %set (keep) to be reversible -0401 if rev==1 || reversibility.rev(end)==1 -0402 reversibility.rev(end)=1; -0403 else -0404 %This means that the reaction was already loaded, that -0405 %it was irreversible before and irreversible in the new -0406 %reaction. However, it could be that they are written -0407 %in diferent directions. If the product differ, then -0408 %set to be reversible. This assumes that the reactions -0409 %are written with the same metabolite as the last one -0410 %if they are in the same direction -0411 if ~strcmp(prod,reversibility.product(end)) -0412 reversibility.rev(end)=1; -0413 end -0414 end -0415 else -0416 reversibility.rxns=[reversibility.rxns;rxn]; -0417 reversibility.product=[reversibility.product;prod]; -0418 reversibility.rev=[reversibility.rev;rev]; -0419 end -0420 end -0421 fclose(fid); -0422 -0423 %Update the reversibility -0424 model.rev=ones(rxnCounter,1); -0425 %Match the reaction ids -0426 irrevIDs=find(reversibility.rev==0); -0427 [~, I]=ismember(reversibility.rxns(irrevIDs),model.rxns); -0428 [~, prodMetIDs]=ismember(reversibility.product(irrevIDs),model.mets); -0429 model.rev(I)=0; +0369 %There is some limited evidence for directionality in +0370 %reaction_mapformula.lst. The information there concerns how the +0371 %reactions are drawn in the KEGG maps. If a reaction is +0372 %irreversible in the same direction for all maps, then I consider +0373 %is irreversible, otherwise reversible. Also, not all reactions are +0374 %present in the maps, so not all will have directionality. They +0375 %will be considered to be reversible +0376 +0377 %The format is R00005: 00330: C01010 => C00011 Generate a +0378 %reversibility structure with the fields: *rxns: reaction ids +0379 %*product: one met id that is a product. This is because the +0380 %*reactions might be written in another direction compared to in +0381 % the reactions.lst file +0382 %*rev: 1 if reversible, otherwise 0 +0383 reversibility.rxns={}; +0384 reversibility.product={}; +0385 reversibility.rev=[]; +0386 +0387 fid = fopen(fullfile(keggPath,'reaction_mapformula.lst'), 'r'); +0388 while 1 +0389 %Get the next line +0390 tline = fgetl(fid); +0391 +0392 %Abort at end of file +0393 if ~ischar(tline) +0394 break; +0395 end +0396 +0397 rxn=tline(1:6); +0398 prod=tline(end-5:end); +0399 rev=any(strfind(tline,'<=>')); +0400 if isempty(reversibility.rxns) +0401 reversibility.rxns{1}=rxn; +0402 reversibility.product{1}=prod; +0403 reversibility.rev(1)=rev; +0404 elseif strcmp(reversibility.rxns(end),rxn) +0405 %Check if the reaction was added before. It's an ordered +0406 %list, so only check the last element If it's reversible in +0407 %the new reaction or reversible in the old reaction then +0408 %set (keep) to be reversible +0409 if rev==1 || reversibility.rev(end)==1 +0410 reversibility.rev(end)=1; +0411 else +0412 %This means that the reaction was already loaded, that +0413 %it was irreversible before and irreversible in the new +0414 %reaction. However, it could be that they are written +0415 %in diferent directions. If the product differ, then +0416 %set to be reversible. This assumes that the reactions +0417 %are written with the same metabolite as the last one +0418 %if they are in the same direction +0419 if ~strcmp(prod,reversibility.product(end)) +0420 reversibility.rev(end)=1; +0421 end +0422 end +0423 else +0424 reversibility.rxns=[reversibility.rxns;rxn]; +0425 reversibility.product=[reversibility.product;prod]; +0426 reversibility.rev=[reversibility.rev;rev]; +0427 end +0428 end +0429 fclose(fid); 0430 -0431 %See if the reactions are written in the same order in model.S -0432 linearInd=sub2ind(size(model.S), prodMetIDs, I); -0433 changeOrder=I(model.S(linearInd)<0); -0434 %Change the order of these reactions -0435 model.S(:,changeOrder)=model.S(:,changeOrder).*-1; -0436 -0437 %Add some stuff to get a correct model structure -0438 model.ub=ones(rxnCounter,1)*1000; -0439 model.lb=model.rev*-1000; -0440 model.c=zeros(rxnCounter,1); -0441 model.b=zeros(numel(model.mets),1); -0442 model=removeReactions(model,badRxns,true,true); -0443 -0444 %Identify reactions with undefined stoichiometry. Such -0445 %reactions involve metabolites with an ID containing the letter "n" -0446 %or "m" -0447 I=cellfun(@any,strfind(model.mets,'n')) | cellfun(@any,strfind(model.mets,'m')); -0448 [~, J]=find(model.S(I,:)); -0449 isUndefinedStoich=model.rxns(unique(J)); -0450 %Sort model that metabolites with undefined stoichiometry would -0451 %appear in the end of metabolites list -0452 metList=[model.mets(~I);model.mets(I)]; -0453 [~,metIndexes]=ismember(metList,model.mets); -0454 model=permuteModel(model,metIndexes,'mets'); -0455 -0456 %Sort model that i) spontaneous, ii) with undefined -0457 %stoichiometry, iii) incomplete and iv) general reactions would bve -0458 %ranked in the end of the model -0459 endRxnList=unique([model.rxns(ismember(model.rxns,isSpontaneous));model.rxns(ismember(model.rxns,isUndefinedStoich));model.rxns(ismember(model.rxns,isIncomplete));model.rxns(ismember(model.rxns,isGeneral))],'stable'); -0460 rxnList=[model.rxns(~ismember(model.rxns,endRxnList));endRxnList]; -0461 [~,rxnIndexes]=ismember(rxnList,model.rxns); -0462 model=permuteModel(model,rxnIndexes,'rxns'); +0431 %Update the reversibility +0432 model.rev=ones(rxnCounter,1); +0433 %Match the reaction ids +0434 irrevIDs=find(reversibility.rev==0); +0435 [~, I]=ismember(reversibility.rxns(irrevIDs),model.rxns); +0436 [~, prodMetIDs]=ismember(reversibility.product(irrevIDs),model.mets); +0437 model.rev(I)=0; +0438 +0439 %See if the reactions are written in the same order in model.S +0440 linearInd=sub2ind(size(model.S), prodMetIDs, I); +0441 changeOrder=I(model.S(linearInd)<0); +0442 %Change the order of these reactions +0443 model.S(:,changeOrder)=model.S(:,changeOrder).*-1; +0444 +0445 %Add some stuff to get a correct model structure +0446 model.ub=ones(rxnCounter,1)*1000; +0447 model.lb=model.rev*-1000; +0448 model.c=zeros(rxnCounter,1); +0449 model.b=zeros(numel(model.mets),1); +0450 model=removeReactions(model,badRxns,true,true); +0451 +0452 %Identify reactions with undefined stoichiometry. Such +0453 %reactions involve metabolites with an ID containing the letter "n" +0454 %or "m" +0455 I=cellfun(@any,strfind(model.mets,'n')) | cellfun(@any,strfind(model.mets,'m')); +0456 [~, J]=find(model.S(I,:)); +0457 isUndefinedStoich=model.rxns(unique(J)); +0458 %Sort model that metabolites with undefined stoichiometry would +0459 %appear in the end of metabolites list +0460 metList=[model.mets(~I);model.mets(I)]; +0461 [~,metIndexes]=ismember(metList,model.mets); +0462 model=permuteModel(model,metIndexes,'mets'); 0463 -0464 %Add information in rxnNotes, whether reaction belongs to any of -0465 %type i-iv mentioned a few lines above -0466 for i=(numel(rxnList)-numel(endRxnList)+1):numel(model.rxns) -0467 if ismember(model.rxns(i),isSpontaneous) -0468 model.rxnNotes(i)=strcat(model.rxnNotes(i),'Spontaneous'); -0469 end -0470 if ismember(model.rxns(i),isUndefinedStoich) -0471 if isempty(model.rxnNotes{i}) -0472 model.rxnNotes(i)=strcat(model.rxnNotes(i),'With undefined stoichiometry'); -0473 else -0474 model.rxnNotes(i)=strcat(model.rxnNotes(i),', with undefined stoichiometry'); -0475 end -0476 end -0477 if ismember(model.rxns(i),isIncomplete) -0478 if isempty(model.rxnNotes{i}) -0479 model.rxnNotes(i)=strcat(model.rxnNotes(i),'Incomplete'); -0480 else -0481 model.rxnNotes(i)=strcat(model.rxnNotes(i),', incomplete'); -0482 end -0483 end -0484 if ismember(model.rxns(i),isGeneral) -0485 if isempty(model.rxnNotes{i}) -0486 model.rxnNotes(i)=strcat(model.rxnNotes(i),'General'); -0487 else -0488 model.rxnNotes(i)=strcat(model.rxnNotes(i),', general'); -0489 end -0490 end -0491 model.rxnNotes(i)=strcat(model.rxnNotes(i),' reaction'); -0492 end -0493 -0494 %Save the model structure -0495 save(rxnsFile,'model','isGeneral','isIncomplete','isUndefinedStoich','isSpontaneous'); -0496 end -0497 end -0498 fprintf('COMPLETE\n'); -0499 -0500 end +0464 %Sort model that i) spontaneous, ii) with undefined +0465 %stoichiometry, iii) incomplete and iv) general reactions would bve +0466 %ranked in the end of the model +0467 endRxnList=unique([model.rxns(ismember(model.rxns,isSpontaneous));model.rxns(ismember(model.rxns,isUndefinedStoich));model.rxns(ismember(model.rxns,isIncomplete));model.rxns(ismember(model.rxns,isGeneral))],'stable'); +0468 rxnList=[model.rxns(~ismember(model.rxns,endRxnList));endRxnList]; +0469 [~,rxnIndexes]=ismember(rxnList,model.rxns); +0470 model=permuteModel(model,rxnIndexes,'rxns'); +0471 +0472 %Add information in rxnNotes, whether reaction belongs to any of +0473 %type i-iv mentioned a few lines above +0474 for i=(numel(rxnList)-numel(endRxnList)+1):numel(model.rxns) +0475 if ismember(model.rxns(i),isSpontaneous) +0476 model.rxnNotes(i)=strcat(model.rxnNotes(i),'Spontaneous'); +0477 end +0478 if ismember(model.rxns(i),isUndefinedStoich) +0479 if isempty(model.rxnNotes{i}) +0480 model.rxnNotes(i)=strcat(model.rxnNotes(i),'With undefined stoichiometry'); +0481 else +0482 model.rxnNotes(i)=strcat(model.rxnNotes(i),', with undefined stoichiometry'); +0483 end +0484 end +0485 if ismember(model.rxns(i),isIncomplete) +0486 if isempty(model.rxnNotes{i}) +0487 model.rxnNotes(i)=strcat(model.rxnNotes(i),'Incomplete'); +0488 else +0489 model.rxnNotes(i)=strcat(model.rxnNotes(i),', incomplete'); +0490 end +0491 end +0492 if ismember(model.rxns(i),isGeneral) +0493 if isempty(model.rxnNotes{i}) +0494 model.rxnNotes(i)=strcat(model.rxnNotes(i),'General'); +0495 else +0496 model.rxnNotes(i)=strcat(model.rxnNotes(i),', general'); +0497 end +0498 end +0499 model.rxnNotes(i)=strcat(model.rxnNotes(i),' reaction'); +0500 end +0501 +0502 %Save the model structure +0503 save(rxnsFile,'model','isGeneral','isIncomplete','isUndefinedStoich','isSpontaneous'); +0504 end +0505 end +0506 fprintf('COMPLETE\n'); +0507 +0508 end
    Generated by m2html © 2005
    \ No newline at end of file diff --git a/doc/external/metacyc/getRxnsFromMetaCyc.html b/doc/external/metacyc/getRxnsFromMetaCyc.html index 1fa93322..f3b26589 100644 --- a/doc/external/metacyc/getRxnsFromMetaCyc.html +++ b/doc/external/metacyc/getRxnsFromMetaCyc.html @@ -336,7 +336,7 @@

    SOURCE CODE ^if x -0247 metaCycRxns.subSystems{rxnCounter,1}{1,numel(metaCycRxns.subSystems{rxnCounter,1})+1}=pwyNames{y}; +0247 metaCycRxns.subSystems{rxnCounter,1}{numel(metaCycRxns.subSystems{rxnCounter,1})+1,1}=pwyNames{y}; 0248 end 0249 end 0250 diff --git a/doc/installation/checkFunctionUniqueness.html b/doc/installation/checkFunctionUniqueness.html index a8d2ddee..5b55f77a 100644 --- a/doc/installation/checkFunctionUniqueness.html +++ b/doc/installation/checkFunctionUniqueness.html @@ -48,7 +48,7 @@

    CROSS-REFERENCE INFORMATION ^
 </ul>
 This function is called by:
 <ul style= -
  • checkInstallation checkInstallation
  • +
  • checkInstallation checkInstallation
  • diff --git a/doc/installation/checkInstallation.html b/doc/installation/checkInstallation.html index 3f5370a0..3ee04260 100644 --- a/doc/installation/checkInstallation.html +++ b/doc/installation/checkInstallation.html @@ -24,7 +24,7 @@

    PURPOSE ^checkInstallation

    SYNOPSIS ^

    -
    function [currVer, installType] = checkInstallation(developMode)
    +
    function [currVer, installType] = checkInstallation(developMode,checkBinaries)

    DESCRIPTION ^

     checkInstallation
    @@ -39,6 +39,9 @@ 

    DESCRIPTION ^SUBFUNCTIONS ^function res = interpretResults(results)
  • function str = myStr(InputStr,len)
  • function status = makeBinaryExecutable(ravenDir)
  • function printOrange(stringToPrint)
  • SOURCE CODE ^

    -
    0001 function [currVer, installType] = checkInstallation(developMode)
    +
    0001 function [currVer, installType] = checkInstallation(developMode,checkBinaries)
     0002 % checkInstallation
     0003 %   The purpose of this function is to check if all necessary functions are
     0004 %   installed and working. It also checks whether there are any functions
    @@ -80,373 +83,390 @@ 

    SOURCE CODE ^% HMMs (optional, default false). If 'versionOnly' is 0012 % specified, only the version is reported as currVer, no 0013 % further installation or tests are performed. -0014 % -0015 % Output: -0016 % currVer current RAVEN version -0017 % installType how RAVEN is installed -0018 % 0: via git (as .git folder is found) -0019 % 1: as MATLAB Add-On -0020 % 2: neither of the above, direct download of ZIP file -0021 % This matches the installations mentioned in the wiki: -0022 % https://github.com/SysBioChalmers/RAVEN/wiki/Installation -0023 % 0 = advanced / 1 = easy / 2 = medium -0024 % -0025 % Usage: [currVer, installType] = checkInstallation(developMode) -0026 -0027 if nargin<1 -0028 developMode=false; -0029 end -0030 if ischar(developMode) && strcmp(developMode,'versionOnly') -0031 versionOnly = true; -0032 else -0033 versionOnly = false; -0034 end -0035 -0036 %Get the RAVEN path -0037 [ST, I]=dbstack('-completenames'); -0038 [ravenDir,~,~]=fileparts(fileparts(ST(I).file)); -0039 -0040 installType = 2; % If neither git nor add-on, then ZIP was downloaded -0041 addList = matlab.addons.installedAddons; -0042 if isfolder(fullfile(ravenDir,'.git')) -0043 installType = 0; -0044 elseif any(strcmp(addList.Name,'RAVEN Toolbox')) -0045 installType = 1; -0046 end -0047 -0048 % Do not print first few lines if only version should be reported -0049 if ~versionOnly -0050 fprintf('\n*** THE RAVEN TOOLBOX ***\n\n'); -0051 %Print the RAVEN version if it is not the development version -0052 fprintf(myStr(' > Installation type',40)); -0053 switch installType -0054 case 0 -0055 fprintf('Advanced (via git)\n'); -0056 case 1 -0057 fprintf('Easy (as MATLAB Add-On)\n'); -0058 case 2 -0059 fprintf('Medium (as downloaded ZIP file)\n'); -0060 end -0061 fprintf(myStr(' > Installing from location',40)); -0062 fprintf('%s\n',ravenDir) -0063 fprintf(myStr(' > Checking RAVEN release',40)); -0064 end -0065 -0066 if exist(fullfile(ravenDir,'version.txt'), 'file') == 2 -0067 currVer = fgetl(fopen(fullfile(ravenDir,'version.txt'))); -0068 fclose('all'); -0069 if ~versionOnly -0070 fprintf([currVer '\n']); -0071 try -0072 newVer=strtrim(webread('https://raw.githubusercontent.com/SysBioChalmers/RAVEN/main/version.txt')); -0073 newVerNum=str2double(strsplit(newVer,'.')); -0074 currVerNum=str2double(strsplit(currVer,'.')); -0075 for i=1:3 -0076 if currVerNum(i)<newVerNum(i) -0077 fprintf(myStr(' > Latest RAVEN release available',40)) -0078 printOrange([newVer,'\n']) -0079 switch installType -0080 case 0 -0081 printOrange(' Run git pull in your favourite git client\n') -0082 printOrange(' to get the latest RAVEN release\n'); -0083 case 1 -0084 printOrange(myStr(' Instructions on how to upgrade',40)) -0085 fprintf('<a href="https://github.com/SysBioChalmers/RAVEN/wiki/Installation#upgrade-raven-after-easy-installation">here</a>\n'); -0086 case 2 -0087 printOrange(myStr(' Instructions on how to upgrade',40)) -0088 fprintf('<a href="https://github.com/SysBioChalmers/RAVEN/wiki/Installation#upgrade-raven-after-medium-installation">here</a>\n'); -0089 end -0090 break -0091 elseif i==3 -0092 fprintf(' > You are running the latest RAVEN release\n'); -0093 end -0094 end -0095 catch -0096 fprintf(myStr(' > Checking for latest RAVEN release',40)) -0097 printOrange('Fail\n'); -0098 printOrange(' Cannot reach GitHub for release info\n'); -0099 end -0100 end -0101 else -0102 currVer = 'develop'; -0103 if ~versionOnly; fprintf('DEVELOPMENT\n'); end -0104 end -0105 if strcmp(developMode,'versionOnly') -0106 return; -0107 end -0108 -0109 fprintf(myStr(' > Checking MATLAB release',40)) -0110 fprintf([version('-release') '\n']) -0111 fprintf(myStr(' > Checking system architecture',40)) -0112 fprintf([computer('arch'),'\n']) -0113 -0114 fprintf(myStr(' > Set RAVEN in MATLAB path',40)) -0115 subpath=regexp(genpath(ravenDir),pathsep,'split'); %List all subdirectories -0116 pathsToKeep=cellfun(@(x) ~contains(x,'.git'),subpath) & cellfun(@(x) ~contains(x,'doc'),subpath); -0117 try -0118 addpath(strjoin(subpath(pathsToKeep),pathsep)); -0119 fprintf('Pass\n'); -0120 fprintf(myStr(' > Save MATLAB path',40)) -0121 try -0122 savepath -0123 fprintf('Pass\n') -0124 catch -0125 printOrange('Fail\n') -0126 fprintf([' You might have to rerun checkInstallation again\n'... -0127 ' next time you start up MATLAB\n']) -0128 end -0129 catch -0130 printOrange('Fail\n') -0131 end -0132 -0133 if isunix -0134 fprintf(myStr(' > Make binaries executable',40)) -0135 status = makeBinaryExecutable(ravenDir); -0136 if status == 0 -0137 fprintf('Pass\n') -0138 else -0139 printOrange('Fail\n') -0140 end -0141 end -0142 -0143 %Check if it is possible to parse an Excel file -0144 fprintf('\n=== Model import and export ===\n'); -0145 fprintf(myStr(' > Add Java paths for Excel format',40)) -0146 try -0147 %Add the required classes to the static Java path if not already added -0148 addJavaPaths(); -0149 fprintf('Pass\n') -0150 catch -0151 printOrange('Fail\n') -0152 end -0153 fprintf(myStr(' > Checking libSBML version',40)) -0154 try -0155 evalc('importModel(fullfile(ravenDir,''tutorial'',''empty.xml''))'); -0156 try -0157 libSBMLver=OutputSBML_RAVEN; % Only works in libSBML 5.17.0+ -0158 fprintf([libSBMLver.libSBML_version_string '\n']); -0159 catch -0160 printOrange('Fail\n') -0161 fprintf(' An older libSBML version was found, update to version 5.17.0 or higher for a significant improvement of model import\n'); -0162 end +0014 % checkBinaries logical whether non-developMode binaries should be +0015 % checked for functionality. If false, it overwrites +0016 % developMode. Default true. +0017 % +0018 % Output: +0019 % currVer current RAVEN version +0020 % installType how RAVEN is installed +0021 % 0: via git (as .git folder is found) +0022 % 1: as MATLAB Add-On +0023 % 2: neither of the above, direct download of ZIP file +0024 % This matches the installations mentioned in the wiki: +0025 % https://github.com/SysBioChalmers/RAVEN/wiki/Installation +0026 % 0 = advanced / 1 = easy / 2 = medium +0027 % +0028 % Usage: [currVer, installType] = checkInstallation(developMode) +0029 +0030 if nargin<1 +0031 developMode=false; +0032 end +0033 if nargin<2 +0034 checkBinaries=true; +0035 end +0036 if ischar(developMode) && strcmp(developMode,'versionOnly') +0037 versionOnly = true; +0038 else +0039 versionOnly = false; +0040 end +0041 +0042 %Get the RAVEN path +0043 [ST, I]=dbstack('-completenames'); +0044 [ravenDir,~,~]=fileparts(fileparts(ST(I).file)); +0045 +0046 installType = 2; % If neither git nor add-on, then ZIP was downloaded +0047 addList = matlab.addons.installedAddons; +0048 if isfolder(fullfile(ravenDir,'.git')) +0049 installType = 0; +0050 elseif any(strcmp(addList.Name,'RAVEN Toolbox')) +0051 installType = 1; +0052 end +0053 +0054 % Do not print first few lines if only version should be reported +0055 if ~versionOnly +0056 fprintf('\n*** THE RAVEN TOOLBOX ***\n\n'); +0057 %Print the RAVEN version if it is not the development version +0058 fprintf(myStr(' > Installation type',40)); +0059 switch installType +0060 case 0 +0061 fprintf('Advanced (via git)\n'); +0062 case 1 +0063 fprintf('Easy (as MATLAB Add-On)\n'); +0064 case 2 +0065 fprintf('Medium (as downloaded ZIP file)\n'); +0066 end +0067 fprintf(myStr(' > Installing from location',40)); +0068 fprintf('%s\n',ravenDir) +0069 fprintf(myStr(' > Checking RAVEN release',40)); +0070 end +0071 +0072 if exist(fullfile(ravenDir,'version.txt'), 'file') == 2 +0073 currVer = fgetl(fopen(fullfile(ravenDir,'version.txt'))); +0074 fclose('all'); +0075 if ~versionOnly +0076 fprintf([currVer '\n']); +0077 try +0078 newVer=strtrim(webread('https://raw.githubusercontent.com/SysBioChalmers/RAVEN/main/version.txt')); +0079 newVerNum=str2double(strsplit(newVer,'.')); +0080 currVerNum=str2double(strsplit(currVer,'.')); +0081 for i=1:3 +0082 if currVerNum(i)<newVerNum(i) +0083 fprintf(myStr(' > Latest RAVEN release available',40)) +0084 printOrange([newVer,'\n']) +0085 switch installType +0086 case 0 +0087 printOrange(' Run git pull in your favourite git client\n') +0088 printOrange(' to get the latest RAVEN release\n'); +0089 case 1 +0090 printOrange(myStr(' Instructions on how to upgrade',40)) +0091 fprintf('<a href="https://github.com/SysBioChalmers/RAVEN/wiki/Installation#upgrade-raven-after-easy-installation">here</a>\n'); +0092 case 2 +0093 printOrange(myStr(' Instructions on how to upgrade',40)) +0094 fprintf('<a href="https://github.com/SysBioChalmers/RAVEN/wiki/Installation#upgrade-raven-after-medium-installation">here</a>\n'); +0095 end +0096 break +0097 elseif i==3 +0098 fprintf(' > You are running the latest RAVEN release\n'); +0099 end +0100 end +0101 catch +0102 fprintf(myStr(' > Checking for latest RAVEN release',40)) +0103 printOrange('Fail\n'); +0104 printOrange(' Cannot reach GitHub for release info\n'); +0105 end +0106 end +0107 else +0108 currVer = 'develop'; +0109 if ~versionOnly; fprintf('DEVELOPMENT\n'); end +0110 end +0111 if strcmp(developMode,'versionOnly') +0112 return; +0113 end +0114 +0115 fprintf(myStr(' > Checking MATLAB release',40)) +0116 fprintf([version('-release') '\n']) +0117 fprintf(myStr(' > Checking system architecture',40)) +0118 fprintf([computer('arch'),'\n']) +0119 +0120 fprintf(myStr(' > Set RAVEN in MATLAB path',40)) +0121 subpath=regexp(genpath(ravenDir),pathsep,'split'); %List all subdirectories +0122 pathsToKeep=cellfun(@(x) ~contains(x,'.git'),subpath) & cellfun(@(x) ~contains(x,'doc'),subpath); +0123 try +0124 addpath(strjoin(subpath(pathsToKeep),pathsep)); +0125 fprintf('Pass\n'); +0126 fprintf(myStr(' > Save MATLAB path',40)) +0127 try +0128 savepath +0129 fprintf('Pass\n') +0130 catch +0131 printOrange('Fail\n') +0132 fprintf([' You might have to rerun checkInstallation again\n'... +0133 ' next time you start up MATLAB\n']) +0134 end +0135 catch +0136 printOrange('Fail\n') +0137 end +0138 fprintf(myStr(' > Store RAVEN path as MATLAB pref',40)) +0139 try +0140 setpref('RAVEN','ravenPath',ravenDir); +0141 fprintf('Pass\n'); +0142 catch +0143 printOrange('Fail\n') +0144 end +0145 +0146 if isunix +0147 fprintf(myStr(' > Make binaries executable',40)) +0148 status = makeBinaryExecutable(ravenDir); +0149 if status == 0 +0150 fprintf('Pass\n') +0151 else +0152 printOrange('Fail\n') +0153 end +0154 end +0155 +0156 %Check if it is possible to parse an Excel file +0157 fprintf('\n=== Model import and export ===\n'); +0158 fprintf(myStr(' > Add Java paths for Excel format',40)) +0159 try +0160 %Add the required classes to the static Java path if not already added +0161 addJavaPaths(); +0162 fprintf('Pass\n') 0163 catch 0164 printOrange('Fail\n') -0165 fprintf(' Download libSBML from http://sbml.org/Software/libSBML/Downloading_libSBML and add to MATLAB path\n'); -0166 end -0167 fprintf(' > Checking model import and export\n') -0168 [~,res]=evalc("runtests('importExportTests.m');"); -0169 -0170 fprintf(myStr(' > Import Excel format',40)) -0171 if res(1).Passed == 1 -0172 fprintf('Pass\n') -0173 else -0174 printOrange('Fail\n') -0175 if any(strcmpi(addList.Name,'Text Analytics Toolbox')) -0176 fprintf([' Excel import/export is incompatible with MATLAB Text Analytics Toolbox.\n' ... -0177 ' Further instructions => https://github.com/SysBioChalmers/RAVEN/issues/55#issuecomment-1514369299\n']) -0178 end +0165 end +0166 fprintf(myStr(' > Checking libSBML version',40)) +0167 try +0168 evalc('importModel(fullfile(ravenDir,''tutorial'',''empty.xml''))'); +0169 try +0170 libSBMLver=OutputSBML_RAVEN; % Only works in libSBML 5.17.0+ +0171 fprintf([libSBMLver.libSBML_version_string '\n']); +0172 catch +0173 printOrange('Fail\n') +0174 fprintf(' An older libSBML version was found, update to version 5.17.0 or higher for a significant improvement of model import\n'); +0175 end +0176 catch +0177 printOrange('Fail\n') +0178 fprintf(' Download libSBML from http://sbml.org/Software/libSBML/Downloading_libSBML and add to MATLAB path\n'); 0179 end -0180 -0181 fprintf(myStr(' > Export Excel format',40)) -0182 if res(4).Passed == 1 -0183 fprintf('Pass\n') -0184 else -0185 printOrange('Fail\n') -0186 end -0187 -0188 fprintf(myStr(' > Import SBML format',40)) -0189 if res(2).Passed == 1 -0190 fprintf('Pass\n') -0191 else -0192 printOrange('Fail\n') -0193 end -0194 -0195 fprintf(myStr(' > Export SBML format',40)) -0196 if res(5).Passed == 1 -0197 fprintf('Pass\n') -0198 else -0199 printOrange('Fail\n') -0200 end -0201 -0202 fprintf(myStr(' > Import YAML format',40)) -0203 if res(3).Passed == 1 -0204 fprintf('Pass\n') -0205 else -0206 printOrange('Fail\n') -0207 end -0208 -0209 fprintf(myStr(' > Export YAML format',40)) -0210 if res(6).Passed == 1 -0211 fprintf('Pass\n') -0212 else -0213 printOrange('Fail\n') -0214 end -0215 -0216 fprintf('\n=== Model solvers ===\n'); -0217 -0218 %Get current solver. Set it to 'none', if it is not set -0219 fprintf(' > Checking for LP solvers\n') -0220 [~,res]=evalc("runtests('solverTests.m');"); +0180 fprintf(' > Checking model import and export\n') +0181 [~,res]=evalc("runtests('importExportTests.m');"); +0182 +0183 fprintf(myStr(' > Import Excel format',40)) +0184 if res(1).Passed == 1 +0185 fprintf('Pass\n') +0186 else +0187 printOrange('Fail\n') +0188 if any(strcmpi(addList.Name,'Text Analytics Toolbox')) +0189 fprintf([' Excel import/export is incompatible with MATLAB Text Analytics Toolbox.\n' ... +0190 ' Further instructions => https://github.com/SysBioChalmers/RAVEN/issues/55#issuecomment-1514369299\n']) +0191 end +0192 end +0193 +0194 fprintf(myStr(' > Export Excel format',40)) +0195 if res(4).Passed == 1 +0196 fprintf('Pass\n') +0197 else +0198 printOrange('Fail\n') +0199 end +0200 +0201 fprintf(myStr(' > Import SBML format',40)) +0202 if res(2).Passed == 1 +0203 fprintf('Pass\n') +0204 else +0205 printOrange('Fail\n') +0206 end +0207 +0208 fprintf(myStr(' > Export SBML format',40)) +0209 if res(5).Passed == 1 +0210 fprintf('Pass\n') +0211 else +0212 printOrange('Fail\n') +0213 end +0214 +0215 fprintf(myStr(' > Import YAML format',40)) +0216 if res(3).Passed == 1 +0217 fprintf('Pass\n') +0218 else +0219 printOrange('Fail\n') +0220 end 0221 -0222 fprintf(myStr(' > glpk',40)) -0223 if res(1).Passed == 1 +0222 fprintf(myStr(' > Export YAML format',40)) +0223 if res(6).Passed == 1 0224 fprintf('Pass\n') 0225 else 0226 printOrange('Fail\n') 0227 end 0228 -0229 fprintf(myStr(' > gurobi',40)) -0230 if res(2).Passed == 1 -0231 fprintf('Pass\n') -0232 else -0233 printOrange('Fail\n') -0234 end -0235 -0236 fprintf(myStr(' > scip',40)) -0237 if res(3).Passed == 1 -0238 fprintf('Pass\n') -0239 else -0240 printOrange('Fail\n') -0241 end -0242 -0243 fprintf(myStr(' > cobra',40)) -0244 if res(4).Passed == 1 -0245 fprintf('Pass\n') -0246 else -0247 printOrange('Fail\n') -0248 end -0249 fprintf(myStr(' > Set RAVEN solver',40)) -0250 try -0251 oldSolver=getpref('RAVEN','solver'); -0252 solverIdx=find(strcmp(oldSolver,{'glpk','gurobi','scip','cobra'})); -0253 catch -0254 solverIdx=0; -0255 end -0256 % Do not change old solver if functional -0257 if solverIdx~=0 && res(solverIdx).Passed == 1 -0258 fprintf([oldSolver '\n']) -0259 % Order of preference: gurobi > glpk > scip > cobra -0260 elseif res(2).Passed == 1 -0261 fprintf('gurobi\n') -0262 setRavenSolver('gurobi'); -0263 elseif res(1).Passed == 1 -0264 fprintf('glpk\n') -0265 setRavenSolver('glpk'); -0266 elseif res(3).Passed == 1 -0267 fprintf('scip\n') -0268 setRavenSolver('scip'); -0269 elseif res(4).Passed == 1 -0270 fprintf('cobra\n') -0271 setRavenSolver('cobra'); -0272 else -0273 fprintf('None, no functional solvers\n') -0274 fprintf(' The glpk should always be working, check your RAVEN installation to make sure all files are present\n') -0275 end -0276 -0277 fprintf('\n=== Essential binary executables ===\n'); -0278 fprintf(myStr(' > Checking BLAST+',40)) -0279 [~,res]=evalc("runtests('blastPlusTests.m');"); -0280 res=interpretResults(res); -0281 if res==false -0282 fprintf(' This is essential to run getBlast()\n') -0283 end -0284 -0285 fprintf(myStr(' > Checking DIAMOND',40)) -0286 [~,res]=evalc("runtests('diamondTests.m');"); -0287 res=interpretResults(res); -0288 if res==false -0289 fprintf(' This is essential to run the getDiamond()\n') -0290 end -0291 -0292 fprintf(myStr(' > Checking HMMER',40)) -0293 [~,res]=evalc("runtests('hmmerTests.m')"); -0294 res=interpretResults(res); -0295 if res==false -0296 fprintf([' This is essential to run getKEGGModelFromHomology()\n'... -0297 ' when using a FASTA file as input\n']) -0298 end -0299 -0300 if developMode -0301 fprintf('\n=== Development binary executables ===\n'); -0302 fprintf('NOTE: These binaries are only required when using KEGG FTP dump files in getKEGGModelForOrganism\n'); -0303 -0304 fprintf(myStr(' > Checking CD-HIT',40)) -0305 [~,res]=evalc("runtests('cdhitTests.m');"); -0306 interpretResults(res); +0229 fprintf('\n=== Model solvers ===\n'); +0230 +0231 %Get current solver. Set it to 'none', if it is not set +0232 fprintf(' > Checking for LP solvers\n') +0233 [~,res]=evalc("runtests('solverTests.m');"); +0234 +0235 fprintf(myStr(' > glpk',40)) +0236 if res(1).Passed == 1 +0237 fprintf('Pass\n') +0238 else +0239 printOrange('Fail\n') +0240 end +0241 +0242 fprintf(myStr(' > gurobi',40)) +0243 if res(2).Passed == 1 +0244 fprintf('Pass\n') +0245 else +0246 printOrange('Fail\n') +0247 end +0248 +0249 fprintf(myStr(' > scip',40)) +0250 if res(3).Passed == 1 +0251 fprintf('Pass\n') +0252 else +0253 printOrange('Fail\n') +0254 end +0255 +0256 fprintf(myStr(' > cobra',40)) +0257 if res(4).Passed == 1 +0258 fprintf('Pass\n') +0259 else +0260 printOrange('Fail\n') +0261 end +0262 fprintf(myStr(' > Set RAVEN solver',40)) +0263 try +0264 oldSolver=getpref('RAVEN','solver'); +0265 solverIdx=find(strcmp(oldSolver,{'glpk','gurobi','scip','cobra'})); +0266 catch +0267 solverIdx=0; +0268 end +0269 % Do not change old solver if functional +0270 if solverIdx~=0 && res(solverIdx).Passed == 1 +0271 fprintf([oldSolver '\n']) +0272 % Order of preference: gurobi > glpk > scip > cobra +0273 elseif res(2).Passed == 1 +0274 fprintf('gurobi\n') +0275 setRavenSolver('gurobi'); +0276 elseif res(1).Passed == 1 +0277 fprintf('glpk\n') +0278 setRavenSolver('glpk'); +0279 elseif res(3).Passed == 1 +0280 fprintf('scip\n') +0281 setRavenSolver('scip'); +0282 elseif res(4).Passed == 1 +0283 fprintf('cobra\n') +0284 setRavenSolver('cobra'); +0285 else +0286 fprintf('None, no functional solvers\n') +0287 fprintf(' The glpk should always be working, check your RAVEN installation to make sure all files are present\n') +0288 end +0289 +0290 fprintf('\n=== Essential binary executables ===\n'); +0291 if ~checkBinaries +0292 printOrange(' Skipping check of binary executables\n') +0293 else +0294 fprintf(myStr(' > Checking BLAST+',40)) +0295 [~,res]=evalc("runtests('blastPlusTests.m');"); +0296 res=interpretResults(res); +0297 if res==false +0298 fprintf(' This is essential to run getBlast()\n') +0299 end +0300 +0301 fprintf(myStr(' > Checking DIAMOND',40)) +0302 [~,res]=evalc("runtests('diamondTests.m');"); +0303 res=interpretResults(res); +0304 if res==false +0305 fprintf(' This is essential to run the getDiamond()\n') +0306 end 0307 -0308 fprintf(myStr(' > Checking MAFFT',40)) -0309 [~,res]=evalc("runtests('mafftTests.m');"); -0310 interpretResults(res); -0311 end -0312 -0313 fprintf('\n=== Compatibility ===\n'); -0314 fprintf(myStr(' > Checking function uniqueness',40)) -0315 checkFunctionUniqueness(); -0316 -0317 fprintf('\n*** checkInstallation complete ***\n\n'); -0318 end +0308 fprintf(myStr(' > Checking HMMER',40)) +0309 [~,res]=evalc("runtests('hmmerTests.m')"); +0310 res=interpretResults(res); +0311 if res==false +0312 fprintf([' This is essential to run getKEGGModelFromHomology()\n'... +0313 ' when using a FASTA file as input\n']) +0314 end +0315 +0316 if developMode +0317 fprintf('\n=== Development binary executables ===\n'); +0318 fprintf('NOTE: These binaries are only required when using KEGG FTP dump files in getKEGGModelForOrganism\n'); 0319 -0320 function res = interpretResults(results) -0321 if results.Failed==0 && results.Incomplete==0 -0322 fprintf('Pass\n'); -0323 res=true; -0324 else -0325 printOrange('Fail\n') -0326 fprintf(' Download/compile the binary and rerun checkInstallation\n'); -0327 res=false; +0320 fprintf(myStr(' > Checking CD-HIT',40)) +0321 [~,res]=evalc("runtests('cdhitTests.m');"); +0322 interpretResults(res); +0323 +0324 fprintf(myStr(' > Checking MAFFT',40)) +0325 [~,res]=evalc("runtests('mafftTests.m');"); +0326 interpretResults(res); +0327 end 0328 end -0329 end -0330 -0331 function str = myStr(InputStr,len) -0332 str=InputStr; -0333 lenDiff = len - length(str); -0334 if lenDiff < 0 -0335 warning('String too long'); -0336 else -0337 str = [str blanks(lenDiff)]; -0338 end -0339 end -0340 -0341 function status = makeBinaryExecutable(ravenDir) -0342 % This function is required to run when RAVEN is downloaded as MATLAB -0343 % Add-On, in which case the file permissions are not correctly set -0344 if ispc -0345 status = 0; % No need to run on Windows -0346 return; -0347 end -0348 binDir = fullfile(ravenDir,'software'); -0349 -0350 binList = {fullfile(binDir,'blast+','blastp'); fullfile(binDir,'blast+','blastp.mac'); -0351 fullfile(binDir,'blast+','makeblastdb'); fullfile(binDir,'blast+','makeblastdb.mac'); -0352 fullfile(binDir,'cd-hit','cd-hit'); fullfile(binDir,'cd-hit','cd-hit.mac'); -0353 fullfile(binDir,'diamond','diamond'); fullfile(binDir,'diamond','diamond.mac'); -0354 fullfile(binDir,'hmmer','hmmbuild'); fullfile(binDir,'hmmer','hmmbuild.mac'); -0355 fullfile(binDir,'hmmer','hmmsearch'); fullfile(binDir,'hmmer','hmmsearch.mac'); -0356 fullfile(binDir,'GLPKmex','glpkcc.mexa64'); fullfile(binDir,'GLPKmex','glpkcc.mexglx'); fullfile(binDir,'GLPKmex','glpkcc.mexmaci64'); fullfile(binDir,'GLPKmex','glpkcc.mexmaca64'); -0357 fullfile(binDir,'libSBML','TranslateSBML_RAVEN.mexa64'); fullfile(binDir,'libSBML','TranslateSBML_RAVEN.mexglx'); fullfile(binDir,'libSBML','TranslateSBML_RAVEN.mexmaci64'); fullfile(binDir,'libSBML','TranslateSBML_RAVEN.mexmaca64'); -0358 fullfile(binDir,'libSBML','OutputSBML_RAVEN.mexa64'); fullfile(binDir,'libSBML','OutputSBML_RAVEN.mexglx'); fullfile(binDir,'libSBML','OutputSBML_RAVEN.mexmaci64'); fullfile(binDir,'libSBML','OutputSBML_RAVEN.mexmaca64'); -0359 fullfile(binDir,'mafft','mafft-linux64','mafft.bat'); -0360 fullfile(binDir,'mafft','mafft-mac','mafft.bat');}; -0361 -0362 for i=1:numel(binList) -0363 [status,cmdout] = system(['chmod +x "' binList{i} '"']); -0364 if status ~= 0 -0365 warning('Failed to make %s executable: %s ',binList{i},strip(cmdout)) -0366 end -0367 end -0368 end -0369 -0370 function printOrange(stringToPrint) -0371 % printOrange -0372 % Duplicate of RAVEN/core/printOrange is also kept here, as this function -0373 % should be able to run before adding RAVEN to the MATLAB path. -0374 try useDesktop = usejava('desktop'); catch, useDesktop = false; end -0375 if useDesktop -0376 fprintf(['[\b' stringToPrint,']\b']) -0377 else -0378 fprintf(stringToPrint) -0379 end -0380 end

    +0329 +0330 fprintf('\n=== Compatibility ===\n'); +0331 fprintf(myStr(' > Checking function uniqueness',40)) +0332 checkFunctionUniqueness(); +0333 +0334 fprintf('\n*** checkInstallation complete ***\n'); +0335 end +0336 +0337 function res = interpretResults(results) +0338 if results.Failed==0 && results.Incomplete==0 +0339 fprintf('Pass\n'); +0340 res=true; +0341 else +0342 printOrange('Fail\n') +0343 fprintf(' Download/compile the binary and rerun checkInstallation\n'); +0344 res=false; +0345 end +0346 end +0347 +0348 function str = myStr(InputStr,len) +0349 str=InputStr; +0350 lenDiff = len - length(str); +0351 if lenDiff < 0 +0352 warning('String too long'); +0353 else +0354 str = [str blanks(lenDiff)]; +0355 end +0356 end +0357 +0358 function status = makeBinaryExecutable(ravenDir) +0359 % This function is required to run when RAVEN is downloaded as MATLAB +0360 % Add-On, in which case the file permissions are not correctly set +0361 if ispc +0362 status = 0; % No need to run on Windows +0363 return; +0364 end +0365 binDir = fullfile(ravenDir,'software'); +0366 +0367 binList = {fullfile(binDir,'blast+','blastp'); fullfile(binDir,'blast+','blastp.mac'); +0368 fullfile(binDir,'blast+','makeblastdb'); fullfile(binDir,'blast+','makeblastdb.mac'); +0369 fullfile(binDir,'cd-hit','cd-hit'); fullfile(binDir,'cd-hit','cd-hit.mac'); +0370 fullfile(binDir,'diamond','diamond'); fullfile(binDir,'diamond','diamond.mac'); +0371 fullfile(binDir,'hmmer','hmmbuild'); fullfile(binDir,'hmmer','hmmbuild.mac'); +0372 fullfile(binDir,'hmmer','hmmsearch'); fullfile(binDir,'hmmer','hmmsearch.mac'); +0373 fullfile(binDir,'GLPKmex','glpkcc.mexa64'); fullfile(binDir,'GLPKmex','glpkcc.mexglx'); fullfile(binDir,'GLPKmex','glpkcc.mexmaci64'); fullfile(binDir,'GLPKmex','glpkcc.mexmaca64'); +0374 fullfile(binDir,'libSBML','TranslateSBML_RAVEN.mexa64'); fullfile(binDir,'libSBML','TranslateSBML_RAVEN.mexglx'); fullfile(binDir,'libSBML','TranslateSBML_RAVEN.mexmaci64'); fullfile(binDir,'libSBML','TranslateSBML_RAVEN.mexmaca64'); +0375 fullfile(binDir,'libSBML','OutputSBML_RAVEN.mexa64'); fullfile(binDir,'libSBML','OutputSBML_RAVEN.mexglx'); fullfile(binDir,'libSBML','OutputSBML_RAVEN.mexmaci64'); fullfile(binDir,'libSBML','OutputSBML_RAVEN.mexmaca64'); +0376 fullfile(binDir,'mafft','mafft-linux64','mafft.bat'); +0377 fullfile(binDir,'mafft','mafft-mac','mafft.bat');}; +0378 +0379 for i=1:numel(binList) +0380 [status,cmdout] = system(['chmod +x "' binList{i} '"']); +0381 if status ~= 0 +0382 warning('Failed to make %s executable: %s ',binList{i},strip(cmdout)) +0383 end +0384 end +0385 end +0386 +0387 function printOrange(stringToPrint) +0388 % printOrange +0389 % Duplicate of RAVEN/core/printOrange is also kept here, as this function +0390 % should be able to run before adding RAVEN to the MATLAB path. +0391 try useDesktop = usejava('desktop'); catch, useDesktop = false; end +0392 if useDesktop +0393 fprintf(['[\b' stringToPrint,']\b']) +0394 else +0395 fprintf(stringToPrint) +0396 end +0397 end

    Generated by m2html © 2005
    \ No newline at end of file diff --git a/doc/io/exportToExcelFormat.html b/doc/io/exportToExcelFormat.html index 70b7328f..72adbf32 100644 --- a/doc/io/exportToExcelFormat.html +++ b/doc/io/exportToExcelFormat.html @@ -243,214 +243,217 @@

    SOURCE CODE ^''; 0186 if isfield(model,'subSystems') 0187 for i=1:numel(model.subSystems) -0188 if ~isempty(model.subSystems{i,1}) -0189 subsystems{i,1}=strjoin(model.subSystems{i,1},';'); -0190 else -0191 subsystems{i,1}=''; -0192 end -0193 end -0194 rxnSheet=[rxnSheet subsystems]; -0195 else -0196 rxnSheet=[rxnSheet emptyColumn]; -0197 end -0198 -0199 %For REPLACEMENT ID which isn't in the model -0200 rxnSheet=[rxnSheet emptyColumn]; +0188 if ~iscell(model.subSystems{i}) +0189 model.subSystems{i} = {model.subSystems{i}}; +0190 end +0191 if ~isempty(model.subSystems{i,1}) +0192 subsystems{i,1}=strjoin(model.subSystems{i,1},';'); +0193 else +0194 subsystems{i,1}=''; +0195 end +0196 end +0197 rxnSheet=[rxnSheet subsystems]; +0198 else +0199 rxnSheet=[rxnSheet emptyColumn]; +0200 end 0201 -0202 if isfield(model,'rxnNotes') -0203 rxnSheet=[rxnSheet model.rxnNotes]; -0204 else -0205 rxnSheet=[rxnSheet emptyColumn]; -0206 end -0207 -0208 if isfield(model,'rxnReferences') -0209 rxnSheet=[rxnSheet model.rxnReferences]; -0210 else -0211 rxnSheet=[rxnSheet emptyColumn]; -0212 end -0213 -0214 if isfield(model,'rxnConfidenceScores') -0215 rxnSheet=[rxnSheet num2cell(model.rxnConfidenceScores)]; -0216 else -0217 rxnSheet=[rxnSheet emptyColumn]; -0218 end -0219 -0220 wb=writeSheet(wb,'RXNS',0,headers,[],rxnSheet); -0221 -0222 headers={'#';'ID';'NAME';'UNCONSTRAINED';'MIRIAM';'COMPOSITION';'InChI';'COMPARTMENT';'REPLACEMENT ID';'CHARGE'}; -0223 -0224 metSheet=cell(numel(model.mets),numel(headers)); -0225 -0226 for i=1:numel(model.mets) -0227 metSheet{i,2}=[model.metNames{i} '[' model.comps{model.metComps(i)} ']']; -0228 -0229 if isfield(model,'metNames') -0230 metSheet(i,3)=model.metNames(i); -0231 end -0232 -0233 if isfield(model,'unconstrained') -0234 if model.unconstrained(i)~=0 -0235 metSheet{i,4}=true; -0236 end -0237 end -0238 -0239 if isfield(model,'metMiriams') -0240 if ~isempty(model.metMiriams{i}) -0241 toPrint=[]; -0242 for j=1:numel(model.metMiriams{i}.name) -0243 toPrint=[toPrint strtrim(model.metMiriams{i}.name{j}) '/' strtrim(model.metMiriams{i}.value{j}) ';']; -0244 end -0245 metSheet{i,5}=toPrint(1:end-1); -0246 end -0247 end -0248 -0249 % Making sure that only these metFormulas are exported, which don't -0250 % have InChI strings -0251 if isfield(model,'metFormulas') -0252 if isfield(model,'inchis') -0253 if isempty(model.inchis{i}) -0254 metSheet(i,6)=model.metFormulas(i); -0255 end -0256 else -0257 metSheet(i,6)=model.metFormulas(i); -0258 end -0259 end -0260 -0261 if isfield(model,'inchis') -0262 metSheet(i,7)=model.inchis(i); -0263 end -0264 -0265 if isfield(model,'metComps') -0266 metSheet(i,8)=model.comps(model.metComps(i)); -0267 end -0268 -0269 metSheet(i,9)=model.mets(i); -0270 -0271 if isfield(model,'metCharges') -0272 metSheet{i,10}=model.metCharges(i); -0273 end -0274 end -0275 -0276 wb=writeSheet(wb,'METS',1,headers,[],metSheet); -0277 -0278 %Add the COMPS sheet -0279 -0280 %Create the header row -0281 headers={'#';'ABBREVIATION';'NAME';'INSIDE';'MIRIAM'}; +0202 %For REPLACEMENT ID which isn't in the model +0203 rxnSheet=[rxnSheet emptyColumn]; +0204 +0205 if isfield(model,'rxnNotes') +0206 rxnSheet=[rxnSheet model.rxnNotes]; +0207 else +0208 rxnSheet=[rxnSheet emptyColumn]; +0209 end +0210 +0211 if isfield(model,'rxnReferences') +0212 rxnSheet=[rxnSheet model.rxnReferences]; +0213 else +0214 rxnSheet=[rxnSheet emptyColumn]; +0215 end +0216 +0217 if isfield(model,'rxnConfidenceScores') +0218 rxnSheet=[rxnSheet num2cell(model.rxnConfidenceScores)]; +0219 else +0220 rxnSheet=[rxnSheet emptyColumn]; +0221 end +0222 +0223 wb=writeSheet(wb,'RXNS',0,headers,[],rxnSheet); +0224 +0225 headers={'#';'ID';'NAME';'UNCONSTRAINED';'MIRIAM';'COMPOSITION';'InChI';'COMPARTMENT';'REPLACEMENT ID';'CHARGE'}; +0226 +0227 metSheet=cell(numel(model.mets),numel(headers)); +0228 +0229 for i=1:numel(model.mets) +0230 metSheet{i,2}=[model.metNames{i} '[' model.comps{model.metComps(i)} ']']; +0231 +0232 if isfield(model,'metNames') +0233 metSheet(i,3)=model.metNames(i); +0234 end +0235 +0236 if isfield(model,'unconstrained') +0237 if model.unconstrained(i)~=0 +0238 metSheet{i,4}=true; +0239 end +0240 end +0241 +0242 if isfield(model,'metMiriams') +0243 if ~isempty(model.metMiriams{i}) +0244 toPrint=[]; +0245 for j=1:numel(model.metMiriams{i}.name) +0246 toPrint=[toPrint strtrim(model.metMiriams{i}.name{j}) '/' strtrim(model.metMiriams{i}.value{j}) ';']; +0247 end +0248 metSheet{i,5}=toPrint(1:end-1); +0249 end +0250 end +0251 +0252 % Making sure that only these metFormulas are exported, which don't +0253 % have InChI strings +0254 if isfield(model,'metFormulas') +0255 if isfield(model,'inchis') +0256 if isempty(model.inchis{i}) +0257 metSheet(i,6)=model.metFormulas(i); +0258 end +0259 else +0260 metSheet(i,6)=model.metFormulas(i); +0261 end +0262 end +0263 +0264 if isfield(model,'inchis') +0265 metSheet(i,7)=model.inchis(i); +0266 end +0267 +0268 if isfield(model,'metComps') +0269 metSheet(i,8)=model.comps(model.metComps(i)); +0270 end +0271 +0272 metSheet(i,9)=model.mets(i); +0273 +0274 if isfield(model,'metCharges') +0275 metSheet{i,10}=model.metCharges(i); +0276 end +0277 end +0278 +0279 wb=writeSheet(wb,'METS',1,headers,[],metSheet); +0280 +0281 %Add the COMPS sheet 0282 -0283 compSheet=cell(numel(model.comps),numel(headers)); -0284 -0285 for i=1:numel(model.comps) -0286 compSheet(i,2)=model.comps(i); -0287 -0288 if isfield(model,'compNames') -0289 compSheet(i,3)=model.compNames(i); -0290 end -0291 -0292 if isfield(model,'compOutside') -0293 compSheet(i,4)=model.compOutside(i); -0294 end -0295 -0296 if isfield(model,'compMiriams') -0297 if ~isempty(model.compMiriams{i}) -0298 toPrint=[]; -0299 for j=1:numel(model.compMiriams{i}.name) -0300 toPrint=[toPrint strtrim(model.compMiriams{i}.name{j}) '/' strtrim(model.compMiriams{i}.value{j}) ';']; -0301 end -0302 compSheet{i,5}=toPrint(1:end-1); -0303 end -0304 end -0305 end -0306 -0307 wb=writeSheet(wb,'COMPS',2,headers,[],compSheet); -0308 -0309 %Add the GENES sheet -0310 if isfield(model,'genes') -0311 %Create the header row -0312 headers={'#';'NAME';'MIRIAM';'SHORT NAME';'COMPARTMENT'}; -0313 -0314 geneSheet=cell(numel(model.genes),numel(headers)); -0315 -0316 for i=1:numel(model.genes) -0317 geneSheet(i,2)=model.genes(i); -0318 -0319 if isfield(model,'geneMiriams') -0320 if ~isempty(model.geneMiriams{i}) -0321 toPrint=[]; -0322 for j=1:numel(model.geneMiriams{i}.name) -0323 toPrint=[toPrint strtrim(model.geneMiriams{i}.name{j}) '/' strtrim(model.geneMiriams{i}.value{j}) ';']; -0324 end -0325 geneSheet{i,3}=toPrint(1:end-1); -0326 end -0327 end -0328 if isfield(model,'geneShortNames') -0329 geneSheet(i,4)=model.geneShortNames(i); +0283 %Create the header row +0284 headers={'#';'ABBREVIATION';'NAME';'INSIDE';'MIRIAM'}; +0285 +0286 compSheet=cell(numel(model.comps),numel(headers)); +0287 +0288 for i=1:numel(model.comps) +0289 compSheet(i,2)=model.comps(i); +0290 +0291 if isfield(model,'compNames') +0292 compSheet(i,3)=model.compNames(i); +0293 end +0294 +0295 if isfield(model,'compOutside') +0296 compSheet(i,4)=model.compOutside(i); +0297 end +0298 +0299 if isfield(model,'compMiriams') +0300 if ~isempty(model.compMiriams{i}) +0301 toPrint=[]; +0302 for j=1:numel(model.compMiriams{i}.name) +0303 toPrint=[toPrint strtrim(model.compMiriams{i}.name{j}) '/' strtrim(model.compMiriams{i}.value{j}) ';']; +0304 end +0305 compSheet{i,5}=toPrint(1:end-1); +0306 end +0307 end +0308 end +0309 +0310 wb=writeSheet(wb,'COMPS',2,headers,[],compSheet); +0311 +0312 %Add the GENES sheet +0313 if isfield(model,'genes') +0314 %Create the header row +0315 headers={'#';'NAME';'MIRIAM';'SHORT NAME';'COMPARTMENT'}; +0316 +0317 geneSheet=cell(numel(model.genes),numel(headers)); +0318 +0319 for i=1:numel(model.genes) +0320 geneSheet(i,2)=model.genes(i); +0321 +0322 if isfield(model,'geneMiriams') +0323 if ~isempty(model.geneMiriams{i}) +0324 toPrint=[]; +0325 for j=1:numel(model.geneMiriams{i}.name) +0326 toPrint=[toPrint strtrim(model.geneMiriams{i}.name{j}) '/' strtrim(model.geneMiriams{i}.value{j}) ';']; +0327 end +0328 geneSheet{i,3}=toPrint(1:end-1); +0329 end 0330 end -0331 if isfield(model,'geneComps') -0332 geneSheet(i,5)=model.comps(model.geneComps(i)); +0331 if isfield(model,'geneShortNames') +0332 geneSheet(i,4)=model.geneShortNames(i); 0333 end -0334 end -0335 -0336 wb=writeSheet(wb,'GENES',3,headers,[],geneSheet); -0337 end -0338 -0339 %Add the MODEL sheet -0340 -0341 %Create the header row -0342 headers={'#';'ID';'NAME';'TAXONOMY';'DEFAULT LOWER';'DEFAULT UPPER';'CONTACT GIVEN NAME';'CONTACT FAMILY NAME';'CONTACT EMAIL';'ORGANIZATION';'NOTES'}; +0334 if isfield(model,'geneComps') +0335 geneSheet(i,5)=model.comps(model.geneComps(i)); +0336 end +0337 end +0338 +0339 wb=writeSheet(wb,'GENES',3,headers,[],geneSheet); +0340 end +0341 +0342 %Add the MODEL sheet 0343 -0344 modelSheet=cell(1,numel(headers)); -0345 -0346 if ~isfield(model,'annotation') -0347 model.annotation = []; -0348 end -0349 -0350 if isfield(model,'id') -0351 modelSheet{1,2}=model.id; -0352 else -0353 modelSheet{1,2}='blankID'; -0354 end -0355 if isfield(model,'name') -0356 modelSheet{1,3}=model.name; -0357 else -0358 modelSheet{1,3}='blankName'; -0359 end -0360 if isfield(model.annotation,'taxonomy') -0361 modelSheet{1,4}=model.annotation.taxonomy; +0344 %Create the header row +0345 headers={'#';'ID';'NAME';'TAXONOMY';'DEFAULT LOWER';'DEFAULT UPPER';'CONTACT GIVEN NAME';'CONTACT FAMILY NAME';'CONTACT EMAIL';'ORGANIZATION';'NOTES'}; +0346 +0347 modelSheet=cell(1,numel(headers)); +0348 +0349 if ~isfield(model,'annotation') +0350 model.annotation = []; +0351 end +0352 +0353 if isfield(model,'id') +0354 modelSheet{1,2}=model.id; +0355 else +0356 modelSheet{1,2}='blankID'; +0357 end +0358 if isfield(model,'name') +0359 modelSheet{1,3}=model.name; +0360 else +0361 modelSheet{1,3}='blankName'; 0362 end -0363 if isfield(model.annotation,'defaultLB') -0364 modelSheet{1,5}=model.annotation.defaultLB; +0363 if isfield(model.annotation,'taxonomy') +0364 modelSheet{1,4}=model.annotation.taxonomy; 0365 end -0366 if isfield(model.annotation,'defaultUB') -0367 modelSheet{1,6}=model.annotation.defaultUB; +0366 if isfield(model.annotation,'defaultLB') +0367 modelSheet{1,5}=model.annotation.defaultLB; 0368 end -0369 if isfield(model.annotation,'givenName') -0370 modelSheet{1,7}=model.annotation.givenName; +0369 if isfield(model.annotation,'defaultUB') +0370 modelSheet{1,6}=model.annotation.defaultUB; 0371 end -0372 if isfield(model.annotation,'familyName') -0373 modelSheet{1,8}=model.annotation.familyName; +0372 if isfield(model.annotation,'givenName') +0373 modelSheet{1,7}=model.annotation.givenName; 0374 end -0375 if isfield(model.annotation,'email') -0376 modelSheet{1,9}=model.annotation.email; +0375 if isfield(model.annotation,'familyName') +0376 modelSheet{1,8}=model.annotation.familyName; 0377 end -0378 if isfield(model.annotation,'organization') -0379 modelSheet{1,10}=model.annotation.organization; +0378 if isfield(model.annotation,'email') +0379 modelSheet{1,9}=model.annotation.email; 0380 end -0381 if isfield(model.annotation,'note') -0382 modelSheet{1,11}=model.annotation.note; +0381 if isfield(model.annotation,'organization') +0382 modelSheet{1,10}=model.annotation.organization; 0383 end -0384 -0385 if isfield(model,'genes') -0386 wb=writeSheet(wb,'MODEL',4,headers,[],modelSheet); -0387 else -0388 wb=writeSheet(wb,'MODEL',3,headers,[],modelSheet); -0389 end -0390 -0391 %Open the output stream -0392 out = FileOutputStream(fileName); -0393 wb.write(out); -0394 out.close(); -0395 end

    +0384 if isfield(model.annotation,'note') +0385 modelSheet{1,11}=model.annotation.note; +0386 end +0387 +0388 if isfield(model,'genes') +0389 wb=writeSheet(wb,'MODEL',4,headers,[],modelSheet); +0390 else +0391 wb=writeSheet(wb,'MODEL',3,headers,[],modelSheet); +0392 end +0393 +0394 %Open the output stream +0395 out = FileOutputStream(fileName); +0396 wb.write(out); +0397 out.close(); +0398 end
    Generated by m2html © 2005
    \ No newline at end of file diff --git a/doc/io/exportToTabDelimited.html b/doc/io/exportToTabDelimited.html index 827b0d7e..11fe1e42 100644 --- a/doc/io/exportToTabDelimited.html +++ b/doc/io/exportToTabDelimited.html @@ -167,238 +167,241 @@

    SOURCE CODE ^if isfield(model,'subSystems') 0108 if ~isempty(model.subSystems{i}) -0109 fprintf(rxnFile,[strjoin(model.subSystems{i,1},';') '\t']); -0110 else -0111 fprintf(rxnFile,'\t'); -0112 end -0113 end -0114 -0115 %Print replacement IDs -0116 fprintf(rxnFile,'\t'); +0109 if ~iscell(model.subSystems{i}) +0110 model.subSystems{i} = {model.subSystems{i}}; +0111 end +0112 fprintf(rxnFile,[strjoin(model.subSystems{i,1},';') '\t']); +0113 else +0114 fprintf(rxnFile,'\t'); +0115 end +0116 end 0117 -0118 if isfield(model,'rxnNotes') -0119 fprintf(rxnFile,[model.rxnNotes{i} '\t']); -0120 else -0121 fprintf(rxnFile,'\t'); -0122 end -0123 -0124 if isfield(model,'rxnReferences') -0125 fprintf(rxnFile,[model.rxnReferences{i} '\t']); -0126 else -0127 fprintf(rxnFile,'\t'); -0128 end -0129 -0130 if isfield(model,'rxnConfidenceScores') -0131 fprintf(rxnFile,[num2str(model.rxnConfidenceScores(i)) '\t' ]); -0132 else -0133 fprintf(rxnFile,'\t'); -0134 end -0135 -0136 fprintf(rxnFile,'\n'); -0137 end -0138 -0139 fclose(rxnFile); -0140 -0141 %Open for printing the metabolites sheet -0142 metFile=fopen(fullfile(path,'excelMets.txt'),'wt'); +0118 %Print replacement IDs +0119 fprintf(rxnFile,'\t'); +0120 +0121 if isfield(model,'rxnNotes') +0122 fprintf(rxnFile,[model.rxnNotes{i} '\t']); +0123 else +0124 fprintf(rxnFile,'\t'); +0125 end +0126 +0127 if isfield(model,'rxnReferences') +0128 fprintf(rxnFile,[model.rxnReferences{i} '\t']); +0129 else +0130 fprintf(rxnFile,'\t'); +0131 end +0132 +0133 if isfield(model,'rxnConfidenceScores') +0134 fprintf(rxnFile,[num2str(model.rxnConfidenceScores(i)) '\t' ]); +0135 else +0136 fprintf(rxnFile,'\t'); +0137 end +0138 +0139 fprintf(rxnFile,'\n'); +0140 end +0141 +0142 fclose(rxnFile); 0143 -0144 %Print header -0145 fprintf(metFile,'#\tID\tNAME\tUNCONSTRAINED\tMIRIAM\tCOMPOSITION\tInChI\tCOMPARTMENT\tREPLACEMENT ID\tMETS FIELD\tCHARGE\n'); +0144 %Open for printing the metabolites sheet +0145 metFile=fopen(fullfile(path,'excelMets.txt'),'wt'); 0146 -0147 %Loop through the metabolites -0148 for i=1:numel(model.mets) -0149 fprintf(metFile,['\t' model.metNames{i} '[' model.comps{model.metComps(i)} ']\t' model.metNames{i} '\t']); -0150 -0151 if isfield(model,'unconstrained') -0152 if model.unconstrained(i)~=0 -0153 fprintf(metFile,'TRUE\t'); -0154 else -0155 fprintf(metFile,'\t'); -0156 end -0157 else -0158 fprintf(metFile,'\t'); -0159 end -0160 -0161 if isfield(model,'metMiriams') -0162 if ~isempty(model.metMiriams{i}) -0163 toPrint=[]; -0164 for j=1:numel(model.metMiriams{i}.name) -0165 toPrint=[toPrint strtrim(model.metMiriams{i}.name{j}) '/' strtrim(model.metMiriams{i}.value{j}) ';']; -0166 end -0167 fprintf(rxnFile,[toPrint(1:end-1) '\t']); -0168 else -0169 fprintf(metFile,'\t'); -0170 end -0171 else -0172 fprintf(metFile,'\t'); -0173 end -0174 -0175 if isfield(model,'metFormulas') -0176 fprintf(metFile,[model.metFormulas{i} '\t']); -0177 else -0178 fprintf(metFile,'\t'); -0179 end -0180 -0181 if isfield(model,'inchis') -0182 fprintf(metFile,[model.inchis{i} '\t']); -0183 else -0184 fprintf(metFile,'\t'); -0185 end -0186 -0187 fprintf(metFile,[model.comps{model.metComps(i)} '\t']); -0188 -0189 %There can be no replacement IDs in the structure, but it has to be -0190 %something to give working met IDs. -0191 fprintf(metFile,['m' int2str(i) '\t']); -0192 -0193 %Print the model.mets field. The reason for not putting this as -0194 %replacement ID is that it's not guaranteed to be a valid SBML id. -0195 fprintf(metFile,[model.mets{i} '\t']); -0196 -0197 if isfield(model,'metCharges') -0198 fprintf(metFile,[num2str(model.metCharges(i)) '\t']); -0199 else -0200 fprintf(metFile,'\t'); -0201 end -0202 -0203 fprintf(metFile,'\n'); -0204 end -0205 -0206 fclose(metFile); -0207 -0208 if isfield(model,'genes') -0209 %Open for printing the genes sheet -0210 geneFile=fopen(fullfile(path,'excelGenes.txt'),'wt'); -0211 -0212 %Print header -0213 fprintf(geneFile,'#\tNAME\tMIRIAM\tSHORT NAME\tCOMPARTMENT\n'); +0147 %Print header +0148 fprintf(metFile,'#\tID\tNAME\tUNCONSTRAINED\tMIRIAM\tCOMPOSITION\tInChI\tCOMPARTMENT\tREPLACEMENT ID\tMETS FIELD\tCHARGE\n'); +0149 +0150 %Loop through the metabolites +0151 for i=1:numel(model.mets) +0152 fprintf(metFile,['\t' model.metNames{i} '[' model.comps{model.metComps(i)} ']\t' model.metNames{i} '\t']); +0153 +0154 if isfield(model,'unconstrained') +0155 if model.unconstrained(i)~=0 +0156 fprintf(metFile,'TRUE\t'); +0157 else +0158 fprintf(metFile,'\t'); +0159 end +0160 else +0161 fprintf(metFile,'\t'); +0162 end +0163 +0164 if isfield(model,'metMiriams') +0165 if ~isempty(model.metMiriams{i}) +0166 toPrint=[]; +0167 for j=1:numel(model.metMiriams{i}.name) +0168 toPrint=[toPrint strtrim(model.metMiriams{i}.name{j}) '/' strtrim(model.metMiriams{i}.value{j}) ';']; +0169 end +0170 fprintf(rxnFile,[toPrint(1:end-1) '\t']); +0171 else +0172 fprintf(metFile,'\t'); +0173 end +0174 else +0175 fprintf(metFile,'\t'); +0176 end +0177 +0178 if isfield(model,'metFormulas') +0179 fprintf(metFile,[model.metFormulas{i} '\t']); +0180 else +0181 fprintf(metFile,'\t'); +0182 end +0183 +0184 if isfield(model,'inchis') +0185 fprintf(metFile,[model.inchis{i} '\t']); +0186 else +0187 fprintf(metFile,'\t'); +0188 end +0189 +0190 fprintf(metFile,[model.comps{model.metComps(i)} '\t']); +0191 +0192 %There can be no replacement IDs in the structure, but it has to be +0193 %something to give working met IDs. +0194 fprintf(metFile,['m' int2str(i) '\t']); +0195 +0196 %Print the model.mets field. The reason for not putting this as +0197 %replacement ID is that it's not guaranteed to be a valid SBML id. +0198 fprintf(metFile,[model.mets{i} '\t']); +0199 +0200 if isfield(model,'metCharges') +0201 fprintf(metFile,[num2str(model.metCharges(i)) '\t']); +0202 else +0203 fprintf(metFile,'\t'); +0204 end +0205 +0206 fprintf(metFile,'\n'); +0207 end +0208 +0209 fclose(metFile); +0210 +0211 if isfield(model,'genes') +0212 %Open for printing the genes sheet +0213 geneFile=fopen(fullfile(path,'excelGenes.txt'),'wt'); 0214 -0215 %Loop through the genes -0216 for i=1:numel(model.genes) -0217 fprintf(geneFile,['\t' model.genes{i} '\t']); -0218 -0219 if isfield(model,'geneMiriams') -0220 if ~isempty(model.geneMiriams{i}) -0221 toPrint=[]; -0222 for j=1:numel(model.geneMiriams{i}.name) -0223 toPrint=[toPrint strtrim(model.geneMiriams{i}.name{j}) '/' strtrim(model.geneMiriams{i}.value{j}) ';']; -0224 end -0225 fprintf(geneFile,[toPrint(1:end-1) '\t']); -0226 else -0227 fprintf(geneFile,'\t'); -0228 end -0229 else -0230 fprintf(geneFile,'\t'); -0231 end -0232 -0233 if isfield(model,'geneShortNames') -0234 fprintf(geneFile,[model.geneShortNames{i} '\t']); -0235 else -0236 fprintf(geneFile,'\t'); -0237 end -0238 -0239 if isfield(model,'geneComps') -0240 fprintf(geneFile,[model.comps{model.geneComps(i)} '\t']); -0241 else -0242 fprintf(geneFile,'\t'); -0243 end -0244 -0245 fprintf(geneFile,'\n'); -0246 end -0247 fclose(geneFile); -0248 end -0249 -0250 if isfield(model,'id') -0251 %Open for printing the model sheet -0252 modelFile=fopen(fullfile(path,'excelModel.txt'),'wt'); -0253 -0254 %Print header -0255 fprintf(geneFile,'#\tID\tNAME\tDEFAULT LOWER\tDEFAULT UPPER\tCONTACT GIVEN NAME\tCONTACT FAMILY NAME\tCONTACT EMAIL\tORGANIZATION\tTAXONOMY\tNOTES\n'); +0215 %Print header +0216 fprintf(geneFile,'#\tNAME\tMIRIAM\tSHORT NAME\tCOMPARTMENT\n'); +0217 +0218 %Loop through the genes +0219 for i=1:numel(model.genes) +0220 fprintf(geneFile,['\t' model.genes{i} '\t']); +0221 +0222 if isfield(model,'geneMiriams') +0223 if ~isempty(model.geneMiriams{i}) +0224 toPrint=[]; +0225 for j=1:numel(model.geneMiriams{i}.name) +0226 toPrint=[toPrint strtrim(model.geneMiriams{i}.name{j}) '/' strtrim(model.geneMiriams{i}.value{j}) ';']; +0227 end +0228 fprintf(geneFile,[toPrint(1:end-1) '\t']); +0229 else +0230 fprintf(geneFile,'\t'); +0231 end +0232 else +0233 fprintf(geneFile,'\t'); +0234 end +0235 +0236 if isfield(model,'geneShortNames') +0237 fprintf(geneFile,[model.geneShortNames{i} '\t']); +0238 else +0239 fprintf(geneFile,'\t'); +0240 end +0241 +0242 if isfield(model,'geneComps') +0243 fprintf(geneFile,[model.comps{model.geneComps(i)} '\t']); +0244 else +0245 fprintf(geneFile,'\t'); +0246 end +0247 +0248 fprintf(geneFile,'\n'); +0249 end +0250 fclose(geneFile); +0251 end +0252 +0253 if isfield(model,'id') +0254 %Open for printing the model sheet +0255 modelFile=fopen(fullfile(path,'excelModel.txt'),'wt'); 0256 -0257 %Print model ID and name. It is assumed that the default lower/upper -0258 %bound correspond to min/max of the bounds -0259 toPrint=['\t' model.id '\t' model.name '\t']; -0260 if isfield(model,'annotation') -0261 if isfield(model.annotation,'defaultLB') -0262 toPrint=[toPrint num2str(model.annotation.defaultLB) '\t']; -0263 else -0264 toPrint=[toPrint num2str(min(model.lb)) '\t']; -0265 end -0266 if isfield(model.annotation,'defaultUB') -0267 toPrint=[toPrint num2str(model.annotation.defaultUB) '\t']; -0268 else -0269 toPrint=[toPrint num2str(max(model.ub)) '\t']; -0270 end -0271 if isfield(model.annotation,'givenName') -0272 toPrint=[toPrint model.annotation.givenName '\t']; -0273 else -0274 toPrint=[toPrint '\t']; -0275 end -0276 if isfield(model.annotation,'familyName') -0277 toPrint=[toPrint model.annotation.familyName '\t']; -0278 else -0279 toPrint=[toPrint '\t']; -0280 end -0281 if isfield(model.annotation,'email') -0282 toPrint=[toPrint model.annotation.email '\t']; -0283 else -0284 toPrint=[toPrint '\t']; -0285 end -0286 if isfield(model.annotation,'organization') -0287 toPrint=[toPrint model.annotation.organization '\t']; -0288 else -0289 toPrint=[toPrint '\t']; -0290 end -0291 if isfield(model.annotation,'taxonomy') -0292 toPrint=[toPrint model.annotation.taxonomy '\t']; -0293 else -0294 toPrint=[toPrint '\t']; -0295 end -0296 if isfield(model.annotation,'note') -0297 toPrint=[toPrint model.annotation.note '\t']; -0298 else -0299 toPrint=[toPrint '\t']; -0300 end -0301 else -0302 toPrint=[toPrint num2str(min(model.lb)) '\t' num2str(max(model.ub)) '\t\t\t\t\t\t\n']; -0303 end -0304 fprintf(modelFile,toPrint); -0305 fclose(modelFile); -0306 end -0307 -0308 if isfield(model,'comps') -0309 %Open for printing the model sheet -0310 compsFile=fopen(fullfile(path,'excelComps.txt'),'wt'); -0311 -0312 %Print header -0313 fprintf(compsFile,'#\tABBREVIATION\tNAME\tINSIDE\tMIRIAM\n'); +0257 %Print header +0258 fprintf(geneFile,'#\tID\tNAME\tDEFAULT LOWER\tDEFAULT UPPER\tCONTACT GIVEN NAME\tCONTACT FAMILY NAME\tCONTACT EMAIL\tORGANIZATION\tTAXONOMY\tNOTES\n'); +0259 +0260 %Print model ID and name. It is assumed that the default lower/upper +0261 %bound correspond to min/max of the bounds +0262 toPrint=['\t' model.id '\t' model.name '\t']; +0263 if isfield(model,'annotation') +0264 if isfield(model.annotation,'defaultLB') +0265 toPrint=[toPrint num2str(model.annotation.defaultLB) '\t']; +0266 else +0267 toPrint=[toPrint num2str(min(model.lb)) '\t']; +0268 end +0269 if isfield(model.annotation,'defaultUB') +0270 toPrint=[toPrint num2str(model.annotation.defaultUB) '\t']; +0271 else +0272 toPrint=[toPrint num2str(max(model.ub)) '\t']; +0273 end +0274 if isfield(model.annotation,'givenName') +0275 toPrint=[toPrint model.annotation.givenName '\t']; +0276 else +0277 toPrint=[toPrint '\t']; +0278 end +0279 if isfield(model.annotation,'familyName') +0280 toPrint=[toPrint model.annotation.familyName '\t']; +0281 else +0282 toPrint=[toPrint '\t']; +0283 end +0284 if isfield(model.annotation,'email') +0285 toPrint=[toPrint model.annotation.email '\t']; +0286 else +0287 toPrint=[toPrint '\t']; +0288 end +0289 if isfield(model.annotation,'organization') +0290 toPrint=[toPrint model.annotation.organization '\t']; +0291 else +0292 toPrint=[toPrint '\t']; +0293 end +0294 if isfield(model.annotation,'taxonomy') +0295 toPrint=[toPrint model.annotation.taxonomy '\t']; +0296 else +0297 toPrint=[toPrint '\t']; +0298 end +0299 if isfield(model.annotation,'note') +0300 toPrint=[toPrint model.annotation.note '\t']; +0301 else +0302 toPrint=[toPrint '\t']; +0303 end +0304 else +0305 toPrint=[toPrint num2str(min(model.lb)) '\t' num2str(max(model.ub)) '\t\t\t\t\t\t\n']; +0306 end +0307 fprintf(modelFile,toPrint); +0308 fclose(modelFile); +0309 end +0310 +0311 if isfield(model,'comps') +0312 %Open for printing the model sheet +0313 compsFile=fopen(fullfile(path,'excelComps.txt'),'wt'); 0314 -0315 for i=1:numel(model.comps) -0316 toPrint=['\t' model.comps{i} '\t' model.compNames{i} '\t']; -0317 if isfield(model,'compOutside') -0318 toPrint=[toPrint model.compOutside{i} '\t']; -0319 else -0320 toPrint=[toPrint '\t']; -0321 end -0322 if isfield(model,'compMiriams') -0323 if ~isempty(model.compMiriams{i}) -0324 for j=1:numel(model.compMiriams{i}.name) -0325 toPrint=[toPrint strtrim(model.compMiriams{i}.name{j}) '/' strtrim(model.compMiriams{i}.value{j}) ';']; -0326 end -0327 toPrint(end)=[]; -0328 toPrint=[toPrint '\t']; -0329 else -0330 toPrint=[toPrint '\t']; -0331 end -0332 else -0333 toPrint=[toPrint '\t']; -0334 end -0335 toPrint=[toPrint '\n']; -0336 fprintf(compsFile,toPrint); -0337 end -0338 fclose(compsFile); -0339 end -0340 end +0315 %Print header +0316 fprintf(compsFile,'#\tABBREVIATION\tNAME\tINSIDE\tMIRIAM\n'); +0317 +0318 for i=1:numel(model.comps) +0319 toPrint=['\t' model.comps{i} '\t' model.compNames{i} '\t']; +0320 if isfield(model,'compOutside') +0321 toPrint=[toPrint model.compOutside{i} '\t']; +0322 else +0323 toPrint=[toPrint '\t']; +0324 end +0325 if isfield(model,'compMiriams') +0326 if ~isempty(model.compMiriams{i}) +0327 for j=1:numel(model.compMiriams{i}.name) +0328 toPrint=[toPrint strtrim(model.compMiriams{i}.name{j}) '/' strtrim(model.compMiriams{i}.value{j}) ';']; +0329 end +0330 toPrint(end)=[]; +0331 toPrint=[toPrint '\t']; +0332 else +0333 toPrint=[toPrint '\t']; +0334 end +0335 else +0336 toPrint=[toPrint '\t']; +0337 end +0338 toPrint=[toPrint '\n']; +0339 fprintf(compsFile,toPrint); +0340 end +0341 fclose(compsFile); +0342 end +0343 end
    Generated by m2html © 2005
    \ No newline at end of file diff --git a/doc/io/importModel.html b/doc/io/importModel.html index 95ea0716..dff37de8 100644 --- a/doc/io/importModel.html +++ b/doc/io/importModel.html @@ -1102,158 +1102,162 @@

    SOURCE CODE ^'subSystems'); 0993 else 0994 model.subSystems(cellfun(@isempty,subsystems))={{''}}; -0995 end -0996 if isempty(model.eccodes) -0997 model=rmfield(model,'eccodes'); -0998 end -0999 if isempty(model.rxnMiriams) -1000 model=rmfield(model,'rxnMiriams'); -1001 end -1002 if cellfun(@isempty,model.rxnNotes) -1003 model=rmfield(model,'rxnNotes'); -1004 end -1005 if cellfun(@isempty,model.rxnReferences) -1006 model=rmfield(model,'rxnReferences'); -1007 end -1008 if isempty(model.rxnConfidenceScores) || all(isnan(model.rxnConfidenceScores)) -1009 model=rmfield(model,'rxnConfidenceScores'); -1010 end -1011 if isempty(model.genes) -1012 model=rmfield(model,'genes'); -1013 elseif isrow(model.genes) -1014 model.genes=transpose(model.genes); -1015 end -1016 if isempty(model.geneComps) -1017 model=rmfield(model,'geneComps'); -1018 end -1019 if isempty(model.geneMiriams) -1020 model=rmfield(model,'geneMiriams'); -1021 end -1022 if isempty(model.geneShortNames) -1023 model=rmfield(model,'geneShortNames'); -1024 end -1025 if isempty(model.proteins) -1026 model=rmfield(model,'proteins'); -1027 end -1028 if isempty(model.inchis) -1029 model=rmfield(model,'inchis'); -1030 end -1031 if isempty(model.metFormulas) -1032 model=rmfield(model,'metFormulas'); -1033 end -1034 if isempty(model.metMiriams) -1035 model=rmfield(model,'metMiriams'); -1036 end -1037 if ~any(model.metCharges) -1038 model=rmfield(model,'metCharges'); -1039 end -1040 -1041 %This just removes the grRules if no genes have been loaded -1042 if ~isfield(model,'genes') && isfield(model,'grRules') -1043 model=rmfield(model,'grRules'); -1044 end -1045 -1046 %Print warnings about bad structure -1047 if supressWarnings==false -1048 checkModelStruct(model,false); -1049 end -1050 -1051 if removeExcMets==true -1052 model=simplifyModel(model); +0995 % If all subSystems have single entries, then unnest them +0996 if all(cellfun(@(x) iscell(x) && isscalar(x), model.subSystems)) +0997 model.subSystems = transpose([model.subSystems{:}]); +0998 end +0999 end +1000 if isempty(model.eccodes) +1001 model=rmfield(model,'eccodes'); +1002 end +1003 if isempty(model.rxnMiriams) +1004 model=rmfield(model,'rxnMiriams'); +1005 end +1006 if cellfun(@isempty,model.rxnNotes) +1007 model=rmfield(model,'rxnNotes'); +1008 end +1009 if cellfun(@isempty,model.rxnReferences) +1010 model=rmfield(model,'rxnReferences'); +1011 end +1012 if isempty(model.rxnConfidenceScores) || all(isnan(model.rxnConfidenceScores)) +1013 model=rmfield(model,'rxnConfidenceScores'); +1014 end +1015 if isempty(model.genes) +1016 model=rmfield(model,'genes'); +1017 elseif isrow(model.genes) +1018 model.genes=transpose(model.genes); +1019 end +1020 if isempty(model.geneComps) +1021 model=rmfield(model,'geneComps'); +1022 end +1023 if isempty(model.geneMiriams) +1024 model=rmfield(model,'geneMiriams'); +1025 end +1026 if isempty(model.geneShortNames) +1027 model=rmfield(model,'geneShortNames'); +1028 end +1029 if isempty(model.proteins) +1030 model=rmfield(model,'proteins'); +1031 end +1032 if isempty(model.inchis) +1033 model=rmfield(model,'inchis'); +1034 end +1035 if isempty(model.metFormulas) +1036 model=rmfield(model,'metFormulas'); +1037 end +1038 if isempty(model.metMiriams) +1039 model=rmfield(model,'metMiriams'); +1040 end +1041 if ~any(model.metCharges) +1042 model=rmfield(model,'metCharges'); +1043 end +1044 +1045 %This just removes the grRules if no genes have been loaded +1046 if ~isfield(model,'genes') && isfield(model,'grRules') +1047 model=rmfield(model,'grRules'); +1048 end +1049 +1050 %Print warnings about bad structure +1051 if supressWarnings==false +1052 checkModelStruct(model,false); 1053 end -1054 end -1055 -1056 function fieldContent=parseNote(searchString,fieldName) -1057 %The function obtains the particular information from 'notes' field, using -1058 %fieldName as the dummy string +1054 +1055 if removeExcMets==true +1056 model=simplifyModel(model); +1057 end +1058 end 1059 -1060 fieldContent=''; -1061 -1062 if strfind(searchString,fieldName) -1063 [~,targetString] = regexp(searchString,['<p>' fieldName '.*?</p>'],'tokens','match'); -1064 targetString=regexprep(targetString,'<p>|</p>',''); -1065 targetString=regexprep(targetString,[fieldName, ':'],''); -1066 for i=1:numel(targetString) -1067 fieldContent=[fieldContent ';' strtrim(targetString{1,i})]; -1068 end -1069 fieldContent=regexprep(fieldContent,'^;|;$',''); -1070 else -1071 fieldContent=''; -1072 end -1073 end -1074 -1075 function fieldContent=parseAnnotation(searchString,startString,midString,fieldName) -1076 -1077 fieldContent=''; +1060 function fieldContent=parseNote(searchString,fieldName) +1061 %The function obtains the particular information from 'notes' field, using +1062 %fieldName as the dummy string +1063 +1064 fieldContent=''; +1065 +1066 if strfind(searchString,fieldName) +1067 [~,targetString] = regexp(searchString,['<p>' fieldName '.*?</p>'],'tokens','match'); +1068 targetString=regexprep(targetString,'<p>|</p>',''); +1069 targetString=regexprep(targetString,[fieldName, ':'],''); +1070 for i=1:numel(targetString) +1071 fieldContent=[fieldContent ';' strtrim(targetString{1,i})]; +1072 end +1073 fieldContent=regexprep(fieldContent,'^;|;$',''); +1074 else +1075 fieldContent=''; +1076 end +1077 end 1078 -1079 %Removing whitespace characters from the ending strings, which may occur in -1080 %several cases -1081 searchString=regexprep(searchString,'" />','"/>'); -1082 [~,targetString] = regexp(searchString,['<rdf:li rdf:resource="' startString fieldName midString '.*?"/>'],'tokens','match'); -1083 targetString=regexprep(targetString,'<rdf:li rdf:resource="|"/>',''); -1084 targetString=regexprep(targetString,startString,''); -1085 targetString=regexprep(targetString,[fieldName midString],''); -1086 -1087 for i=1:numel(targetString) -1088 fieldContent=[fieldContent ';' strtrim(targetString{1,i})]; -1089 end +1079 function fieldContent=parseAnnotation(searchString,startString,midString,fieldName) +1080 +1081 fieldContent=''; +1082 +1083 %Removing whitespace characters from the ending strings, which may occur in +1084 %several cases +1085 searchString=regexprep(searchString,'" />','"/>'); +1086 [~,targetString] = regexp(searchString,['<rdf:li rdf:resource="' startString fieldName midString '.*?"/>'],'tokens','match'); +1087 targetString=regexprep(targetString,'<rdf:li rdf:resource="|"/>',''); +1088 targetString=regexprep(targetString,startString,''); +1089 targetString=regexprep(targetString,[fieldName midString],''); 1090 -1091 fieldContent=regexprep(fieldContent,'^;|;$',''); -1092 end -1093 -1094 function miriamStruct=parseMiriam(searchString) -1095 %Generates miriam structure from annotation field -1096 -1097 %Finding whether miriams are written in the old or the new way -1098 if strfind(searchString,'urn:miriam:') -1099 startString='urn:miriam:'; -1100 elseif strfind(searchString,'http://identifiers.org/') -1101 startString='http://identifiers.org/'; -1102 elseif strfind(searchString,'https://identifiers.org/') -1103 startString='https://identifiers.org/'; -1104 else -1105 miriamStruct=[]; -1106 return; -1107 end -1108 -1109 miriamStruct=[]; -1110 -1111 searchString=regexprep(searchString,'" />','"/>'); -1112 [~,targetString] = regexp(searchString,'<rdf:li rdf:resource=".*?"/>','tokens','match'); -1113 targetString=regexprep(targetString,'<rdf:li rdf:resource="|"/>',''); -1114 targetString=regexprep(targetString,startString,''); -1115 -1116 fwdslash = contains(targetString,'/'); -1117 midString = cell(numel(targetString),1); -1118 midString(fwdslash) = {'/'}; -1119 midString(~fwdslash) = {':'}; -1120 -1121 counter=0; -1122 for i=1:numel(targetString) -1123 if isempty(regexp(targetString{1,i},'inchi|ec-code', 'once')) -1124 counter=counter+1; -1125 miriamStruct.name{counter,1} = regexprep(targetString{1,i},[midString{i} '.+'],'','once'); -1126 miriamStruct.value{counter,1} = regexprep(targetString{1,i},[miriamStruct.name{counter,1} midString{i}],'','once'); -1127 miriamStruct.name{counter,1} = regexprep(miriamStruct.name{counter,1},'^obo\.',''); -1128 end -1129 end -1130 end -1131 -1132 function miriam = addSBOtoMiriam(miriam,sboTerm) -1133 %Appends SBO term to miriam structure -1134 -1135 sboTerm = {['SBO:' sprintf('%07u',sboTerm)]}; % convert to proper format -1136 if isempty(miriam) -1137 miriam.name = {'sbo'}; -1138 miriam.value = sboTerm; -1139 elseif any(strcmp('sbo',miriam.name)) -1140 currSbo = strcmp('sbo',miriam.name); -1141 miriam.value(currSbo) = sboTerm; -1142 else -1143 miriam.name(end+1) = {'sbo'}; -1144 miriam.value(end+1) = sboTerm; -1145 end -1146 end +1091 for i=1:numel(targetString) +1092 fieldContent=[fieldContent ';' strtrim(targetString{1,i})]; +1093 end +1094 +1095 fieldContent=regexprep(fieldContent,'^;|;$',''); +1096 end +1097 +1098 function miriamStruct=parseMiriam(searchString) +1099 %Generates miriam structure from annotation field +1100 +1101 %Finding whether miriams are written in the old or the new way +1102 if strfind(searchString,'urn:miriam:') +1103 startString='urn:miriam:'; +1104 elseif strfind(searchString,'http://identifiers.org/') +1105 startString='http://identifiers.org/'; +1106 elseif strfind(searchString,'https://identifiers.org/') +1107 startString='https://identifiers.org/'; +1108 else +1109 miriamStruct=[]; +1110 return; +1111 end +1112 +1113 miriamStruct=[]; +1114 +1115 searchString=regexprep(searchString,'" />','"/>'); +1116 [~,targetString] = regexp(searchString,'<rdf:li rdf:resource=".*?"/>','tokens','match'); +1117 targetString=regexprep(targetString,'<rdf:li rdf:resource="|"/>',''); +1118 targetString=regexprep(targetString,startString,''); +1119 +1120 fwdslash = contains(targetString,'/'); +1121 midString = cell(numel(targetString),1); +1122 midString(fwdslash) = {'/'}; +1123 midString(~fwdslash) = {':'}; +1124 +1125 counter=0; +1126 for i=1:numel(targetString) +1127 if isempty(regexp(targetString{1,i},'inchi|ec-code', 'once')) +1128 counter=counter+1; +1129 miriamStruct.name{counter,1} = regexprep(targetString{1,i},[midString{i} '.+'],'','once'); +1130 miriamStruct.value{counter,1} = regexprep(targetString{1,i},[miriamStruct.name{counter,1} midString{i}],'','once'); +1131 miriamStruct.name{counter,1} = regexprep(miriamStruct.name{counter,1},'^obo\.',''); +1132 end +1133 end +1134 end +1135 +1136 function miriam = addSBOtoMiriam(miriam,sboTerm) +1137 %Appends SBO term to miriam structure +1138 +1139 sboTerm = {['SBO:' sprintf('%07u',sboTerm)]}; % convert to proper format +1140 if isempty(miriam) +1141 miriam.name = {'sbo'}; +1142 miriam.value = sboTerm; +1143 elseif any(strcmp('sbo',miriam.name)) +1144 currSbo = strcmp('sbo',miriam.name); +1145 miriam.value(currSbo) = sboTerm; +1146 else +1147 miriam.name(end+1) = {'sbo'}; +1148 miriam.value(end+1) = sboTerm; +1149 end +1150 end
    Generated by m2html © 2005
    \ No newline at end of file diff --git a/doc/io/readYAMLmodel.html b/doc/io/readYAMLmodel.html index e8c684be..d1e03747 100644 --- a/doc/io/readYAMLmodel.html +++ b/doc/io/readYAMLmodel.html @@ -649,93 +649,102 @@

    SOURCE CODE ^% end 0593 % end 0594 -0595 % Make rxnGeneMat fields and map to the existing model.genes field -0596 [genes, rxnGeneMat] = getGenesFromGrRules(model.grRules); -0597 model.rxnGeneMat = sparse(numel(model.rxns),numel(model.genes)); -0598 [~,geneOrder] = ismember(genes,model.genes); -0599 if any(geneOrder == 0) -0600 error(['The grRules includes the following gene(s), that are not in '... -0601 'the list of model genes: ', genes{~geneOrder}]) -0602 end -0603 model.rxnGeneMat(:,geneOrder) = rxnGeneMat; -0604 -0605 % Finalize GECKO model -0606 if isGECKO -0607 % Fill in empty fields and empty entries -0608 for i={'kcat','source','notes','eccodes'} % Even keep empty -0609 model.ec = emptyOrFill(model.ec,i{1},{''},'rxns',true); +0595 if isfield(model,'subSystems') +0596 % If all entries are 1x1, then flatten +0597 if all(cellfun(@(x) numel(x) <= 1, model.subSystems)) +0598 model.subSystems = transpose([model.subSystems{:}]); +0599 end +0600 end +0601 +0602 % Make rxnGeneMat fields and map to the existing model.genes field +0603 if isfield(model,'grRules') +0604 [genes, rxnGeneMat] = getGenesFromGrRules(model.grRules); +0605 model.rxnGeneMat = sparse(numel(model.rxns),numel(model.genes)); +0606 [~,geneOrder] = ismember(genes,model.genes); +0607 if any(geneOrder == 0) +0608 error(['The grRules includes the following gene(s), that are not in '... +0609 'the list of model genes: ', genes{~geneOrder}]) 0610 end -0611 for i={'enzymes','mw','sequence'} -0612 model.ec = emptyOrFill(model.ec,i{1},{''},'genes',true); -0613 end -0614 model.ec = emptyOrFill(model.ec,'concs',{'NaN'},'genes',true); -0615 model.ec = emptyOrFill(model.ec,'kcat',{'0'},'genes',true); -0616 % Change string to double -0617 for i={'kcat','mw','concs'} -0618 if isfield(model.ec,i{1}) -0619 model.ec.(i{1}) = str2double(model.ec.(i{1})); -0620 end -0621 end -0622 % Fill rxnEnzMat -0623 rxnIdx = cellfun('isempty', enzStoich(:,1)); -0624 enzStoich(rxnIdx,:) = ''; -0625 rxnIdx = cell2mat(enzStoich(:,1)); -0626 [~,enzIdx] = ismember(enzStoich(:,2),model.ec.enzymes); -0627 coeffs = cell2mat(enzStoich(:,3)); -0628 model.ec.rxnEnzMat = zeros(numel(model.ec.rxns), numel(model.ec.genes)); -0629 linearIndices = sub2ind([numel(model.ec.rxns), numel(model.ec.genes)], rxnIdx, enzIdx); -0630 model.ec.rxnEnzMat(linearIndices) = coeffs; -0631 %Parse ec-codes -0632 if ~isempty(ecGecko) -0633 locs = cell2mat(ecGecko(:,1)); -0634 for i=unique(locs)' -0635 ecGeckoCat=strjoin(ecGecko(locs==i,2),';'); -0636 model.ec.eccodes{i,1}=ecGeckoCat; -0637 end -0638 emptyEc=cellfun('isempty',model.ec.eccodes); -0639 model.ec.eccodes(emptyEc)={''}; -0640 end -0641 end -0642 -0643 if verbose -0644 fprintf(' Done!\n'); -0645 end -0646 end -0647 -0648 function model = emptyOrFill(model,field,emptyEntry,type,keepEmpty) -0649 if nargin<5 -0650 keepEmpty=false; -0651 end -0652 if isnumeric(emptyEntry) -0653 emptyCells=isempty(model.(field)); -0654 else -0655 emptyCells=cellfun('isempty',model.(field)); -0656 end -0657 if all(emptyCells) && ~keepEmpty -0658 model = rmfield(model, field); -0659 elseif numel(model.(field))<numel(model.(type)) -0660 model.(field)(end+1:numel(model.(type)),1)=emptyEntry; -0661 end -0662 end -0663 -0664 function model = readFieldValue(model, fieldName, value, pos) -0665 if numel(model.(fieldName))<pos-1 -0666 model.(fieldName)(end+1:pos,1) = {''}; -0667 end -0668 model.(fieldName)(pos,1) = {value}; -0669 end -0670 -0671 function [miriams,miriamKey,entryNumber] = gatherAnnotation(pos,miriams,key,value,miriamKey,entryNumber) -0672 if isempty(key) -0673 key=miriamKey; -0674 else -0675 miriamKey=key; +0611 model.rxnGeneMat(:,geneOrder) = rxnGeneMat; +0612 end +0613 +0614 % Finalize GECKO model +0615 if isGECKO +0616 % Fill in empty fields and empty entries +0617 for i={'kcat','source','notes','eccodes'} % Even keep empty +0618 model.ec = emptyOrFill(model.ec,i{1},{''},'rxns',true); +0619 end +0620 for i={'enzymes','mw','sequence'} +0621 model.ec = emptyOrFill(model.ec,i{1},{''},'genes',true); +0622 end +0623 model.ec = emptyOrFill(model.ec,'concs',{'NaN'},'genes',true); +0624 model.ec = emptyOrFill(model.ec,'kcat',{'0'},'genes',true); +0625 % Change string to double +0626 for i={'kcat','mw','concs'} +0627 if isfield(model.ec,i{1}) +0628 model.ec.(i{1}) = str2double(model.ec.(i{1})); +0629 end +0630 end +0631 % Fill rxnEnzMat +0632 rxnIdx = cellfun('isempty', enzStoich(:,1)); +0633 enzStoich(rxnIdx,:) = ''; +0634 rxnIdx = cell2mat(enzStoich(:,1)); +0635 [~,enzIdx] = ismember(enzStoich(:,2),model.ec.enzymes); +0636 coeffs = cell2mat(enzStoich(:,3)); +0637 model.ec.rxnEnzMat = zeros(numel(model.ec.rxns), numel(model.ec.genes)); +0638 linearIndices = sub2ind([numel(model.ec.rxns), numel(model.ec.genes)], rxnIdx, enzIdx); +0639 model.ec.rxnEnzMat(linearIndices) = coeffs; +0640 %Parse ec-codes +0641 if ~isempty(ecGecko) +0642 locs = cell2mat(ecGecko(:,1)); +0643 for i=unique(locs)' +0644 ecGeckoCat=strjoin(ecGecko(locs==i,2),';'); +0645 model.ec.eccodes{i,1}=ecGeckoCat; +0646 end +0647 emptyEc=cellfun('isempty',model.ec.eccodes); +0648 model.ec.eccodes(emptyEc)={''}; +0649 end +0650 end +0651 +0652 if verbose +0653 fprintf(' Done!\n'); +0654 end +0655 end +0656 +0657 function model = emptyOrFill(model,field,emptyEntry,type,keepEmpty) +0658 if nargin<5 +0659 keepEmpty=false; +0660 end +0661 if isnumeric(emptyEntry) +0662 emptyCells=isempty(model.(field)); +0663 else +0664 emptyCells=cellfun('isempty',model.(field)); +0665 end +0666 if all(emptyCells) && ~keepEmpty +0667 model = rmfield(model, field); +0668 elseif numel(model.(field))<numel(model.(type)) +0669 model.(field)(end+1:numel(model.(type)),1)=emptyEntry; +0670 end +0671 end +0672 +0673 function model = readFieldValue(model, fieldName, value, pos) +0674 if numel(model.(fieldName))<pos-1 +0675 model.(fieldName)(end+1:pos,1) = {''}; 0676 end -0677 if ~isempty(value) -0678 miriams(entryNumber,1:3) = {pos, key, strip(value)}; -0679 entryNumber = entryNumber + 1; -0680 end -0681 end +0677 model.(fieldName)(pos,1) = {value}; +0678 end +0679 +0680 function [miriams,miriamKey,entryNumber] = gatherAnnotation(pos,miriams,key,value,miriamKey,entryNumber) +0681 if isempty(key) +0682 key=miriamKey; +0683 else +0684 miriamKey=key; +0685 end +0686 if ~isempty(value) +0687 miriams(entryNumber,1:3) = {pos, key, strip(value)}; +0688 entryNumber = entryNumber + 1; +0689 end +0690 end
    Generated by m2html © 2005
    \ No newline at end of file diff --git a/doc/io/writeYAMLmodel.html b/doc/io/writeYAMLmodel.html index 8894eeb0..e4120416 100644 --- a/doc/io/writeYAMLmodel.html +++ b/doc/io/writeYAMLmodel.html @@ -170,277 +170,279 @@

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

    SOURCE CODE ^switch exitflag 0243 case 11 0244 res.stat = 1; -0245 case [5, 6, 7, 8, 9, 10, 13] +0245 case {1, 5, 6, 7, 8, 9, 10, 13} % If user-interrupted, not sure if optimal 0246 res.stat = 2; 0247 otherwise 0248 res.stat = 0; diff --git a/doc/struct_conversion/ravenCobraWrapper.html b/doc/struct_conversion/ravenCobraWrapper.html index 6bb7c386..fdbcf58d 100644 --- a/doc/struct_conversion/ravenCobraWrapper.html +++ b/doc/struct_conversion/ravenCobraWrapper.html @@ -260,7 +260,7 @@

    SOURCE CODE ^'E',size(model.mets)); 0188 if isfield(model,'geneMiriams') -0189 [miriams,extractedMiriamNames]=extractMiriam(model.geneMiriams); +0189 [~,extractedMiriamNames]=extractMiriam(model.geneMiriams); 0190 for i = 1:length(geneCOBRAfields) 0191 j=ismember(extractedMiriamNames,geneNamespaces{i}); 0192 if any(j) @@ -276,242 +276,253 @@

    SOURCE CODE ^else 0203 fprintf('WARNING: no genes detected. The model therefore may not be exportable to SBML file with writeCbModel\n'); 0204 end -0205 newModel.osenseStr='max'; -0206 else -0207 fprintf('Converting COBRA structure to RAVEN..\n'); -0208 %Convert from COBRA to RAVEN structure -0209 -0210 %Mandatory RAVEN fields -0211 newModel.mets=model.mets; -0212 if ~isfield(model,'comps') -0213 %Since 'comps' field is not mandatory in COBRA, it may be required -0214 %to obtain the non-redundant list of comps from metabolite ids, if -0215 %'comps' field is not available -0216 newModel.comps = unique(regexprep(model.mets,'.*\[([^\]]+)\]$','$1')); -0217 newModel.compNames = newModel.comps; -0218 end -0219 for i=1:numel(newModel.comps) -0220 newModel.mets=regexprep(newModel.mets,['\[', newModel.comps{i}, '\]$'],''); -0221 newModel.mets=regexprep(newModel.mets,['\[', newModel.compNames{i}, '\]$'],''); -0222 end -0223 -0224 %In some cases (e.g. any model that uses BiGG ids as main ids), there -0225 %may be overlapping mets due to removal of compartment info. To avoid -0226 %this, we change compartments from e.g. [c] into _c -0227 if numel(unique(newModel.mets))~=numel(model.mets) -0228 newModel.mets=model.mets; -0229 for i=1:numel(newModel.comps) -0230 newModel.mets=regexprep(newModel.mets,['\[' newModel.comps{i} '\]$'],['_' newModel.comps{i}]); -0231 end -0232 end -0233 %Since COBRA no longer contains rev field it is assumed that rxn is -0234 %reversible if its lower bound is set below zero -0235 if ~isfield(model,'rev') -0236 for i=1:numel(model.rxns) -0237 if model.lb(i)<0 -0238 newModel.rev(i,1)=1; -0239 else -0240 newModel.rev(i,1)=0; -0241 end -0242 end -0243 end -0244 newModel.b=zeros(numel(model.mets),1); -0245 -0246 %metComps is also mandatory, but defined later to match the order of -0247 %fields -0248 -0249 %Fields 'name' and 'id' are also considered as mandatory, but -0250 %these are added to the model during exportModel/exportToExcelFormat -0251 %anyway, so there is no point to add this information here -0252 -0253 %Optional RAVEN fields -0254 if isfield(model,'modelID') -0255 newModel.id=model.modelID; -0256 end -0257 if isfield(model,'modelName') -0258 newModel.name=model.modelName; -0259 end -0260 if isfield(model,'rules') && ~isfield(model,'grRules') -0261 model.grRules = rulesTogrrules(model); -0262 end -0263 if isfield(model,'grRules') -0264 [grRules,rxnGeneMat] = standardizeGrRules(model,true); -0265 newModel.grRules = grRules; -0266 newModel.rxnGeneMat = rxnGeneMat; +0205 % If needed, normalise subSystems to cell-of-cells format +0206 if isfield(newModel,'subSystems') && ~isempty(newModel.subSystems) +0207 if ~iscell(newModel.subSystems{1}) +0208 newModel.subSystems = cellfun(@(x) {x}, newModel.subSystems, 'UniformOutput', false); +0209 end +0210 end +0211 else +0212 fprintf('Converting COBRA structure to RAVEN..\n'); +0213 %Convert from COBRA to RAVEN structure +0214 +0215 %Mandatory RAVEN fields +0216 newModel.mets=model.mets; +0217 if ~isfield(model,'comps') +0218 %Since 'comps' field is not mandatory in COBRA, it may be required +0219 %to obtain the non-redundant list of comps from metabolite ids, if +0220 %'comps' field is not available +0221 newModel.comps = unique(regexprep(model.mets,'.*\[([^\]]+)\]$','$1')); +0222 newModel.compNames = newModel.comps; +0223 end +0224 for i=1:numel(newModel.comps) +0225 newModel.mets=regexprep(newModel.mets,['\[', newModel.comps{i}, '\]$'],''); +0226 newModel.mets=regexprep(newModel.mets,['\[', newModel.compNames{i}, '\]$'],''); +0227 end +0228 +0229 %In some cases (e.g. any model that uses BiGG ids as main ids), there +0230 %may be overlapping mets due to removal of compartment info. To avoid +0231 %this, we change compartments from e.g. [c] into _c +0232 if numel(unique(newModel.mets))~=numel(model.mets) +0233 newModel.mets=model.mets; +0234 for i=1:numel(newModel.comps) +0235 newModel.mets=regexprep(newModel.mets,['\[' newModel.comps{i} '\]$'],['_' newModel.comps{i}]); +0236 end +0237 end +0238 %Since COBRA no longer contains rev field it is assumed that rxn is +0239 %reversible if its lower bound is set below zero +0240 if ~isfield(model,'rev') +0241 for i=1:numel(model.rxns) +0242 if model.lb(i)<0 +0243 newModel.rev(i,1)=1; +0244 else +0245 newModel.rev(i,1)=0; +0246 end +0247 end +0248 end +0249 newModel.b=zeros(numel(model.mets),1); +0250 +0251 %metComps is also mandatory, but defined later to match the order of +0252 %fields +0253 +0254 %Fields 'name' and 'id' are also considered as mandatory, but +0255 %these are added to the model during exportModel/exportToExcelFormat +0256 %anyway, so there is no point to add this information here +0257 +0258 %Optional RAVEN fields +0259 if isfield(model,'modelID') +0260 newModel.id=model.modelID; +0261 end +0262 if isfield(model,'modelName') +0263 newModel.name=model.modelName; +0264 end +0265 if isfield(model,'rules') && ~isfield(model,'grRules') +0266 model.grRules = rulesTogrrules(model); 0267 end -0268 if isfield(model,'rxnECNumbers') -0269 newModel.eccodes=regexprep(model.rxnECNumbers,'EC|EC:',''); -0270 end -0271 if any(isfield(model,rxnCOBRAfields)) -0272 for i=1:numel(model.rxns) -0273 counter=1; -0274 newModel.rxnMiriams{i,1}=[]; -0275 if isfield(model,'rxnReferences') -0276 if ~isempty(model.rxnReferences{i}) -0277 pmids = model.rxnReferences{i}; -0278 pmids = strsplit(pmids,'; '); -0279 nonPmids = cellfun(@isempty,regexp(pmids,'^\d+$','match','once')); -0280 if any(nonPmids) %Not a pubmed id, keep in rxnReferences instead -0281 newModel.rxnReferences{i,1} = strjoin(pmids(nonPmids),', '); -0282 pmids(nonPmids)=[]; -0283 end -0284 for j = 1:length(pmids) -0285 newModel.rxnMiriams{i,1}.name{counter,1} = 'pubmed'; -0286 newModel.rxnMiriams{i,1}.value{counter,1} = pmids{j}; -0287 counter=counter+1; +0268 if isfield(model,'grRules') +0269 [grRules,rxnGeneMat] = standardizeGrRules(model,true); +0270 newModel.grRules = grRules; +0271 newModel.rxnGeneMat = rxnGeneMat; +0272 end +0273 if isfield(model,'rxnECNumbers') +0274 newModel.eccodes=regexprep(model.rxnECNumbers,'EC|EC:',''); +0275 end +0276 if any(isfield(model,rxnCOBRAfields)) +0277 for i=1:numel(model.rxns) +0278 counter=1; +0279 newModel.rxnMiriams{i,1}=[]; +0280 if isfield(model,'rxnReferences') +0281 if ~isempty(model.rxnReferences{i}) +0282 pmids = model.rxnReferences{i}; +0283 pmids = strsplit(pmids,'; '); +0284 nonPmids = cellfun(@isempty,regexp(pmids,'^\d+$','match','once')); +0285 if any(nonPmids) %Not a pubmed id, keep in rxnReferences instead +0286 newModel.rxnReferences{i,1} = strjoin(pmids(nonPmids),', '); +0287 pmids(nonPmids)=[]; 0288 end -0289 end -0290 end -0291 for j = 2:length(rxnCOBRAfields) %Start from 2, as 1 is rxnReferences -0292 if isfield(model,rxnCOBRAfields{j}) -0293 rxnAnnotation = eval(['model.' rxnCOBRAfields{j} '{i}']); -0294 if ~isempty(rxnAnnotation) -0295 rxnAnnotation = strtrim(strsplit(rxnAnnotation,';')); -0296 for a=1:length(rxnAnnotation) -0297 newModel.rxnMiriams{i,1}.name{counter,1} = rxnNamespaces{j}; -0298 newModel.rxnMiriams{i,1}.value{counter,1} = rxnAnnotation{a}; -0299 counter=counter+1; -0300 end -0301 end -0302 end -0303 end -0304 end -0305 end -0306 if isfield(newModel,'rxnReferences') -0307 emptyEntry = cellfun(@isempty,newModel.rxnReferences); -0308 newModel.rxnReferences(emptyEntry)={''}; -0309 diffNumel = numel(newModel.rxns) - numel(newModel.rxnReferences); -0310 if diffNumel > 0 -0311 newModel.rxnReferences(end+1:end+diffNumel) = {''}; -0312 end -0313 end -0314 if any(isfield(model,geneCOBRAfields)) -0315 for i=1:numel(model.genes) -0316 counter=1; -0317 newModel.geneMiriams{i,1}=[]; -0318 for j = 1:length(geneCOBRAfields) -0319 if isfield(model,geneCOBRAfields{j}) -0320 geneAnnotation = eval(['model.' geneCOBRAfields{j} '{i}']); -0321 if ~isempty(geneAnnotation) -0322 geneAnnotation = strtrim(strsplit(geneAnnotation,';')); -0323 for a=1:length(geneAnnotation) -0324 newModel.geneMiriams{i,1}.name{counter,1} = geneNamespaces{j}; -0325 newModel.geneMiriams{i,1}.value{counter,1} = geneAnnotation{a}; -0326 counter=counter+1; -0327 end -0328 end -0329 end -0330 end -0331 end -0332 end -0333 if isfield(model,'geneNames') -0334 newModel.geneShortNames=model.geneNames; -0335 end -0336 newModel.metNames=model.metNames; -0337 for i=1:numel(newModel.comps) -0338 newModel.metNames=regexprep(newModel.metNames,['\[', newModel.comps{i}, '\]$'],''); -0339 newModel.metNames=regexprep(newModel.metNames,['\[', newModel.compNames{i}, '\]$'],''); +0289 for j = 1:length(pmids) +0290 newModel.rxnMiriams{i,1}.name{counter,1} = 'pubmed'; +0291 newModel.rxnMiriams{i,1}.value{counter,1} = pmids{j}; +0292 counter=counter+1; +0293 end +0294 end +0295 end +0296 for j = 2:length(rxnCOBRAfields) %Start from 2, as 1 is rxnReferences +0297 if isfield(model,rxnCOBRAfields{j}) +0298 rxnAnnotation = eval(['model.' rxnCOBRAfields{j} '{i}']); +0299 if ~isempty(rxnAnnotation) +0300 rxnAnnotation = strtrim(strsplit(rxnAnnotation,';')); +0301 for a=1:length(rxnAnnotation) +0302 newModel.rxnMiriams{i,1}.name{counter,1} = rxnNamespaces{j}; +0303 newModel.rxnMiriams{i,1}.value{counter,1} = rxnAnnotation{a}; +0304 counter=counter+1; +0305 end +0306 end +0307 end +0308 end +0309 end +0310 end +0311 if isfield(newModel,'rxnReferences') +0312 emptyEntry = cellfun(@isempty,newModel.rxnReferences); +0313 newModel.rxnReferences(emptyEntry)={''}; +0314 diffNumel = numel(newModel.rxns) - numel(newModel.rxnReferences); +0315 if diffNumel > 0 +0316 newModel.rxnReferences(end+1:end+diffNumel) = {''}; +0317 end +0318 end +0319 if any(isfield(model,geneCOBRAfields)) +0320 for i=1:numel(model.genes) +0321 counter=1; +0322 newModel.geneMiriams{i,1}=[]; +0323 for j = 1:length(geneCOBRAfields) +0324 if isfield(model,geneCOBRAfields{j}) +0325 geneAnnotation = eval(['model.' geneCOBRAfields{j} '{i}']); +0326 if ~isempty(geneAnnotation) +0327 geneAnnotation = strtrim(strsplit(geneAnnotation,';')); +0328 for a=1:length(geneAnnotation) +0329 newModel.geneMiriams{i,1}.name{counter,1} = geneNamespaces{j}; +0330 newModel.geneMiriams{i,1}.value{counter,1} = geneAnnotation{a}; +0331 counter=counter+1; +0332 end +0333 end +0334 end +0335 end +0336 end +0337 end +0338 if isfield(model,'geneNames') +0339 newModel.geneShortNames=model.geneNames; 0340 end -0341 newModel.metNames=deblank(newModel.metNames); -0342 newModel.metComps=regexprep(model.mets,'^.+\[',''); -0343 newModel.metComps=regexprep(newModel.metComps,'\]$',''); -0344 [~, newModel.metComps]=ismember(newModel.metComps,newModel.comps); -0345 if isfield(model,'metInChIString') -0346 newModel.inchis=regexprep(model.metInChIString,'^InChI=',''); -0347 end -0348 printWarning=false; -0349 if any(isfield(model,[metCOBRAfields;'metKEGGID';'metPubChemID'])) -0350 for i=1:numel(model.mets) -0351 counter=1; -0352 newModel.metMiriams{i,1}=[]; -0353 if isfield(model,'metKEGGID') -0354 if ~isempty(model.metKEGGID{i}) -0355 if strcmp(model.metKEGGID{i}(1),'C') -0356 newModel.metMiriams{i,1}.name{counter,1} = 'kegg.compound'; -0357 newModel.metMiriams{i,1}.value{counter,1} = model.metKEGGID{i}; -0358 counter=counter+1; -0359 elseif strcmp(model.metKEGGID{i}(1),'G') -0360 newModel.metMiriams{i,1}.name{counter,1} = 'kegg.glycan'; -0361 newModel.metMiriams{i,1}.value{counter,1} = model.metKEGGID{i}; -0362 counter=counter+1; -0363 end -0364 end -0365 end -0366 if isfield(model,'metPubChemID') -0367 if ~isempty(model.metPubChemID{i}) -0368 if length(model.metPubChemID{i})>3 && strcmp(model.metPubChemID{i}(1:4),'CID:') -0369 newModel.metMiriams{i,1}.name{counter,1} = 'pubchem.compound'; -0370 newModel.metMiriams{i,1}.value{counter,1} = model.metPubChemID{i}; -0371 counter=counter+1; -0372 elseif length(model.metPubChemID{i})>3 && strcmp(model.metPubChemID{i}(1:4),'SID:') -0373 newModel.metMiriams{i,1}.name{counter,1} = 'pubchem.substance'; -0374 newModel.metMiriams{i,1}.value{counter,1} = model.metPubChemID{i}; -0375 counter=counter+1; -0376 else -0377 newModel.metMiriams{i,1}.name{counter,1} = 'pubchem.compound'; -0378 newModel.metMiriams{i,1}.value{counter,1} = model.metPubChemID{i}; -0379 counter=counter+1; -0380 printWarning=true; -0381 end -0382 end -0383 end -0384 for j = 1:length(metCOBRAfields) -0385 if isfield(model,metCOBRAfields{j}) -0386 metAnnotation = eval(['model.' metCOBRAfields{j} '{i}']); -0387 if ~isempty(metAnnotation) -0388 metAnnotation = strtrim(strsplit(metAnnotation,';')); -0389 for a=1:length(metAnnotation) -0390 newModel.metMiriams{i,1}.name{counter,1} = metNamespaces{j}; -0391 newModel.metMiriams{i,1}.value{counter,1} = metAnnotation{a}; -0392 counter=counter+1; -0393 end -0394 end -0395 end -0396 end -0397 end -0398 end -0399 if printWarning -0400 fprintf('Could not determine whether PubChemIDs are compounds (CID)\n or substances (SID). All annotated PubChemIDs will therefore \n be assigned as compounds (CID).\n'); -0401 end -0402 end -0403 -0404 % Order fields -0405 newModel=standardizeModelFieldOrder(newModel); % Corrects for both RAVEN and COBRA models -0406 end -0407 -0408 function rules=grrulesToRules(model) -0409 %This function just takes grRules, changes all gene names to -0410 %'x(geneNumber)' and also changes 'or' and 'and' relations to corresponding -0411 %symbols -0412 replacingGenes=cell([size(model.genes,1) 1]); -0413 for i=1:numel(replacingGenes) -0414 replacingGenes{i}=strcat('x(',num2str(i),')'); -0415 end -0416 rules = strcat({' '},model.grRules,{' '}); -0417 for i=1:length(model.genes) -0418 rules=regexprep(rules,[' ' model.genes{i} ' '],[' ' replacingGenes{i} ' ']); -0419 rules=regexprep(rules,['(' model.genes{i} ' '],['(' replacingGenes{i} ' ']); -0420 rules=regexprep(rules,[' ' model.genes{i} ')'],[' ' replacingGenes{i} ')']); -0421 end -0422 rules=regexprep(rules,' and ',' & '); -0423 rules=regexprep(rules,' or ',' | '); -0424 rules=strtrim(rules); -0425 end -0426 -0427 function grRules=rulesTogrrules(model) -0428 %This function takes rules, replaces &/| for and/or, replaces the x(i) -0429 %format with the actual gene ID, and takes out extra whitespace and -0430 %redundant parenthesis introduced by COBRA, to create grRules. -0431 grRules = strrep(model.rules,'&','and'); -0432 grRules = strrep(grRules,'|','or'); -0433 for i = 1:length(model.genes) -0434 grRules = strrep(grRules,['x(' num2str(i) ')'],model.genes{i}); -0435 end -0436 grRules = strrep(grRules,'( ','('); -0437 grRules = strrep(grRules,' )',')'); -0438 grRules = regexprep(grRules,'^(',''); %rules that start with a "(" -0439 grRules = regexprep(grRules,')$',''); %rules that end with a ")" -0440 end +0341 newModel.metNames=model.metNames; +0342 for i=1:numel(newModel.comps) +0343 newModel.metNames=regexprep(newModel.metNames,['\[', newModel.comps{i}, '\]$'],''); +0344 newModel.metNames=regexprep(newModel.metNames,['\[', newModel.compNames{i}, '\]$'],''); +0345 end +0346 newModel.metNames=deblank(newModel.metNames); +0347 newModel.metComps=regexprep(model.mets,'^.+\[',''); +0348 newModel.metComps=regexprep(newModel.metComps,'\]$',''); +0349 [~, newModel.metComps]=ismember(newModel.metComps,newModel.comps); +0350 if isfield(model,'metInChIString') +0351 newModel.inchis=regexprep(model.metInChIString,'^InChI=',''); +0352 end +0353 printWarning=false; +0354 if any(isfield(model,[metCOBRAfields;'metKEGGID';'metPubChemID'])) +0355 for i=1:numel(model.mets) +0356 counter=1; +0357 newModel.metMiriams{i,1}=[]; +0358 if isfield(model,'metKEGGID') +0359 if ~isempty(model.metKEGGID{i}) +0360 if strcmp(model.metKEGGID{i}(1),'C') +0361 newModel.metMiriams{i,1}.name{counter,1} = 'kegg.compound'; +0362 newModel.metMiriams{i,1}.value{counter,1} = model.metKEGGID{i}; +0363 counter=counter+1; +0364 elseif strcmp(model.metKEGGID{i}(1),'G') +0365 newModel.metMiriams{i,1}.name{counter,1} = 'kegg.glycan'; +0366 newModel.metMiriams{i,1}.value{counter,1} = model.metKEGGID{i}; +0367 counter=counter+1; +0368 end +0369 end +0370 end +0371 if isfield(model,'metPubChemID') +0372 if ~isempty(model.metPubChemID{i}) +0373 if length(model.metPubChemID{i})>3 && strcmp(model.metPubChemID{i}(1:4),'CID:') +0374 newModel.metMiriams{i,1}.name{counter,1} = 'pubchem.compound'; +0375 newModel.metMiriams{i,1}.value{counter,1} = model.metPubChemID{i}; +0376 counter=counter+1; +0377 elseif length(model.metPubChemID{i})>3 && strcmp(model.metPubChemID{i}(1:4),'SID:') +0378 newModel.metMiriams{i,1}.name{counter,1} = 'pubchem.substance'; +0379 newModel.metMiriams{i,1}.value{counter,1} = model.metPubChemID{i}; +0380 counter=counter+1; +0381 else +0382 newModel.metMiriams{i,1}.name{counter,1} = 'pubchem.compound'; +0383 newModel.metMiriams{i,1}.value{counter,1} = model.metPubChemID{i}; +0384 counter=counter+1; +0385 printWarning=true; +0386 end +0387 end +0388 end +0389 for j = 1:length(metCOBRAfields) +0390 if isfield(model,metCOBRAfields{j}) +0391 metAnnotation = eval(['model.' metCOBRAfields{j} '{i}']); +0392 if ~isempty(metAnnotation) +0393 metAnnotation = strtrim(strsplit(metAnnotation,';')); +0394 for a=1:length(metAnnotation) +0395 newModel.metMiriams{i,1}.name{counter,1} = metNamespaces{j}; +0396 newModel.metMiriams{i,1}.value{counter,1} = metAnnotation{a}; +0397 counter=counter+1; +0398 end +0399 end +0400 end +0401 end +0402 end +0403 end +0404 % Flatten subSystems if every reaction has exactly one subsystem. +0405 if isfield(newModel,'subSystems') && ~isempty(newModel.subSystems) +0406 if all(cellfun(@(x) iscell(x) && isscalar(x), newModel.subSystems)) +0407 newModel.subSystems = transpose([newModel.subSystems{:}]); +0408 end +0409 end +0410 if printWarning +0411 fprintf('Could not determine whether PubChemIDs are compounds (CID)\n or substances (SID). All annotated PubChemIDs will therefore \n be assigned as compounds (CID).\n'); +0412 end +0413 end +0414 +0415 % Order fields +0416 newModel=standardizeModelFieldOrder(newModel); % Corrects for both RAVEN and COBRA models +0417 end +0418 +0419 function rules=grrulesToRules(model) +0420 %This function just takes grRules, changes all gene names to +0421 %'x(geneNumber)' and also changes 'or' and 'and' relations to corresponding +0422 %symbols +0423 replacingGenes=cell([size(model.genes,1) 1]); +0424 for i=1:numel(replacingGenes) +0425 replacingGenes{i}=strcat('x(',num2str(i),')'); +0426 end +0427 rules = strcat({' '},model.grRules,{' '}); +0428 for i=1:length(model.genes) +0429 rules=regexprep(rules,[' ' model.genes{i} ' '],[' ' replacingGenes{i} ' ']); +0430 rules=regexprep(rules,['(' model.genes{i} ' '],['(' replacingGenes{i} ' ']); +0431 rules=regexprep(rules,[' ' model.genes{i} ')'],[' ' replacingGenes{i} ')']); +0432 end +0433 rules=regexprep(rules,' and ',' & '); +0434 rules=regexprep(rules,' or ',' | '); +0435 rules=strtrim(rules); +0436 end +0437 +0438 function grRules=rulesTogrrules(model) +0439 %This function takes rules, replaces &/| for and/or, replaces the x(i) +0440 %format with the actual gene ID, and takes out extra whitespace and +0441 %redundant parenthesis introduced by COBRA, to create grRules. +0442 grRules = strrep(model.rules,'&','and'); +0443 grRules = strrep(grRules,'|','or'); +0444 for i = 1:length(model.genes) +0445 grRules = strrep(grRules,['x(' num2str(i) ')'],model.genes{i}); +0446 end +0447 grRules = strrep(grRules,'( ','('); +0448 grRules = strrep(grRules,' )',')'); +0449 grRules = regexprep(grRules,'^(',''); %rules that start with a "(" +0450 grRules = regexprep(grRules,')$',''); %rules that end with a ")" +0451 end
    Generated by m2html © 2005
    \ No newline at end of file diff --git a/doc/tutorial/index.html b/doc/tutorial/index.html index b1ccd2cc..efef9dc9 100644 --- a/doc/tutorial/index.html +++ b/doc/tutorial/index.html @@ -24,7 +24,9 @@

    Matlab files in this directory:

    Other Matlab-specific files in this directory:

    - +

    Subsequent directories:

    +
    Generated by m2html © 2005
    diff --git a/external/kegg/getKEGGModelForOrganism.m b/external/kegg/getKEGGModelForOrganism.m index 770d9da1..4a20875e 100755 --- a/external/kegg/getKEGGModelForOrganism.m +++ b/external/kegg/getKEGGModelForOrganism.m @@ -1026,10 +1026,6 @@ model.grRules = grRules; model.rxnGeneMat = rxnGeneMat; -%Fix subsystems -emptySubSystems=cellfun(@isempty, model.subSystems); -model.subSystems(emptySubSystems)={{''}}; - %Add the description to the reactions for i=1:numel(model.rxns) if ~isempty(model.rxnNotes{i}) diff --git a/external/kegg/getRxnsFromKEGG.m b/external/kegg/getRxnsFromKEGG.m index 0ad96efc..ed94d8b9 100755 --- a/external/kegg/getRxnsFromKEGG.m +++ b/external/kegg/getRxnsFromKEGG.m @@ -131,7 +131,12 @@ if numel(tline)<12 continue; end - + % Skip other lines with unused information + if strcmp(tline(1:5),'BRITE') + pathway = false; + continue; + end + %Check if it's a new reaction if strcmp(tline(1:12),'ENTRY ') rxnCounter=rxnCounter+1; @@ -139,7 +144,7 @@ %Add empty strings where there should be such model.rxnNames{rxnCounter}=''; model.eccodes{rxnCounter}=''; - %model.subSystems{rxnCounter}=''; %remain empty cell + %model.subSystems{rxnCounter}={''}; %remain empty cell model.rxnNotes{rxnCounter}=''; equations{rxnCounter}=''; @@ -305,7 +310,7 @@ model.subSystems{rxnCounter}=tline(28:end); else %The new format - model.subSystems{rxnCounter,1}{1,numel(model.subSystems{rxnCounter,1})+1}=tline(22:end); + model.subSystems{rxnCounter,1}{numel(model.subSystems{rxnCounter,1})+1,1}=tline(22:end); end end end @@ -330,6 +335,9 @@ model.rxnNotes=model.rxnNotes(1:rxnCounter); model.subSystems=model.subSystems(1:rxnCounter); + emptySubSys = cellfun(@isempty,model.subSystems); + model.subSystems(emptySubSys) = {{''}}; + %Then load the equations from another file. This is because the %equations are easier to retrieve from there diff --git a/external/kegg/keggRxns.mat b/external/kegg/keggRxns.mat index b9993055..f5a62f8d 100644 --- a/external/kegg/keggRxns.mat +++ b/external/kegg/keggRxns.mat @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bdb029b557419ea09c6ae0e98c019948ccab9aa94ee6b881eb2f4d3dc2bcf8d4 -size 1912218 +oid sha256:6e857ff568c094811a524a688b58e5c812b9df46425131b722ef3a59763c23b0 +size 1110994 diff --git a/external/metacyc/getRxnsFromMetaCyc.m b/external/metacyc/getRxnsFromMetaCyc.m index d5611c43..8d6b0b8a 100755 --- a/external/metacyc/getRxnsFromMetaCyc.m +++ b/external/metacyc/getRxnsFromMetaCyc.m @@ -244,7 +244,7 @@ [x, y]=ismember(tline(14:end),pwys); if x - metaCycRxns.subSystems{rxnCounter,1}{1,numel(metaCycRxns.subSystems{rxnCounter,1})+1}=pwyNames{y}; + metaCycRxns.subSystems{rxnCounter,1}{numel(metaCycRxns.subSystems{rxnCounter,1})+1,1}=pwyNames{y}; end end diff --git a/installation/checkInstallation.m b/installation/checkInstallation.m index 4a1784fa..de8c1236 100755 --- a/installation/checkInstallation.m +++ b/installation/checkInstallation.m @@ -1,4 +1,4 @@ -function [currVer, installType] = checkInstallation(developMode) +function [currVer, installType] = checkInstallation(developMode,checkBinaries) % checkInstallation % The purpose of this function is to check if all necessary functions are % installed and working. It also checks whether there are any functions @@ -11,6 +11,9 @@ % HMMs (optional, default false). If 'versionOnly' is % specified, only the version is reported as currVer, no % further installation or tests are performed. +% checkBinaries logical whether non-developMode binaries should be +% checked for functionality. If false, it overwrites +% developMode. Default true. % % Output: % currVer current RAVEN version @@ -27,6 +30,9 @@ if nargin<1 developMode=false; end +if nargin<2 + checkBinaries=true; +end if ischar(developMode) && strcmp(developMode,'versionOnly') versionOnly = true; else @@ -129,6 +135,13 @@ catch printOrange('Fail\n') end +fprintf(myStr(' > Store RAVEN path as MATLAB pref',40)) +try + setpref('RAVEN','ravenPath',ravenDir); + fprintf('Pass\n'); +catch + printOrange('Fail\n') +end if isunix fprintf(myStr(' > Make binaries executable',40)) @@ -275,46 +288,50 @@ end fprintf('\n=== Essential binary executables ===\n'); -fprintf(myStr(' > Checking BLAST+',40)) -[~,res]=evalc("runtests('blastPlusTests.m');"); -res=interpretResults(res); -if res==false - fprintf(' This is essential to run getBlast()\n') -end +if ~checkBinaries + printOrange(' Skipping check of binary executables\n') +else + fprintf(myStr(' > Checking BLAST+',40)) + [~,res]=evalc("runtests('blastPlusTests.m');"); + res=interpretResults(res); + if res==false + fprintf(' This is essential to run getBlast()\n') + end -fprintf(myStr(' > Checking DIAMOND',40)) -[~,res]=evalc("runtests('diamondTests.m');"); -res=interpretResults(res); -if res==false - fprintf(' This is essential to run the getDiamond()\n') -end + fprintf(myStr(' > Checking DIAMOND',40)) + [~,res]=evalc("runtests('diamondTests.m');"); + res=interpretResults(res); + if res==false + fprintf(' This is essential to run the getDiamond()\n') + end -fprintf(myStr(' > Checking HMMER',40)) -[~,res]=evalc("runtests('hmmerTests.m')"); -res=interpretResults(res); -if res==false - fprintf([' This is essential to run getKEGGModelFromHomology()\n'... - ' when using a FASTA file as input\n']) -end + fprintf(myStr(' > Checking HMMER',40)) + [~,res]=evalc("runtests('hmmerTests.m')"); + res=interpretResults(res); + if res==false + fprintf([' This is essential to run getKEGGModelFromHomology()\n'... + ' when using a FASTA file as input\n']) + end -if developMode - fprintf('\n=== Development binary executables ===\n'); - fprintf('NOTE: These binaries are only required when using KEGG FTP dump files in getKEGGModelForOrganism\n'); + if developMode + fprintf('\n=== Development binary executables ===\n'); + fprintf('NOTE: These binaries are only required when using KEGG FTP dump files in getKEGGModelForOrganism\n'); - fprintf(myStr(' > Checking CD-HIT',40)) - [~,res]=evalc("runtests('cdhitTests.m');"); - interpretResults(res); + fprintf(myStr(' > Checking CD-HIT',40)) + [~,res]=evalc("runtests('cdhitTests.m');"); + interpretResults(res); - fprintf(myStr(' > Checking MAFFT',40)) - [~,res]=evalc("runtests('mafftTests.m');"); - interpretResults(res); + fprintf(myStr(' > Checking MAFFT',40)) + [~,res]=evalc("runtests('mafftTests.m');"); + interpretResults(res); + end end fprintf('\n=== Compatibility ===\n'); fprintf(myStr(' > Checking function uniqueness',40)) checkFunctionUniqueness(); -fprintf('\n*** checkInstallation complete ***\n\n'); +fprintf('\n*** checkInstallation complete ***\n'); end function res = interpretResults(results) diff --git a/io/exportToExcelFormat.m b/io/exportToExcelFormat.m index 7274c387..9337e76e 100755 --- a/io/exportToExcelFormat.m +++ b/io/exportToExcelFormat.m @@ -185,6 +185,9 @@ function exportToExcelFormat(model,fileName,sortIds) subsystems=''; if isfield(model,'subSystems') for i=1:numel(model.subSystems) + if ~iscell(model.subSystems{i}) + model.subSystems{i} = {model.subSystems{i}}; + end if ~isempty(model.subSystems{i,1}) subsystems{i,1}=strjoin(model.subSystems{i,1},';'); else diff --git a/io/exportToTabDelimited.m b/io/exportToTabDelimited.m index 8a773407..98ad6bb7 100755 --- a/io/exportToTabDelimited.m +++ b/io/exportToTabDelimited.m @@ -106,6 +106,9 @@ function exportToTabDelimited(model,path,sortIds) if isfield(model,'subSystems') if ~isempty(model.subSystems{i}) + if ~iscell(model.subSystems{i}) + model.subSystems{i} = {model.subSystems{i}}; + end fprintf(rxnFile,[strjoin(model.subSystems{i,1},';') '\t']); else fprintf(rxnFile,'\t'); diff --git a/io/importModel.m b/io/importModel.m index 68bfe6fc..dae96063 100755 --- a/io/importModel.m +++ b/io/importModel.m @@ -992,6 +992,10 @@ model=rmfield(model,'subSystems'); else model.subSystems(cellfun(@isempty,subsystems))={{''}}; + % If all subSystems have single entries, then unnest them + if all(cellfun(@(x) iscell(x) && isscalar(x), model.subSystems)) + model.subSystems = transpose([model.subSystems{:}]); + end end if isempty(model.eccodes) model=rmfield(model,'eccodes'); diff --git a/io/readYAMLmodel.m b/io/readYAMLmodel.m index bc93d78c..1eb65f3b 100755 --- a/io/readYAMLmodel.m +++ b/io/readYAMLmodel.m @@ -592,15 +592,24 @@ % end % end +if isfield(model,'subSystems') +% If all entries are 1x1, then flatten + if all(cellfun(@(x) numel(x) <= 1, model.subSystems)) + model.subSystems = transpose([model.subSystems{:}]); + end +end + % Make rxnGeneMat fields and map to the existing model.genes field -[genes, rxnGeneMat] = getGenesFromGrRules(model.grRules); -model.rxnGeneMat = sparse(numel(model.rxns),numel(model.genes)); -[~,geneOrder] = ismember(genes,model.genes); -if any(geneOrder == 0) - error(['The grRules includes the following gene(s), that are not in '... - 'the list of model genes: ', genes{~geneOrder}]) -end -model.rxnGeneMat(:,geneOrder) = rxnGeneMat; +if isfield(model,'grRules') + [genes, rxnGeneMat] = getGenesFromGrRules(model.grRules); + model.rxnGeneMat = sparse(numel(model.rxns),numel(model.genes)); + [~,geneOrder] = ismember(genes,model.genes); + if any(geneOrder == 0) + error(['The grRules includes the following gene(s), that are not in '... + 'the list of model genes: ', genes{~geneOrder}]) + end + model.rxnGeneMat(:,geneOrder) = rxnGeneMat; +end % Finalize GECKO model if isGECKO diff --git a/io/writeYAMLmodel.m b/io/writeYAMLmodel.m index 2042c5e3..2ada7074 100755 --- a/io/writeYAMLmodel.m +++ b/io/writeYAMLmodel.m @@ -111,13 +111,15 @@ function writeYAMLmodel(model,fileName,preserveQuotes,sortIds) end %Genes: -fprintf(fid,'- genes:\n'); -for i = 1:length(model.genes) - fprintf(fid,' - !!omap\n'); - writeField(model, fid, 'genes', 'txt', i, ' - id', preserveQuotes) - writeField(model, fid, 'geneShortNames', 'txt', i, ' - name', preserveQuotes) - writeField(model, fid, 'proteins', 'txt', i, ' - protein', preserveQuotes) - writeField(model, fid, 'geneMiriams', 'txt', i, ' - annotation', preserveQuotes) +if isfield(model,'genes') + fprintf(fid,'- genes:\n'); + for i = 1:length(model.genes) + fprintf(fid,' - !!omap\n'); + writeField(model, fid, 'genes', 'txt', i, ' - id', preserveQuotes) + writeField(model, fid, 'geneShortNames', 'txt', i, ' - name', preserveQuotes) + writeField(model, fid, 'proteins', 'txt', i, ' - protein', preserveQuotes) + writeField(model, fid, 'geneMiriams', 'txt', i, ' - annotation', preserveQuotes) + end end %Compartments: diff --git a/solver/optimizeProb.m b/solver/optimizeProb.m index 3aa3bce2..3430c45d 100755 --- a/solver/optimizeProb.m +++ b/solver/optimizeProb.m @@ -242,7 +242,7 @@ switch exitflag case 11 res.stat = 1; - case [5, 6, 7, 8, 9, 10, 13] + case {1, 5, 6, 7, 8, 9, 10, 13} % If user-interrupted, not sure if optimal res.stat = 2; otherwise res.stat = 0; diff --git a/struct_conversion/ravenCobraWrapper.m b/struct_conversion/ravenCobraWrapper.m index 6bb14d7c..47b48525 100755 --- a/struct_conversion/ravenCobraWrapper.m +++ b/struct_conversion/ravenCobraWrapper.m @@ -186,7 +186,7 @@ newModel.b=zeros(numel(model.mets),1); newModel.csense=repmat('E',size(model.mets)); if isfield(model,'geneMiriams') - [miriams,extractedMiriamNames]=extractMiriam(model.geneMiriams); + [~,extractedMiriamNames]=extractMiriam(model.geneMiriams); for i = 1:length(geneCOBRAfields) j=ismember(extractedMiriamNames,geneNamespaces{i}); if any(j) @@ -202,11 +202,16 @@ else fprintf('WARNING: no genes detected. The model therefore may not be exportable to SBML file with writeCbModel\n'); end - newModel.osenseStr='max'; + % If needed, normalise subSystems to cell-of-cells format + if isfield(newModel,'subSystems') && ~isempty(newModel.subSystems) + if ~iscell(newModel.subSystems{1}) + newModel.subSystems = cellfun(@(x) {x}, newModel.subSystems, 'UniformOutput', false); + end + end else fprintf('Converting COBRA structure to RAVEN..\n'); %Convert from COBRA to RAVEN structure - + %Mandatory RAVEN fields newModel.mets=model.mets; if ~isfield(model,'comps') @@ -396,6 +401,12 @@ end end end + % Flatten subSystems if every reaction has exactly one subsystem. + if isfield(newModel,'subSystems') && ~isempty(newModel.subSystems) + if all(cellfun(@(x) iscell(x) && isscalar(x), newModel.subSystems)) + newModel.subSystems = transpose([newModel.subSystems{:}]); + end + end if printWarning fprintf('Could not determine whether PubChemIDs are compounds (CID)\n or substances (SID). All annotated PubChemIDs will therefore \n be assigned as compounds (CID).\n'); end