diff --git a/core/getAllowedBounds.m b/core/getAllowedBounds.m index babad784..ed580fd0 100755 --- a/core/getAllowedBounds.m +++ b/core/getAllowedBounds.m @@ -49,24 +49,25 @@ tmpModel = model; tmpModel.c = c; + % Get maximal flux + tmpModel.c(rxns(i)) = 1; + [solMax,hsSol]=solveLP(tmpModel); + if ~isempty(solMax.f) + maxFluxes(i) = solMax.x(rxns(i)); + else + maxFluxes(i) = NaN; + end + % Get minimal flux tmpModel.c(rxns(i)) = -1; - solMin = solveLP(tmpModel); + solMin = solveLP(tmpModel,[],[],hsSol); if ~isempty(solMin.f) minFluxes(i) = solMin.x(rxns(i)); else minFluxes(i) = NaN; end - - % Get maximal flux - tmpModel.c(rxns(i)) = 1; - solMax=solveLP(tmpModel); exitFlags(i,:) = [solMin.stat solMax.stat]; - if ~isempty(solMax.f) - maxFluxes(i) = solMax.x(rxns(i)); - else - maxFluxes(i) = NaN; - end + end % Reset original Parallel setting ps.Pool.AutoCreate = oldPoolAutoCreateSetting; diff --git a/core/getGenesFromGrRules.m b/core/getGenesFromGrRules.m index ac97c771..a251d6bd 100755 --- a/core/getGenesFromGrRules.m +++ b/core/getGenesFromGrRules.m @@ -54,7 +54,7 @@ % construct new gene list nonEmpty = ~cellfun(@isempty,rxnGenes); -genes = unique([rxnGenes{nonEmpty}]'); +genes = unique(transpose([rxnGenes{nonEmpty}])); genes(cellfun(@isempty,genes)) = []; if ~isempty(originalGenes) diff --git a/core/haveFlux.m b/core/haveFlux.m index 92f211e2..01215959 100755 --- a/core/haveFlux.m +++ b/core/haveFlux.m @@ -1,23 +1,25 @@ function I=haveFlux(model,cutOff,rxns) % haveFlux -% Checks which reactions can carry a (positive or negative) flux. -% Is used as a faster version of getAllowedBounds if it is only interesting +% Checks which reactions can carry a (positive or negative) flux. Is used +% as a faster version of getAllowedBounds if it is only interesting % whether the reactions can carry a flux or not % +% Input: % model a model structure % cutOff the flux value that a reaction has to carry to be % identified as positive (optional, default 10^-8) % rxns either a cell array of IDs, a logical vector with the -% same number of elements as metabolites in the model, -% of a vector of indexes (optional, default model.rxns) +% same number of elements as metabolites in the model, or a +% vector of indexes (optional, default model.rxns) % -% I logical array with true if the corresponding -% reaction can carry a flux +% Output: +% I logical array with true if the corresponding reaction can +% carry a flux % -% NOTE: If a model has +/- Inf bounds then those are replaced with an -% arbitary large value of +/- 10000 prior to solving +% If a model has +/- Inf bounds then those are replaced with an arbitary +% large value of +/- 10000 prior to solving % -% Usage: I=haveFlux(model,cutOff, rxns) +% Usage: I = haveFlux(model, cutOff, rxns) if nargin<2 cutOff=10^-6; diff --git a/doc/core/getAllowedBounds.html b/doc/core/getAllowedBounds.html index 51d69e29..ec6855e9 100644 --- a/doc/core/getAllowedBounds.html +++ b/doc/core/getAllowedBounds.html @@ -118,28 +118,29 @@

SOURCE CODE ^% Get minimal flux -0053 tmpModel.c(rxns(i)) = -1; -0054 solMin = solveLP(tmpModel); -0055 if ~isempty(solMin.f) -0056 minFluxes(i) = solMin.x(rxns(i)); +0052 % Get maximal flux +0053 tmpModel.c(rxns(i)) = 1; +0054 [solMax,hsSol]=solveLP(tmpModel); +0055 if ~isempty(solMax.f) +0056 maxFluxes(i) = solMax.x(rxns(i)); 0057 else -0058 minFluxes(i) = NaN; +0058 maxFluxes(i) = NaN; 0059 end 0060 -0061 % Get maximal flux -0062 tmpModel.c(rxns(i)) = 1; -0063 solMax=solveLP(tmpModel); -0064 exitFlags(i,:) = [solMin.stat solMax.stat]; -0065 if ~isempty(solMax.f) -0066 maxFluxes(i) = solMax.x(rxns(i)); -0067 else -0068 maxFluxes(i) = NaN; -0069 end -0070 end -0071 % Reset original Parallel setting -0072 ps.Pool.AutoCreate = oldPoolAutoCreateSetting; -0073 end +0061 % Get minimal flux +0062 tmpModel.c(rxns(i)) = -1; +0063 solMin = solveLP(tmpModel,[],[],hsSol); +0064 if ~isempty(solMin.f) +0065 minFluxes(i) = solMin.x(rxns(i)); +0066 else +0067 minFluxes(i) = NaN; +0068 end +0069 exitFlags(i,:) = [solMin.stat solMax.stat]; +0070 +0071 end +0072 % Reset original Parallel setting +0073 ps.Pool.AutoCreate = oldPoolAutoCreateSetting; +0074 end
Generated by m2html © 2005
\ No newline at end of file diff --git a/doc/core/getGenesFromGrRules.html b/doc/core/getGenesFromGrRules.html index 19302a47..84f78e8c 100644 --- a/doc/core/getGenesFromGrRules.html +++ b/doc/core/getGenesFromGrRules.html @@ -120,7 +120,7 @@

SOURCE CODE ^% construct new gene list 0056 nonEmpty = ~cellfun(@isempty,rxnGenes); -0057 genes = unique([rxnGenes{nonEmpty}]'); +0057 genes = unique(transpose([rxnGenes{nonEmpty}])); 0058 genes(cellfun(@isempty,genes)) = []; 0059 0060 if ~isempty(originalGenes) diff --git a/doc/core/haveFlux.html b/doc/core/haveFlux.html index c4b30ffb..4fdbd8b6 100644 --- a/doc/core/haveFlux.html +++ b/doc/core/haveFlux.html @@ -28,24 +28,26 @@

SYNOPSIS ^DESCRIPTION ^

 haveFlux
-   Checks which reactions can carry a (positive or negative) flux.
-   Is used as a faster version of getAllowedBounds if it is only interesting
+   Checks which reactions can carry a (positive or negative) flux. Is used
+   as a faster version of getAllowedBounds if it is only interesting
    whether the reactions can carry a flux or not
 
+ Input:
    model       a model structure
    cutOff      the flux value that a reaction has to carry to be
                identified as positive (optional, default 10^-8)
    rxns        either a cell array of IDs, a logical vector with the
-               same number of elements as metabolites in the model,
-               of a vector of indexes (optional, default model.rxns)
+               same number of elements as metabolites in the model, or a
+               vector of indexes (optional, default model.rxns)
 
-   I           logical array with true if the corresponding
-               reaction can carry a flux
+ Output:
+   I           logical array with true if the corresponding reaction can
+               carry a flux
 
-   NOTE: If a model has +/- Inf bounds then those are replaced with an
-   arbitary large value of +/- 10000 prior to solving
+ If a model has +/- Inf bounds then those are replaced with an arbitary
+ large value of +/- 10000 prior to solving
 
- Usage: I=haveFlux(model,cutOff, rxns)
+ Usage: I = haveFlux(model, cutOff, rxns)

CROSS-REFERENCE INFORMATION ^

@@ -62,83 +64,85 @@

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

0001 function I=haveFlux(model,cutOff,rxns)
 0002 % haveFlux
-0003 %   Checks which reactions can carry a (positive or negative) flux.
-0004 %   Is used as a faster version of getAllowedBounds if it is only interesting
+0003 %   Checks which reactions can carry a (positive or negative) flux. Is used
+0004 %   as a faster version of getAllowedBounds if it is only interesting
 0005 %   whether the reactions can carry a flux or not
 0006 %
-0007 %   model       a model structure
-0008 %   cutOff      the flux value that a reaction has to carry to be
-0009 %               identified as positive (optional, default 10^-8)
-0010 %   rxns        either a cell array of IDs, a logical vector with the
-0011 %               same number of elements as metabolites in the model,
-0012 %               of a vector of indexes (optional, default model.rxns)
-0013 %
-0014 %   I           logical array with true if the corresponding
-0015 %               reaction can carry a flux
-0016 %
-0017 %   NOTE: If a model has +/- Inf bounds then those are replaced with an
-0018 %   arbitary large value of +/- 10000 prior to solving
-0019 %
-0020 % Usage: I=haveFlux(model,cutOff, rxns)
-0021 
-0022 if nargin<2
-0023     cutOff=10^-6;
-0024 end
-0025 if isempty(cutOff)
-0026     cutOff=10^-6;
-0027 end
-0028 if nargin<3
-0029     rxns=model.rxns;
-0030 elseif ~islogical(rxns) && ~isnumeric(rxns)
-0031     rxns=convertCharArray(rxns);
-0032 end
-0033 
-0034 %This is since we're maximizing for the sum of fluxes, which isn't possible
-0035 %when there are infinite bounds
-0036 model.lb(model.lb==-inf)=-10000;
-0037 model.ub(model.ub==inf)=10000;
-0038 
-0039 %Get the reaction IDs. A bit of an awkward way, but fine.
-0040 indexes=getIndexes(model,rxns,'rxns');
-0041 rxns=model.rxns(indexes);
-0042 
-0043 %First remove all dead-end reactions
-0044 smallModel=simplifyModel(model,false,false,true,true);
-0045 
-0046 %Get the indexes of the reactions in the connected model
-0047 indexes=getIndexes(smallModel,intersect(smallModel.rxns,rxns),'rxns');
-0048 J=false(numel(indexes),1);
-0049 mixIndexes=indexes(randperm(numel(indexes)));
-0050 
-0051 %Maximize for all fluxes first in order to get fewer rxns to test
-0052 smallModel.c=ones(numel(smallModel.c),1);
-0053 sol=solveLP(smallModel);
-0054 if ~isempty(sol.x)
-0055     J(abs(sol.x(mixIndexes))>cutOff)=true;
-0056 end
-0057 
-0058 %Loop through and maximize then minimize each rxn if it does not already
-0059 %have a flux
-0060 Z=zeros(numel(smallModel.c),1);
-0061 hsSolOut=[];
-0062 for i=[1 -1]
-0063     for j=1:numel(J)
-0064         if J(j)==false
-0065             %Only minimize for reversible reactions
-0066             if i==1 || smallModel.rev(mixIndexes(j))~=0
-0067                 smallModel.c=Z;
-0068                 smallModel.c(mixIndexes(j))=i;
-0069                 [sol, hsSolOut]=solveLP(smallModel,0,[],hsSolOut);
-0070                 if any(sol.x)
-0071                     J(abs(sol.x(mixIndexes))>cutOff)=true;
-0072                 end
-0073             end
-0074         end
-0075     end
-0076 end
-0077 
-0078 I=ismember(rxns,smallModel.rxns(mixIndexes(J)));
-0079 end
+0007 % Input: +0008 % model a model structure +0009 % cutOff the flux value that a reaction has to carry to be +0010 % identified as positive (optional, default 10^-8) +0011 % rxns either a cell array of IDs, a logical vector with the +0012 % same number of elements as metabolites in the model, or a +0013 % vector of indexes (optional, default model.rxns) +0014 % +0015 % Output: +0016 % I logical array with true if the corresponding reaction can +0017 % carry a flux +0018 % +0019 % If a model has +/- Inf bounds then those are replaced with an arbitary +0020 % large value of +/- 10000 prior to solving +0021 % +0022 % Usage: I = haveFlux(model, cutOff, rxns) +0023 +0024 if nargin<2 +0025 cutOff=10^-6; +0026 end +0027 if isempty(cutOff) +0028 cutOff=10^-6; +0029 end +0030 if nargin<3 +0031 rxns=model.rxns; +0032 elseif ~islogical(rxns) && ~isnumeric(rxns) +0033 rxns=convertCharArray(rxns); +0034 end +0035 +0036 %This is since we're maximizing for the sum of fluxes, which isn't possible +0037 %when there are infinite bounds +0038 model.lb(model.lb==-inf)=-10000; +0039 model.ub(model.ub==inf)=10000; +0040 +0041 %Get the reaction IDs. A bit of an awkward way, but fine. +0042 indexes=getIndexes(model,rxns,'rxns'); +0043 rxns=model.rxns(indexes); +0044 +0045 %First remove all dead-end reactions +0046 smallModel=simplifyModel(model,false,false,true,true); +0047 +0048 %Get the indexes of the reactions in the connected model +0049 indexes=getIndexes(smallModel,intersect(smallModel.rxns,rxns),'rxns'); +0050 J=false(numel(indexes),1); +0051 mixIndexes=indexes(randperm(numel(indexes))); +0052 +0053 %Maximize for all fluxes first in order to get fewer rxns to test +0054 smallModel.c=ones(numel(smallModel.c),1); +0055 sol=solveLP(smallModel); +0056 if ~isempty(sol.x) +0057 J(abs(sol.x(mixIndexes))>cutOff)=true; +0058 end +0059 +0060 %Loop through and maximize then minimize each rxn if it does not already +0061 %have a flux +0062 Z=zeros(numel(smallModel.c),1); +0063 hsSolOut=[]; +0064 for i=[1 -1] +0065 for j=1:numel(J) +0066 if J(j)==false +0067 %Only minimize for reversible reactions +0068 if i==1 || smallModel.rev(mixIndexes(j))~=0 +0069 smallModel.c=Z; +0070 smallModel.c(mixIndexes(j))=i; +0071 [sol, hsSolOut]=solveLP(smallModel,0,[],hsSolOut); +0072 if any(sol.x) +0073 J(abs(sol.x(mixIndexes))>cutOff)=true; +0074 end +0075 end +0076 end +0077 end +0078 end +0079 +0080 I=ismember(rxns,smallModel.rxns(mixIndexes(J))); +0081 end
Generated by m2html © 2005
\ No newline at end of file diff --git a/doc/installation/checkInstallation.html b/doc/installation/checkInstallation.html index 58b3c801..02a58994 100644 --- a/doc/installation/checkInstallation.html +++ b/doc/installation/checkInstallation.html @@ -188,7 +188,7 @@

SOURCE CODE ^try 0127 evalc('importModel(fullfile(ravenDir,''tutorial'',''empty.xml''))'); 0128 try -0129 libSBMLver=OutputSBML; % Only works in libSBML 5.17.0+ +0129 libSBMLver=OutputSBML_RAVEN; % Only works in libSBML 5.17.0+ 0130 fprintf([libSBMLver.libSBML_version_string '\n']); 0131 catch 0132 printOrange('Fail\n') @@ -375,43 +375,45 @@

SOURCE CODE ^end 0314 0315 function status = makeBinaryExecutable(ravenDir) -0316 if ispc -0317 status = 0; % No need to run on Windows -0318 return; -0319 end -0320 binDir = fullfile(ravenDir,'software'); -0321 -0322 binList = {fullfile(binDir,'blast+','blastp'); fullfile(binDir,'blast+','blastp.mac'); -0323 fullfile(binDir,'blast+','makeblastdb'); fullfile(binDir,'blast+','makeblastdb.mac'); -0324 fullfile(binDir,'cd-hit','cd-hit'); fullfile(binDir,'cd-hit','cd-hit.mac'); -0325 fullfile(binDir,'diamond','diamond'); fullfile(binDir,'diamond','diamond.mac'); -0326 fullfile(binDir,'hmmer','hmmbuild'); fullfile(binDir,'hmmer','hmmbuild.mac'); -0327 fullfile(binDir,'hmmer','hmmsearch'); fullfile(binDir,'hmmer','hmmsearch.mac'); -0328 fullfile(binDir,'GLPKmex','glpkcc.mexa64'); fullfile(binDir,'GLPKmex','glpkcc.mexglx'); fullfile(binDir,'GLPKmex','glpkcc.mexmaci64'); -0329 fullfile(binDir,'libSBML','TranslateSBML.mexa64'); fullfile(binDir,'libSBML','TranslateSBML.mexglx'); fullfile(binDir,'libSBML','TranslateSBML.mexmaci64'); -0330 fullfile(binDir,'libSBML','OutputSBML.mexa64'); fullfile(binDir,'libSBML','OutputSBML.mexglx'); fullfile(binDir,'libSBML','OutputSBML.mexmaci64'); -0331 fullfile(binDir,'mafft','mafft-linux64','mafft.bat'); -0332 fullfile(binDir,'mafft','mafft-mac','mafft.bat');}; -0333 -0334 for i=1:numel(binList) -0335 [status,cmdout] = system(['chmod +x "' binList{i} '"']); -0336 if status ~= 0 -0337 warning('Failed to make %s executable: %s ',binList{i},strip(cmdout)) -0338 end -0339 end -0340 end -0341 -0342 function printOrange(stringToPrint) -0343 % printOrange -0344 % Duplicate of RAVEN/core/printOrange is also kept here, as this function -0345 % should be able to run before adding RAVEN to the MATLAB path. -0346 try useDesktop = usejava('desktop'); catch, useDesktop = false; end -0347 if useDesktop -0348 fprintf(['[\b' stringToPrint,']\b']) -0349 else -0350 fprintf(stringToPrint) -0351 end -0352 end +0316 % This function is required to run when RAVEN is downloaded as MATLAB +0317 % Add-On, in which case the file permissions are not correctly set +0318 if ispc +0319 status = 0; % No need to run on Windows +0320 return; +0321 end +0322 binDir = fullfile(ravenDir,'software'); +0323 +0324 binList = {fullfile(binDir,'blast+','blastp'); fullfile(binDir,'blast+','blastp.mac'); +0325 fullfile(binDir,'blast+','makeblastdb'); fullfile(binDir,'blast+','makeblastdb.mac'); +0326 fullfile(binDir,'cd-hit','cd-hit'); fullfile(binDir,'cd-hit','cd-hit.mac'); +0327 fullfile(binDir,'diamond','diamond'); fullfile(binDir,'diamond','diamond.mac'); +0328 fullfile(binDir,'hmmer','hmmbuild'); fullfile(binDir,'hmmer','hmmbuild.mac'); +0329 fullfile(binDir,'hmmer','hmmsearch'); fullfile(binDir,'hmmer','hmmsearch.mac'); +0330 fullfile(binDir,'GLPKmex','glpkcc.mexa64'); fullfile(binDir,'GLPKmex','glpkcc.mexglx'); fullfile(binDir,'GLPKmex','glpkcc.mexmaci64'); fullfile(binDir,'GLPKmex','glpkcc.mexmaca64'); +0331 fullfile(binDir,'libSBML','TranslateSBML_RAVEN.mexa64'); fullfile(binDir,'libSBML','TranslateSBML_RAVEN.mexglx'); fullfile(binDir,'libSBML','TranslateSBML_RAVEN.mexmaci64'); fullfile(binDir,'libSBML','TranslateSBML_RAVEN.mexmaca64'); +0332 fullfile(binDir,'libSBML','OutputSBML_RAVEN.mexa64'); fullfile(binDir,'libSBML','OutputSBML_RAVEN.mexglx'); fullfile(binDir,'libSBML','OutputSBML_RAVEN.mexmaci64'); fullfile(binDir,'libSBML','OutputSBML_RAVEN.mexmaca64'); +0333 fullfile(binDir,'mafft','mafft-linux64','mafft.bat'); +0334 fullfile(binDir,'mafft','mafft-mac','mafft.bat');}; +0335 +0336 for i=1:numel(binList) +0337 [status,cmdout] = system(['chmod +x "' binList{i} '"']); +0338 if status ~= 0 +0339 warning('Failed to make %s executable: %s ',binList{i},strip(cmdout)) +0340 end +0341 end +0342 end +0343 +0344 function printOrange(stringToPrint) +0345 % printOrange +0346 % Duplicate of RAVEN/core/printOrange is also kept here, as this function +0347 % should be able to run before adding RAVEN to the MATLAB path. +0348 try useDesktop = usejava('desktop'); catch, useDesktop = false; end +0349 if useDesktop +0350 fprintf(['[\b' stringToPrint,']\b']) +0351 else +0352 fprintf(stringToPrint) +0353 end +0354 end
Generated by m2html © 2005
\ No newline at end of file diff --git a/doc/io/exportForGit.html b/doc/io/exportForGit.html index 8aae4734..85d9acd8 100644 --- a/doc/io/exportForGit.html +++ b/doc/io/exportForGit.html @@ -136,93 +136,91 @@

SOURCE CODE ^%Retrieve libSBML version: 0067 [ravenDir,prevDir]=findRAVENroot(); -0068 cd(fullfile(ravenDir,'software','libSBML')); -0069 try % 5.17.0 and newer -0070 libSBMLver=OutputSBML; -0071 libSBMLver=libSBMLver.libSBML_version_string; -0072 catch % before 5.17.0 -0073 fid = fopen('tempModelForLibSBMLversion.xml','w+'); -0074 fclose(fid); -0075 evalc('[~,~,libSBMLver]=TranslateSBML(''tempModelForLibSBMLversion.xml'',0,0)'); -0076 libSBMLver=libSBMLver.libSBML_version_string; -0077 delete('tempModelForLibSBMLversion.xml'); -0078 end -0079 cd(prevDir) -0080 -0081 % Make models folder, no warnings if folder already exists -0082 if subDirs -0083 path=fullfile(path,'model'); -0084 filePath=strcat(path,filesep,{'txt','yml','mat','xlsx','xml'}); -0085 [~,~,~]=mkdir(path); -0086 for i = 1:length(formats) -0087 [~,~,~]=mkdir(fullfile(path,formats{i})); -0088 end -0089 else -0090 filePath=cell(1,5); filePath(:)={path}; -0091 end -0092 -0093 -0094 % Write TXT format -0095 if ismember('txt', formats) -0096 fid=fopen(fullfile(filePath{1},strcat(prefix,'.txt')),'w'); -0097 if cobraText==true -0098 eqns=constructEquations(model,model.rxns,false,false,false); -0099 eqns=strrep(eqns,' => ',' -> '); -0100 eqns=strrep(eqns,' <=> ',' <=> '); -0101 eqns=regexprep(eqns,'> $','>'); -0102 grRules=regexprep(model.grRules,'\((?!\()','( '); -0103 grRules=regexprep(grRules,'(?<!\))\)',' )'); -0104 else -0105 eqns=constructEquations(model,model.rxns); -0106 grRules=model.grRules; -0107 end -0108 fprintf(fid, 'Rxn name\tFormula\tGene-reaction association\tLB\tUB\tObjective\n'); -0109 for i = 1:numel(model.rxns) -0110 fprintf(fid, '%s\t', model.rxns{i}); -0111 fprintf(fid, '%s \t', eqns{i}); -0112 fprintf(fid, '%s\t', grRules{i}); -0113 fprintf(fid, '%6.2f\t%6.2f\t%6.2f\n', model.lb(i), model.ub(i), model.c(i)); -0114 end -0115 fclose(fid); -0116 end -0117 -0118 % Write YML format -0119 if ismember('yml', formats) -0120 writeYAMLmodel(model,fullfile(filePath{2},strcat(prefix,'.yml'))); -0121 end -0122 -0123 % Write MAT format -0124 if ismember('mat', formats) -0125 save(fullfile(filePath{3},strcat(prefix,'.mat')),'model'); -0126 end -0127 -0128 % Write XLSX format -0129 if ismember('xlsx', formats) -0130 exportToExcelFormat(model,fullfile(filePath{4},strcat(prefix,'.xlsx'))); -0131 end -0132 -0133 % Write XML format -0134 if ismember('xml', formats) -0135 exportModel(model,fullfile(filePath{5},strcat(prefix,'.xml'))); -0136 end -0137 -0138 %Save file with versions: -0139 fid = fopen(fullfile(path,'dependencies.txt'),'wt'); -0140 fprintf(fid,['MATLAB\t' version '\n']); -0141 fprintf(fid,['libSBML\t' libSBMLver '\n']); -0142 fprintf(fid,['RAVEN_toolbox\t' RAVENver '\n']); -0143 if ~isempty(COBRAver) -0144 fprintf(fid,['COBRA_toolbox\t' COBRAver '\n']); -0145 end -0146 if isfield(model,'modelVersion') -0147 fields = fieldnames(model.modelVersion); -0148 for i = 1:length(fields) -0149 value = model.modelVersion.(fields{i}); -0150 fprintf(fid,[fields{i} '\t' num2str(value) '\n']); -0151 end -0152 end -0153 fclose(fid); -0154 end +0068 try % 5.17.0 and newer +0069 libSBMLver=OutputSBML_RAVEN; +0070 libSBMLver=libSBMLver.libSBML_version_string; +0071 catch % before 5.17.0 +0072 fid = fopen('tempModelForLibSBMLversion.xml','w+'); +0073 fclose(fid); +0074 evalc('[~,~,libSBMLver]=TranslateSBML_RAVEN(''tempModelForLibSBMLversion.xml'',0,0)'); +0075 libSBMLver=libSBMLver.libSBML_version_string; +0076 delete('tempModelForLibSBMLversion.xml'); +0077 end +0078 +0079 % Make models folder, no warnings if folder already exists +0080 if subDirs +0081 path=fullfile(path,'model'); +0082 filePath=strcat(path,filesep,{'txt','yml','mat','xlsx','xml'}); +0083 [~,~,~]=mkdir(path); +0084 for i = 1:length(formats) +0085 [~,~,~]=mkdir(fullfile(path,formats{i})); +0086 end +0087 else +0088 filePath=cell(1,5); filePath(:)={path}; +0089 end +0090 +0091 +0092 % Write TXT format +0093 if ismember('txt', formats) +0094 fid=fopen(fullfile(filePath{1},strcat(prefix,'.txt')),'w'); +0095 if cobraText==true +0096 eqns=constructEquations(model,model.rxns,false,false,false); +0097 eqns=strrep(eqns,' => ',' -> '); +0098 eqns=strrep(eqns,' <=> ',' <=> '); +0099 eqns=regexprep(eqns,'> $','>'); +0100 grRules=regexprep(model.grRules,'\((?!\()','( '); +0101 grRules=regexprep(grRules,'(?<!\))\)',' )'); +0102 else +0103 eqns=constructEquations(model,model.rxns); +0104 grRules=model.grRules; +0105 end +0106 fprintf(fid, 'Rxn name\tFormula\tGene-reaction association\tLB\tUB\tObjective\n'); +0107 for i = 1:numel(model.rxns) +0108 fprintf(fid, '%s\t', model.rxns{i}); +0109 fprintf(fid, '%s \t', eqns{i}); +0110 fprintf(fid, '%s\t', grRules{i}); +0111 fprintf(fid, '%6.2f\t%6.2f\t%6.2f\n', model.lb(i), model.ub(i), model.c(i)); +0112 end +0113 fclose(fid); +0114 end +0115 +0116 % Write YML format +0117 if ismember('yml', formats) +0118 writeYAMLmodel(model,fullfile(filePath{2},strcat(prefix,'.yml'))); +0119 end +0120 +0121 % Write MAT format +0122 if ismember('mat', formats) +0123 save(fullfile(filePath{3},strcat(prefix,'.mat')),'model'); +0124 end +0125 +0126 % Write XLSX format +0127 if ismember('xlsx', formats) +0128 exportToExcelFormat(model,fullfile(filePath{4},strcat(prefix,'.xlsx'))); +0129 end +0130 +0131 % Write XML format +0132 if ismember('xml', formats) +0133 exportModel(model,fullfile(filePath{5},strcat(prefix,'.xml'))); +0134 end +0135 +0136 %Save file with versions: +0137 fid = fopen(fullfile(path,'dependencies.txt'),'wt'); +0138 fprintf(fid,['MATLAB\t' version '\n']); +0139 fprintf(fid,['libSBML\t' libSBMLver '\n']); +0140 fprintf(fid,['RAVEN_toolbox\t' RAVENver '\n']); +0141 if ~isempty(COBRAver) +0142 fprintf(fid,['COBRA_toolbox\t' COBRAver '\n']); +0143 end +0144 if isfield(model,'modelVersion') +0145 fields = fieldnames(model.modelVersion); +0146 for i = 1:length(fields) +0147 value = model.modelVersion.(fields{i}); +0148 fprintf(fid,[fields{i} '\t' num2str(value) '\n']); +0149 end +0150 end +0151 fclose(fid); +0152 end
Generated by m2html © 2005
\ No newline at end of file diff --git a/doc/io/exportModel.html b/doc/io/exportModel.html index 20f66f8e..8e175fff 100644 --- a/doc/io/exportModel.html +++ b/doc/io/exportModel.html @@ -221,662 +221,656 @@

SOURCE CODE ^'<notes><body xmlns="http://www.w3.org/1999/xhtml"><p>This file was generated using the exportModel function in RAVEN Toolbox 2 and OutputSBML in libSBML </p></body></notes>'; 0160 end 0161 -0162 modelSBML.annotation=['<annotation><rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:vCard="http://www.w3.org/2001/vcard-rdf/3.0#" xmlns:bqbiol="http://biomodels.net/biology-qualifiers/" xmlns:bqmodel="http://biomodels.net/model-qualifiers/"><rdf:Description rdf:about="#meta_' model.id '">']; -0163 if isfield(model,'annotation') -0164 nameString=''; -0165 if isfield(model.annotation,'familyName') -0166 if ~isempty(model.annotation.familyName) -0167 nameString=['<vCard:Family>' model.annotation.familyName '</vCard:Family>']; -0168 end -0169 end -0170 if isfield(model.annotation,'givenName') -0171 if ~isempty(model.annotation.givenName) -0172 nameString=[nameString '<vCard:Given>' model.annotation.givenName '</vCard:Given>']; -0173 end -0174 end -0175 email=''; -0176 if isfield(model.annotation,'email') -0177 if ~isempty(model.annotation.email) -0178 email=['<vCard:EMAIL>' model.annotation.email '</vCard:EMAIL>']; -0179 end -0180 end -0181 org=''; -0182 if isfield(model.annotation,'organization') -0183 if ~isempty(model.annotation.organization) -0184 org=['<vCard:ORG rdf:parseType="Resource"><vCard:Orgname>' model.annotation.organization '</vCard:Orgname></vCard:ORG>']; -0185 end -0186 end -0187 if ~isempty(nameString) || ~isempty(email) || ~isempty(org) +0162 if isfield(model,'annotation') +0163 nameString=''; +0164 if isfield(model.annotation,'familyName') +0165 if ~isempty(model.annotation.familyName) +0166 nameString=['<vCard:Family>' model.annotation.familyName '</vCard:Family>']; +0167 end +0168 end +0169 if isfield(model.annotation,'givenName') +0170 if ~isempty(model.annotation.givenName) +0171 nameString=[nameString '<vCard:Given>' model.annotation.givenName '</vCard:Given>']; +0172 end +0173 end +0174 email=''; +0175 if isfield(model.annotation,'email') +0176 if ~isempty(model.annotation.email) +0177 email=['<vCard:EMAIL>' model.annotation.email '</vCard:EMAIL>']; +0178 end +0179 end +0180 org=''; +0181 if isfield(model.annotation,'organization') +0182 if ~isempty(model.annotation.organization) +0183 org=['<vCard:ORG rdf:parseType="Resource"><vCard:Orgname>' model.annotation.organization '</vCard:Orgname></vCard:ORG>']; +0184 end +0185 end +0186 if ~isempty(nameString) || ~isempty(email) || ~isempty(org) % Only fill .annotation if ownership data is provided +0187 modelSBML.annotation=['<annotation><rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:vCard="http://www.w3.org/2001/vcard-rdf/3.0#" xmlns:bqbiol="http://biomodels.net/biology-qualifiers/" xmlns:bqmodel="http://biomodels.net/model-qualifiers/"><rdf:Description rdf:about="#meta_' model.id '">']; 0188 modelSBML.annotation=[modelSBML.annotation '<dc:creator><rdf:Bag><rdf:li rdf:parseType="Resource">']; 0189 if ~isempty(nameString) 0190 modelSBML.annotation=[modelSBML.annotation '<vCard:N rdf:parseType="Resource">' nameString '</vCard:N>']; 0191 end 0192 modelSBML.annotation=[modelSBML.annotation email org '</rdf:li></rdf:Bag></dc:creator>']; -0193 end -0194 end -0195 modelSBML.annotation=[modelSBML.annotation '<dcterms:created rdf:parseType="Resource">'... -0196 '<dcterms:W3CDTF>' datestr(now,'yyyy-mm-ddTHH:MM:SSZ') '</dcterms:W3CDTF>'... -0197 '</dcterms:created>'... -0198 '<dcterms:modified rdf:parseType="Resource">'... -0199 '<dcterms:W3CDTF>' datestr(now,'yyyy-mm-ddTHH:MM:SSZ') '</dcterms:W3CDTF>'... -0200 '</dcterms:modified>']; -0201 -0202 if isfield(model,'annotation') -0203 if isfield(model.annotation,'taxonomy') -0204 modelSBML.annotation=[modelSBML.annotation '<bqbiol:is><rdf:Bag><rdf:li rdf:resource="https://identifiers.org/taxonomy/' regexprep(model.annotation.taxonomy,'taxonomy/','') '"/></rdf:Bag></bqbiol:is>']; -0205 end -0206 end -0207 modelSBML.annotation=[modelSBML.annotation '</rdf:Description></rdf:RDF></annotation>']; -0208 -0209 %Prepare compartments -0210 for i=1:numel(model.comps) -0211 %Add the default values, as these will be the same in all entries -0212 if i==1 -0213 if isfield(modelSBML.compartment, 'sboTerm') -0214 modelSBML.compartment(i).sboTerm=290; +0193 modelSBML.annotation=[modelSBML.annotation '<dcterms:created rdf:parseType="Resource">'... +0194 '<dcterms:W3CDTF>' datestr(now,'yyyy-mm-ddTHH:MM:SSZ') '</dcterms:W3CDTF></dcterms:created><dcterms:modified rdf:parseType="Resource">'... +0195 '<dcterms:W3CDTF>' datestr(now,'yyyy-mm-ddTHH:MM:SSZ') '</dcterms:W3CDTF></dcterms:modified>']; +0196 if isfield(model.annotation,'taxonomy') +0197 modelSBML.annotation=[modelSBML.annotation '<bqbiol:is><rdf:Bag><rdf:li rdf:resource="https://identifiers.org/taxonomy/' regexprep(model.annotation.taxonomy,'taxonomy/','') '"/></rdf:Bag></bqbiol:is>']; +0198 end +0199 modelSBML.annotation=[modelSBML.annotation '</rdf:Description></rdf:RDF></annotation>']; +0200 end +0201 end +0202 +0203 %Prepare compartments +0204 for i=1:numel(model.comps) +0205 %Add the default values, as these will be the same in all entries +0206 if i==1 +0207 if isfield(modelSBML.compartment, 'sboTerm') +0208 modelSBML.compartment(i).sboTerm=290; +0209 end +0210 if isfield(modelSBML.compartment, 'spatialDimensions') +0211 modelSBML.compartment(i).spatialDimensions=3; +0212 end +0213 if isfield(modelSBML.compartment, 'size') +0214 modelSBML.compartment(i).size=1; 0215 end -0216 if isfield(modelSBML.compartment, 'spatialDimensions') -0217 modelSBML.compartment(i).spatialDimensions=3; +0216 if isfield(modelSBML.compartment, 'constant') +0217 modelSBML.compartment(i).constant=1; 0218 end -0219 if isfield(modelSBML.compartment, 'size') -0220 modelSBML.compartment(i).size=1; +0219 if isfield(modelSBML.compartment, 'isSetSize') +0220 modelSBML.compartment(i).isSetSize=1; 0221 end -0222 if isfield(modelSBML.compartment, 'constant') -0223 modelSBML.compartment(i).constant=1; +0222 if isfield(modelSBML.compartment, 'isSetSpatialDimensions') +0223 modelSBML.compartment(i).isSetSpatialDimensions=1; 0224 end -0225 if isfield(modelSBML.compartment, 'isSetSize') -0226 modelSBML.compartment(i).isSetSize=1; -0227 end -0228 if isfield(modelSBML.compartment, 'isSetSpatialDimensions') -0229 modelSBML.compartment(i).isSetSpatialDimensions=1; -0230 end -0231 end -0232 %Copy the default values to the next entry as long as it is not the -0233 %last one -0234 if i<numel(model.comps) -0235 modelSBML.compartment(i+1)=modelSBML.compartment(i); -0236 end -0237 -0238 if isfield(modelSBML.compartment,'metaid') -0239 if regexp(model.comps{i},'^[^a-zA-Z_]') -0240 EM='The compartment IDs are in numeric format. For the compliance with SBML specifications, compartment IDs will be preceded with "c_" string'; -0241 dispEM(EM,false); -0242 model.comps(i)=strcat('c_',model.comps(i)); -0243 end -0244 modelSBML.compartment(i).metaid=model.comps{i}; -0245 end -0246 %Prepare Miriam strings -0247 if ~isempty(model.compMiriams{i}) -0248 [~,sbo_ind] = ismember('sbo',model.compMiriams{i}.name); -0249 if sbo_ind > 0 -0250 modelSBML.compartment(i).sboTerm=str2double(regexprep(model.compMiriams{i}.value{sbo_ind},'SBO:','','ignorecase')); -0251 % remove the SBO term from compMiriams so the information is -0252 % not duplicated in the "annotation" field later on -0253 model.compMiriams{i}.name(sbo_ind) = []; -0254 model.compMiriams{i}.value(sbo_ind) = []; -0255 end -0256 end -0257 if ~isempty(model.compMiriams{i}) && isfield(modelSBML.compartment(i),'annotation') -0258 modelSBML.compartment(i).annotation=['<annotation><rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:vCard="http://www.w3.org/2001/vcard-rdf/3.0#" xmlns:bqbiol="http://biomodels.net/biology-qualifiers/" xmlns:bqmodel="http://biomodels.net/model-qualifiers/"><rdf:Description rdf:about="#meta_' model.comps{i} '">']; -0259 modelSBML.compartment(i).annotation=[modelSBML.compartment(i).annotation '<bqbiol:is><rdf:Bag>']; -0260 modelSBML.compartment(i).annotation=[modelSBML.compartment(i).annotation getMiriam(model.compMiriams{i}) '</rdf:Bag></bqbiol:is></rdf:Description></rdf:RDF></annotation>']; +0225 end +0226 %Copy the default values to the next entry as long as it is not the +0227 %last one +0228 if i<numel(model.comps) +0229 modelSBML.compartment(i+1)=modelSBML.compartment(i); +0230 end +0231 +0232 if isfield(modelSBML.compartment,'metaid') +0233 if regexp(model.comps{i},'^[^a-zA-Z_]') +0234 EM='The compartment IDs are in numeric format. For the compliance with SBML specifications, compartment IDs will be preceded with "c_" string'; +0235 dispEM(EM,false); +0236 model.comps(i)=strcat('c_',model.comps(i)); +0237 end +0238 modelSBML.compartment(i).metaid=model.comps{i}; +0239 end +0240 %Prepare Miriam strings +0241 if ~isempty(model.compMiriams{i}) +0242 [~,sbo_ind] = ismember('sbo',model.compMiriams{i}.name); +0243 if sbo_ind > 0 +0244 modelSBML.compartment(i).sboTerm=str2double(regexprep(model.compMiriams{i}.value{sbo_ind},'SBO:','','ignorecase')); +0245 % remove the SBO term from compMiriams so the information is +0246 % not duplicated in the "annotation" field later on +0247 model.compMiriams{i}.name(sbo_ind) = []; +0248 model.compMiriams{i}.value(sbo_ind) = []; +0249 end +0250 end +0251 if ~isempty(model.compMiriams{i}) && isfield(modelSBML.compartment(i),'annotation') +0252 modelSBML.compartment(i).annotation=['<annotation><rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:vCard="http://www.w3.org/2001/vcard-rdf/3.0#" xmlns:bqbiol="http://biomodels.net/biology-qualifiers/" xmlns:bqmodel="http://biomodels.net/model-qualifiers/"><rdf:Description rdf:about="#meta_' model.comps{i} '">']; +0253 modelSBML.compartment(i).annotation=[modelSBML.compartment(i).annotation '<bqbiol:is><rdf:Bag>']; +0254 modelSBML.compartment(i).annotation=[modelSBML.compartment(i).annotation getMiriam(model.compMiriams{i}) '</rdf:Bag></bqbiol:is></rdf:Description></rdf:RDF></annotation>']; +0255 end +0256 if isfield(modelSBML.compartment, 'name') +0257 modelSBML.compartment(i).name=model.compNames{i}; +0258 end +0259 if isfield(modelSBML.compartment, 'id') +0260 modelSBML.compartment(i).id=model.comps{i}; 0261 end -0262 if isfield(modelSBML.compartment, 'name') -0263 modelSBML.compartment(i).name=model.compNames{i}; -0264 end -0265 if isfield(modelSBML.compartment, 'id') -0266 modelSBML.compartment(i).id=model.comps{i}; -0267 end -0268 -0269 end -0270 -0271 %Begin writing species -0272 for i=1:numel(model.mets) -0273 %Add the default values, as these will be the same in all entries -0274 if i==1 -0275 if isfield(modelSBML.species, 'sboTerm') -0276 modelSBML.species(i).sboTerm=247; +0262 +0263 end +0264 +0265 %Begin writing species +0266 for i=1:numel(model.mets) +0267 %Add the default values, as these will be the same in all entries +0268 if i==1 +0269 if isfield(modelSBML.species, 'sboTerm') +0270 modelSBML.species(i).sboTerm=247; +0271 end +0272 if isfield(modelSBML.species, 'initialAmount') +0273 modelSBML.species(i).initialAmount=1; +0274 end +0275 if isfield(modelSBML.species, 'initialConcentration') +0276 modelSBML.species(i).initialConcentration=0; 0277 end -0278 if isfield(modelSBML.species, 'initialAmount') -0279 modelSBML.species(i).initialAmount=1; +0278 if isfield(modelSBML.species, 'isSetInitialAmount') +0279 modelSBML.species(i).isSetInitialAmount=1; 0280 end -0281 if isfield(modelSBML.species, 'initialConcentration') -0282 modelSBML.species(i).initialConcentration=0; +0281 if isfield(modelSBML.species, 'isSetInitialConcentration') +0282 modelSBML.species(i).isSetInitialConcentration=1; 0283 end -0284 if isfield(modelSBML.species, 'isSetInitialAmount') -0285 modelSBML.species(i).isSetInitialAmount=1; -0286 end -0287 if isfield(modelSBML.species, 'isSetInitialConcentration') -0288 modelSBML.species(i).isSetInitialConcentration=1; -0289 end -0290 end -0291 %Copy the default values to the next entry as long as it is not the -0292 %last one -0293 if i<numel(model.mets) -0294 modelSBML.species(i+1)=modelSBML.species(i); -0295 end -0296 -0297 if isfield(modelSBML.species,'metaid') -0298 modelSBML.species(i).metaid=['M_' model.mets{i}]; +0284 end +0285 %Copy the default values to the next entry as long as it is not the +0286 %last one +0287 if i<numel(model.mets) +0288 modelSBML.species(i+1)=modelSBML.species(i); +0289 end +0290 +0291 if isfield(modelSBML.species,'metaid') +0292 modelSBML.species(i).metaid=['M_' model.mets{i}]; +0293 end +0294 if isfield(modelSBML.species, 'name') +0295 modelSBML.species(i).name=model.metNames{i}; +0296 end +0297 if isfield(modelSBML.species, 'id') +0298 modelSBML.species(i).id=['M_' model.mets{i}]; 0299 end -0300 if isfield(modelSBML.species, 'name') -0301 modelSBML.species(i).name=model.metNames{i}; +0300 if isfield(modelSBML.species, 'compartment') +0301 modelSBML.species(i).compartment=model.comps{model.metComps(i)}; 0302 end -0303 if isfield(modelSBML.species, 'id') -0304 modelSBML.species(i).id=['M_' model.mets{i}]; -0305 end -0306 if isfield(modelSBML.species, 'compartment') -0307 modelSBML.species(i).compartment=model.comps{model.metComps(i)}; -0308 end -0309 if isfield(model,'unconstrained') -0310 if model.unconstrained(i) -0311 modelSBML.species(i).boundaryCondition=1; -0312 end -0313 end -0314 if isfield(modelSBML.species, 'fbc_charge') && isfield(model,'metCharges') -0315 if ~isnan(model.metCharges(i)) -0316 modelSBML.species(i).fbc_charge=model.metCharges(i); -0317 modelSBML.species(i).isSetfbc_charge=1; -0318 else -0319 modelSBML.species(i).isSetfbc_charge=0; -0320 end -0321 end -0322 if ~isempty(model.metMiriams{i}) -0323 [~,sbo_ind] = ismember('sbo',model.metMiriams{i}.name); -0324 if sbo_ind > 0 -0325 modelSBML.species(i).sboTerm=str2double(regexprep(model.metMiriams{i}.value{sbo_ind},'SBO:','','ignorecase')); -0326 % remove the SBO term from metMiriams so the information is -0327 % not duplicated in the "annotation" field later on -0328 model.metMiriams{i}.name(sbo_ind) = []; -0329 model.metMiriams{i}.value(sbo_ind) = []; -0330 end -0331 end -0332 if isfield(modelSBML.species,'annotation') -0333 if ~isempty(model.metMiriams{i}) || ~isempty(model.metFormulas{i}) -0334 hasInchi=false; -0335 if ~isempty(model.metFormulas{i}) -0336 %Only export formula if there is no InChI. This is because -0337 %the metFormulas field is populated by InChIs if available -0338 if ~isempty(model.inchis{i}) -0339 hasInchi=true; -0340 end -0341 if hasInchi==false -0342 modelSBML.species(i).fbc_chemicalFormula=model.metFormulas{i}; -0343 end -0344 end -0345 if ~isempty(model.metMiriams{i}) || hasInchi==true -0346 modelSBML.species(i).annotation=['<annotation><rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:vCard="http://www.w3.org/2001/vcard-rdf/3.0#" xmlns:bqbiol="http://biomodels.net/biology-qualifiers/" xmlns:bqmodel="http://biomodels.net/model-qualifiers/"><rdf:Description rdf:about="#meta_M_' model.mets{i} '">']; -0347 modelSBML.species(i).annotation=[modelSBML.species(i).annotation '<bqbiol:is><rdf:Bag>']; -0348 if ~isempty(model.metMiriams{i}) -0349 modelSBML.species(i).annotation=[modelSBML.species(i).annotation getMiriam(model.metMiriams{i})]; -0350 end -0351 if hasInchi==true -0352 modelSBML.species(i).annotation=[modelSBML.species(i).annotation '<rdf:li rdf:resource="https://identifiers.org/inchi/InChI=' regexprep(model.inchis{i},'^InChI=','') '"/>']; -0353 modelSBML.species(i).fbc_chemicalFormula=char(regexp(model.inchis{i}, '/(\w+)/', 'tokens', 'once')); -0354 end -0355 modelSBML.species(i).annotation=[modelSBML.species(i).annotation '</rdf:Bag></bqbiol:is></rdf:Description></rdf:RDF></annotation>']; -0356 end -0357 end -0358 end -0359 end -0360 -0361 if isfield(model,'genes') -0362 for i=1:numel(model.genes) -0363 %Add the default values, as these will be the same in all entries -0364 if i==1 -0365 if isfield(modelSBML.fbc_geneProduct, 'sboTerm') -0366 modelSBML.fbc_geneProduct(i).sboTerm=243; -0367 end -0368 end -0369 %Copy the default values to the next index as long as it is not the -0370 %last one -0371 if i<numel(model.genes) -0372 modelSBML.fbc_geneProduct(i+1)=modelSBML.fbc_geneProduct(i); -0373 end -0374 -0375 if isfield(modelSBML.fbc_geneProduct,'metaid') -0376 modelSBML.fbc_geneProduct(i).metaid=model.genes{i}; -0377 end -0378 if ~isempty(model.geneMiriams{i}) -0379 [~,sbo_ind] = ismember('sbo',model.geneMiriams{i}.name); -0380 if sbo_ind > 0 -0381 modelSBML.fbc_geneProduct(i).sboTerm=str2double(regexprep(model.geneMiriams{i}.value{sbo_ind},'SBO:','','ignorecase')); -0382 % remove the SBO term from compMiriams so the information is -0383 % not duplicated in the "annotation" field later on -0384 model.geneMiriams{i}.name(sbo_ind) = []; -0385 model.geneMiriams{i}.value(sbo_ind) = []; -0386 end -0387 end -0388 if ~isempty(model.geneMiriams{i}) && isfield(modelSBML.fbc_geneProduct(i),'annotation') -0389 modelSBML.fbc_geneProduct(i).annotation=['<annotation><rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:vCard="http://www.w3.org/2001/vcard-rdf/3.0#" xmlns:bqbiol="http://biomodels.net/biology-qualifiers/" xmlns:bqmodel="http://biomodels.net/model-qualifiers/"><rdf:Description rdf:about="#meta_' model.genes{i} '">']; -0390 modelSBML.fbc_geneProduct(i).annotation=[modelSBML.fbc_geneProduct(i).annotation '<bqbiol:is><rdf:Bag>']; -0391 modelSBML.fbc_geneProduct(i).annotation=[modelSBML.fbc_geneProduct(i).annotation getMiriam(model.geneMiriams{i}) '</rdf:Bag></bqbiol:is></rdf:Description></rdf:RDF></annotation>']; -0392 end -0393 if isfield(modelSBML.fbc_geneProduct, 'fbc_id') -0394 modelSBML.fbc_geneProduct(i).fbc_id=model.genes{i}; -0395 end -0396 if isfield(modelSBML.fbc_geneProduct, 'fbc_label') && isfield(model,'geneShortNames') -0397 if isempty(model.geneShortNames{i}) -0398 modelSBML.fbc_geneProduct(i).fbc_label=model.genes{i}; -0399 else -0400 modelSBML.fbc_geneProduct(i).fbc_label=model.geneShortNames{i}; -0401 end -0402 end -0403 end -0404 if exportGeneComplexes==true -0405 %Also add the complexes as genes. This is done by splitting grRules -0406 %on "or" and adding the ones which contain several genes -0407 geneComplexes={}; -0408 if isfield(model,'grRules') -0409 %Only grRules which contain " and " can be complexes -0410 uniqueRules=unique(model.grRules); -0411 I=cellfun(@any,strfind(uniqueRules,' and ')); -0412 uniqueRules(~I)=[]; -0413 uniqueRules=strrep(uniqueRules,'(',''); -0414 uniqueRules=strrep(uniqueRules,')',''); -0415 uniqueRules=strrep(uniqueRules,' and ',':'); -0416 for i=1:numel(uniqueRules) -0417 genes=regexp(uniqueRules(i),' or ','split'); -0418 genes=genes{1}(:); -0419 %Check which ones are complexes -0420 I=cellfun(@any,strfind(genes,':')); -0421 geneComplexes=[geneComplexes;genes(I)]; -0422 end -0423 end -0424 geneComplexes=unique(geneComplexes); -0425 if ~isempty(geneComplexes) -0426 %Then add them as genes. There is a possiblity that a complex -0427 %A&B is added as separate from B&A. This is not really an issue -0428 %so this is not dealt with -0429 for i=1:numel(geneComplexes) -0430 modelSBML.fbc_geneProduct(numel(model.genes)+i)=modelSBML.fbc_geneProduct(1); -0431 if isfield(modelSBML.fbc_geneProduct,'metaid') -0432 modelSBML.fbc_geneProduct(numel(model.genes)+i).metaid=geneComplexes{i}; -0433 end -0434 if isfield(modelSBML.fbc_geneProduct,'fbc_id') -0435 modelSBML.fbc_geneProduct(numel(model.genes)+i).fbc_id=geneComplexes{i}; -0436 else -0437 modelSBML.fbc_geneProduct(i).fbc_label=modelSBML.fbc_geneProduct(i).fbc_id; -0438 end -0439 end -0440 end -0441 end -0442 end +0303 if isfield(model,'unconstrained') +0304 if model.unconstrained(i) +0305 modelSBML.species(i).boundaryCondition=1; +0306 end +0307 end +0308 if isfield(modelSBML.species, 'fbc_charge') && isfield(model,'metCharges') +0309 if ~isnan(model.metCharges(i)) +0310 modelSBML.species(i).fbc_charge=model.metCharges(i); +0311 modelSBML.species(i).isSetfbc_charge=1; +0312 else +0313 modelSBML.species(i).isSetfbc_charge=0; +0314 end +0315 end +0316 if ~isempty(model.metMiriams{i}) +0317 [~,sbo_ind] = ismember('sbo',model.metMiriams{i}.name); +0318 if sbo_ind > 0 +0319 modelSBML.species(i).sboTerm=str2double(regexprep(model.metMiriams{i}.value{sbo_ind},'SBO:','','ignorecase')); +0320 % remove the SBO term from metMiriams so the information is +0321 % not duplicated in the "annotation" field later on +0322 model.metMiriams{i}.name(sbo_ind) = []; +0323 model.metMiriams{i}.value(sbo_ind) = []; +0324 end +0325 end +0326 if isfield(modelSBML.species,'annotation') +0327 if ~isempty(model.metMiriams{i}) || ~isempty(model.metFormulas{i}) +0328 hasInchi=false; +0329 if ~isempty(model.metFormulas{i}) +0330 %Only export formula if there is no InChI. This is because +0331 %the metFormulas field is populated by InChIs if available +0332 if ~isempty(model.inchis{i}) +0333 hasInchi=true; +0334 end +0335 if hasInchi==false +0336 modelSBML.species(i).fbc_chemicalFormula=model.metFormulas{i}; +0337 end +0338 end +0339 if ~isempty(model.metMiriams{i}) || hasInchi==true +0340 modelSBML.species(i).annotation=['<annotation><rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:vCard="http://www.w3.org/2001/vcard-rdf/3.0#" xmlns:bqbiol="http://biomodels.net/biology-qualifiers/" xmlns:bqmodel="http://biomodels.net/model-qualifiers/"><rdf:Description rdf:about="#meta_M_' model.mets{i} '">']; +0341 modelSBML.species(i).annotation=[modelSBML.species(i).annotation '<bqbiol:is><rdf:Bag>']; +0342 if ~isempty(model.metMiriams{i}) +0343 modelSBML.species(i).annotation=[modelSBML.species(i).annotation getMiriam(model.metMiriams{i})]; +0344 end +0345 if hasInchi==true +0346 modelSBML.species(i).annotation=[modelSBML.species(i).annotation '<rdf:li rdf:resource="https://identifiers.org/inchi/InChI=' regexprep(model.inchis{i},'^InChI=','') '"/>']; +0347 modelSBML.species(i).fbc_chemicalFormula=char(regexp(model.inchis{i}, '/(\w+)/', 'tokens', 'once')); +0348 end +0349 modelSBML.species(i).annotation=[modelSBML.species(i).annotation '</rdf:Bag></bqbiol:is></rdf:Description></rdf:RDF></annotation>']; +0350 end +0351 end +0352 end +0353 end +0354 +0355 if isfield(model,'genes') +0356 for i=1:numel(model.genes) +0357 %Add the default values, as these will be the same in all entries +0358 if i==1 +0359 if isfield(modelSBML.fbc_geneProduct, 'sboTerm') +0360 modelSBML.fbc_geneProduct(i).sboTerm=243; +0361 end +0362 end +0363 %Copy the default values to the next index as long as it is not the +0364 %last one +0365 if i<numel(model.genes) +0366 modelSBML.fbc_geneProduct(i+1)=modelSBML.fbc_geneProduct(i); +0367 end +0368 +0369 if isfield(modelSBML.fbc_geneProduct,'metaid') +0370 modelSBML.fbc_geneProduct(i).metaid=model.genes{i}; +0371 end +0372 if ~isempty(model.geneMiriams{i}) +0373 [~,sbo_ind] = ismember('sbo',model.geneMiriams{i}.name); +0374 if sbo_ind > 0 +0375 modelSBML.fbc_geneProduct(i).sboTerm=str2double(regexprep(model.geneMiriams{i}.value{sbo_ind},'SBO:','','ignorecase')); +0376 % remove the SBO term from compMiriams so the information is +0377 % not duplicated in the "annotation" field later on +0378 model.geneMiriams{i}.name(sbo_ind) = []; +0379 model.geneMiriams{i}.value(sbo_ind) = []; +0380 end +0381 end +0382 if ~isempty(model.geneMiriams{i}) && isfield(modelSBML.fbc_geneProduct(i),'annotation') +0383 modelSBML.fbc_geneProduct(i).annotation=['<annotation><rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:vCard="http://www.w3.org/2001/vcard-rdf/3.0#" xmlns:bqbiol="http://biomodels.net/biology-qualifiers/" xmlns:bqmodel="http://biomodels.net/model-qualifiers/"><rdf:Description rdf:about="#meta_' model.genes{i} '">']; +0384 modelSBML.fbc_geneProduct(i).annotation=[modelSBML.fbc_geneProduct(i).annotation '<bqbiol:is><rdf:Bag>']; +0385 modelSBML.fbc_geneProduct(i).annotation=[modelSBML.fbc_geneProduct(i).annotation getMiriam(model.geneMiriams{i}) '</rdf:Bag></bqbiol:is></rdf:Description></rdf:RDF></annotation>']; +0386 end +0387 if isfield(modelSBML.fbc_geneProduct, 'fbc_id') +0388 modelSBML.fbc_geneProduct(i).fbc_id=model.genes{i}; +0389 end +0390 if isfield(modelSBML.fbc_geneProduct, 'fbc_label') && isfield(model,'geneShortNames') +0391 if isempty(model.geneShortNames{i}) +0392 modelSBML.fbc_geneProduct(i).fbc_label=model.genes{i}; +0393 else +0394 modelSBML.fbc_geneProduct(i).fbc_label=model.geneShortNames{i}; +0395 end +0396 end +0397 end +0398 if exportGeneComplexes==true +0399 %Also add the complexes as genes. This is done by splitting grRules +0400 %on "or" and adding the ones which contain several genes +0401 geneComplexes={}; +0402 if isfield(model,'grRules') +0403 %Only grRules which contain " and " can be complexes +0404 uniqueRules=unique(model.grRules); +0405 I=cellfun(@any,strfind(uniqueRules,' and ')); +0406 uniqueRules(~I)=[]; +0407 uniqueRules=strrep(uniqueRules,'(',''); +0408 uniqueRules=strrep(uniqueRules,')',''); +0409 uniqueRules=strrep(uniqueRules,' and ',':'); +0410 for i=1:numel(uniqueRules) +0411 genes=regexp(uniqueRules(i),' or ','split'); +0412 genes=genes{1}(:); +0413 %Check which ones are complexes +0414 I=cellfun(@any,strfind(genes,':')); +0415 geneComplexes=[geneComplexes;genes(I)]; +0416 end +0417 end +0418 geneComplexes=unique(geneComplexes); +0419 if ~isempty(geneComplexes) +0420 %Then add them as genes. There is a possiblity that a complex +0421 %A&B is added as separate from B&A. This is not really an issue +0422 %so this is not dealt with +0423 for i=1:numel(geneComplexes) +0424 modelSBML.fbc_geneProduct(numel(model.genes)+i)=modelSBML.fbc_geneProduct(1); +0425 if isfield(modelSBML.fbc_geneProduct,'metaid') +0426 modelSBML.fbc_geneProduct(numel(model.genes)+i).metaid=geneComplexes{i}; +0427 end +0428 if isfield(modelSBML.fbc_geneProduct,'fbc_id') +0429 modelSBML.fbc_geneProduct(numel(model.genes)+i).fbc_id=geneComplexes{i}; +0430 else +0431 modelSBML.fbc_geneProduct(i).fbc_label=modelSBML.fbc_geneProduct(i).fbc_id; +0432 end +0433 end +0434 end +0435 end +0436 end +0437 +0438 %Generate a list of unique fbc_bound names +0439 totalValues=[model.lb; model.ub]; +0440 totalNames=cell(size(totalValues,1),1); +0441 +0442 listUniqueValues=unique(totalValues); 0443 -0444 %Generate a list of unique fbc_bound names -0445 totalValues=[model.lb; model.ub]; -0446 totalNames=cell(size(totalValues,1),1); -0447 -0448 listUniqueValues=unique(totalValues); +0444 for i=1:length(listUniqueValues) +0445 listUniqueNames{i,1}=['FB',num2str(i),'N',num2str(abs(round(listUniqueValues(i))))]; % create unique flux bound IDs. +0446 ind=find(ismember(totalValues,listUniqueValues(i))); +0447 totalNames(ind)=listUniqueNames(i,1); +0448 end 0449 -0450 for i=1:length(listUniqueValues) -0451 listUniqueNames{i,1}=['FB',num2str(i),'N',num2str(abs(round(listUniqueValues(i))))]; % create unique flux bound IDs. -0452 ind=find(ismember(totalValues,listUniqueValues(i))); -0453 totalNames(ind)=listUniqueNames(i,1); -0454 end -0455 -0456 for i=1:length(listUniqueNames) -0457 %Add the default values, as these will be the same in all entries -0458 if i==1 -0459 if isfield(modelSBML.parameter, 'constant') -0460 modelSBML.parameter(i).constant=1; -0461 end -0462 if isfield(modelSBML.parameter, 'isSetValue') -0463 modelSBML.parameter(i).isSetValue=1; -0464 end -0465 end -0466 %Copy the default values to the next index as long as it is not the -0467 %last one -0468 if i<numel(listUniqueNames) -0469 modelSBML.parameter(i+1)=modelSBML.parameter(i); -0470 end -0471 modelSBML.parameter(i).id=listUniqueNames{i}; -0472 modelSBML.parameter(i).value=listUniqueValues(i); -0473 end -0474 -0475 for i=1:numel(model.rxns) -0476 %Add the default values, as these will be the same in all entries -0477 if i==1 -0478 if isfield(modelSBML.reaction, 'sboTerm') -0479 modelSBML.reaction(i).sboTerm=176; -0480 end -0481 if isfield(modelSBML.reaction, 'isSetFast') -0482 modelSBML.reaction(i).isSetFast=1; -0483 end -0484 end -0485 %Copy the default values to the next index as long as it is not the -0486 %last one -0487 if i<numel(model.rxns) -0488 modelSBML.reaction(i+1)=modelSBML.reaction(i); -0489 end -0490 -0491 if isfield(modelSBML.reaction,'metaid') -0492 modelSBML.reaction(i).metaid=['R_' model.rxns{i}]; -0493 end -0494 -0495 %Export notes information -0496 if (~isnan(model.rxnConfidenceScores(i)) || ~isempty(model.rxnReferences{i}) || ~isempty(model.rxnNotes{i})) -0497 modelSBML.reaction(i).notes='<notes><body xmlns="http://www.w3.org/1999/xhtml">'; -0498 if ~isnan(model.rxnConfidenceScores(i)) -0499 modelSBML.reaction(i).notes=[modelSBML.reaction(i).notes '<p>Confidence Level: ' num2str(model.rxnConfidenceScores(i)) '</p>']; +0450 for i=1:length(listUniqueNames) +0451 %Add the default values, as these will be the same in all entries +0452 if i==1 +0453 if isfield(modelSBML.parameter, 'constant') +0454 modelSBML.parameter(i).constant=1; +0455 end +0456 if isfield(modelSBML.parameter, 'isSetValue') +0457 modelSBML.parameter(i).isSetValue=1; +0458 end +0459 end +0460 %Copy the default values to the next index as long as it is not the +0461 %last one +0462 if i<numel(listUniqueNames) +0463 modelSBML.parameter(i+1)=modelSBML.parameter(i); +0464 end +0465 modelSBML.parameter(i).id=listUniqueNames{i}; +0466 modelSBML.parameter(i).value=listUniqueValues(i); +0467 end +0468 +0469 for i=1:numel(model.rxns) +0470 %Add the default values, as these will be the same in all entries +0471 if i==1 +0472 if isfield(modelSBML.reaction, 'sboTerm') +0473 modelSBML.reaction(i).sboTerm=176; +0474 end +0475 if isfield(modelSBML.reaction, 'isSetFast') +0476 modelSBML.reaction(i).isSetFast=1; +0477 end +0478 end +0479 %Copy the default values to the next index as long as it is not the +0480 %last one +0481 if i<numel(model.rxns) +0482 modelSBML.reaction(i+1)=modelSBML.reaction(i); +0483 end +0484 +0485 if isfield(modelSBML.reaction,'metaid') +0486 modelSBML.reaction(i).metaid=['R_' model.rxns{i}]; +0487 end +0488 +0489 %Export notes information +0490 if (~isnan(model.rxnConfidenceScores(i)) || ~isempty(model.rxnReferences{i}) || ~isempty(model.rxnNotes{i})) +0491 modelSBML.reaction(i).notes='<notes><body xmlns="http://www.w3.org/1999/xhtml">'; +0492 if ~isnan(model.rxnConfidenceScores(i)) +0493 modelSBML.reaction(i).notes=[modelSBML.reaction(i).notes '<p>Confidence Level: ' num2str(model.rxnConfidenceScores(i)) '</p>']; +0494 end +0495 if ~isempty(model.rxnReferences{i}) +0496 modelSBML.reaction(i).notes=[modelSBML.reaction(i).notes '<p>AUTHORS: ' model.rxnReferences{i} '</p>']; +0497 end +0498 if ~isempty(model.rxnNotes{i}) +0499 modelSBML.reaction(i).notes=[modelSBML.reaction(i).notes '<p>NOTES: ' model.rxnNotes{i} '</p>']; 0500 end -0501 if ~isempty(model.rxnReferences{i}) -0502 modelSBML.reaction(i).notes=[modelSBML.reaction(i).notes '<p>AUTHORS: ' model.rxnReferences{i} '</p>']; -0503 end -0504 if ~isempty(model.rxnNotes{i}) -0505 modelSBML.reaction(i).notes=[modelSBML.reaction(i).notes '<p>NOTES: ' model.rxnNotes{i} '</p>']; -0506 end -0507 modelSBML.reaction(i).notes=[modelSBML.reaction(i).notes '</body></notes>']; -0508 end -0509 -0510 % Export SBO terms from rxnMiriams -0511 if ~isempty(model.rxnMiriams{i}) -0512 [~,sbo_ind] = ismember('sbo',model.rxnMiriams{i}.name); -0513 if sbo_ind > 0 -0514 modelSBML.reaction(i).sboTerm=str2double(regexprep(model.rxnMiriams{i}.value{sbo_ind},'SBO:','','ignorecase')); -0515 % remove the SBO term from rxnMiriams so the information is not -0516 % duplicated in the "annotation" field later on -0517 model.rxnMiriams{i}.name(sbo_ind) = []; -0518 model.rxnMiriams{i}.value(sbo_ind) = []; -0519 end -0520 end -0521 -0522 %Export annotation information from rxnMiriams -0523 if (~isempty(model.rxnMiriams{i}) && isfield(modelSBML.reaction(i),'annotation')) || ~isempty(model.eccodes{i}) -0524 modelSBML.reaction(i).annotation=['<annotation><rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:vCard="http://www.w3.org/2001/vcard-rdf/3.0#" xmlns:bqbiol="http://biomodels.net/biology-qualifiers/" xmlns:bqmodel="http://biomodels.net/model-qualifiers/"><rdf:Description rdf:about="#meta_R_' model.rxns{i} '">']; -0525 modelSBML.reaction(i).annotation=[modelSBML.reaction(i).annotation '<bqbiol:is><rdf:Bag>']; -0526 if ~isempty(model.eccodes{i}) -0527 eccodes=regexp(model.eccodes{i},';','split'); -0528 for j=1:numel(eccodes) -0529 modelSBML.reaction(i).annotation=[modelSBML.reaction(i).annotation '<rdf:li rdf:resource="https://identifiers.org/ec-code/' regexprep(eccodes{j},'ec-code/|EC','') '"/>']; -0530 end -0531 end -0532 modelSBML.reaction(i).annotation=[modelSBML.reaction(i).annotation getMiriam(model.rxnMiriams{i}) '</rdf:Bag></bqbiol:is></rdf:Description></rdf:RDF></annotation>']; -0533 end -0534 -0535 if isfield(modelSBML.reaction, 'name') -0536 modelSBML.reaction(i).name=model.rxnNames{i}; -0537 end -0538 if isfield(modelSBML.reaction, 'id') -0539 modelSBML.reaction(i).id=['R_' model.rxns{i}]; -0540 end -0541 -0542 %Add the information about reactants and products -0543 involvedMets=addReactantsProducts(model,modelSBML,i); -0544 for j=1:numel(involvedMets.reactant) -0545 if j<numel(involvedMets.reactant) -0546 modelSBML.reaction(i).reactant(j+1)=modelSBML.reaction(i).reactant(j); -0547 end -0548 modelSBML.reaction(i).reactant(j).species=involvedMets.reactant(j).species; -0549 modelSBML.reaction(i).reactant(j).stoichiometry=involvedMets.reactant(j).stoichiometry; -0550 modelSBML.reaction(i).reactant(j).isSetStoichiometry=involvedMets.reactant(j).isSetStoichiometry; -0551 modelSBML.reaction(i).reactant(j).constant=involvedMets.reactant(j).constant; -0552 end -0553 if numel(involvedMets.reactant)==0 -0554 modelSBML.reaction(i).reactant=''; -0555 end -0556 for j=1:numel(involvedMets.product) -0557 if j<numel(involvedMets.product) -0558 modelSBML.reaction(i).product(j+1)=modelSBML.reaction(i).product(j); -0559 end -0560 modelSBML.reaction(i).product(j).species=involvedMets.product(j).species; -0561 modelSBML.reaction(i).product(j).stoichiometry=involvedMets.product(j).stoichiometry; -0562 modelSBML.reaction(i).product(j).isSetStoichiometry=involvedMets.product(j).isSetStoichiometry; -0563 modelSBML.reaction(i).product(j).constant=involvedMets.product(j).constant; -0564 end -0565 if numel(involvedMets.product)==0 -0566 modelSBML.reaction(i).product=''; -0567 end -0568 %Export reversibility information. Reactions are irreversible by -0569 %default -0570 if model.rev(i)==1 -0571 modelSBML.reaction(i).reversible=1; +0501 modelSBML.reaction(i).notes=[modelSBML.reaction(i).notes '</body></notes>']; +0502 end +0503 +0504 % Export SBO terms from rxnMiriams +0505 if ~isempty(model.rxnMiriams{i}) +0506 [~,sbo_ind] = ismember('sbo',model.rxnMiriams{i}.name); +0507 if sbo_ind > 0 +0508 modelSBML.reaction(i).sboTerm=str2double(regexprep(model.rxnMiriams{i}.value{sbo_ind},'SBO:','','ignorecase')); +0509 % remove the SBO term from rxnMiriams so the information is not +0510 % duplicated in the "annotation" field later on +0511 model.rxnMiriams{i}.name(sbo_ind) = []; +0512 model.rxnMiriams{i}.value(sbo_ind) = []; +0513 end +0514 end +0515 +0516 %Export annotation information from rxnMiriams +0517 if (~isempty(model.rxnMiriams{i}) && isfield(modelSBML.reaction(i),'annotation')) || ~isempty(model.eccodes{i}) +0518 modelSBML.reaction(i).annotation=['<annotation><rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:vCard="http://www.w3.org/2001/vcard-rdf/3.0#" xmlns:bqbiol="http://biomodels.net/biology-qualifiers/" xmlns:bqmodel="http://biomodels.net/model-qualifiers/"><rdf:Description rdf:about="#meta_R_' model.rxns{i} '">']; +0519 modelSBML.reaction(i).annotation=[modelSBML.reaction(i).annotation '<bqbiol:is><rdf:Bag>']; +0520 if ~isempty(model.eccodes{i}) +0521 eccodes=regexp(model.eccodes{i},';','split'); +0522 for j=1:numel(eccodes) +0523 modelSBML.reaction(i).annotation=[modelSBML.reaction(i).annotation '<rdf:li rdf:resource="https://identifiers.org/ec-code/' regexprep(eccodes{j},'ec-code/|EC','') '"/>']; +0524 end +0525 end +0526 modelSBML.reaction(i).annotation=[modelSBML.reaction(i).annotation getMiriam(model.rxnMiriams{i}) '</rdf:Bag></bqbiol:is></rdf:Description></rdf:RDF></annotation>']; +0527 end +0528 +0529 if isfield(modelSBML.reaction, 'name') +0530 modelSBML.reaction(i).name=model.rxnNames{i}; +0531 end +0532 if isfield(modelSBML.reaction, 'id') +0533 modelSBML.reaction(i).id=['R_' model.rxns{i}]; +0534 end +0535 +0536 %Add the information about reactants and products +0537 involvedMets=addReactantsProducts(model,modelSBML,i); +0538 for j=1:numel(involvedMets.reactant) +0539 if j<numel(involvedMets.reactant) +0540 modelSBML.reaction(i).reactant(j+1)=modelSBML.reaction(i).reactant(j); +0541 end +0542 modelSBML.reaction(i).reactant(j).species=involvedMets.reactant(j).species; +0543 modelSBML.reaction(i).reactant(j).stoichiometry=involvedMets.reactant(j).stoichiometry; +0544 modelSBML.reaction(i).reactant(j).isSetStoichiometry=involvedMets.reactant(j).isSetStoichiometry; +0545 modelSBML.reaction(i).reactant(j).constant=involvedMets.reactant(j).constant; +0546 end +0547 if numel(involvedMets.reactant)==0 +0548 modelSBML.reaction(i).reactant=''; +0549 end +0550 for j=1:numel(involvedMets.product) +0551 if j<numel(involvedMets.product) +0552 modelSBML.reaction(i).product(j+1)=modelSBML.reaction(i).product(j); +0553 end +0554 modelSBML.reaction(i).product(j).species=involvedMets.product(j).species; +0555 modelSBML.reaction(i).product(j).stoichiometry=involvedMets.product(j).stoichiometry; +0556 modelSBML.reaction(i).product(j).isSetStoichiometry=involvedMets.product(j).isSetStoichiometry; +0557 modelSBML.reaction(i).product(j).constant=involvedMets.product(j).constant; +0558 end +0559 if numel(involvedMets.product)==0 +0560 modelSBML.reaction(i).product=''; +0561 end +0562 %Export reversibility information. Reactions are irreversible by +0563 %default +0564 if model.rev(i)==1 +0565 modelSBML.reaction(i).reversible=1; +0566 end +0567 if isfield(model, 'rxnComps') +0568 modelSBML.reaction(i).compartment=model.comps{model.rxnComps(i)}; +0569 end +0570 if isfield(model, 'grRules') +0571 modelSBML.reaction(i).fbc_geneProductAssociation.fbc_association.fbc_association=model.grRules{i}; 0572 end -0573 if isfield(model, 'rxnComps') -0574 modelSBML.reaction(i).compartment=model.comps{model.rxnComps(i)}; -0575 end -0576 if isfield(model, 'grRules') -0577 modelSBML.reaction(i).fbc_geneProductAssociation.fbc_association.fbc_association=model.grRules{i}; -0578 end -0579 modelSBML.reaction(i).fbc_lowerFluxBound=totalNames{i}; -0580 modelSBML.reaction(i).fbc_upperFluxBound=totalNames{length(model.lb)+i}; -0581 end -0582 -0583 %Prepare subSystems Code taken from COBRA functions getModelSubSystems, -0584 %writeSBML, findRxnsFromSubSystem under GNU General Public License v3.0, -0585 %license file in readme/GPL.MD. Code modified for RAVEN -0586 if modelHasSubsystems -0587 modelSBML.groups_group.groups_kind = 'partonomy'; -0588 modelSBML.groups_group.sboTerm = 633; -0589 tmpStruct=modelSBML.groups_group; -0590 -0591 rxns=strcat('R_',model.rxns); -0592 if ~any(cellfun(@iscell,model.subSystems)) -0593 if ~any(~cellfun(@isempty,model.subSystems)) -0594 subSystems = {}; -0595 else -0596 subSystems = setdiff(model.subSystems,''); -0597 end -0598 else -0599 orderedSubs = cellfun(@(x) columnVector(x),model.subSystems,'UniformOUtput',false); -0600 subSystems = setdiff(vertcat(orderedSubs{:}),''); -0601 end -0602 if isempty(subSystems) -0603 subSystems = {}; -0604 end -0605 if ~isempty(subSystems) -0606 %Build the groups for the group package -0607 groupIDs = strcat('group',cellfun(@num2str, num2cell(1:length(subSystems)),'UniformOutput',false)); -0608 for i = 1:length(subSystems) -0609 cgroup = tmpStruct; -0610 if ~any(cellfun(@iscell,model.subSystems)) -0611 present = ismember(model.subSystems,subSystems{i}); -0612 else -0613 present = cellfun(@(x) any(ismember(x,subSystems{i})),model.subSystems); -0614 end -0615 groupMembers = rxns(present); -0616 for j = 1:numel(groupMembers) -0617 cMember = tmpStruct.groups_member; -0618 cMember.groups_idRef = groupMembers{j}; -0619 if j == 1 -0620 cgroup.groups_member = cMember; -0621 else -0622 cgroup.groups_member(j) = cMember; -0623 end -0624 end -0625 cgroup.groups_id = groupIDs{i}; -0626 cgroup.groups_name = subSystems{i}; -0627 if i == 1 -0628 modelSBML.groups_group = cgroup; -0629 else -0630 modelSBML.groups_group(i) = cgroup; -0631 end -0632 end -0633 end -0634 end -0635 -0636 %Prepare fbc_objective subfield -0637 -0638 modelSBML.fbc_objective.fbc_type='maximize'; -0639 modelSBML.fbc_objective.fbc_id='obj'; -0640 -0641 ind=find(model.c); -0642 -0643 if isempty(ind) -0644 modelSBML.fbc_objective.fbc_fluxObjective.fbc_coefficient=0; -0645 else -0646 for i=1:length(ind) -0647 %Copy the default values to the next index as long as it is not the -0648 %last one -0649 if i<numel(ind) -0650 modelSBML.reaction(i+1)=modelSBML.reaction(i); -0651 end -0652 values=model.c(model.c~=0); -0653 modelSBML.fbc_objective(i).fbc_fluxObjective.fbc_reaction=modelSBML.reaction(ind(i)).id; -0654 modelSBML.fbc_objective(i).fbc_fluxObjective.fbc_coefficient=values(i); -0655 modelSBML.fbc_objective(i).fbc_fluxObjective.isSetfbc_coefficient=1; -0656 end -0657 end -0658 -0659 modelSBML.fbc_activeObjective=modelSBML.fbc_objective.fbc_id; -0660 -0661 fbcStr=['http://www.sbml.org/sbml/level', num2str(sbmlLevel), '/version', num2str(sbmlVersion), '/fbc/version',num2str(sbmlPackageVersions(1))]; -0662 if modelHasSubsystems -0663 groupStr=['http://www.sbml.org/sbml/level', num2str(sbmlLevel), '/version', num2str(sbmlVersion), '/groups/version',num2str(sbmlPackageVersions(2))]; -0664 modelSBML.namespaces=struct('prefix',{'','fbc','groups'},... -0665 'uri',{['http://www.sbml.org/sbml/level', num2str(sbmlLevel), '/version', num2str(sbmlVersion), '/core'],... -0666 fbcStr,groupStr}); -0667 else -0668 modelSBML.namespaces=struct('prefix',{'','fbc'},... -0669 'uri',{['http://www.sbml.org/sbml/level', num2str(sbmlLevel), '/version', num2str(sbmlVersion), '/core'],... -0670 fbcStr}); -0671 end -0672 -0673 if sbmlPackageVersions(1) == 2 -0674 modelSBML.fbc_strict=1; -0675 end -0676 -0677 modelSBML.rule=[]; -0678 modelSBML.constraint=[]; -0679 -0680 [ravenDir,prevDir]=findRAVENroot(); -0681 fileName=checkFileExistence(fileName,1,true,false); -0682 cd(fullfile(ravenDir,'software','libSBML')); -0683 OutputSBML(modelSBML,fileName,1,0,[1,0]); -0684 cd(prevDir); -0685 end -0686 -0687 -0688 function modelSBML=getSBMLStructure(sbmlLevel,sbmlVersion,sbmlPackages,sbmlPackageVersions) -0689 %Returns the blank SBML model structure by using appropriate libSBML -0690 %functions. This creates structure by considering three levels -0691 -0692 sbmlFieldNames=getStructureFieldnames('model',sbmlLevel,sbmlVersion,sbmlPackages,sbmlPackageVersions); -0693 sbmlDefaultValues=getDefaultValues('model',sbmlLevel,sbmlVersion,sbmlPackages,sbmlPackageVersions); -0694 -0695 for i=1:numel(sbmlFieldNames) -0696 modelSBML.(sbmlFieldNames{1,i})=sbmlDefaultValues{1,i}; -0697 sbmlSubfieldNames=getStructureFieldnames(sbmlFieldNames{1,i},sbmlLevel,sbmlVersion,sbmlPackages,sbmlPackageVersions); -0698 sbmlSubfieldValues=getDefaultValues(sbmlFieldNames{1,i},sbmlLevel,sbmlVersion,sbmlPackages,sbmlPackageVersions); -0699 if ~strcmp(sbmlFieldNames{1,i},'event') && ~strcmp(sbmlFieldNames{1,i},'functionDefinition') && ~strcmp(sbmlFieldNames{1,i},'initialAssignment') -0700 for j=1:numel(sbmlSubfieldNames) -0701 modelSBML.(sbmlFieldNames{1,i}).(sbmlSubfieldNames{1,j})=sbmlSubfieldValues{1,j}; -0702 sbmlSubsubfieldNames=getStructureFieldnames(sbmlSubfieldNames{1,j},sbmlLevel,sbmlVersion,sbmlPackages,sbmlPackageVersions); -0703 sbmlSubsubfieldValues=getDefaultValues(sbmlSubfieldNames{1,j},sbmlLevel,sbmlVersion,sbmlPackages,sbmlPackageVersions); -0704 if ~strcmp(sbmlSubfieldNames{1,j},'modifier') && ~strcmp(sbmlSubfieldNames{1,j},'kineticLaw') -0705 for k=1:numel(sbmlSubsubfieldNames) -0706 %'compartment' and 'species' fields are not supposed to -0707 %have their standalone structures if they are subfields -0708 %or subsubfields -0709 if ~strcmp(sbmlSubfieldNames{1,j},'compartment') && ~strcmp(sbmlSubfieldNames{1,j},'species') -0710 modelSBML.(sbmlFieldNames{1,i}).(sbmlSubfieldNames{1,j}).(sbmlSubsubfieldNames{1,k})=sbmlSubsubfieldValues{1,k}; -0711 end -0712 %If it is fbc_association in the third level, we need -0713 %to establish the fourth level, since libSBML requires -0714 %it -0715 if strcmp(sbmlSubsubfieldNames{1,k},'fbc_association') -0716 fbc_associationFieldNames=getStructureFieldnames('fbc_association',sbmlLevel,sbmlVersion,sbmlPackages,sbmlPackageVersions); -0717 fbc_associationFieldValues=getDefaultValues('fbc_association',sbmlLevel,sbmlVersion,sbmlPackages,sbmlPackageVersions); -0718 for l=1:numel(fbc_associationFieldNames) -0719 modelSBML.(sbmlFieldNames{1,i}).(sbmlSubfieldNames{1,j}).(sbmlSubsubfieldNames{1,k}).(fbc_associationFieldNames{1,l})=fbc_associationFieldValues{1,l}; -0720 end -0721 end -0722 end -0723 end -0724 end -0725 end -0726 if ~isstruct(modelSBML.(sbmlFieldNames{1,i})) -0727 modelSBML.(sbmlFieldNames{1,i})=sbmlDefaultValues{1,i}; -0728 end -0729 end -0730 -0731 modelSBML.unitDefinition.id='mmol_per_gDW_per_hr'; -0732 -0733 unitFieldNames=getStructureFieldnames('unit',sbmlLevel,sbmlVersion,sbmlPackages,sbmlPackageVersions); -0734 unitDefaultValues=getDefaultValues('unit',sbmlLevel,sbmlVersion,sbmlPackages,sbmlPackageVersions); -0735 -0736 kinds={'mole','gram','second'}; -0737 exponents=[1 -1 -1]; -0738 scales=[-3 0 0]; -0739 multipliers=[1 1 1*60*60]; -0740 -0741 for i=1:numel(unitFieldNames) -0742 modelSBML.unitDefinition.unit(1).(unitFieldNames{1,i})=unitDefaultValues{1,i}; -0743 for j=1:3 -0744 modelSBML.unitDefinition.unit(j).(unitFieldNames{1,i})=unitDefaultValues{1,i}; -0745 if strcmp(unitFieldNames{1,i},'kind') -0746 modelSBML.unitDefinition.unit(j).(unitFieldNames{1,i})=kinds{j}; -0747 elseif strcmp(unitFieldNames{1,i},'exponent') -0748 modelSBML.unitDefinition.unit(j).(unitFieldNames{1,i})=exponents(j); -0749 elseif strcmp(unitFieldNames{1,i},'scale') -0750 modelSBML.unitDefinition.unit(j).(unitFieldNames{1,i})=scales(j); -0751 elseif strcmp(unitFieldNames{1,i},'multiplier') -0752 modelSBML.unitDefinition.unit(j).(unitFieldNames{1,i})=multipliers(j); -0753 end -0754 end -0755 end -0756 end +0573 modelSBML.reaction(i).fbc_lowerFluxBound=totalNames{i}; +0574 modelSBML.reaction(i).fbc_upperFluxBound=totalNames{length(model.lb)+i}; +0575 end +0576 +0577 %Prepare subSystems Code taken from COBRA functions getModelSubSystems, +0578 %writeSBML, findRxnsFromSubSystem under GNU General Public License v3.0, +0579 %license file in readme/GPL.MD. Code modified for RAVEN +0580 if modelHasSubsystems +0581 modelSBML.groups_group.groups_kind = 'partonomy'; +0582 modelSBML.groups_group.sboTerm = 633; +0583 tmpStruct=modelSBML.groups_group; +0584 +0585 rxns=strcat('R_',model.rxns); +0586 if ~any(cellfun(@iscell,model.subSystems)) +0587 if ~any(~cellfun(@isempty,model.subSystems)) +0588 subSystems = {}; +0589 else +0590 subSystems = setdiff(model.subSystems,''); +0591 end +0592 else +0593 orderedSubs = cellfun(@(x) columnVector(x),model.subSystems,'UniformOUtput',false); +0594 subSystems = setdiff(vertcat(orderedSubs{:}),''); +0595 end +0596 if isempty(subSystems) +0597 subSystems = {}; +0598 end +0599 if ~isempty(subSystems) +0600 %Build the groups for the group package +0601 groupIDs = strcat('group',cellfun(@num2str, num2cell(1:length(subSystems)),'UniformOutput',false)); +0602 for i = 1:length(subSystems) +0603 cgroup = tmpStruct; +0604 if ~any(cellfun(@iscell,model.subSystems)) +0605 present = ismember(model.subSystems,subSystems{i}); +0606 else +0607 present = cellfun(@(x) any(ismember(x,subSystems{i})),model.subSystems); +0608 end +0609 groupMembers = rxns(present); +0610 for j = 1:numel(groupMembers) +0611 cMember = tmpStruct.groups_member; +0612 cMember.groups_idRef = groupMembers{j}; +0613 if j == 1 +0614 cgroup.groups_member = cMember; +0615 else +0616 cgroup.groups_member(j) = cMember; +0617 end +0618 end +0619 cgroup.groups_id = groupIDs{i}; +0620 cgroup.groups_name = subSystems{i}; +0621 if i == 1 +0622 modelSBML.groups_group = cgroup; +0623 else +0624 modelSBML.groups_group(i) = cgroup; +0625 end +0626 end +0627 end +0628 end +0629 +0630 %Prepare fbc_objective subfield +0631 +0632 modelSBML.fbc_objective.fbc_type='maximize'; +0633 modelSBML.fbc_objective.fbc_id='obj'; +0634 +0635 ind=find(model.c); +0636 +0637 if isempty(ind) +0638 modelSBML.fbc_objective.fbc_fluxObjective.fbc_coefficient=0; +0639 else +0640 for i=1:length(ind) +0641 %Copy the default values to the next index as long as it is not the +0642 %last one +0643 if i<numel(ind) +0644 modelSBML.reaction(i+1)=modelSBML.reaction(i); +0645 end +0646 values=model.c(model.c~=0); +0647 modelSBML.fbc_objective(i).fbc_fluxObjective.fbc_reaction=modelSBML.reaction(ind(i)).id; +0648 modelSBML.fbc_objective(i).fbc_fluxObjective.fbc_coefficient=values(i); +0649 modelSBML.fbc_objective(i).fbc_fluxObjective.isSetfbc_coefficient=1; +0650 end +0651 end +0652 +0653 modelSBML.fbc_activeObjective=modelSBML.fbc_objective.fbc_id; +0654 +0655 fbcStr=['http://www.sbml.org/sbml/level', num2str(sbmlLevel), '/version', num2str(sbmlVersion), '/fbc/version',num2str(sbmlPackageVersions(1))]; +0656 if modelHasSubsystems +0657 groupStr=['http://www.sbml.org/sbml/level', num2str(sbmlLevel), '/version', num2str(sbmlVersion), '/groups/version',num2str(sbmlPackageVersions(2))]; +0658 modelSBML.namespaces=struct('prefix',{'','fbc','groups'},... +0659 'uri',{['http://www.sbml.org/sbml/level', num2str(sbmlLevel), '/version', num2str(sbmlVersion), '/core'],... +0660 fbcStr,groupStr}); +0661 else +0662 modelSBML.namespaces=struct('prefix',{'','fbc'},... +0663 'uri',{['http://www.sbml.org/sbml/level', num2str(sbmlLevel), '/version', num2str(sbmlVersion), '/core'],... +0664 fbcStr}); +0665 end +0666 +0667 if sbmlPackageVersions(1) == 2 +0668 modelSBML.fbc_strict=1; +0669 modelSBML.isSetfbc_strict = 1; +0670 end +0671 +0672 modelSBML.rule=[]; +0673 modelSBML.constraint=[]; +0674 +0675 [ravenDir,prevDir]=findRAVENroot(); +0676 fileName=checkFileExistence(fileName,1,true,false); +0677 +0678 OutputSBML_RAVEN(modelSBML,fileName,1,0,[1,0]); +0679 end +0680 +0681 +0682 function modelSBML=getSBMLStructure(sbmlLevel,sbmlVersion,sbmlPackages,sbmlPackageVersions) +0683 %Returns the blank SBML model structure by using appropriate libSBML +0684 %functions. This creates structure by considering three levels +0685 +0686 sbmlFieldNames=getStructureFieldnames('model',sbmlLevel,sbmlVersion,sbmlPackages,sbmlPackageVersions); +0687 sbmlDefaultValues=getDefaultValues('model',sbmlLevel,sbmlVersion,sbmlPackages,sbmlPackageVersions); +0688 +0689 for i=1:numel(sbmlFieldNames) +0690 modelSBML.(sbmlFieldNames{1,i})=sbmlDefaultValues{1,i}; +0691 sbmlSubfieldNames=getStructureFieldnames(sbmlFieldNames{1,i},sbmlLevel,sbmlVersion,sbmlPackages,sbmlPackageVersions); +0692 sbmlSubfieldValues=getDefaultValues(sbmlFieldNames{1,i},sbmlLevel,sbmlVersion,sbmlPackages,sbmlPackageVersions); +0693 if ~strcmp(sbmlFieldNames{1,i},'event') && ~strcmp(sbmlFieldNames{1,i},'functionDefinition') && ~strcmp(sbmlFieldNames{1,i},'initialAssignment') +0694 for j=1:numel(sbmlSubfieldNames) +0695 modelSBML.(sbmlFieldNames{1,i}).(sbmlSubfieldNames{1,j})=sbmlSubfieldValues{1,j}; +0696 sbmlSubsubfieldNames=getStructureFieldnames(sbmlSubfieldNames{1,j},sbmlLevel,sbmlVersion,sbmlPackages,sbmlPackageVersions); +0697 sbmlSubsubfieldValues=getDefaultValues(sbmlSubfieldNames{1,j},sbmlLevel,sbmlVersion,sbmlPackages,sbmlPackageVersions); +0698 if ~strcmp(sbmlSubfieldNames{1,j},'modifier') && ~strcmp(sbmlSubfieldNames{1,j},'kineticLaw') +0699 for k=1:numel(sbmlSubsubfieldNames) +0700 %'compartment' and 'species' fields are not supposed to +0701 %have their standalone structures if they are subfields +0702 %or subsubfields +0703 if ~strcmp(sbmlSubfieldNames{1,j},'compartment') && ~strcmp(sbmlSubfieldNames{1,j},'species') +0704 modelSBML.(sbmlFieldNames{1,i}).(sbmlSubfieldNames{1,j}).(sbmlSubsubfieldNames{1,k})=sbmlSubsubfieldValues{1,k}; +0705 end +0706 %If it is fbc_association in the third level, we need +0707 %to establish the fourth level, since libSBML requires +0708 %it +0709 if strcmp(sbmlSubsubfieldNames{1,k},'fbc_association') +0710 fbc_associationFieldNames=getStructureFieldnames('fbc_association',sbmlLevel,sbmlVersion,sbmlPackages,sbmlPackageVersions); +0711 fbc_associationFieldValues=getDefaultValues('fbc_association',sbmlLevel,sbmlVersion,sbmlPackages,sbmlPackageVersions); +0712 for l=1:numel(fbc_associationFieldNames) +0713 modelSBML.(sbmlFieldNames{1,i}).(sbmlSubfieldNames{1,j}).(sbmlSubsubfieldNames{1,k}).(fbc_associationFieldNames{1,l})=fbc_associationFieldValues{1,l}; +0714 end +0715 end +0716 end +0717 end +0718 end +0719 end +0720 if ~isstruct(modelSBML.(sbmlFieldNames{1,i})) +0721 modelSBML.(sbmlFieldNames{1,i})=sbmlDefaultValues{1,i}; +0722 end +0723 end +0724 +0725 modelSBML.unitDefinition.id='mmol_per_gDW_per_hr'; +0726 +0727 unitFieldNames=getStructureFieldnames('unit',sbmlLevel,sbmlVersion,sbmlPackages,sbmlPackageVersions); +0728 unitDefaultValues=getDefaultValues('unit',sbmlLevel,sbmlVersion,sbmlPackages,sbmlPackageVersions); +0729 +0730 kinds={'mole','gram','second'}; +0731 exponents=[1 -1 -1]; +0732 scales=[-3 0 0]; +0733 multipliers=[1 1 1*60*60]; +0734 +0735 for i=1:numel(unitFieldNames) +0736 modelSBML.unitDefinition.unit(1).(unitFieldNames{1,i})=unitDefaultValues{1,i}; +0737 for j=1:3 +0738 modelSBML.unitDefinition.unit(j).(unitFieldNames{1,i})=unitDefaultValues{1,i}; +0739 if strcmp(unitFieldNames{1,i},'kind') +0740 modelSBML.unitDefinition.unit(j).(unitFieldNames{1,i})=kinds{j}; +0741 elseif strcmp(unitFieldNames{1,i},'exponent') +0742 modelSBML.unitDefinition.unit(j).(unitFieldNames{1,i})=exponents(j); +0743 elseif strcmp(unitFieldNames{1,i},'scale') +0744 modelSBML.unitDefinition.unit(j).(unitFieldNames{1,i})=scales(j); +0745 elseif strcmp(unitFieldNames{1,i},'multiplier') +0746 modelSBML.unitDefinition.unit(j).(unitFieldNames{1,i})=multipliers(j); +0747 end +0748 end +0749 end +0750 end +0751 +0752 function miriamString=getMiriam(miriamStruct) +0753 %Returns a string with list elements for a miriam structure ('<rdf:li +0754 %rdf:resource="https://identifiers.org/go/GO:0005739"/>' for example). This +0755 %is just to speed up things since this is done many times during the +0756 %exporting 0757 -0758 function miriamString=getMiriam(miriamStruct) -0759 %Returns a string with list elements for a miriam structure ('<rdf:li -0760 %rdf:resource="https://identifiers.org/go/GO:0005739"/>' for example). This -0761 %is just to speed up things since this is done many times during the -0762 %exporting -0763 -0764 miriamString=''; -0765 if isfield(miriamStruct,'name') -0766 for i=1:numel(miriamStruct.name) -0767 miriamString=[miriamString '<rdf:li rdf:resource="https://identifiers.org/' miriamStruct.name{i} '/' miriamStruct.value{i} '"/>']; -0768 end -0769 end -0770 end -0771 -0772 function [tmp_Rxn]=addReactantsProducts(model,sbmlModel,i) -0773 %This function provides reactants and products for particular reaction. The -0774 %function was 'borrowed' from writeSBML in COBRA toolbox, lines 663-679 -0775 -0776 met_idx = find(model.S(:, i)); -0777 tmp_Rxn.product=[]; -0778 tmp_Rxn.reactant=[]; -0779 for j_met=1:size(met_idx,1) -0780 tmp_idx = met_idx(j_met,1); -0781 sbml_tmp_species_ref.species = sbmlModel.species(tmp_idx).id; -0782 met_stoich = model.S(tmp_idx, i); -0783 sbml_tmp_species_ref.stoichiometry = abs(met_stoich); -0784 sbml_tmp_species_ref.isSetStoichiometry=1; -0785 sbml_tmp_species_ref.constant=1; -0786 if (met_stoich > 0) -0787 tmp_Rxn.product = [ tmp_Rxn.product, sbml_tmp_species_ref ]; -0788 else -0789 tmp_Rxn.reactant = [ tmp_Rxn.reactant, sbml_tmp_species_ref]; -0790 end -0791 end -0792 end -0793 -0794 function vecT = columnVector(vec) -0795 % Code below taken from COBRA Toolbox under GNU General Public License v3.0 -0796 % license file in readme/GPL.MD. +0758 miriamString=''; +0759 if isfield(miriamStruct,'name') +0760 for i=1:numel(miriamStruct.name) +0761 miriamString=[miriamString '<rdf:li rdf:resource="https://identifiers.org/' miriamStruct.name{i} '/' miriamStruct.value{i} '"/>']; +0762 end +0763 end +0764 end +0765 +0766 function [tmp_Rxn]=addReactantsProducts(model,sbmlModel,i) +0767 %This function provides reactants and products for particular reaction. The +0768 %function was 'borrowed' from writeSBML in COBRA toolbox, lines 663-679 +0769 +0770 met_idx = find(model.S(:, i)); +0771 tmp_Rxn.product=[]; +0772 tmp_Rxn.reactant=[]; +0773 for j_met=1:size(met_idx,1) +0774 tmp_idx = met_idx(j_met,1); +0775 sbml_tmp_species_ref.species = sbmlModel.species(tmp_idx).id; +0776 met_stoich = model.S(tmp_idx, i); +0777 sbml_tmp_species_ref.stoichiometry = abs(met_stoich); +0778 sbml_tmp_species_ref.isSetStoichiometry=1; +0779 sbml_tmp_species_ref.constant=1; +0780 if (met_stoich > 0) +0781 tmp_Rxn.product = [ tmp_Rxn.product, sbml_tmp_species_ref ]; +0782 else +0783 tmp_Rxn.reactant = [ tmp_Rxn.reactant, sbml_tmp_species_ref]; +0784 end +0785 end +0786 end +0787 +0788 function vecT = columnVector(vec) +0789 % Code below taken from COBRA Toolbox under GNU General Public License v3.0 +0790 % license file in readme/GPL.MD. +0791 % +0792 % Converts a vector to a column vector +0793 % +0794 % USAGE: +0795 % +0796 % vecT = columnVector(vec) 0797 % -0798 % Converts a vector to a column vector -0799 % -0800 % USAGE: -0801 % -0802 % vecT = columnVector(vec) -0803 % -0804 % INPUT: -0805 % vec: a vector -0806 % -0807 % OUTPUT: -0808 % vecT: a column vector -0809 -0810 [n, m] = size(vec); -0811 -0812 if n < m -0813 vecT = vec'; -0814 else -0815 vecT = vec; -0816 end -0817 end +0798 % INPUT: +0799 % vec: a vector +0800 % +0801 % OUTPUT: +0802 % vecT: a column vector +0803 +0804 [n, m] = size(vec); +0805 +0806 if n < m +0807 vecT = vec'; +0808 else +0809 vecT = vec; +0810 end +0811 end
Generated by m2html © 2005
\ No newline at end of file diff --git a/doc/io/importModel.html b/doc/io/importModel.html index baf5515b..0d069812 100644 --- a/doc/io/importModel.html +++ b/doc/io/importModel.html @@ -235,1093 +235,1094 @@

SOURCE CODE ^%Load the model using libSBML 0130 [ravenDir,prevDir]=findRAVENroot(); 0131 fileName=checkFileExistence(fileName,1); -0132 cd(fullfile(ravenDir,'software','libSBML')); -0133 modelSBML = TranslateSBML(fileName,0,0,[1 1]); -0134 cd(prevDir); -0135 -0136 if isempty(modelSBML) -0137 EM='There is a problem with the SBML file. Try using the SBML Validator at http://sbml.org/Facilities/Validator'; -0138 dispEM(EM); -0139 end -0140 -0141 %Remove the preceding strings for reactions, compartments and -0142 %reactants/products in 'reaction' field. The strings for metabolites, genes -0143 %and complexes are not removed, as we will need them later to identify them -0144 %from 'species' field -0145 for i=1:numel(modelSBML.reaction) -0146 modelSBML.reaction(i).name=regexprep(modelSBML.reaction(i).name,'^R_',''); -0147 modelSBML.reaction(i).id=regexprep(modelSBML.reaction(i).id,'^R_',''); -0148 if isfield(modelSBML.reaction(i),'compartment') -0149 modelSBML.reaction(i).compartment=regexprep(modelSBML.reaction(i).compartment,'^C_',''); -0150 end -0151 for j=1:numel(modelSBML.reaction(i).reactant) -0152 modelSBML.reaction(i).reactant(j).species=regexprep(modelSBML.reaction(i).reactant(j).species,'^M_',''); -0153 end -0154 for j=1:numel(modelSBML.reaction(i).product) -0155 modelSBML.reaction(i).product(j).species=regexprep(modelSBML.reaction(i).product(j).species,'^M_',''); -0156 end -0157 end -0158 -0159 %Retrieve compartment names and IDs -0160 compartmentNames=cell(numel(modelSBML.compartment),1); -0161 compartmentIDs=cell(numel(modelSBML.compartment),1); -0162 compartmentOutside=cell(numel(modelSBML.compartment),1); -0163 compartmentMiriams=cell(numel(modelSBML.compartment),1); -0164 -0165 if isfield(modelSBML.compartment,'sboTerm') && numel(unique([modelSBML.compartment.sboTerm])) == 1 -0166 %If all the SBO terms are identical, don't add them to compMiriams -0167 modelSBML.compartment = rmfield(modelSBML.compartment,'sboTerm'); -0168 end -0169 -0170 for i=1:numel(modelSBML.compartment) -0171 compartmentNames{i}=modelSBML.compartment(i).name; -0172 compartmentIDs{i}=regexprep(modelSBML.compartment(i).id,'^C_',''); -0173 if isfield(modelSBML.compartment(i),'outside') -0174 if ~isempty(modelSBML.compartment(i).outside) -0175 compartmentOutside{i}=regexprep(modelSBML.compartment(i).outside,'^C_',''); -0176 else -0177 compartmentOutside{i}=''; -0178 end -0179 else -0180 compartmentOutside{i}=[]; -0181 end -0182 -0183 if isfield(modelSBML.compartment(i),'annotation') -0184 compartmentMiriams{i}=parseMiriam(modelSBML.compartment(i).annotation); -0185 else -0186 compartmentMiriams{i}=[]; -0187 end -0188 -0189 if isfield(modelSBML.compartment(i),'sboTerm') && ~(modelSBML.compartment(i).sboTerm==-1) -0190 compartmentMiriams{i} = addSBOtoMiriam(compartmentMiriams{i},modelSBML.compartment(i).sboTerm); -0191 end -0192 end -0193 -0194 %If there are no compartment names then use compartment id as name -0195 if all(cellfun(@isempty,compartmentNames)) -0196 compartmentNames=compartmentIDs; -0197 end -0198 -0199 %Retrieve info on metabolites, genes, complexes -0200 metaboliteNames={}; -0201 metaboliteIDs={}; -0202 metaboliteCompartments={}; -0203 metaboliteUnconstrained=[]; -0204 metaboliteFormula={}; -0205 metaboliteInChI={}; -0206 metaboliteMiriams={}; -0207 metaboliteCharges=[]; -0208 -0209 geneNames={}; -0210 geneIDs={}; -0211 geneMiriams={}; -0212 geneShortNames={}; -0213 geneCompartments={}; -0214 complexIDs={}; -0215 complexNames={}; -0216 -0217 %If the file is not a COBRA Toolbox model. According to the format -0218 %specified in the yeast consensus model both metabolites and genes are a -0219 %type of 'species'. The metabolites have names starting with 'M_' and genes -0220 %with 'E_' -0221 geneSBOs = []; -0222 metSBOs = []; -0223 %Regex of compartment names, later to be used to remove from metabolite -0224 %names if present as suffix. -0225 regexCompNames = ['\s?\[((' strjoin({modelSBML.compartment.name},')|(') '))\]$']; -0226 for i=1:numel(modelSBML.species) -0227 if ~isSBML2COBRA -0228 if length(modelSBML.species(i).id)>=2 && strcmpi(modelSBML.species(i).id(1:2),'E_') -0229 geneNames{numel(geneNames)+1,1}=modelSBML.species(i).name; -0230 -0231 %The "E_" is included in the ID. This is because it's only used -0232 %internally in this file and it makes the matching a little -0233 %smoother -0234 geneIDs{numel(geneIDs)+1,1}=modelSBML.species(i).id; -0235 geneCompartments{numel(geneCompartments)+1,1}=regexprep(modelSBML.species(i).compartment,'^C_',''); -0236 -0237 %Get Miriam structure -0238 if isfield(modelSBML.species(i),'annotation') -0239 %Get Miriam info -0240 geneMiriam=parseMiriam(modelSBML.species(i).annotation); -0241 geneMiriams{numel(geneMiriams)+1,1}=geneMiriam; -0242 else -0243 geneMiriams{numel(geneMiriams)+1,1}=[]; -0244 end -0245 -0246 %Protein short names (for example ERG10) are saved as SHORT -0247 %NAME: NAME in the notes-section of metabolites for SBML Level -0248 %2 and as PROTEIN_ASSOCIATION for each reaction in SBML Level 2 -0249 %COBRA Toolbox format. For now only the SHORT NAME is loaded -0250 %and no mapping takes place -0251 if isfield(modelSBML.species(i),'notes') -0252 geneShortNames{numel(geneShortNames)+1,1}=parseNote(modelSBML.species(i).notes,'SHORT NAME'); -0253 else -0254 geneShortNames{numel(geneShortNames)+1,1}=''; -0255 end -0256 -0257 %Get SBO term -0258 if isfield(modelSBML.species(i),'sboTerm') && ~(modelSBML.species(i).sboTerm==-1) -0259 geneSBOs(end+1,1) = modelSBML.species(i).sboTerm; -0260 end -0261 elseif length(modelSBML.species(i).id)>=2 && strcmpi(modelSBML.species(i).id(1:3),'Cx_') -0262 %If it's a complex keep the ID and name -0263 complexIDs=[complexIDs;modelSBML.species(i).id]; -0264 complexNames=[complexNames;modelSBML.species(i).name]; -0265 else -0266 %If it is not gene or complex, then it must be a metabolite -0267 metaboliteNames{numel(metaboliteNames)+1,1}=modelSBML.species(i).name; -0268 metaboliteIDs{numel(metaboliteIDs)+1,1}=regexprep(modelSBML.species(i).id,'^M_',''); -0269 metaboliteCompartments{numel(metaboliteCompartments)+1,1}=regexprep(modelSBML.species(i).compartment,'^C_',''); -0270 metaboliteUnconstrained(numel(metaboliteUnconstrained)+1,1)=modelSBML.species(i).boundaryCondition; -0271 -0272 %For each metabolite retrieve the formula and the InChI code if -0273 %available First add the InChI code and the formula from the -0274 %InChI. This allows for overwriting the formula by setting the -0275 %actual formula field -0276 if ~isempty(modelSBML.species(i).annotation) -0277 %Get the formula if available -0278 startString='>InChI='; -0279 endString='</in:inchi>'; -0280 formStart=strfind(modelSBML.species(i).annotation,startString); -0281 if isempty(formStart) -0282 startString='InChI='; -0283 endString='"/>'; -0284 end -0285 formStart=strfind(modelSBML.species(i).annotation,startString); -0286 if ~isempty(formStart) -0287 formEnd=strfind(modelSBML.species(i).annotation,endString); -0288 formEndIndex=find(formEnd>formStart, 1 ); -0289 formula=modelSBML.species(i).annotation(formStart+numel(startString):formEnd(formEndIndex)-1); -0290 metaboliteInChI{numel(metaboliteInChI)+1,1}=formula; -0291 -0292 %The composition is most often present between the -0293 %first and second "/" in the model. In some simple -0294 %molecules, such as salts, there is no second "/". The -0295 %formula is then assumed to be to the end of the string -0296 compositionIndexes=strfind(formula,'/'); -0297 if numel(compositionIndexes)>1 -0298 metaboliteFormula{numel(metaboliteFormula)+1,1}=... -0299 formula(compositionIndexes(1)+1:compositionIndexes(2)-1); -0300 else -0301 if numel(compositionIndexes)==1 -0302 %Probably a simple molecule which can have only -0303 %one conformation -0304 metaboliteFormula{numel(metaboliteFormula)+1,1}=... -0305 formula(compositionIndexes(1)+1:numel(formula)); -0306 else -0307 metaboliteFormula{numel(metaboliteFormula)+1,1}=''; -0308 end -0309 end -0310 elseif isfield(modelSBML.species(i),'fbc_chemicalFormula') -0311 metaboliteInChI{numel(metaboliteInChI)+1,1}=''; -0312 if ~isempty(modelSBML.species(i).fbc_chemicalFormula) -0313 %Cannot extract InChi from formula, so remains -0314 %empty -0315 metaboliteFormula{numel(metaboliteFormula)+1,1}=modelSBML.species(i).fbc_chemicalFormula; -0316 else -0317 metaboliteFormula{numel(metaboliteFormula)+1,1}=''; -0318 end -0319 else -0320 metaboliteInChI{numel(metaboliteInChI)+1,1}=''; -0321 metaboliteFormula{numel(metaboliteFormula)+1,1}=''; -0322 end -0323 -0324 %Get Miriam info -0325 metMiriam=parseMiriam(modelSBML.species(i).annotation); -0326 metaboliteMiriams{numel(metaboliteMiriams)+1,1}=metMiriam; -0327 else -0328 metaboliteInChI{numel(metaboliteInChI)+1,1}=''; -0329 if isfield(modelSBML.species(i),'notes') -0330 metaboliteFormula{numel(metaboliteFormula)+1,1}=parseNote(modelSBML.species(i).notes,'FORMULA'); -0331 else -0332 metaboliteFormula{numel(metaboliteFormula)+1,1}=''; -0333 end -0334 metaboliteMiriams{numel(metaboliteMiriams)+1,1}=[]; -0335 end -0336 if ~isempty(modelSBML.species(i).notes) -0337 if ~isfield(modelSBML.species(i),'annotation') -0338 metaboliteFormula{numel(metaboliteFormula)+1,1}=parseNote(modelSBML.species(i).notes,'FORMULA'); -0339 end -0340 elseif ~isfield(modelSBML.species(i),'annotation') -0341 metaboliteFormula{numel(metaboliteFormula)+1,1}=''; -0342 end -0343 %Get SBO term -0344 if isfield(modelSBML.species(i),'sboTerm') && ~(modelSBML.species(i).sboTerm==-1) -0345 metSBOs(end+1,1) = modelSBML.species(i).sboTerm; -0346 end -0347 end -0348 -0349 elseif isSBML2COBRA -0350 %The metabolite names are assumed to be M_NAME_COMPOSITION or -0351 %_NAME_COMPOSITION or NAME_COMPOSITION or NAME. Regular expressions -0352 %are used that only NAME_COMPOSITION or NAME would be possible -0353 -0354 modelSBML.species(i).name=regexprep(modelSBML.species(i).name,'^M_',''); -0355 modelSBML.species(i).name=regexprep(modelSBML.species(i).name,'^_',''); -0356 underscoreIndex=strfind(modelSBML.species(i).name,'_'); +0132 modelSBML = TranslateSBML_RAVEN(fileName,0,0,[1 1]); +0133 +0134 if isempty(modelSBML) +0135 EM='There is a problem with the SBML file. Try using the SBML Validator at http://sbml.org/Facilities/Validator'; +0136 dispEM(EM); +0137 end +0138 +0139 %Remove the preceding strings for reactions, compartments and +0140 %reactants/products in 'reaction' field. The strings for metabolites, genes +0141 %and complexes are not removed, as we will need them later to identify them +0142 %from 'species' field +0143 for i=1:numel(modelSBML.reaction) +0144 modelSBML.reaction(i).name=regexprep(modelSBML.reaction(i).name,'^R_',''); +0145 modelSBML.reaction(i).id=regexprep(modelSBML.reaction(i).id,'^R_',''); +0146 if isfield(modelSBML.reaction(i),'compartment') +0147 modelSBML.reaction(i).compartment=regexprep(modelSBML.reaction(i).compartment,'^C_',''); +0148 end +0149 for j=1:numel(modelSBML.reaction(i).reactant) +0150 modelSBML.reaction(i).reactant(j).species=regexprep(modelSBML.reaction(i).reactant(j).species,'^M_',''); +0151 end +0152 for j=1:numel(modelSBML.reaction(i).product) +0153 modelSBML.reaction(i).product(j).species=regexprep(modelSBML.reaction(i).product(j).species,'^M_',''); +0154 end +0155 end +0156 +0157 %Retrieve compartment names and IDs +0158 compartmentNames=cell(numel(modelSBML.compartment),1); +0159 compartmentIDs=cell(numel(modelSBML.compartment),1); +0160 compartmentOutside=cell(numel(modelSBML.compartment),1); +0161 compartmentMiriams=cell(numel(modelSBML.compartment),1); +0162 +0163 if isfield(modelSBML.compartment,'sboTerm') && numel(unique([modelSBML.compartment.sboTerm])) == 1 +0164 %If all the SBO terms are identical, don't add them to compMiriams +0165 modelSBML.compartment = rmfield(modelSBML.compartment,'sboTerm'); +0166 end +0167 +0168 for i=1:numel(modelSBML.compartment) +0169 compartmentNames{i}=modelSBML.compartment(i).name; +0170 compartmentIDs{i}=regexprep(modelSBML.compartment(i).id,'^C_',''); +0171 if isfield(modelSBML.compartment(i),'outside') +0172 if ~isempty(modelSBML.compartment(i).outside) +0173 compartmentOutside{i}=regexprep(modelSBML.compartment(i).outside,'^C_',''); +0174 else +0175 compartmentOutside{i}=''; +0176 end +0177 else +0178 compartmentOutside{i}=[]; +0179 end +0180 +0181 if isfield(modelSBML.compartment(i),'annotation') +0182 compartmentMiriams{i}=parseMiriam(modelSBML.compartment(i).annotation); +0183 else +0184 compartmentMiriams{i}=[]; +0185 end +0186 +0187 if isfield(modelSBML.compartment(i),'sboTerm') && ~(modelSBML.compartment(i).sboTerm==-1) +0188 compartmentMiriams{i} = addSBOtoMiriam(compartmentMiriams{i},modelSBML.compartment(i).sboTerm); +0189 end +0190 end +0191 +0192 %If there are no compartment names then use compartment id as name +0193 if all(cellfun(@isempty,compartmentNames)) +0194 compartmentNames=compartmentIDs; +0195 end +0196 +0197 %Retrieve info on metabolites, genes, complexes +0198 metaboliteNames={}; +0199 metaboliteIDs={}; +0200 metaboliteCompartments={}; +0201 metaboliteUnconstrained=[]; +0202 metaboliteFormula={}; +0203 metaboliteInChI={}; +0204 metaboliteMiriams={}; +0205 metaboliteCharges=[]; +0206 +0207 geneNames={}; +0208 geneIDs={}; +0209 geneMiriams={}; +0210 geneShortNames={}; +0211 geneCompartments={}; +0212 complexIDs={}; +0213 complexNames={}; +0214 +0215 %If the file is not a COBRA Toolbox model. According to the format +0216 %specified in the yeast consensus model both metabolites and genes are a +0217 %type of 'species'. The metabolites have names starting with 'M_' and genes +0218 %with 'E_' +0219 geneSBOs = []; +0220 metSBOs = []; +0221 %Regex of compartment names, later to be used to remove from metabolite +0222 %names if present as suffix. +0223 regexCompNames = ['\s?\[((' strjoin({modelSBML.compartment.name},')|(') '))\]$']; +0224 for i=1:numel(modelSBML.species) +0225 if ~isSBML2COBRA +0226 if length(modelSBML.species(i).id)>=2 && strcmpi(modelSBML.species(i).id(1:2),'E_') +0227 geneNames{numel(geneNames)+1,1}=modelSBML.species(i).name; +0228 +0229 %The "E_" is included in the ID. This is because it's only used +0230 %internally in this file and it makes the matching a little +0231 %smoother +0232 geneIDs{numel(geneIDs)+1,1}=modelSBML.species(i).id; +0233 geneCompartments{numel(geneCompartments)+1,1}=regexprep(modelSBML.species(i).compartment,'^C_',''); +0234 +0235 %Get Miriam structure +0236 if isfield(modelSBML.species(i),'annotation') +0237 %Get Miriam info +0238 geneMiriam=parseMiriam(modelSBML.species(i).annotation); +0239 geneMiriams{numel(geneMiriams)+1,1}=geneMiriam; +0240 else +0241 geneMiriams{numel(geneMiriams)+1,1}=[]; +0242 end +0243 +0244 %Protein short names (for example ERG10) are saved as SHORT +0245 %NAME: NAME in the notes-section of metabolites for SBML Level +0246 %2 and as PROTEIN_ASSOCIATION for each reaction in SBML Level 2 +0247 %COBRA Toolbox format. For now only the SHORT NAME is loaded +0248 %and no mapping takes place +0249 if isfield(modelSBML.species(i),'notes') +0250 geneShortNames{numel(geneShortNames)+1,1}=parseNote(modelSBML.species(i).notes,'SHORT NAME'); +0251 else +0252 geneShortNames{numel(geneShortNames)+1,1}=''; +0253 end +0254 +0255 %Get SBO term +0256 if isfield(modelSBML.species(i),'sboTerm') && ~(modelSBML.species(i).sboTerm==-1) +0257 geneSBOs(end+1,1) = modelSBML.species(i).sboTerm; +0258 end +0259 elseif length(modelSBML.species(i).id)>=2 && strcmpi(modelSBML.species(i).id(1:3),'Cx_') +0260 %If it's a complex keep the ID and name +0261 complexIDs=[complexIDs;modelSBML.species(i).id]; +0262 complexNames=[complexNames;modelSBML.species(i).name]; +0263 else +0264 %If it is not gene or complex, then it must be a metabolite +0265 metaboliteNames{numel(metaboliteNames)+1,1}=modelSBML.species(i).name; +0266 metaboliteIDs{numel(metaboliteIDs)+1,1}=regexprep(modelSBML.species(i).id,'^M_',''); +0267 metaboliteCompartments{numel(metaboliteCompartments)+1,1}=regexprep(modelSBML.species(i).compartment,'^C_',''); +0268 metaboliteUnconstrained(numel(metaboliteUnconstrained)+1,1)=modelSBML.species(i).boundaryCondition; +0269 +0270 %For each metabolite retrieve the formula and the InChI code if +0271 %available First add the InChI code and the formula from the +0272 %InChI. This allows for overwriting the formula by setting the +0273 %actual formula field +0274 if ~isempty(modelSBML.species(i).annotation) +0275 %Get the formula if available +0276 startString='>InChI='; +0277 endString='</in:inchi>'; +0278 formStart=strfind(modelSBML.species(i).annotation,startString); +0279 if isempty(formStart) +0280 startString='InChI='; +0281 endString='"/>'; +0282 end +0283 formStart=strfind(modelSBML.species(i).annotation,startString); +0284 if ~isempty(formStart) +0285 formEnd=strfind(modelSBML.species(i).annotation,endString); +0286 formEndIndex=find(formEnd>formStart, 1 ); +0287 formula=modelSBML.species(i).annotation(formStart+numel(startString):formEnd(formEndIndex)-1); +0288 metaboliteInChI{numel(metaboliteInChI)+1,1}=formula; +0289 +0290 %The composition is most often present between the +0291 %first and second "/" in the model. In some simple +0292 %molecules, such as salts, there is no second "/". The +0293 %formula is then assumed to be to the end of the string +0294 compositionIndexes=strfind(formula,'/'); +0295 if numel(compositionIndexes)>1 +0296 metaboliteFormula{numel(metaboliteFormula)+1,1}=... +0297 formula(compositionIndexes(1)+1:compositionIndexes(2)-1); +0298 else +0299 if numel(compositionIndexes)==1 +0300 %Probably a simple molecule which can have only +0301 %one conformation +0302 metaboliteFormula{numel(metaboliteFormula)+1,1}=... +0303 formula(compositionIndexes(1)+1:numel(formula)); +0304 else +0305 metaboliteFormula{numel(metaboliteFormula)+1,1}=''; +0306 end +0307 end +0308 elseif isfield(modelSBML.species(i),'fbc_chemicalFormula') +0309 metaboliteInChI{numel(metaboliteInChI)+1,1}=''; +0310 if ~isempty(modelSBML.species(i).fbc_chemicalFormula) +0311 %Cannot extract InChi from formula, so remains +0312 %empty +0313 metaboliteFormula{numel(metaboliteFormula)+1,1}=modelSBML.species(i).fbc_chemicalFormula; +0314 else +0315 metaboliteFormula{numel(metaboliteFormula)+1,1}=''; +0316 end +0317 else +0318 metaboliteInChI{numel(metaboliteInChI)+1,1}=''; +0319 metaboliteFormula{numel(metaboliteFormula)+1,1}=''; +0320 end +0321 +0322 %Get Miriam info +0323 metMiriam=parseMiriam(modelSBML.species(i).annotation); +0324 metaboliteMiriams{numel(metaboliteMiriams)+1,1}=metMiriam; +0325 else +0326 metaboliteInChI{numel(metaboliteInChI)+1,1}=''; +0327 if isfield(modelSBML.species(i),'notes') +0328 metaboliteFormula{numel(metaboliteFormula)+1,1}=parseNote(modelSBML.species(i).notes,'FORMULA'); +0329 else +0330 metaboliteFormula{numel(metaboliteFormula)+1,1}=''; +0331 end +0332 metaboliteMiriams{numel(metaboliteMiriams)+1,1}=[]; +0333 end +0334 if ~isempty(modelSBML.species(i).notes) +0335 if ~isfield(modelSBML.species(i),'annotation') +0336 metaboliteFormula{numel(metaboliteFormula)+1,1}=parseNote(modelSBML.species(i).notes,'FORMULA'); +0337 end +0338 elseif ~isfield(modelSBML.species(i),'annotation') +0339 metaboliteFormula{numel(metaboliteFormula)+1,1}=''; +0340 end +0341 %Get SBO term +0342 if isfield(modelSBML.species(i),'sboTerm') && ~(modelSBML.species(i).sboTerm==-1) +0343 metSBOs(end+1,1) = modelSBML.species(i).sboTerm; +0344 end +0345 end +0346 +0347 elseif isSBML2COBRA +0348 %The metabolite names are assumed to be M_NAME_COMPOSITION or +0349 %_NAME_COMPOSITION or NAME_COMPOSITION or NAME. Regular expressions +0350 %are used that only NAME_COMPOSITION or NAME would be possible +0351 +0352 modelSBML.species(i).name=regexprep(modelSBML.species(i).name,'^M_',''); +0353 modelSBML.species(i).name=regexprep(modelSBML.species(i).name,'^_',''); +0354 underscoreIndex=strfind(modelSBML.species(i).name,'_'); +0355 +0356 metaboliteNames{numel(metaboliteNames)+1,1}=modelSBML.species(i).name; 0357 -0358 metaboliteNames{numel(metaboliteNames)+1,1}=modelSBML.species(i).name; -0359 -0360 metaboliteIDs{numel(metaboliteIDs)+1,1}=regexprep(modelSBML.species(i).id,'^M_',''); -0361 metaboliteCompartments{numel(metaboliteCompartments)+1,1}=regexprep(modelSBML.species(i).compartment,'^C_',''); -0362 -0363 %I think that COBRA doesn't set the boundary condition, but rather -0364 %uses name_b. Check for either -0365 metaboliteUnconstrained(numel(metaboliteUnconstrained)+1,1)=modelSBML.species(i).boundaryCondition; -0366 if strcmp(metaboliteIDs{end}(max(end-1,1):end),'_b') -0367 metaboliteUnconstrained(end)=1; -0368 end -0369 -0370 %Get the formula -0371 if max(underscoreIndex)<length(modelSBML.species(i).name) -0372 metaboliteFormula{numel(metaboliteFormula)+1,1}=modelSBML.species(i).name(max(underscoreIndex)+1:length(modelSBML.species(i).name)); -0373 else -0374 metaboliteFormula{numel(metaboliteFormula)+1,1}=''; -0375 end -0376 -0377 %The old COBRA version sometimes has composition information in the -0378 %notes instead -0379 if isfield(modelSBML.species(i),'notes') && ~isempty(parseNote(modelSBML.species(i).notes,'FORMULA')) -0380 metaboliteFormula{numel(metaboliteFormula)+1,1}=parseNote(modelSBML.species(i).notes,'FORMULA'); -0381 end -0382 -0383 %Get Miriam info -0384 if ~isempty(modelSBML.species(i).annotation) -0385 metMiriam=parseMiriam(modelSBML.species(i).annotation); -0386 else -0387 metMiriam=[]; -0388 end -0389 metaboliteMiriams{numel(metaboliteMiriams)+1,1}=metMiriam; -0390 -0391 %Get SBO term -0392 if isfield(modelSBML.species(i),'sboTerm') && ~(modelSBML.species(i).sboTerm==-1) -0393 metSBOs(end+1,1) = modelSBML.species(i).sboTerm; -0394 end -0395 end -0396 %The following lines are executed regardless isSBML2COBRA setting -0397 if isempty(modelSBML.species(i).id) || ~strcmpi(modelSBML.species(i).id(1:2),'E_') -0398 if isempty(modelSBML.species(i).id) || ~strcmpi(modelSBML.species(i).id(1:3),'Cx_') -0399 %Remove trailing [compartment] from metabolite name if present -0400 metaboliteNames{end,1}=regexprep(metaboliteNames{end,1},regexCompNames,''); -0401 metaboliteNames{end,1}=regexprep(metaboliteNames{end,1},'^M_',''); -0402 if isfield(modelSBML.species(i),'fbc_charge') -0403 if ~isempty(modelSBML.species(i).fbc_charge) && modelSBML.species(i).isSetfbc_charge -0404 metaboliteCharges(numel(metaboliteCharges)+1,1)=double(modelSBML.species(i).fbc_charge); -0405 else -0406 if isfield(modelSBML.species(i),'notes') -0407 if strfind(modelSBML.species(i).notes,'CHARGE') -0408 metaboliteCharges(numel(metaboliteCharges)+1,1)=str2double(parseNote(modelSBML.species(i).notes,'CHARGE')); -0409 else -0410 metaboliteCharges(numel(metaboliteCharges)+1,1)=NaN; -0411 end -0412 else -0413 metaboliteCharges(numel(metaboliteCharges)+1,1)=NaN; -0414 end -0415 end -0416 elseif isfield(modelSBML.species(i),'notes') -0417 if strfind(modelSBML.species(i).notes,'CHARGE') -0418 metaboliteCharges(numel(metaboliteCharges)+1,1)=str2double(parseNote(modelSBML.species(i).notes,'CHARGE')); -0419 else -0420 metaboliteCharges(numel(metaboliteCharges)+1,1)=NaN; -0421 end -0422 else -0423 metaboliteCharges(numel(metaboliteCharges)+1,1)=NaN; -0424 end -0425 %Additional information from FBC format Chemical formula -0426 if isfield(modelSBML.species(i),'fbc_chemicalFormula') -0427 if ~isempty(modelSBML.species(i).fbc_chemicalFormula) -0428 metaboliteFormula{numel(metaboliteFormula),1}=modelSBML.species(i).fbc_chemicalFormula; -0429 end -0430 end -0431 end -0432 end -0433 end -0434 -0435 %Add SBO terms to gene and metabolite miriam fields -0436 if numel(unique(geneSBOs)) > 1 % don't add if they're all identical -0437 for i = 1:numel(geneNames) -0438 geneMiriams{i} = addSBOtoMiriam(geneMiriams{i},geneSBOs(i)); -0439 end -0440 end -0441 if numel(unique(metSBOs)) > 1 -0442 for i = 1:numel(metaboliteNames) -0443 metaboliteMiriams{i} = addSBOtoMiriam(metaboliteMiriams{i},metSBOs(i)); -0444 end -0445 end -0446 -0447 %Retrieve info on reactions -0448 reactionNames=cell(numel(modelSBML.reaction),1); -0449 reactionIDs=cell(numel(modelSBML.reaction),1); -0450 subsystems=cell(numel(modelSBML.reaction),1); -0451 eccodes=cell(numel(modelSBML.reaction),1); -0452 eccodes(:,:)=cellstr(''); -0453 rxnconfidencescores=NaN(numel(modelSBML.reaction),1); -0454 rxnreferences=cell(numel(modelSBML.reaction),1); -0455 rxnreferences(:,:)=cellstr(''); -0456 rxnnotes=cell(numel(modelSBML.reaction),1); -0457 rxnnotes(:,:)=cellstr(''); -0458 grRules=cell(numel(modelSBML.reaction),1); -0459 grRules(:,:)=cellstr(''); -0460 grRulesFromModifier=grRules; -0461 rxnComps=zeros(numel(modelSBML.reaction),1); -0462 rxnMiriams=cell(numel(modelSBML.reaction),1); -0463 reactionReversibility=zeros(numel(modelSBML.reaction),1); -0464 reactionUB=zeros(numel(modelSBML.reaction),1); -0465 reactionLB=zeros(numel(modelSBML.reaction),1); -0466 reactionObjective=zeros(numel(modelSBML.reaction),1); -0467 -0468 %Construct the stoichiometric matrix while the reaction info is read -0469 S=zeros(numel(metaboliteIDs),numel(modelSBML.reaction)); -0470 -0471 counter=0; -0472 %If FBC, then bounds have parameter ids defined for the whole model -0473 if isfield(modelSBML,'parameter') -0474 parameter.name=cell(numel(modelSBML.parameter),1); -0475 parameter.name={modelSBML.parameter(:).id}'; -0476 parameter.value={modelSBML.parameter(:).value}'; -0477 end -0478 -0479 if isfield(modelSBML.reaction,'sboTerm') && numel(unique([modelSBML.reaction.sboTerm])) == 1 -0480 %If all the SBO terms are identical, don't add them to rxnMiriams -0481 modelSBML.reaction = rmfield(modelSBML.reaction,'sboTerm'); -0482 end -0483 -0484 for i=1:numel(modelSBML.reaction) -0485 -0486 %Check that the reaction doesn't produce a complex and nothing else. If -0487 %so, then jump to the next reaction. This is because I get the genes -0488 %for complexes from the names and not from the reactions that create -0489 %them. This only applies to the non-COBRA format -0490 if numel(modelSBML.reaction(i).product)==1 -0491 if length(modelSBML.reaction(i).product(1).species)>=3 -0492 if strcmp(modelSBML.reaction(i).product(1).species(1:3),'Cx_')==true -0493 continue; -0494 end -0495 end -0496 end -0497 -0498 %It didn't look like a gene complex-forming reaction -0499 counter=counter+1; +0358 metaboliteIDs{numel(metaboliteIDs)+1,1}=regexprep(modelSBML.species(i).id,'^M_',''); +0359 metaboliteCompartments{numel(metaboliteCompartments)+1,1}=regexprep(modelSBML.species(i).compartment,'^C_',''); +0360 +0361 %I think that COBRA doesn't set the boundary condition, but rather +0362 %uses name_b. Check for either +0363 metaboliteUnconstrained(numel(metaboliteUnconstrained)+1,1)=modelSBML.species(i).boundaryCondition; +0364 if strcmp(metaboliteIDs{end}(max(end-1,1):end),'_b') +0365 metaboliteUnconstrained(end)=1; +0366 end +0367 +0368 %Get the formula +0369 if max(underscoreIndex)<length(modelSBML.species(i).name) +0370 metaboliteFormula{numel(metaboliteFormula)+1,1}=modelSBML.species(i).name(max(underscoreIndex)+1:length(modelSBML.species(i).name)); +0371 else +0372 metaboliteFormula{numel(metaboliteFormula)+1,1}=''; +0373 end +0374 +0375 %The old COBRA version sometimes has composition information in the +0376 %notes instead +0377 if isfield(modelSBML.species(i),'notes') && ~isempty(parseNote(modelSBML.species(i).notes,'FORMULA')) +0378 metaboliteFormula{numel(metaboliteFormula)+1,1}=parseNote(modelSBML.species(i).notes,'FORMULA'); +0379 end +0380 +0381 %Get Miriam info +0382 if ~isempty(modelSBML.species(i).annotation) +0383 metMiriam=parseMiriam(modelSBML.species(i).annotation); +0384 else +0385 metMiriam=[]; +0386 end +0387 metaboliteMiriams{numel(metaboliteMiriams)+1,1}=metMiriam; +0388 +0389 %Get SBO term +0390 if isfield(modelSBML.species(i),'sboTerm') && ~(modelSBML.species(i).sboTerm==-1) +0391 metSBOs(end+1,1) = modelSBML.species(i).sboTerm; +0392 end +0393 end +0394 %The following lines are executed regardless isSBML2COBRA setting +0395 if isempty(modelSBML.species(i).id) || ~strcmpi(modelSBML.species(i).id(1:2),'E_') +0396 if isempty(modelSBML.species(i).id) || ~strcmpi(modelSBML.species(i).id(1:3),'Cx_') +0397 %Remove trailing [compartment] from metabolite name if present +0398 metaboliteNames{end,1}=regexprep(metaboliteNames{end,1},regexCompNames,''); +0399 metaboliteNames{end,1}=regexprep(metaboliteNames{end,1},'^M_',''); +0400 if isfield(modelSBML.species(i),'fbc_charge') +0401 if ~isempty(modelSBML.species(i).fbc_charge) && modelSBML.species(i).isSetfbc_charge +0402 metaboliteCharges(numel(metaboliteCharges)+1,1)=double(modelSBML.species(i).fbc_charge); +0403 else +0404 if isfield(modelSBML.species(i),'notes') +0405 if strfind(modelSBML.species(i).notes,'CHARGE') +0406 metaboliteCharges(numel(metaboliteCharges)+1,1)=str2double(parseNote(modelSBML.species(i).notes,'CHARGE')); +0407 else +0408 metaboliteCharges(numel(metaboliteCharges)+1,1)=NaN; +0409 end +0410 else +0411 metaboliteCharges(numel(metaboliteCharges)+1,1)=NaN; +0412 end +0413 end +0414 elseif isfield(modelSBML.species(i),'notes') +0415 if strfind(modelSBML.species(i).notes,'CHARGE') +0416 metaboliteCharges(numel(metaboliteCharges)+1,1)=str2double(parseNote(modelSBML.species(i).notes,'CHARGE')); +0417 else +0418 metaboliteCharges(numel(metaboliteCharges)+1,1)=NaN; +0419 end +0420 else +0421 metaboliteCharges(numel(metaboliteCharges)+1,1)=NaN; +0422 end +0423 %Additional information from FBC format Chemical formula +0424 if isfield(modelSBML.species(i),'fbc_chemicalFormula') +0425 if ~isempty(modelSBML.species(i).fbc_chemicalFormula) +0426 metaboliteFormula{numel(metaboliteFormula),1}=modelSBML.species(i).fbc_chemicalFormula; +0427 end +0428 end +0429 end +0430 end +0431 end +0432 +0433 %Add SBO terms to gene and metabolite miriam fields +0434 if numel(unique(geneSBOs)) > 1 % don't add if they're all identical +0435 for i = 1:numel(geneNames) +0436 geneMiriams{i} = addSBOtoMiriam(geneMiriams{i},geneSBOs(i)); +0437 end +0438 end +0439 if numel(unique(metSBOs)) > 1 +0440 for i = 1:numel(metaboliteNames) +0441 metaboliteMiriams{i} = addSBOtoMiriam(metaboliteMiriams{i},metSBOs(i)); +0442 end +0443 end +0444 +0445 %Retrieve info on reactions +0446 reactionNames=cell(numel(modelSBML.reaction),1); +0447 reactionIDs=cell(numel(modelSBML.reaction),1); +0448 subsystems=cell(numel(modelSBML.reaction),1); +0449 eccodes=cell(numel(modelSBML.reaction),1); +0450 eccodes(:,:)=cellstr(''); +0451 rxnconfidencescores=NaN(numel(modelSBML.reaction),1); +0452 rxnreferences=cell(numel(modelSBML.reaction),1); +0453 rxnreferences(:,:)=cellstr(''); +0454 rxnnotes=cell(numel(modelSBML.reaction),1); +0455 rxnnotes(:,:)=cellstr(''); +0456 grRules=cell(numel(modelSBML.reaction),1); +0457 grRules(:,:)=cellstr(''); +0458 grRulesFromModifier=grRules; +0459 rxnComps=zeros(numel(modelSBML.reaction),1); +0460 rxnMiriams=cell(numel(modelSBML.reaction),1); +0461 reactionReversibility=zeros(numel(modelSBML.reaction),1); +0462 reactionUB=zeros(numel(modelSBML.reaction),1); +0463 reactionLB=zeros(numel(modelSBML.reaction),1); +0464 reactionObjective=zeros(numel(modelSBML.reaction),1); +0465 +0466 %Construct the stoichiometric matrix while the reaction info is read +0467 S=zeros(numel(metaboliteIDs),numel(modelSBML.reaction)); +0468 +0469 counter=0; +0470 %If FBC, then bounds have parameter ids defined for the whole model +0471 if isfield(modelSBML,'parameter') +0472 parameter.name=cell(numel(modelSBML.parameter),1); +0473 parameter.name={modelSBML.parameter(:).id}'; +0474 parameter.value={modelSBML.parameter(:).value}'; +0475 end +0476 +0477 if isfield(modelSBML.reaction,'sboTerm') && numel(unique([modelSBML.reaction.sboTerm])) == 1 +0478 %If all the SBO terms are identical, don't add them to rxnMiriams +0479 modelSBML.reaction = rmfield(modelSBML.reaction,'sboTerm'); +0480 end +0481 +0482 for i=1:numel(modelSBML.reaction) +0483 +0484 %Check that the reaction doesn't produce a complex and nothing else. If +0485 %so, then jump to the next reaction. This is because I get the genes +0486 %for complexes from the names and not from the reactions that create +0487 %them. This only applies to the non-COBRA format +0488 if numel(modelSBML.reaction(i).product)==1 +0489 if length(modelSBML.reaction(i).product(1).species)>=3 +0490 if strcmp(modelSBML.reaction(i).product(1).species(1:3),'Cx_')==true +0491 continue; +0492 end +0493 end +0494 end +0495 +0496 %It didn't look like a gene complex-forming reaction +0497 counter=counter+1; +0498 +0499 reactionNames{counter}=modelSBML.reaction(i).name; 0500 -0501 reactionNames{counter}=modelSBML.reaction(i).name; -0502 -0503 reactionIDs{counter}=modelSBML.reaction(i).id; -0504 reactionReversibility(counter)=modelSBML.reaction(i).reversible; -0505 -0506 %If model is FBC, first get parameter of bound and then replace it with -0507 %the correct value. Probably faster with replace(), but this was only -0508 %introduced in Matlab R2016b -0509 if isfield(modelSBML.reaction(i),'fbc_lowerFluxBound') -0510 lb=modelSBML.reaction(i).fbc_lowerFluxBound; -0511 ub=modelSBML.reaction(i).fbc_upperFluxBound; -0512 for n=1:numel(parameter.value) -0513 lb=regexprep(lb,parameter.name(n),num2str(parameter.value{n})); -0514 ub=regexprep(ub,parameter.name(n),num2str(parameter.value{n})); -0515 end -0516 if isempty(lb) -0517 lb='-Inf'; -0518 end -0519 if isempty(ub) -0520 ub='Inf'; -0521 end -0522 reactionLB(counter)=str2num(lb); -0523 reactionUB(counter)=str2num(ub); -0524 %The order of these parameters should not be hard coded -0525 elseif isfield(modelSBML.reaction(i).kineticLaw,'parameter') -0526 reactionLB(counter)=modelSBML.reaction(i).kineticLaw.parameter(1).value; -0527 reactionUB(counter)=modelSBML.reaction(i).kineticLaw.parameter(2).value; -0528 reactionObjective(counter)=modelSBML.reaction(i).kineticLaw.parameter(3).value; -0529 else -0530 if reactionReversibility(counter)==true -0531 reactionLB(counter)=-inf; -0532 else -0533 reactionLB(counter)=0; -0534 end -0535 reactionUB(counter)=inf; -0536 reactionObjective(counter)=0; -0537 end -0538 -0539 %Find the associated gene if available -0540 %If FBC, get gene association data from corresponding fields -0541 if isfield(modelSBML.reaction(i),'fbc_geneProductAssociation') -0542 if ~isempty(modelSBML.reaction(i).fbc_geneProductAssociation) && ~isempty(modelSBML.reaction(i).fbc_geneProductAssociation.fbc_association) -0543 grRules{counter}=modelSBML.reaction(i).fbc_geneProductAssociation.fbc_association.fbc_association; -0544 end -0545 elseif isfield(modelSBML.reaction(i),'notes') -0546 %This section was previously executed only if isSBML2COBRA is true. Now -0547 %it will be executed, if 'GENE_ASSOCIATION' is found in -0548 %modelSBML.reaction(i).notes -0549 if strfind(modelSBML.reaction(i).notes,'GENE_ASSOCIATION') -0550 geneAssociation=parseNote(modelSBML.reaction(i).notes,'GENE_ASSOCIATION'); -0551 elseif strfind(modelSBML.reaction(i).notes,'GENE ASSOCIATION') -0552 geneAssociation=parseNote(modelSBML.reaction(i).notes,'GENE ASSOCIATION'); -0553 else -0554 geneAssociation=''; -0555 end -0556 if ~isempty(geneAssociation) -0557 %This adds the grRules. The gene list and rxnGeneMat are created -0558 %later -0559 grRules{counter}=geneAssociation; -0560 end -0561 end -0562 if isempty(grRules{counter}) && ~isempty(modelSBML.reaction(i).modifier) -0563 rules=''; -0564 for j=1:numel(modelSBML.reaction(i).modifier) -0565 modifier=modelSBML.reaction(i).modifier(j).species; -0566 if ~isempty(modifier) -0567 if strcmpi(modifier(1:2),'E_') -0568 index=find(strcmp(modifier,geneIDs)); -0569 %This should be unique and in the geneIDs list, -0570 %otherwise something is wrong -0571 if numel(index)~=1 -0572 EM=['Could not get the gene association data from reaction ' reactionIDs{i}]; -0573 dispEM(EM); -0574 end -0575 if ~isempty(rules) -0576 rules=[rules ' or (' geneNames{index} ')']; -0577 else -0578 rules=['(' geneNames{index} ')']; -0579 end -0580 elseif strcmp(modifier(1:2),'s_') -0581 index=find(strcmp(modifier,metaboliteIDs)); -0582 %This should be unique and in the geneIDs list, -0583 %otherwise something is wrong -0584 if numel(index)~=1 -0585 EM=['Could not get the gene association data from reaction ' reactionIDs{i}]; -0586 dispEM(EM); -0587 end -0588 if ~isempty(rules) -0589 rules=[rules ' or (' metaboliteIDs{index} ')']; -0590 else -0591 rules=['(' metaboliteIDs{index} ')']; -0592 end -0593 else -0594 %It seems to be a complex. Add the corresponding -0595 %genes from the name of the complex (not the -0596 %reaction that creates it) -0597 index=find(strcmp(modifier,complexIDs)); -0598 if numel(index)==1 -0599 if ~isempty(rules) -0600 rules=[rules ' or (' strrep(complexNames{index},':',' and ') ')']; -0601 else -0602 rules=['(' strrep(complexNames{index},':',' and ') ')']; -0603 end -0604 else -0605 %Could not find a complex -0606 EM=['Could not get the gene association data from reaction ' reactionIDs{i}]; -0607 dispEM(EM); -0608 end -0609 end -0610 end -0611 end -0612 grRules{counter}=rules; -0613 grRulesFromModifier{counter}=rules;%Backup copy for grRules, useful to parse Yeast 7.6 -0614 end -0615 -0616 %Add reaction compartment -0617 if isfield(modelSBML.reaction(i),'compartment') -0618 if ~isempty(modelSBML.reaction(i).compartment) -0619 rxnComp=modelSBML.reaction(i).compartment; -0620 else -0621 rxnComp=''; -0622 end -0623 elseif isfield(modelSBML.reaction(i),'notes') -0624 rxnComp=parseNote(modelSBML.reaction(i).notes,'COMPARTMENT'); -0625 end -0626 if ~isempty(rxnComp) -0627 %Find it in the compartment list -0628 [~, J]=ismember(rxnComp,compartmentIDs); -0629 rxnComps(counter)=J; -0630 end -0631 -0632 %Get other Miriam fields. This may include for example database indexes -0633 %to organism-specific databases. EC-codes are supported by the COBRA -0634 %Toolbox format and are therefore loaded separately -0635 if isSBML2COBRA==false -0636 miriamStruct=parseMiriam(modelSBML.reaction(i).annotation); -0637 rxnMiriams{counter}=miriamStruct; -0638 if isfield(modelSBML.reaction(i),'notes') -0639 subsystems{counter,1}=cellstr(parseNote(modelSBML.reaction(i).notes,'SUBSYSTEM')); -0640 subsystems{counter,1}(cellfun('isempty',subsystems{counter,1})) = []; -0641 if strfind(modelSBML.reaction(i).notes,'Confidence Level') -0642 rxnconfidencescores(counter)=str2num(parseNote(modelSBML.reaction(i).notes,'Confidence Level')); -0643 end -0644 rxnreferences{counter,1}=parseNote(modelSBML.reaction(i).notes,'AUTHORS'); -0645 rxnnotes{counter,1}=parseNote(modelSBML.reaction(i).notes,'NOTES'); -0646 end -0647 end -0648 -0649 %Get SBO terms -0650 if isfield(modelSBML.reaction(i),'sboTerm') && ~(modelSBML.reaction(i).sboTerm==-1) -0651 rxnMiriams{counter} = addSBOtoMiriam(rxnMiriams{counter}, modelSBML.reaction(i).sboTerm); -0652 end -0653 -0654 %Get ec-codes -0655 eccode=''; -0656 if ~isempty(modelSBML.reaction(i).annotation) -0657 if strfind(modelSBML.reaction(i).annotation,'urn:miriam:ec-code') -0658 eccode=parseAnnotation(modelSBML.reaction(i).annotation,'urn:miriam:',':','ec-code'); -0659 elseif strfind(modelSBML.reaction(i).annotation,'http://identifiers.org/ec-code') -0660 eccode=parseAnnotation(modelSBML.reaction(i).annotation,'http://identifiers.org/','/','ec-code'); -0661 elseif strfind(modelSBML.reaction(i).annotation,'https://identifiers.org/ec-code') -0662 eccode=parseAnnotation(modelSBML.reaction(i).annotation,'https://identifiers.org/','/','ec-code'); -0663 end -0664 elseif isfield(modelSBML.reaction(i),'notes') -0665 if strfind(modelSBML.reaction(i).notes,'EC Number') -0666 eccode=[eccode parseNote(modelSBML.reaction(i).notes,'EC Number')]; -0667 elseif strfind(modelSBML.reaction(i).notes,'PROTEIN_CLASS') -0668 eccode=[eccode parseNote(modelSBML.reaction(i).notes,'PROTEIN_CLASS')]; -0669 end -0670 end -0671 eccodes{counter}=eccode; -0672 -0673 %Add all reactants -0674 for j=1:numel(modelSBML.reaction(i).reactant) -0675 %Get the index of the metabolite in metaboliteIDs. External -0676 %metabolites will be removed at a later stage -0677 metIndex=find(strcmp(modelSBML.reaction(i).reactant(j).species,metaboliteIDs),1); -0678 if isempty(metIndex) -0679 EM=['Could not find metabolite ' modelSBML.reaction(i).reactant(j).species ' in reaction ' reactionIDs{counter}]; -0680 dispEM(EM); -0681 end -0682 S(metIndex,counter)=S(metIndex,counter)+modelSBML.reaction(i).reactant(j).stoichiometry*-1; -0683 end -0684 -0685 %Add all products -0686 for j=1:numel(modelSBML.reaction(i).product) -0687 %Get the index of the metabolite in metaboliteIDs. -0688 metIndex=find(strcmp(modelSBML.reaction(i).product(j).species,metaboliteIDs),1); -0689 if isempty(metIndex) -0690 EM=['Could not find metabolite ' modelSBML.reaction(i).product(j).species ' in reaction ' reactionIDs{counter}]; -0691 dispEM(EM); -0692 end -0693 S(metIndex,counter)=S(metIndex,counter)+modelSBML.reaction(i).product(j).stoichiometry; -0694 end -0695 end -0696 -0697 %if FBC, objective function is separately defined. Multiple objective -0698 %functions can be defined, one is set as active -0699 if isfield(modelSBML, 'fbc_activeObjective') -0700 obj=modelSBML.fbc_activeObjective; -0701 for i=1:numel(modelSBML.fbc_objective) -0702 if strcmp(obj,modelSBML.fbc_objective(i).fbc_id) -0703 if ~isempty(modelSBML.fbc_objective(i).fbc_fluxObjective) -0704 rxn=modelSBML.fbc_objective(i).fbc_fluxObjective.fbc_reaction; -0705 rxn=regexprep(rxn,'^R_',''); -0706 idx=find(ismember(reactionIDs,rxn)); -0707 reactionObjective(idx)=modelSBML.fbc_objective(i).fbc_fluxObjective.fbc_coefficient; -0708 end -0709 end -0710 end -0711 end -0712 -0713 %subSystems can be stored as groups instead of in annotations -0714 if isfield(modelSBML,'groups_group') -0715 for i=1:numel(modelSBML.groups_group) -0716 groupreactions={modelSBML.groups_group(i).groups_member(:).groups_idRef}; -0717 groupreactions=regexprep(groupreactions,'^R_',''); -0718 [~, idx] = ismember(groupreactions, reactionIDs); -0719 if any(idx) -0720 for j=1:numel(idx) -0721 if isempty(subsystems{idx(j)}) % First subsystem -0722 subsystems{idx(j)} = {modelSBML.groups_group(i).groups_name}; -0723 else % Consecutive subsystems: concatenate -0724 subsystems{idx(j)} = horzcat(subsystems{idx(j)}, modelSBML.groups_group(i).groups_name); -0725 end -0726 end -0727 end -0728 end -0729 end -0730 -0731 %Shrink the structures if complex-forming reactions had to be skipped -0732 reactionNames=reactionNames(1:counter); -0733 reactionIDs=reactionIDs(1:counter); -0734 subsystems=subsystems(1:counter); -0735 eccodes=eccodes(1:counter); -0736 rxnconfidencescores=rxnconfidencescores(1:counter); -0737 rxnreferences=rxnreferences(1:counter); -0738 rxnnotes=rxnnotes(1:counter); -0739 grRules=grRules(1:counter); -0740 rxnMiriams=rxnMiriams(1:counter); -0741 reactionReversibility=reactionReversibility(1:counter); -0742 reactionUB=reactionUB(1:counter); -0743 reactionLB=reactionLB(1:counter); -0744 reactionObjective=reactionObjective(1:counter); -0745 S=S(:,1:counter); -0746 -0747 model.name=modelSBML.name; -0748 model.id=regexprep(modelSBML.id,'^M_',''); % COBRA adds M_ prefix -0749 model.rxns=reactionIDs; -0750 model.mets=metaboliteIDs; -0751 model.S=sparse(S); -0752 model.lb=reactionLB; -0753 model.ub=reactionUB; -0754 model.rev=reactionReversibility; -0755 model.c=reactionObjective; -0756 model.b=zeros(numel(metaboliteIDs),1); -0757 model.comps=compartmentIDs; -0758 model.compNames=compartmentNames; -0759 model.rxnConfidenceScores=rxnconfidencescores; -0760 model.rxnReferences=rxnreferences; -0761 model.rxnNotes=rxnnotes; -0762 -0763 %Load annotation if available. If there are several authors, only the first -0764 %author credentials are imported -0765 if isfield(modelSBML,'annotation') -0766 endString='</'; -0767 I=strfind(modelSBML.annotation,endString); -0768 J=strfind(modelSBML.annotation,'<vCard:Family>'); -0769 if any(J) -0770 model.annotation.familyName=modelSBML.annotation(J(1)+14:I(find(I>J(1),1))-1); -0771 end -0772 J=strfind(modelSBML.annotation,'<vCard:Given>'); -0773 if any(J) -0774 model.annotation.givenName=modelSBML.annotation(J(1)+13:I(find(I>J(1),1))-1); -0775 end -0776 J=strfind(modelSBML.annotation,'<vCard:EMAIL>'); -0777 if any(J) -0778 model.annotation.email=modelSBML.annotation(J(1)+13:I(find(I>J(1),1))-1); -0779 end -0780 J=strfind(modelSBML.annotation,'<vCard:Orgname>'); -0781 if any(J) -0782 model.annotation.organization=modelSBML.annotation(J(1)+15:I(find(I>J(1),1))-1); -0783 end -0784 endString='"/>'; -0785 I=strfind(modelSBML.annotation,endString); -0786 if strfind(modelSBML.annotation,'"urn:miriam:') -0787 J=strfind(modelSBML.annotation,'"urn:miriam:'); -0788 if any(J) -0789 model.annotation.taxonomy=modelSBML.annotation(J+12:I(find(I>J,1))-1); -0790 end -0791 else -0792 J=strfind(modelSBML.annotation,'"http://identifiers.org/'); -0793 if any(J) -0794 model.annotation.taxonomy=modelSBML.annotation(J+24:I(find(I>J,1))-1); -0795 else -0796 J=strfind(modelSBML.annotation,'"https://identifiers.org/'); -0797 if any(J) -0798 model.annotation.taxonomy=modelSBML.annotation(J+25:I(find(I>J,1))-1); -0799 end -0800 end -0801 end -0802 end -0803 if isfield(modelSBML,'notes') -0804 startString=strfind(modelSBML.notes,'xhtml">'); -0805 endString=strfind(modelSBML.notes,'</body>'); -0806 if any(startString) && any(endString) -0807 model.annotation.note=modelSBML.notes(startString+7:endString-1); -0808 model.annotation.note=regexprep(model.annotation.note,'<p>|</p>',''); -0809 model.annotation.note=strtrim(model.annotation.note); -0810 end -0811 end -0812 -0813 if any(~cellfun(@isempty,compartmentOutside)) -0814 model.compOutside=compartmentOutside; -0815 end -0816 -0817 model.rxnNames=reactionNames; -0818 model.metNames=metaboliteNames; -0819 -0820 %Match the compartments for metabolites -0821 [~, J]=ismember(metaboliteCompartments,model.comps); -0822 model.metComps=J; -0823 -0824 %If any genes have been loaded (only for the new format) -0825 if ~isempty(geneNames) -0826 %In some rare cases geneNames may not necessarily be used in grRules. -0827 %That is true for Yeast 7.6. It's therefore important to change gene -0828 %systematic names to geneIDs in sophisticated way. Gene systematic -0829 %names are not unique, since exactly the same name may be in different -0830 %compartments -0831 if all(cellfun(@isempty,strfind(grRules,geneNames{1}))) -0832 geneShortNames=geneNames; -0833 %geneShortNames contain compartments as well, so these are removed -0834 geneShortNames=regexprep(geneShortNames,' \[.+$',''); -0835 %grRules obtained from modifier fields contain geneNames. These are -0836 %changed into geneIDs. grRulesFromModifier is a good way to have -0837 %geneIDs and rxns association when it's important to resolve -0838 %systematic name ambiguities -0839 grRulesFromModifier=regexprep(regexprep(grRulesFromModifier,'\[|\]','_'),regexprep(geneNames,'\[|\]','_'),geneIDs); -0840 grRules=regexprep(regexprep(grRules,'\[|\]','_'),regexprep(geneNames,'\[|\]','_'),geneIDs); -0841 -0842 %Yeast 7.6 contains several metabolites, which were used in gene -0843 %associations. For that reason, the list of species ID is created -0844 %and we then check whether any of them have kegg.genes annotation -0845 %thereby obtaining systematic gene names -0846 geneShortNames=vertcat(geneShortNames,metaboliteNames); -0847 geneIDs=vertcat(geneIDs,metaboliteIDs); -0848 geneSystNames=extractMiriam(vertcat(geneMiriams,metaboliteMiriams),'kegg.genes'); -0849 geneCompartments=vertcat(geneCompartments,metaboliteCompartments); -0850 geneMiriams=vertcat(geneMiriams,metaboliteMiriams); -0851 -0852 %Now we retain information for only these entries, which have -0853 %kegg.genes annotation -0854 geneShortNames=geneShortNames(~cellfun('isempty',geneSystNames)); -0855 geneIDs=geneIDs(~cellfun('isempty',geneSystNames)); -0856 geneSystNames=geneSystNames(~cellfun('isempty',geneSystNames)); -0857 geneCompartments=geneCompartments(~cellfun('isempty',geneSystNames)); -0858 geneMiriams=geneMiriams(~cellfun('isempty',geneSystNames)); -0859 %Now we reorder geneIDs and geneSystNames by geneSystNames string -0860 %length -0861 geneNames=geneIDs;%Backuping geneIDs, since we need unsorted order for later -0862 [~, Indx] = sort(cellfun('size', geneSystNames, 2), 'descend'); -0863 geneIDs = geneIDs(Indx); -0864 geneSystNames = geneSystNames(Indx); -0865 for i=1:numel(geneSystNames) -0866 for j=1:numel(grRules) -0867 if strfind(grRules{j},geneSystNames{i}) -0868 if ~isempty(grRules{j}) -0869 if sum(ismember(geneSystNames,geneSystNames{i}))==1 -0870 grRules{j}=regexprep(grRules{j},geneSystNames{i},geneIDs{i}); -0871 elseif sum(ismember(geneSystNames,geneSystNames{i}))>1 -0872 counter=0; -0873 ovrlpIDs=geneIDs(ismember(geneSystNames,geneSystNames{i})); -0874 for k=1:numel(ovrlpIDs) -0875 if strfind(grRulesFromModifier{j},ovrlpIDs{k}) -0876 counter=counter+1; -0877 grRules{j}=regexprep(grRules{j},geneSystNames{i},ovrlpIDs{k}); -0878 end -0879 if counter>1 -0880 EM=['Gene association is ambiguous for reaction ' modelSBML.reaction(j).id]; -0881 dispEM(EM); -0882 end -0883 end -0884 end -0885 end -0886 end -0887 end -0888 end -0889 end -0890 model.genes=geneNames; -0891 model.grRules=grRules; -0892 [grRules,rxnGeneMat] = standardizeGrRules(model,true); -0893 model.grRules = grRules; -0894 model.rxnGeneMat = rxnGeneMat; -0895 -0896 %Match the compartments for genes -0897 [~, J]=ismember(geneCompartments,model.comps); -0898 model.geneComps=J; -0899 else -0900 if ~all(cellfun(@isempty,grRules)) -0901 %If fbc_geneProduct exists, follow the specified gene order, such -0902 %that matching geneShortNames in function below will work -0903 if isfield(modelSBML,'fbc_geneProduct') -0904 genes={modelSBML.fbc_geneProduct.fbc_id}; -0905 -0906 %Get gene Miriams if they were not retrieved above (this occurs -0907 %when genes are stored as fbc_geneProduct instead of species) -0908 if isempty(geneMiriams) -0909 geneMiriams = cell(numel(genes),1); -0910 if isfield(modelSBML.fbc_geneProduct,'sboTerm') && numel(unique([modelSBML.fbc_geneProduct.sboTerm])) == 1 -0911 %If all the SBO terms are identical, don't add them to geneMiriams -0912 modelSBML.fbc_geneProduct = rmfield(modelSBML.fbc_geneProduct,'sboTerm'); -0913 end -0914 for i = 1:numel(genes) -0915 geneMiriams{i}=parseMiriam(modelSBML.fbc_geneProduct(i).annotation); -0916 if isfield(modelSBML.fbc_geneProduct(i),'sboTerm') && ~(modelSBML.fbc_geneProduct(i).sboTerm==-1) -0917 geneMiriams{i} = addSBOtoMiriam(geneMiriams{i},modelSBML.fbc_geneProduct(i).sboTerm); -0918 end -0919 end -0920 end -0921 else -0922 genes=getGeneList(grRules); -0923 end -0924 if strcmpi(genes{1}(1:2),'G_') -0925 genes=regexprep(genes,'^G_',''); -0926 grRules=regexprep(grRules,'^G_',''); -0927 grRules=regexprep(grRules,'\(G_','('); -0928 grRules=regexprep(grRules,' G_',' '); -0929 end -0930 model.genes=genes; -0931 model.grRules=grRules; -0932 [grRules,rxnGeneMat] = standardizeGrRules(model,true); -0933 model.grRules = grRules; -0934 model.rxnGeneMat = rxnGeneMat; -0935 end -0936 end -0937 -0938 if all(cellfun(@isempty,geneShortNames)) -0939 if isfield(modelSBML,'fbc_geneProduct') -0940 for i=1:numel(genes) -0941 if ~isempty(modelSBML.fbc_geneProduct(i).fbc_label) -0942 geneShortNames{i,1}=modelSBML.fbc_geneProduct(i).fbc_label; -0943 elseif ~isempty(modelSBML.fbc_geneProduct(i).fbc_name) -0944 geneShortNames{i,1}=modelSBML.fbc_geneProduct(i).fbc_name; -0945 else -0946 geneShortNames{i,1}=''; -0947 end -0948 end -0949 end -0950 end -0951 -0952 %If any InChIs have been loaded -0953 if any(~cellfun(@isempty,metaboliteInChI)) -0954 model.inchis=metaboliteInChI; -0955 end -0956 -0957 %If any formulas have been loaded -0958 if any(~cellfun(@isempty,metaboliteFormula)) -0959 model.metFormulas=metaboliteFormula; -0960 end -0961 -0962 %If any charges have been loaded -0963 if ~isempty(metaboliteCharges) -0964 model.metCharges=metaboliteCharges; -0965 end -0966 -0967 %If any gene short names have been loaded -0968 if any(~cellfun(@isempty,geneShortNames)) -0969 model.geneShortNames=geneShortNames; -0970 end -0971 -0972 %If any Miriam strings for compartments have been loaded -0973 if any(~cellfun(@isempty,compartmentMiriams)) -0974 model.compMiriams=compartmentMiriams; -0975 end -0976 -0977 %If any Miriam strings for metabolites have been loaded -0978 if any(~cellfun(@isempty,metaboliteMiriams)) -0979 model.metMiriams=metaboliteMiriams; -0980 end -0981 -0982 %If any subsystems have been loaded -0983 if any(~cellfun(@isempty,subsystems)) -0984 model.subSystems=subsystems; -0985 end -0986 if any(rxnComps) -0987 if all(rxnComps) -0988 model.rxnComps=rxnComps; -0989 else -0990 if supressWarnings==false -0991 EM='The compartments for the following reactions could not be matched. Ignoring reaction compartment information'; -0992 dispEM(EM,false,model.rxns(rxnComps==0)); -0993 end -0994 end -0995 end -0996 -0997 %If any ec-codes have been loaded -0998 if any(~cellfun(@isempty,eccodes)) -0999 model.eccodes=eccodes; -1000 end -1001 -1002 %If any Miriam strings for reactions have been loaded -1003 if any(~cellfun(@isempty,rxnMiriams)) -1004 model.rxnMiriams=rxnMiriams; -1005 end -1006 -1007 %If any Miriam strings for genes have been loaded -1008 if any(~cellfun(@isempty,geneMiriams)) -1009 model.geneMiriams=geneMiriams; -1010 end -1011 -1012 model.unconstrained=metaboliteUnconstrained; -1013 -1014 %Convert SBML IDs back into their original strings. Here we are using part -1015 %from convertSBMLID, originating from the COBRA Toolbox -1016 model.rxns=regexprep(model.rxns,'__([0-9]+)__','${char(str2num($1))}'); -1017 model.mets=regexprep(model.mets,'__([0-9]+)__','${char(str2num($1))}'); -1018 model.comps=regexprep(model.comps,'__([0-9]+)__','${char(str2num($1))}'); -1019 model.grRules=regexprep(model.grRules,'__([0-9]+)__','${char(str2num($1))}'); -1020 model.genes=regexprep(model.genes,'__([0-9]+)__','${char(str2num($1))}'); -1021 model.id=regexprep(model.id,'__([0-9]+)__','${char(str2num($1))}'); -1022 -1023 %Remove unused fields -1024 if isempty(model.annotation) -1025 model=rmfield(model,'annotation'); -1026 end -1027 if isempty(model.compOutside) -1028 model=rmfield(model,'compOutside'); -1029 end -1030 if isempty(model.compMiriams) -1031 model=rmfield(model,'compMiriams'); -1032 end -1033 if isempty(model.rxnComps) -1034 model=rmfield(model,'rxnComps'); -1035 end -1036 if isempty(model.grRules) -1037 model=rmfield(model,'grRules'); -1038 end -1039 if isempty(model.rxnGeneMat) -1040 model=rmfield(model,'rxnGeneMat'); -1041 end -1042 if isempty(model.subSystems) -1043 model=rmfield(model,'subSystems'); -1044 else -1045 model.subSystems(cellfun(@isempty,subsystems))={{''}}; -1046 end -1047 if isempty(model.eccodes) -1048 model=rmfield(model,'eccodes'); -1049 end -1050 if isempty(model.rxnMiriams) -1051 model=rmfield(model,'rxnMiriams'); -1052 end -1053 if cellfun(@isempty,model.rxnNotes) -1054 model=rmfield(model,'rxnNotes'); -1055 end -1056 if cellfun(@isempty,model.rxnReferences) -1057 model=rmfield(model,'rxnReferences'); -1058 end -1059 if isempty(model.rxnConfidenceScores) || all(isnan(model.rxnConfidenceScores)) -1060 model=rmfield(model,'rxnConfidenceScores'); -1061 end -1062 if isempty(model.genes) -1063 model=rmfield(model,'genes'); -1064 elseif isrow(model.genes) -1065 model.genes=transpose(model.genes); -1066 end -1067 if isempty(model.geneComps) -1068 model=rmfield(model,'geneComps'); -1069 end -1070 if isempty(model.geneMiriams) -1071 model=rmfield(model,'geneMiriams'); -1072 end -1073 if isempty(model.geneShortNames) -1074 model=rmfield(model,'geneShortNames'); -1075 end -1076 if isempty(model.inchis) -1077 model=rmfield(model,'inchis'); -1078 end -1079 if isempty(model.metFormulas) -1080 model=rmfield(model,'metFormulas'); -1081 end -1082 if isempty(model.metMiriams) -1083 model=rmfield(model,'metMiriams'); -1084 end -1085 if ~any(model.metCharges) -1086 model=rmfield(model,'metCharges'); -1087 end -1088 -1089 %This just removes the grRules if no genes have been loaded -1090 if ~isfield(model,'genes') && isfield(model,'grRules') -1091 model=rmfield(model,'grRules'); -1092 end -1093 -1094 %Print warnings about bad structure -1095 if supressWarnings==false -1096 checkModelStruct(model,false); -1097 end -1098 -1099 if removeExcMets==true -1100 model=simplifyModel(model); -1101 end +0501 reactionIDs{counter}=modelSBML.reaction(i).id; +0502 reactionReversibility(counter)=modelSBML.reaction(i).reversible; +0503 +0504 %If model is FBC, first get parameter of bound and then replace it with +0505 %the correct value. Probably faster with replace(), but this was only +0506 %introduced in Matlab R2016b +0507 if isfield(modelSBML.reaction(i),'fbc_lowerFluxBound') +0508 lb=modelSBML.reaction(i).fbc_lowerFluxBound; +0509 ub=modelSBML.reaction(i).fbc_upperFluxBound; +0510 for n=1:numel(parameter.value) +0511 lb=regexprep(lb,parameter.name(n),num2str(parameter.value{n})); +0512 ub=regexprep(ub,parameter.name(n),num2str(parameter.value{n})); +0513 end +0514 if isempty(lb) +0515 lb='-Inf'; +0516 end +0517 if isempty(ub) +0518 ub='Inf'; +0519 end +0520 reactionLB(counter)=str2num(lb); +0521 reactionUB(counter)=str2num(ub); +0522 %The order of these parameters should not be hard coded +0523 elseif isfield(modelSBML.reaction(i).kineticLaw,'parameter') +0524 reactionLB(counter)=modelSBML.reaction(i).kineticLaw.parameter(1).value; +0525 reactionUB(counter)=modelSBML.reaction(i).kineticLaw.parameter(2).value; +0526 reactionObjective(counter)=modelSBML.reaction(i).kineticLaw.parameter(3).value; +0527 else +0528 if reactionReversibility(counter)==true +0529 reactionLB(counter)=-inf; +0530 else +0531 reactionLB(counter)=0; +0532 end +0533 reactionUB(counter)=inf; +0534 reactionObjective(counter)=0; +0535 end +0536 +0537 %Find the associated gene if available +0538 %If FBC, get gene association data from corresponding fields +0539 if isfield(modelSBML.reaction(i),'fbc_geneProductAssociation') +0540 if ~isempty(modelSBML.reaction(i).fbc_geneProductAssociation) && ~isempty(modelSBML.reaction(i).fbc_geneProductAssociation.fbc_association) +0541 grRules{counter}=modelSBML.reaction(i).fbc_geneProductAssociation.fbc_association.fbc_association; +0542 end +0543 elseif isfield(modelSBML.reaction(i),'notes') +0544 %This section was previously executed only if isSBML2COBRA is true. Now +0545 %it will be executed, if 'GENE_ASSOCIATION' is found in +0546 %modelSBML.reaction(i).notes +0547 if strfind(modelSBML.reaction(i).notes,'GENE_ASSOCIATION') +0548 geneAssociation=parseNote(modelSBML.reaction(i).notes,'GENE_ASSOCIATION'); +0549 elseif strfind(modelSBML.reaction(i).notes,'GENE ASSOCIATION') +0550 geneAssociation=parseNote(modelSBML.reaction(i).notes,'GENE ASSOCIATION'); +0551 else +0552 geneAssociation=''; +0553 end +0554 if ~isempty(geneAssociation) +0555 %This adds the grRules. The gene list and rxnGeneMat are created +0556 %later +0557 grRules{counter}=geneAssociation; +0558 end +0559 end +0560 if isempty(grRules{counter}) && ~isempty(modelSBML.reaction(i).modifier) +0561 rules=''; +0562 for j=1:numel(modelSBML.reaction(i).modifier) +0563 modifier=modelSBML.reaction(i).modifier(j).species; +0564 if ~isempty(modifier) +0565 if strcmpi(modifier(1:2),'E_') +0566 index=find(strcmp(modifier,geneIDs)); +0567 %This should be unique and in the geneIDs list, +0568 %otherwise something is wrong +0569 if numel(index)~=1 +0570 EM=['Could not get the gene association data from reaction ' reactionIDs{i}]; +0571 dispEM(EM); +0572 end +0573 if ~isempty(rules) +0574 rules=[rules ' or (' geneNames{index} ')']; +0575 else +0576 rules=['(' geneNames{index} ')']; +0577 end +0578 elseif strcmp(modifier(1:2),'s_') +0579 index=find(strcmp(modifier,metaboliteIDs)); +0580 %This should be unique and in the geneIDs list, +0581 %otherwise something is wrong +0582 if numel(index)~=1 +0583 EM=['Could not get the gene association data from reaction ' reactionIDs{i}]; +0584 dispEM(EM); +0585 end +0586 if ~isempty(rules) +0587 rules=[rules ' or (' metaboliteIDs{index} ')']; +0588 else +0589 rules=['(' metaboliteIDs{index} ')']; +0590 end +0591 else +0592 %It seems to be a complex. Add the corresponding +0593 %genes from the name of the complex (not the +0594 %reaction that creates it) +0595 index=find(strcmp(modifier,complexIDs)); +0596 if numel(index)==1 +0597 if ~isempty(rules) +0598 rules=[rules ' or (' strrep(complexNames{index},':',' and ') ')']; +0599 else +0600 rules=['(' strrep(complexNames{index},':',' and ') ')']; +0601 end +0602 else +0603 %Could not find a complex +0604 EM=['Could not get the gene association data from reaction ' reactionIDs{i}]; +0605 dispEM(EM); +0606 end +0607 end +0608 end +0609 end +0610 grRules{counter}=rules; +0611 grRulesFromModifier{counter}=rules;%Backup copy for grRules, useful to parse Yeast 7.6 +0612 end +0613 +0614 %Add reaction compartment +0615 if isfield(modelSBML.reaction(i),'compartment') +0616 if ~isempty(modelSBML.reaction(i).compartment) +0617 rxnComp=modelSBML.reaction(i).compartment; +0618 else +0619 rxnComp=''; +0620 end +0621 elseif isfield(modelSBML.reaction(i),'notes') +0622 rxnComp=parseNote(modelSBML.reaction(i).notes,'COMPARTMENT'); +0623 end +0624 if ~isempty(rxnComp) +0625 %Find it in the compartment list +0626 [~, J]=ismember(rxnComp,compartmentIDs); +0627 rxnComps(counter)=J; +0628 end +0629 +0630 %Get other Miriam fields. This may include for example database indexes +0631 %to organism-specific databases. EC-codes are supported by the COBRA +0632 %Toolbox format and are therefore loaded separately +0633 if isSBML2COBRA==false +0634 miriamStruct=parseMiriam(modelSBML.reaction(i).annotation); +0635 rxnMiriams{counter}=miriamStruct; +0636 if isfield(modelSBML.reaction(i),'notes') +0637 subsystems{counter,1}=cellstr(parseNote(modelSBML.reaction(i).notes,'SUBSYSTEM')); +0638 subsystems{counter,1}(cellfun('isempty',subsystems{counter,1})) = []; +0639 if strfind(modelSBML.reaction(i).notes,'Confidence Level') +0640 rxnconfidencescores(counter)=str2num(parseNote(modelSBML.reaction(i).notes,'Confidence Level')); +0641 end +0642 rxnreferences{counter,1}=parseNote(modelSBML.reaction(i).notes,'AUTHORS'); +0643 rxnnotes{counter,1}=parseNote(modelSBML.reaction(i).notes,'NOTES'); +0644 end +0645 end +0646 +0647 %Get SBO terms +0648 if isfield(modelSBML.reaction(i),'sboTerm') && ~(modelSBML.reaction(i).sboTerm==-1) +0649 rxnMiriams{counter} = addSBOtoMiriam(rxnMiriams{counter}, modelSBML.reaction(i).sboTerm); +0650 end +0651 +0652 %Get ec-codes +0653 eccode=''; +0654 if ~isempty(modelSBML.reaction(i).annotation) +0655 if strfind(modelSBML.reaction(i).annotation,'urn:miriam:ec-code') +0656 eccode=parseAnnotation(modelSBML.reaction(i).annotation,'urn:miriam:',':','ec-code'); +0657 elseif strfind(modelSBML.reaction(i).annotation,'http://identifiers.org/ec-code') +0658 eccode=parseAnnotation(modelSBML.reaction(i).annotation,'http://identifiers.org/','/','ec-code'); +0659 elseif strfind(modelSBML.reaction(i).annotation,'https://identifiers.org/ec-code') +0660 eccode=parseAnnotation(modelSBML.reaction(i).annotation,'https://identifiers.org/','/','ec-code'); +0661 end +0662 elseif isfield(modelSBML.reaction(i),'notes') +0663 if strfind(modelSBML.reaction(i).notes,'EC Number') +0664 eccode=[eccode parseNote(modelSBML.reaction(i).notes,'EC Number')]; +0665 elseif strfind(modelSBML.reaction(i).notes,'PROTEIN_CLASS') +0666 eccode=[eccode parseNote(modelSBML.reaction(i).notes,'PROTEIN_CLASS')]; +0667 end +0668 end +0669 eccodes{counter}=eccode; +0670 +0671 %Add all reactants +0672 for j=1:numel(modelSBML.reaction(i).reactant) +0673 %Get the index of the metabolite in metaboliteIDs. External +0674 %metabolites will be removed at a later stage +0675 metIndex=find(strcmp(modelSBML.reaction(i).reactant(j).species,metaboliteIDs),1); +0676 if isempty(metIndex) +0677 EM=['Could not find metabolite ' modelSBML.reaction(i).reactant(j).species ' in reaction ' reactionIDs{counter}]; +0678 dispEM(EM); +0679 end +0680 S(metIndex,counter)=S(metIndex,counter)+modelSBML.reaction(i).reactant(j).stoichiometry*-1; +0681 end +0682 +0683 %Add all products +0684 for j=1:numel(modelSBML.reaction(i).product) +0685 %Get the index of the metabolite in metaboliteIDs. +0686 metIndex=find(strcmp(modelSBML.reaction(i).product(j).species,metaboliteIDs),1); +0687 if isempty(metIndex) +0688 EM=['Could not find metabolite ' modelSBML.reaction(i).product(j).species ' in reaction ' reactionIDs{counter}]; +0689 dispEM(EM); +0690 end +0691 S(metIndex,counter)=S(metIndex,counter)+modelSBML.reaction(i).product(j).stoichiometry; +0692 end +0693 end +0694 +0695 %if FBC, objective function is separately defined. Multiple objective +0696 %functions can be defined, one is set as active +0697 if isfield(modelSBML, 'fbc_activeObjective') +0698 obj=modelSBML.fbc_activeObjective; +0699 for i=1:numel(modelSBML.fbc_objective) +0700 if strcmp(obj,modelSBML.fbc_objective(i).fbc_id) +0701 if ~isempty(modelSBML.fbc_objective(i).fbc_fluxObjective) +0702 rxn=modelSBML.fbc_objective(i).fbc_fluxObjective.fbc_reaction; +0703 rxn=regexprep(rxn,'^R_',''); +0704 idx=find(ismember(reactionIDs,rxn)); +0705 reactionObjective(idx)=modelSBML.fbc_objective(i).fbc_fluxObjective.fbc_coefficient; +0706 end +0707 end +0708 end +0709 end +0710 +0711 %subSystems can be stored as groups instead of in annotations +0712 if isfield(modelSBML,'groups_group') +0713 for i=1:numel(modelSBML.groups_group) +0714 groupreactions={modelSBML.groups_group(i).groups_member(:).groups_idRef}; +0715 groupreactions=regexprep(groupreactions,'^R_',''); +0716 [~, idx] = ismember(groupreactions, reactionIDs); +0717 if any(idx) +0718 for j=1:numel(idx) +0719 if isempty(subsystems{idx(j)}) % First subsystem +0720 subsystems{idx(j)} = {modelSBML.groups_group(i).groups_name}; +0721 else % Consecutive subsystems: concatenate +0722 subsystems{idx(j)} = horzcat(subsystems{idx(j)}, modelSBML.groups_group(i).groups_name); +0723 end +0724 end +0725 end +0726 end +0727 end +0728 +0729 %Shrink the structures if complex-forming reactions had to be skipped +0730 reactionNames=reactionNames(1:counter); +0731 reactionIDs=reactionIDs(1:counter); +0732 subsystems=subsystems(1:counter); +0733 eccodes=eccodes(1:counter); +0734 rxnconfidencescores=rxnconfidencescores(1:counter); +0735 rxnreferences=rxnreferences(1:counter); +0736 rxnnotes=rxnnotes(1:counter); +0737 grRules=grRules(1:counter); +0738 rxnMiriams=rxnMiriams(1:counter); +0739 reactionReversibility=reactionReversibility(1:counter); +0740 reactionUB=reactionUB(1:counter); +0741 reactionLB=reactionLB(1:counter); +0742 reactionObjective=reactionObjective(1:counter); +0743 S=S(:,1:counter); +0744 +0745 model.name=modelSBML.name; +0746 model.id=regexprep(modelSBML.id,'^M_',''); % COBRA adds M_ prefix +0747 model.rxns=reactionIDs; +0748 model.mets=metaboliteIDs; +0749 model.S=sparse(S); +0750 model.lb=reactionLB; +0751 model.ub=reactionUB; +0752 model.rev=reactionReversibility; +0753 model.c=reactionObjective; +0754 model.b=zeros(numel(metaboliteIDs),1); +0755 model.comps=compartmentIDs; +0756 model.compNames=compartmentNames; +0757 model.rxnConfidenceScores=rxnconfidencescores; +0758 model.rxnReferences=rxnreferences; +0759 model.rxnNotes=rxnnotes; +0760 +0761 %Load annotation if available. If there are several authors, only the first +0762 %author credentials are imported +0763 if isfield(modelSBML,'annotation') +0764 endString='</'; +0765 I=strfind(modelSBML.annotation,endString); +0766 J=strfind(modelSBML.annotation,'<vCard:Family>'); +0767 if any(J) +0768 model.annotation.familyName=modelSBML.annotation(J(1)+14:I(find(I>J(1),1))-1); +0769 end +0770 J=strfind(modelSBML.annotation,'<vCard:Given>'); +0771 if any(J) +0772 model.annotation.givenName=modelSBML.annotation(J(1)+13:I(find(I>J(1),1))-1); +0773 end +0774 J=strfind(modelSBML.annotation,'<vCard:EMAIL>'); +0775 if any(J) +0776 model.annotation.email=modelSBML.annotation(J(1)+13:I(find(I>J(1),1))-1); +0777 end +0778 J=strfind(modelSBML.annotation,'<vCard:Orgname>'); +0779 if any(J) +0780 model.annotation.organization=modelSBML.annotation(J(1)+15:I(find(I>J(1),1))-1); +0781 end +0782 endString='"/>'; +0783 I=strfind(modelSBML.annotation,endString); +0784 if strfind(modelSBML.annotation,'"urn:miriam:') +0785 J=strfind(modelSBML.annotation,'"urn:miriam:'); +0786 if any(J) +0787 model.annotation.taxonomy=modelSBML.annotation(J+12:I(find(I>J,1))-1); +0788 end +0789 else +0790 J=strfind(modelSBML.annotation,'"http://identifiers.org/'); +0791 if any(J) +0792 model.annotation.taxonomy=modelSBML.annotation(J+24:I(find(I>J,1))-1); +0793 else +0794 J=strfind(modelSBML.annotation,'"https://identifiers.org/'); +0795 if any(J) +0796 model.annotation.taxonomy=modelSBML.annotation(J+25:I(find(I>J,1))-1); +0797 end +0798 end +0799 end +0800 end +0801 if isfield(modelSBML,'notes') +0802 startString=strfind(modelSBML.notes,'xhtml">'); +0803 endString=strfind(modelSBML.notes,'</body>'); +0804 if any(startString) && any(endString) +0805 model.annotation.note=modelSBML.notes(startString+7:endString-1); +0806 model.annotation.note=regexprep(model.annotation.note,'<p>|</p>',''); +0807 model.annotation.note=strtrim(model.annotation.note); +0808 if regexp(model.annotation.note,'This file was generated using the exportModel function in RAVEN Toolbox \d\.\d and OutputSBML in libSBML') +0809 model.annotation=rmfield(model.annotation,'note'); % Default note added when running exportModel +0810 end +0811 end +0812 end +0813 +0814 if any(~cellfun(@isempty,compartmentOutside)) +0815 model.compOutside=compartmentOutside; +0816 end +0817 +0818 model.rxnNames=reactionNames; +0819 model.metNames=metaboliteNames; +0820 +0821 %Match the compartments for metabolites +0822 [~, J]=ismember(metaboliteCompartments,model.comps); +0823 model.metComps=J; +0824 +0825 %If any genes have been loaded (only for the new format) +0826 if ~isempty(geneNames) +0827 %In some rare cases geneNames may not necessarily be used in grRules. +0828 %That is true for Yeast 7.6. It's therefore important to change gene +0829 %systematic names to geneIDs in sophisticated way. Gene systematic +0830 %names are not unique, since exactly the same name may be in different +0831 %compartments +0832 if all(cellfun(@isempty,strfind(grRules,geneNames{1}))) +0833 geneShortNames=geneNames; +0834 %geneShortNames contain compartments as well, so these are removed +0835 geneShortNames=regexprep(geneShortNames,' \[.+$',''); +0836 %grRules obtained from modifier fields contain geneNames. These are +0837 %changed into geneIDs. grRulesFromModifier is a good way to have +0838 %geneIDs and rxns association when it's important to resolve +0839 %systematic name ambiguities +0840 grRulesFromModifier=regexprep(regexprep(grRulesFromModifier,'\[|\]','_'),regexprep(geneNames,'\[|\]','_'),geneIDs); +0841 grRules=regexprep(regexprep(grRules,'\[|\]','_'),regexprep(geneNames,'\[|\]','_'),geneIDs); +0842 +0843 %Yeast 7.6 contains several metabolites, which were used in gene +0844 %associations. For that reason, the list of species ID is created +0845 %and we then check whether any of them have kegg.genes annotation +0846 %thereby obtaining systematic gene names +0847 geneShortNames=vertcat(geneShortNames,metaboliteNames); +0848 geneIDs=vertcat(geneIDs,metaboliteIDs); +0849 geneSystNames=extractMiriam(vertcat(geneMiriams,metaboliteMiriams),'kegg.genes'); +0850 geneCompartments=vertcat(geneCompartments,metaboliteCompartments); +0851 geneMiriams=vertcat(geneMiriams,metaboliteMiriams); +0852 +0853 %Now we retain information for only these entries, which have +0854 %kegg.genes annotation +0855 geneShortNames=geneShortNames(~cellfun('isempty',geneSystNames)); +0856 geneIDs=geneIDs(~cellfun('isempty',geneSystNames)); +0857 geneSystNames=geneSystNames(~cellfun('isempty',geneSystNames)); +0858 geneCompartments=geneCompartments(~cellfun('isempty',geneSystNames)); +0859 geneMiriams=geneMiriams(~cellfun('isempty',geneSystNames)); +0860 %Now we reorder geneIDs and geneSystNames by geneSystNames string +0861 %length +0862 geneNames=geneIDs;%Backuping geneIDs, since we need unsorted order for later +0863 [~, Indx] = sort(cellfun('size', geneSystNames, 2), 'descend'); +0864 geneIDs = geneIDs(Indx); +0865 geneSystNames = geneSystNames(Indx); +0866 for i=1:numel(geneSystNames) +0867 for j=1:numel(grRules) +0868 if strfind(grRules{j},geneSystNames{i}) +0869 if ~isempty(grRules{j}) +0870 if sum(ismember(geneSystNames,geneSystNames{i}))==1 +0871 grRules{j}=regexprep(grRules{j},geneSystNames{i},geneIDs{i}); +0872 elseif sum(ismember(geneSystNames,geneSystNames{i}))>1 +0873 counter=0; +0874 ovrlpIDs=geneIDs(ismember(geneSystNames,geneSystNames{i})); +0875 for k=1:numel(ovrlpIDs) +0876 if strfind(grRulesFromModifier{j},ovrlpIDs{k}) +0877 counter=counter+1; +0878 grRules{j}=regexprep(grRules{j},geneSystNames{i},ovrlpIDs{k}); +0879 end +0880 if counter>1 +0881 EM=['Gene association is ambiguous for reaction ' modelSBML.reaction(j).id]; +0882 dispEM(EM); +0883 end +0884 end +0885 end +0886 end +0887 end +0888 end +0889 end +0890 end +0891 model.genes=geneNames; +0892 model.grRules=grRules; +0893 [grRules,rxnGeneMat] = standardizeGrRules(model,true); +0894 model.grRules = grRules; +0895 model.rxnGeneMat = rxnGeneMat; +0896 +0897 %Match the compartments for genes +0898 [~, J]=ismember(geneCompartments,model.comps); +0899 model.geneComps=J; +0900 else +0901 if ~all(cellfun(@isempty,grRules)) +0902 %If fbc_geneProduct exists, follow the specified gene order, such +0903 %that matching geneShortNames in function below will work +0904 if isfield(modelSBML,'fbc_geneProduct') +0905 genes={modelSBML.fbc_geneProduct.fbc_id}; +0906 +0907 %Get gene Miriams if they were not retrieved above (this occurs +0908 %when genes are stored as fbc_geneProduct instead of species) +0909 if isempty(geneMiriams) +0910 geneMiriams = cell(numel(genes),1); +0911 if isfield(modelSBML.fbc_geneProduct,'sboTerm') && numel(unique([modelSBML.fbc_geneProduct.sboTerm])) == 1 +0912 %If all the SBO terms are identical, don't add them to geneMiriams +0913 modelSBML.fbc_geneProduct = rmfield(modelSBML.fbc_geneProduct,'sboTerm'); +0914 end +0915 for i = 1:numel(genes) +0916 geneMiriams{i}=parseMiriam(modelSBML.fbc_geneProduct(i).annotation); +0917 if isfield(modelSBML.fbc_geneProduct(i),'sboTerm') && ~(modelSBML.fbc_geneProduct(i).sboTerm==-1) +0918 geneMiriams{i} = addSBOtoMiriam(geneMiriams{i},modelSBML.fbc_geneProduct(i).sboTerm); +0919 end +0920 end +0921 end +0922 else +0923 genes=getGeneList(grRules); +0924 end +0925 if strcmpi(genes{1}(1:2),'G_') +0926 genes=regexprep(genes,'^G_',''); +0927 grRules=regexprep(grRules,'^G_',''); +0928 grRules=regexprep(grRules,'\(G_','('); +0929 grRules=regexprep(grRules,' G_',' '); +0930 end +0931 model.genes=genes; +0932 model.grRules=grRules; +0933 [grRules,rxnGeneMat] = standardizeGrRules(model,true); +0934 model.grRules = grRules; +0935 model.rxnGeneMat = rxnGeneMat; +0936 end +0937 end +0938 +0939 if all(cellfun(@isempty,geneShortNames)) +0940 if isfield(modelSBML,'fbc_geneProduct') +0941 for i=1:numel(genes) +0942 if ~isempty(modelSBML.fbc_geneProduct(i).fbc_label) +0943 geneShortNames{i,1}=modelSBML.fbc_geneProduct(i).fbc_label; +0944 elseif ~isempty(modelSBML.fbc_geneProduct(i).fbc_name) +0945 geneShortNames{i,1}=modelSBML.fbc_geneProduct(i).fbc_name; +0946 else +0947 geneShortNames{i,1}=''; +0948 end +0949 end +0950 end +0951 end +0952 +0953 %If any InChIs have been loaded +0954 if any(~cellfun(@isempty,metaboliteInChI)) +0955 model.inchis=metaboliteInChI; +0956 end +0957 +0958 %If any formulas have been loaded +0959 if any(~cellfun(@isempty,metaboliteFormula)) +0960 model.metFormulas=metaboliteFormula; +0961 end +0962 +0963 %If any charges have been loaded +0964 if ~isempty(metaboliteCharges) +0965 model.metCharges=metaboliteCharges; +0966 end +0967 +0968 %If any gene short names have been loaded +0969 if any(~cellfun(@isempty,geneShortNames)) +0970 model.geneShortNames=geneShortNames; +0971 end +0972 +0973 %If any Miriam strings for compartments have been loaded +0974 if any(~cellfun(@isempty,compartmentMiriams)) +0975 model.compMiriams=compartmentMiriams; +0976 end +0977 +0978 %If any Miriam strings for metabolites have been loaded +0979 if any(~cellfun(@isempty,metaboliteMiriams)) +0980 model.metMiriams=metaboliteMiriams; +0981 end +0982 +0983 %If any subsystems have been loaded +0984 if any(~cellfun(@isempty,subsystems)) +0985 model.subSystems=subsystems; +0986 end +0987 if any(rxnComps) +0988 if all(rxnComps) +0989 model.rxnComps=rxnComps; +0990 else +0991 if supressWarnings==false +0992 EM='The compartments for the following reactions could not be matched. Ignoring reaction compartment information'; +0993 dispEM(EM,false,model.rxns(rxnComps==0)); +0994 end +0995 end +0996 end +0997 +0998 %If any ec-codes have been loaded +0999 if any(~cellfun(@isempty,eccodes)) +1000 model.eccodes=eccodes; +1001 end +1002 +1003 %If any Miriam strings for reactions have been loaded +1004 if any(~cellfun(@isempty,rxnMiriams)) +1005 model.rxnMiriams=rxnMiriams; +1006 end +1007 +1008 %If any Miriam strings for genes have been loaded +1009 if any(~cellfun(@isempty,geneMiriams)) +1010 model.geneMiriams=geneMiriams; +1011 end +1012 +1013 model.unconstrained=metaboliteUnconstrained; +1014 +1015 %Convert SBML IDs back into their original strings. Here we are using part +1016 %from convertSBMLID, originating from the COBRA Toolbox +1017 model.rxns=regexprep(model.rxns,'__([0-9]+)__','${char(str2num($1))}'); +1018 model.mets=regexprep(model.mets,'__([0-9]+)__','${char(str2num($1))}'); +1019 model.comps=regexprep(model.comps,'__([0-9]+)__','${char(str2num($1))}'); +1020 model.grRules=regexprep(model.grRules,'__([0-9]+)__','${char(str2num($1))}'); +1021 model.genes=regexprep(model.genes,'__([0-9]+)__','${char(str2num($1))}'); +1022 model.id=regexprep(model.id,'__([0-9]+)__','${char(str2num($1))}'); +1023 +1024 %Remove unused fields +1025 if isempty(model.annotation) +1026 model=rmfield(model,'annotation'); +1027 end +1028 if isempty(model.compOutside) +1029 model=rmfield(model,'compOutside'); +1030 end +1031 if isempty(model.compMiriams) +1032 model=rmfield(model,'compMiriams'); +1033 end +1034 if isempty(model.rxnComps) +1035 model=rmfield(model,'rxnComps'); +1036 end +1037 if isempty(model.grRules) +1038 model=rmfield(model,'grRules'); +1039 end +1040 if isempty(model.rxnGeneMat) +1041 model=rmfield(model,'rxnGeneMat'); +1042 end +1043 if isempty(model.subSystems) +1044 model=rmfield(model,'subSystems'); +1045 else +1046 model.subSystems(cellfun(@isempty,subsystems))={{''}}; +1047 end +1048 if isempty(model.eccodes) +1049 model=rmfield(model,'eccodes'); +1050 end +1051 if isempty(model.rxnMiriams) +1052 model=rmfield(model,'rxnMiriams'); +1053 end +1054 if cellfun(@isempty,model.rxnNotes) +1055 model=rmfield(model,'rxnNotes'); +1056 end +1057 if cellfun(@isempty,model.rxnReferences) +1058 model=rmfield(model,'rxnReferences'); +1059 end +1060 if isempty(model.rxnConfidenceScores) || all(isnan(model.rxnConfidenceScores)) +1061 model=rmfield(model,'rxnConfidenceScores'); +1062 end +1063 if isempty(model.genes) +1064 model=rmfield(model,'genes'); +1065 elseif isrow(model.genes) +1066 model.genes=transpose(model.genes); +1067 end +1068 if isempty(model.geneComps) +1069 model=rmfield(model,'geneComps'); +1070 end +1071 if isempty(model.geneMiriams) +1072 model=rmfield(model,'geneMiriams'); +1073 end +1074 if isempty(model.geneShortNames) +1075 model=rmfield(model,'geneShortNames'); +1076 end +1077 if isempty(model.inchis) +1078 model=rmfield(model,'inchis'); +1079 end +1080 if isempty(model.metFormulas) +1081 model=rmfield(model,'metFormulas'); +1082 end +1083 if isempty(model.metMiriams) +1084 model=rmfield(model,'metMiriams'); +1085 end +1086 if ~any(model.metCharges) +1087 model=rmfield(model,'metCharges'); +1088 end +1089 +1090 %This just removes the grRules if no genes have been loaded +1091 if ~isfield(model,'genes') && isfield(model,'grRules') +1092 model=rmfield(model,'grRules'); +1093 end +1094 +1095 %Print warnings about bad structure +1096 if supressWarnings==false +1097 checkModelStruct(model,false); +1098 end +1099 +1100 if removeExcMets==true +1101 model=simplifyModel(model); 1102 end -1103 -1104 function matchGenes=getGeneList(grRules) -1105 %Constructs the list of unique genes from grRules -1106 -1107 %Assumes that everything that isn't a paranthesis, " AND " or " or " is a -1108 %gene name -1109 genes=strrep(grRules,'(',''); -1110 genes=strrep(genes,')',''); -1111 genes=strrep(genes,' or ',' '); -1112 genes=strrep(genes,' and ',' '); -1113 genes=strrep(genes,' OR ',' '); -1114 genes=strrep(genes,' AND ',' '); -1115 genes=regexp(genes,' ','split'); -1116 -1117 allNames={}; -1118 for i=1:numel(genes) -1119 allNames=[allNames genes{i}]; -1120 end -1121 matchGenes=unique(allNames)'; -1122 -1123 %Remove the empty element if present -1124 if isempty(matchGenes{1}) -1125 matchGenes(1)=[]; -1126 end +1103 end +1104 +1105 function matchGenes=getGeneList(grRules) +1106 %Constructs the list of unique genes from grRules +1107 +1108 %Assumes that everything that isn't a paranthesis, " AND " or " or " is a +1109 %gene name +1110 genes=strrep(grRules,'(',''); +1111 genes=strrep(genes,')',''); +1112 genes=strrep(genes,' or ',' '); +1113 genes=strrep(genes,' and ',' '); +1114 genes=strrep(genes,' OR ',' '); +1115 genes=strrep(genes,' AND ',' '); +1116 genes=regexp(genes,' ','split'); +1117 +1118 allNames={}; +1119 for i=1:numel(genes) +1120 allNames=[allNames genes{i}]; +1121 end +1122 matchGenes=unique(allNames)'; +1123 +1124 %Remove the empty element if present +1125 if isempty(matchGenes{1}) +1126 matchGenes(1)=[]; 1127 end -1128 -1129 function fieldContent=parseNote(searchString,fieldName) -1130 %The function obtains the particular information from 'notes' field, using -1131 %fieldName as the dummy string -1132 -1133 fieldContent=''; -1134 -1135 if strfind(searchString,fieldName) -1136 [~,targetString] = regexp(searchString,['<p>' fieldName '.*?</p>'],'tokens','match'); -1137 targetString=regexprep(targetString,'<p>|</p>',''); -1138 targetString=regexprep(targetString,[fieldName, ':'],''); -1139 for i=1:numel(targetString) -1140 fieldContent=[fieldContent ';' strtrim(targetString{1,i})]; -1141 end -1142 fieldContent=regexprep(fieldContent,'^;|;$',''); -1143 else -1144 fieldContent=''; -1145 end +1128 end +1129 +1130 function fieldContent=parseNote(searchString,fieldName) +1131 %The function obtains the particular information from 'notes' field, using +1132 %fieldName as the dummy string +1133 +1134 fieldContent=''; +1135 +1136 if strfind(searchString,fieldName) +1137 [~,targetString] = regexp(searchString,['<p>' fieldName '.*?</p>'],'tokens','match'); +1138 targetString=regexprep(targetString,'<p>|</p>',''); +1139 targetString=regexprep(targetString,[fieldName, ':'],''); +1140 for i=1:numel(targetString) +1141 fieldContent=[fieldContent ';' strtrim(targetString{1,i})]; +1142 end +1143 fieldContent=regexprep(fieldContent,'^;|;$',''); +1144 else +1145 fieldContent=''; 1146 end -1147 -1148 function fieldContent=parseAnnotation(searchString,startString,midString,fieldName) -1149 -1150 fieldContent=''; -1151 -1152 %Removing whitespace characters from the ending strings, which may occur in -1153 %several cases -1154 searchString=regexprep(searchString,'" />','"/>'); -1155 [~,targetString] = regexp(searchString,['<rdf:li rdf:resource="' startString fieldName midString '.*?"/>'],'tokens','match'); -1156 targetString=regexprep(targetString,'<rdf:li rdf:resource="|"/>',''); -1157 targetString=regexprep(targetString,startString,''); -1158 targetString=regexprep(targetString,[fieldName midString],''); -1159 -1160 for i=1:numel(targetString) -1161 fieldContent=[fieldContent ';' strtrim(targetString{1,i})]; -1162 end -1163 -1164 fieldContent=regexprep(fieldContent,'^;|;$',''); -1165 end -1166 -1167 function miriamStruct=parseMiriam(searchString) -1168 %Generates miriam structure from annotation field -1169 -1170 %Finding whether miriams are written in the old or the new way -1171 if strfind(searchString,'urn:miriam:') -1172 startString='urn:miriam:'; -1173 midString=':'; -1174 elseif strfind(searchString,'http://identifiers.org/') -1175 startString='http://identifiers.org/'; -1176 midString='/'; -1177 elseif strfind(searchString,'https://identifiers.org/') -1178 startString='https://identifiers.org/'; -1179 midString='/'; -1180 else -1181 miriamStruct=[]; -1182 return; -1183 end -1184 -1185 miriamStruct=[]; -1186 -1187 searchString=regexprep(searchString,'" />','"/>'); -1188 [~,targetString] = regexp(searchString,'<rdf:li rdf:resource=".*?"/>','tokens','match'); -1189 targetString=regexprep(targetString,'<rdf:li rdf:resource="|"/>',''); -1190 targetString=regexprep(targetString,startString,''); -1191 targetString=regexprep(targetString,midString,'/','once'); -1192 -1193 counter=0; -1194 for i=1:numel(targetString) -1195 if isempty(regexp(targetString{1,i},'inchi|ec-code', 'once')) -1196 counter=counter+1; -1197 miriamStruct.name{counter,1} = regexprep(targetString{1,i},'/.+','','once'); -1198 miriamStruct.value{counter,1} = regexprep(targetString{1,i},[miriamStruct.name{counter,1} '/'],'','once'); -1199 miriamStruct.name{counter,1} = regexprep(miriamStruct.name{counter,1},'^obo\.',''); -1200 end -1201 end +1147 end +1148 +1149 function fieldContent=parseAnnotation(searchString,startString,midString,fieldName) +1150 +1151 fieldContent=''; +1152 +1153 %Removing whitespace characters from the ending strings, which may occur in +1154 %several cases +1155 searchString=regexprep(searchString,'" />','"/>'); +1156 [~,targetString] = regexp(searchString,['<rdf:li rdf:resource="' startString fieldName midString '.*?"/>'],'tokens','match'); +1157 targetString=regexprep(targetString,'<rdf:li rdf:resource="|"/>',''); +1158 targetString=regexprep(targetString,startString,''); +1159 targetString=regexprep(targetString,[fieldName midString],''); +1160 +1161 for i=1:numel(targetString) +1162 fieldContent=[fieldContent ';' strtrim(targetString{1,i})]; +1163 end +1164 +1165 fieldContent=regexprep(fieldContent,'^;|;$',''); +1166 end +1167 +1168 function miriamStruct=parseMiriam(searchString) +1169 %Generates miriam structure from annotation field +1170 +1171 %Finding whether miriams are written in the old or the new way +1172 if strfind(searchString,'urn:miriam:') +1173 startString='urn:miriam:'; +1174 midString=':'; +1175 elseif strfind(searchString,'http://identifiers.org/') +1176 startString='http://identifiers.org/'; +1177 midString='/'; +1178 elseif strfind(searchString,'https://identifiers.org/') +1179 startString='https://identifiers.org/'; +1180 midString='/'; +1181 else +1182 miriamStruct=[]; +1183 return; +1184 end +1185 +1186 miriamStruct=[]; +1187 +1188 searchString=regexprep(searchString,'" />','"/>'); +1189 [~,targetString] = regexp(searchString,'<rdf:li rdf:resource=".*?"/>','tokens','match'); +1190 targetString=regexprep(targetString,'<rdf:li rdf:resource="|"/>',''); +1191 targetString=regexprep(targetString,startString,''); +1192 targetString=regexprep(targetString,midString,'/','once'); +1193 +1194 counter=0; +1195 for i=1:numel(targetString) +1196 if isempty(regexp(targetString{1,i},'inchi|ec-code', 'once')) +1197 counter=counter+1; +1198 miriamStruct.name{counter,1} = regexprep(targetString{1,i},'/.+','','once'); +1199 miriamStruct.value{counter,1} = regexprep(targetString{1,i},[miriamStruct.name{counter,1} '/'],'','once'); +1200 miriamStruct.name{counter,1} = regexprep(miriamStruct.name{counter,1},'^obo\.',''); +1201 end 1202 end -1203 -1204 function miriam = addSBOtoMiriam(miriam,sboTerm) -1205 %Appends SBO term to miriam structure -1206 -1207 sboTerm = {['SBO:' sprintf('%07u',sboTerm)]}; % convert to proper format -1208 if isempty(miriam) -1209 miriam.name = {'sbo'}; -1210 miriam.value = sboTerm; -1211 elseif any(strcmp('sbo',miriam.name)) -1212 currSbo = strcmp('sbo',miriam.name); -1213 miriam.value(currSbo) = sboTerm; -1214 else -1215 miriam.name(end+1) = {'sbo'}; -1216 miriam.value(end+1) = sboTerm; -1217 end -1218 end +1203 end +1204 +1205 function miriam = addSBOtoMiriam(miriam,sboTerm) +1206 %Appends SBO term to miriam structure +1207 +1208 sboTerm = {['SBO:' sprintf('%07u',sboTerm)]}; % convert to proper format +1209 if isempty(miriam) +1210 miriam.name = {'sbo'}; +1211 miriam.value = sboTerm; +1212 elseif any(strcmp('sbo',miriam.name)) +1213 currSbo = strcmp('sbo',miriam.name); +1214 miriam.value(currSbo) = sboTerm; +1215 else +1216 miriam.name(end+1) = {'sbo'}; +1217 miriam.value(end+1) = sboTerm; +1218 end +1219 end
Generated by m2html © 2005
\ No newline at end of file diff --git a/doc/solver/optimizeProb.html b/doc/solver/optimizeProb.html index d4c23ea0..ebc32e00 100644 --- a/doc/solver/optimizeProb.html +++ b/doc/solver/optimizeProb.html @@ -109,7 +109,7 @@

SOURCE CODE ^end -0058 +0058 res.obj=[]; 0059 switch solver 0060 %% Use whatever solver is set by COBRA Toolbox changeCobraSolver 0061 case 'cobra' diff --git a/doc/solver/solveLP.html b/doc/solver/solveLP.html index 0ce7bec9..05add194 100644 --- a/doc/solver/solveLP.html +++ b/doc/solver/solveLP.html @@ -183,126 +183,128 @@

SOURCE CODE ^% Parse the problem to the LP solver 0104 res = optimizeProb(prob,params); -0105 -0106 %Check if the problem was feasible and that the solution was optimal -0107 [isFeasible, isOptimal]=checkSolution(res); -0108 -0109 %If the problem was infeasible using hot-start it is often possible to -0110 %re-solve it without hot-start and get a feasible solution -0111 if ~isFeasible && ~isempty(hsSol) -0112 prob=rmfield(prob,{'vbasis','cbasis'}); -0113 res=optimizeProb(prob,params); -0114 [isFeasible, isOptimal]=checkSolution(res); -0115 end -0116 -0117 %Return without solution if the problem was infeasible -0118 if ~isFeasible -0119 solution.msg='The problem is infeasible'; -0120 return; -0121 end -0122 if ~isOptimal -0123 solution.msg='The problem is feasible, but not necessarily optimal'; -0124 solution.stat=0; -0125 else -0126 %All is well -0127 solution.stat=1; -0128 solution.msg='Optimal solution found'; -0129 end -0130 -0131 %Construct the output structure -0132 if isfield(res,'full') -0133 solution.x=res.full; -0134 if minFlux<=1 -0135 if(isfield(res,'vbasis')) % gurobi uses vbasis and cbasis as hotstart -0136 hsSolOut.vbasis=res.vbasis; -0137 hsSolOut.cbasis=res.cbasis; -0138 end -0139 end -0140 solution.f=res.obj; -0141 if isfield(res,'dual') -0142 solution.sPrice=res.dual; -0143 else -0144 solution.sPrice=[]; -0145 end -0146 if isfield(res,'rcost') -0147 solution.rCost=res.rcost(1:numel(model.rxns)); -0148 else -0149 solution.rCost=[]; -0150 end -0151 -0152 %If either the square, the number, or the sum of fluxes should be minimized -0153 %then the objective function value should be fixed before another -0154 %optimization. It is not correct to fix the reactions which participate in -0155 %the objective function to their values in solution.x, as there can be -0156 %multiple solutions with the same objective function value. In addition, -0157 %this approach could result in numerical issues when several fluxes are -0158 %fixed. Instead a new "fake metabolite" is added to the problem. This -0159 %metabolite is produced by each reaction with the stoichiometry that -0160 %reaction has in the objective function. The equality constraint of that -0161 %"fake metabolite" is then set to be at least as good as the objective -0162 %function value. -0163 if minFlux~=0 -0164 model.S=[model.S;(model.c*-1)']; -0165 model.mets=[model.mets;'TEMP']; -0166 -0167 %If the constraint on the objective function value is exact there is a -0168 %larger risk of numerical errors. However for the quadratic fitting -0169 %intervals are not allowed -0170 if minFlux~=2 -0171 if size(model.b,2)==1 -0172 model.b=[model.b model.b]; -0173 end -0174 if solution.f<0 -0175 model.b=[model.b;[-inf solution.f*0.999999]]; -0176 else -0177 model.b=[model.b;[-inf solution.f*1.000001]]; -0178 end -0179 else -0180 model.b=[model.b;ones(1,size(model.b,2))*solution.f]; -0181 end -0182 -0183 switch minFlux -0184 %The sum of fluxes should be minimized -0185 case 1 -0186 %Convert the model to the irreversible format -0187 revRxns=find(model.rev); -0188 if ~isempty(revRxns) -0189 iModel=convertToIrrev(model); -0190 else -0191 iModel=model; -0192 end -0193 %Minimize all fluxes -0194 iModel.c(:)=-1; -0195 sol=solveLP(iModel,0,params); -0196 -0197 %Map back to reversible fluxes -0198 if sol.stat>=0 -0199 solution.x=sol.x(1:numel(model.c)); -0200 solution.x(revRxns)=solution.x(revRxns)-sol.x(numel(model.c)+1:end); -0201 else -0202 EM='Could not solve the problem of minimizing the sum of fluxes. Uses output from original problem'; -0203 dispEM(EM,false); -0204 solution.stat=-2; -0205 end -0206 -0207 case 2 -0208 error('%Minimization of square of fluxes is deprecated') -0209 -0210 %The number of fluxes should be minimized -0211 case 3 -0212 [qx,I]=getMinNrFluxes(model,model.rxns,params); -0213 qx(~I)=0; -0214 if any(I) -0215 solution.x=qx; -0216 else -0217 EM='Could not solve the problem of minimizing the number of fluxes. Uses output from linear program'; -0218 dispEM(EM,false); -0219 solution.stat=-2; -0220 end -0221 end -0222 solution=rmfield(solution,{'sPrice','rCost'}); -0223 end -0224 end +0105 % Swap the sign of the obj-value +0106 res.obj = -res.obj; +0107 +0108 %Check if the problem was feasible and that the solution was optimal +0109 [isFeasible, isOptimal]=checkSolution(res); +0110 +0111 %If the problem was infeasible using hot-start it is often possible to +0112 %re-solve it without hot-start and get a feasible solution +0113 if ~isFeasible && ~isempty(hsSol) +0114 prob=rmfield(prob,{'vbasis','cbasis'}); +0115 res=optimizeProb(prob,params); +0116 [isFeasible, isOptimal]=checkSolution(res); +0117 end +0118 +0119 %Return without solution if the problem was infeasible +0120 if ~isFeasible +0121 solution.msg='The problem is infeasible'; +0122 return; +0123 end +0124 if ~isOptimal +0125 solution.msg='The problem is feasible, but not necessarily optimal'; +0126 solution.stat=0; +0127 else +0128 %All is well +0129 solution.stat=1; +0130 solution.msg='Optimal solution found'; +0131 end +0132 +0133 %Construct the output structure +0134 if isfield(res,'full') +0135 solution.x=res.full; +0136 if minFlux<=1 +0137 if(isfield(res,'vbasis')) % gurobi uses vbasis and cbasis as hotstart +0138 hsSolOut.vbasis=res.vbasis; +0139 hsSolOut.cbasis=res.cbasis; +0140 end +0141 end +0142 solution.f=res.obj; +0143 if isfield(res,'dual') +0144 solution.sPrice=res.dual; +0145 else +0146 solution.sPrice=[]; +0147 end +0148 if isfield(res,'rcost') +0149 solution.rCost=res.rcost(1:numel(model.rxns)); +0150 else +0151 solution.rCost=[]; +0152 end +0153 +0154 %If either the square, the number, or the sum of fluxes should be minimized +0155 %then the objective function value should be fixed before another +0156 %optimization. It is not correct to fix the reactions which participate in +0157 %the objective function to their values in solution.x, as there can be +0158 %multiple solutions with the same objective function value. In addition, +0159 %this approach could result in numerical issues when several fluxes are +0160 %fixed. Instead a new "fake metabolite" is added to the problem. This +0161 %metabolite is produced by each reaction with the stoichiometry that +0162 %reaction has in the objective function. The equality constraint of that +0163 %"fake metabolite" is then set to be at least as good as the objective +0164 %function value. +0165 if minFlux~=0 +0166 model.S=[model.S;(model.c*-1)']; +0167 model.mets=[model.mets;'TEMP']; +0168 +0169 %If the constraint on the objective function value is exact there is a +0170 %larger risk of numerical errors. However for the quadratic fitting +0171 %intervals are not allowed +0172 if minFlux~=2 +0173 if size(model.b,2)==1 +0174 model.b=[model.b model.b]; +0175 end +0176 if solution.f<0 +0177 model.b=[model.b;[-inf solution.f*0.999999]]; +0178 else +0179 model.b=[model.b;[-inf solution.f*1.000001]]; +0180 end +0181 else +0182 model.b=[model.b;ones(1,size(model.b,2))*solution.f]; +0183 end +0184 +0185 switch minFlux +0186 %The sum of fluxes should be minimized +0187 case 1 +0188 %Convert the model to the irreversible format +0189 revRxns=find(model.rev); +0190 if ~isempty(revRxns) +0191 iModel=convertToIrrev(model); +0192 else +0193 iModel=model; +0194 end +0195 %Minimize all fluxes +0196 iModel.c(:)=-1; +0197 sol=solveLP(iModel,0,params); +0198 +0199 %Map back to reversible fluxes +0200 if sol.stat>=0 +0201 solution.x=sol.x(1:numel(model.c)); +0202 solution.x(revRxns)=solution.x(revRxns)-sol.x(numel(model.c)+1:end); +0203 else +0204 EM='Could not solve the problem of minimizing the sum of fluxes. Uses output from original problem'; +0205 dispEM(EM,false); +0206 solution.stat=-2; +0207 end +0208 +0209 case 2 +0210 error('%Minimization of square of fluxes is deprecated') +0211 +0212 %The number of fluxes should be minimized +0213 case 3 +0214 [qx,I]=getMinNrFluxes(model,model.rxns,params); +0215 qx(~I)=0; +0216 if any(I) +0217 solution.x=qx; +0218 else +0219 EM='Could not solve the problem of minimizing the number of fluxes. Uses output from linear program'; +0220 dispEM(EM,false); +0221 solution.stat=-2; +0222 end +0223 end +0224 solution=rmfield(solution,{'sPrice','rCost'}); +0225 end +0226 end
Generated by m2html © 2005
\ No newline at end of file diff --git a/doc/testing/unit_tests/fillGapsLargeTests.html b/doc/testing/unit_tests/fillGapsLargeTests.html index cea0e3c4..63fb598e 100644 --- a/doc/testing/unit_tests/fillGapsLargeTests.html +++ b/doc/testing/unit_tests/fillGapsLargeTests.html @@ -53,92 +53,94 @@

SOURCE CODE ^if testGurobi 0007 try 0008 gurobi_read('solverTests.m'); -0009 catch -0010 testGurobi = false; -0011 end -0012 end -0013 if ~testGurobi -0014 disp('Gurobi not installed or cannot be found in MATLAB path, some fillGapsLargeTests skipped.') -0015 skipTests = contains({tests.Name},'gurobi','IgnoreCase',true); -0016 tests(skipTests) = []; -0017 end -0018 if exist('scip','file')~=3 -0019 disp('SCIP MEX binary not installed or not functional, some fillGapsLargeTests skipped.') -0020 skipTests = contains({tests.Name},'scip','IgnoreCase',true); -0021 tests(skipTests) = []; -0022 end -0023 end -0024 -0025 function testLargeGurobi(testCase) -0026 sourceDir = fileparts(fileparts(fileparts(which(mfilename)))); -0027 evalc('model=importModel(fullfile(sourceDir,''tutorial'',''iAL1006 v1.00.xml''))'); -0028 model.c(1484)=1; -0029 modelDB=model; % Keep as database with reactions -0030 try -0031 oldSolver=getpref('RAVEN','solver'); -0032 catch -0033 end -0034 setRavenSolver('gurobi'); -0035 -0036 %Remove first 10 reactions -0037 model=removeReactions(modelDB,(1:10)); -0038 modelDB.id='DB'; -0039 try -0040 evalc('[newConnected,cannotConnect,addedRxns,model,exitFlag]=fillGaps(model,modelDB,false,false)'); -0041 catch -0042 try -0043 setRavenSolver(oldSolver); -0044 catch -0045 rmpref('RAVEN','solver'); -0046 end -0047 error('Solver not working') -0048 end -0049 sol=solveLP(model); -0050 try -0051 setRavenSolver(oldSolver); -0052 catch -0053 rmpref('RAVEN','solver'); -0054 end -0055 %Expect at least 5% of the original growth -0056 verifyTrue(testCase,-sol.f>0); -0057 end -0058 -0059 function testLargeSCIP(testCase) -0060 sourceDir = fileparts(fileparts(fileparts(which(mfilename)))); -0061 evalc('model=importModel(fullfile(sourceDir,''tutorial'',''iAL1006 v1.00.xml''))'); -0062 model.c(1484)=1; -0063 modelDB=model; % Keep as database with reactions -0064 % Force growth in gapped model -0065 sol=solveLP(model); -0066 model.lb(1484)=abs(sol.f*0.1); -0067 try -0068 oldSolver=getpref('RAVEN','solver'); -0069 catch -0070 end -0071 setRavenSolver('scip'); -0072 -0073 %Remove first 10 reactions -0074 model=removeReactions(model,(1:10)); -0075 modelDB.id='DB'; -0076 try -0077 evalc('[newConnected,cannotConnect,addedRxns,model,exitFlag]=fillGaps(model,modelDB,false,true)'); -0078 catch -0079 try -0080 setRavenSolver(oldSolver); -0081 catch -0082 rmpref('RAVEN','solver'); -0083 end -0084 error('Solver not working') -0085 end -0086 sol=solveLP(model); -0087 try -0088 setRavenSolver(oldSolver); -0089 catch -0090 rmpref('RAVEN','solver'); -0091 end -0092 %Expect at least 5% of the original growth -0093 verifyTrue(testCase,-sol.f>0); -0094 end +0009 catch ME +0010 if ~startsWith(ME.message,'Gurobi error 10012') % Expected error code, others may indicate problems with license +0011 testGurobi = false; +0012 end +0013 end +0014 end +0015 if ~testGurobi +0016 disp('Gurobi not installed or not functional, some fillGapsLargeTests skipped.') +0017 skipTests = contains({tests.Name},'gurobi','IgnoreCase',true); +0018 tests(skipTests) = []; +0019 end +0020 if exist('scip','file')~=3 +0021 disp('SCIP MEX binary not installed or not functional, some fillGapsLargeTests skipped.') +0022 skipTests = contains({tests.Name},'scip','IgnoreCase',true); +0023 tests(skipTests) = []; +0024 end +0025 end +0026 +0027 function testLargeGurobi(testCase) +0028 sourceDir = fileparts(fileparts(fileparts(which(mfilename)))); +0029 evalc('model=importModel(fullfile(sourceDir,''tutorial'',''iAL1006 v1.00.xml''))'); +0030 model.c(1484)=1; +0031 modelDB=model; % Keep as database with reactions +0032 try +0033 oldSolver=getpref('RAVEN','solver'); +0034 catch +0035 end +0036 setRavenSolver('gurobi'); +0037 +0038 %Remove first 10 reactions +0039 model=removeReactions(modelDB,(1:10)); +0040 modelDB.id='DB'; +0041 try +0042 evalc('[newConnected,cannotConnect,addedRxns,model,exitFlag]=fillGaps(model,modelDB,false,false)'); +0043 catch +0044 try +0045 setRavenSolver(oldSolver); +0046 catch +0047 rmpref('RAVEN','solver'); +0048 end +0049 error('Solver not working') +0050 end +0051 sol=solveLP(model); +0052 try +0053 setRavenSolver(oldSolver); +0054 catch +0055 rmpref('RAVEN','solver'); +0056 end +0057 %Expect at least 5% of the original growth +0058 verifyTrue(testCase,sol.f>0); +0059 end +0060 +0061 function testLargeSCIP(testCase) +0062 sourceDir = fileparts(fileparts(fileparts(which(mfilename)))); +0063 evalc('model=importModel(fullfile(sourceDir,''tutorial'',''iAL1006 v1.00.xml''))'); +0064 model.c(1484)=1; +0065 modelDB=model; % Keep as database with reactions +0066 % Force growth in gapped model +0067 sol=solveLP(model); +0068 model.lb(1484)=abs(sol.f*0.1); +0069 try +0070 oldSolver=getpref('RAVEN','solver'); +0071 catch +0072 end +0073 setRavenSolver('scip'); +0074 +0075 %Remove first 10 reactions +0076 model=removeReactions(model,(1:10)); +0077 modelDB.id='DB'; +0078 try +0079 evalc('[newConnected,cannotConnect,addedRxns,model,exitFlag]=fillGaps(model,modelDB,false,true)'); +0080 catch +0081 try +0082 setRavenSolver(oldSolver); +0083 catch +0084 rmpref('RAVEN','solver'); +0085 end +0086 error('Solver not working') +0087 end +0088 sol=solveLP(model); +0089 try +0090 setRavenSolver(oldSolver); +0091 catch +0092 rmpref('RAVEN','solver'); +0093 end +0094 %Expect at least 5% of the original growth +0095 verifyTrue(testCase,sol.f>0); +0096 end
Generated by m2html © 2005
\ No newline at end of file diff --git a/doc/testing/unit_tests/fillGapsSmallTests.html b/doc/testing/unit_tests/fillGapsSmallTests.html index 3c0e1872..3e5fa374 100644 --- a/doc/testing/unit_tests/fillGapsSmallTests.html +++ b/doc/testing/unit_tests/fillGapsSmallTests.html @@ -53,90 +53,92 @@

SOURCE CODE ^if testGurobi 0007 try 0008 gurobi_read('solverTests.m'); -0009 catch -0010 testGurobi = false; -0011 end -0012 end -0013 if ~testGurobi -0014 disp('Gurobi not installed or cannot be found in MATLAB path, some fillGapsLargeTests skipped.') -0015 skipTests = contains({tests.Name},'gurobi','IgnoreCase',true); -0016 tests(skipTests) = []; -0017 end -0018 if exist('scip','file')~=3 -0019 disp('SCIP MEX binary not installed or not functional, some fillGapsSmallTests skipped.') -0020 skipTests = contains({tests.Name},'scip','IgnoreCase',true); -0021 tests(skipTests) = []; -0022 end -0023 end -0024 -0025 function testSmallSCIP(testCase) -0026 %Test using small model -0027 sourceDir = fileparts(which(mfilename)); -0028 load([sourceDir,'/test_data/ecoli_textbook.mat'], 'model'); -0029 modelDB=model; % Keep as database with reactions -0030 try -0031 oldSolver=getpref('RAVEN','solver'); -0032 catch -0033 end -0034 setRavenSolver('scip'); -0035 -0036 %Remove first 10 reactions -0037 model=removeReactions(modelDB,(1:10)); -0038 modelDB.id='DB'; -0039 try -0040 evalc('[newConnected,cannotConnect,addedRxns,model,exitFlag]=fillGaps(model,modelDB)'); -0041 catch -0042 try -0043 setRavenSolver(oldSolver); -0044 catch -0045 rmpref('RAVEN','solver'); -0046 end -0047 error('Solver not working') -0048 end -0049 sol=solveLP(model); -0050 try -0051 setRavenSolver(oldSolver); -0052 catch -0053 rmpref('RAVEN','solver'); -0054 end -0055 %Should give non-zero flux -0056 verifyTrue(testCase,-sol.f>0); -0057 end -0058 -0059 function testSmallGurobi(testCase) -0060 %Test using small model -0061 sourceDir = fileparts(which(mfilename)); -0062 load([sourceDir,'/test_data/ecoli_textbook.mat'], 'model'); -0063 modelDB=model; % Keep as database with reactions -0064 try -0065 oldSolver=getpref('RAVEN','solver'); -0066 catch -0067 end -0068 setRavenSolver('gurobi'); -0069 -0070 %Remove first 10 reactions -0071 model=removeReactions(modelDB,(1:10)); -0072 -0073 modelDB.id='DB'; -0074 try -0075 evalc('[newConnected,cannotConnect,addedRxns,model,exitFlag]=fillGaps(model,modelDB)'); -0076 catch -0077 try -0078 setRavenSolver(oldSolver); -0079 catch -0080 rmpref('RAVEN','solver'); -0081 end -0082 error('Solver not working') -0083 end -0084 sol=solveLP(model); -0085 try -0086 setRavenSolver(oldSolver); -0087 catch -0088 rmpref('RAVEN','solver'); -0089 end -0090 %Expect at least 5% of the original growth -0091 verifyTrue(testCase,-sol.f>0); -0092 end +0009 catch ME +0010 if ~startsWith(ME.message,'Gurobi error 10012') % Expected error code, others may indicate problems with license +0011 testGurobi = false; +0012 end +0013 end +0014 end +0015 if ~testGurobi +0016 disp('Gurobi not installed or not functional, some fillGapsSmallTests skipped.') +0017 skipTests = contains({tests.Name},'gurobi','IgnoreCase',true); +0018 tests(skipTests) = []; +0019 end +0020 if exist('scip','file')~=3 +0021 disp('SCIP MEX binary not installed or not functional, some fillGapsSmallTests skipped.') +0022 skipTests = contains({tests.Name},'scip','IgnoreCase',true); +0023 tests(skipTests) = []; +0024 end +0025 end +0026 +0027 function testSmallSCIP(testCase) +0028 %Test using small model +0029 sourceDir = fileparts(which(mfilename)); +0030 load([sourceDir,'/test_data/ecoli_textbook.mat'], 'model'); +0031 modelDB=model; % Keep as database with reactions +0032 try +0033 oldSolver=getpref('RAVEN','solver'); +0034 catch +0035 end +0036 setRavenSolver('scip'); +0037 +0038 %Remove first 10 reactions +0039 model=removeReactions(modelDB,(1:10)); +0040 modelDB.id='DB'; +0041 try +0042 evalc('[newConnected,cannotConnect,addedRxns,model,exitFlag]=fillGaps(model,modelDB)'); +0043 catch +0044 try +0045 setRavenSolver(oldSolver); +0046 catch +0047 rmpref('RAVEN','solver'); +0048 end +0049 error('Solver not working') +0050 end +0051 sol=solveLP(model); +0052 try +0053 setRavenSolver(oldSolver); +0054 catch +0055 rmpref('RAVEN','solver'); +0056 end +0057 %Should give non-zero flux +0058 verifyTrue(testCase,sol.f>0); +0059 end +0060 +0061 function testSmallGurobi(testCase) +0062 %Test using small model +0063 sourceDir = fileparts(which(mfilename)); +0064 load([sourceDir,'/test_data/ecoli_textbook.mat'], 'model'); +0065 modelDB=model; % Keep as database with reactions +0066 try +0067 oldSolver=getpref('RAVEN','solver'); +0068 catch +0069 end +0070 setRavenSolver('gurobi'); +0071 +0072 %Remove first 10 reactions +0073 model=removeReactions(modelDB,(1:10)); +0074 +0075 modelDB.id='DB'; +0076 try +0077 evalc('[newConnected,cannotConnect,addedRxns,model,exitFlag]=fillGaps(model,modelDB)'); +0078 catch +0079 try +0080 setRavenSolver(oldSolver); +0081 catch +0082 rmpref('RAVEN','solver'); +0083 end +0084 error('Solver not working') +0085 end +0086 sol=solveLP(model); +0087 try +0088 setRavenSolver(oldSolver); +0089 catch +0090 rmpref('RAVEN','solver'); +0091 end +0092 %Expect at least 5% of the original growth +0093 verifyTrue(testCase,sol.f>0); +0094 end
Generated by m2html © 2005
\ No newline at end of file diff --git a/doc/testing/unit_tests/tinitTests.html b/doc/testing/unit_tests/tinitTests.html index b0996041..f699d0e0 100644 --- a/doc/testing/unit_tests/tinitTests.html +++ b/doc/testing/unit_tests/tinitTests.html @@ -52,612 +52,614 @@

SOURCE CODE ^'gurobi','file'), exist('scip.mexw64','file')] ==3; 0006 if solverExist(1) 0007 try -0008 gurobi_read('solverTests.m'); -0009 catch -0010 solverExist(1) = false; -0011 end -0012 end -0013 if all(~solverExist) -0014 disp('No suitable solver (gurobi or scip) was found, ftINIT tests skipped.') -0015 skipTests = contains({tests.Name},'ftinit','IgnoreCase',true); -0016 tests(skipTests) = []; -0017 end -0018 end -0019 -0020 function testparsexpTask1List(testCase) -0021 sourceDir = fileparts(which(mfilename)); -0022 taskStruct = parseTaskList(strcat(sourceDir, '/test_data/test_tasks.txt')); -0023 taskStructExcel = parseTaskList(strcat(sourceDir, '/test_data/test_tasks.xls')); -0024 %check that all fields in the first line are what we expect -0025 -0026 expTask1.id='ER'; -0027 expTask1.description='Aerobic rephosphorylation of ATP from glucose'; -0028 expTask1.shouldFail=true; -0029 expTask1.printFluxes=true; -0030 expTask1.comments='Messed up reaction'; -0031 expTask1.inputs={'O2[s]';'glucose[s]'}; -0032 expTask1.LBin=[23.6;23.6]; -0033 expTask1.UBin=[23.8;23.8]; -0034 expTask1.outputs={'H2O[s]';'CO2[s]'}; -0035 expTask1.LBout=[26.1;26.1]; -0036 expTask1.UBout=[26.2;26.2]; -0037 expTask1.equations={'ATP[c] + H2O[c] => ADP[c] + Pi[c] + H+[c]'}; -0038 expTask1.LBequ=30.2; -0039 expTask1.UBequ=30.6; -0040 expTask1.changed={'ATP[a] + H2O[a] => ADP[a] + Pi[a] + H+[a]'}; -0041 expTask1.LBrxn=56.2; -0042 %check that the check works as expected -0043 verifyNotEqual(testCase,taskStruct(1),expTask1) -0044 expTask1.UBrxn=60;%now add the last -0045 -0046 -0047 verifyEqual(testCase,taskStruct(1),expTask1) -0048 verifyEqual(testCase,taskStructExcel(1),expTask1) -0049 -0050 %check that we have 2 tasks in total -0051 verifyEqual(testCase,length(taskStruct),2) -0052 verifyEqual(testCase,length(taskStructExcel),2) -0053 -0054 expTask2.id='BS'; -0055 expTask2.description='ATP de novo synthesis'; -0056 expTask2.shouldFail=false; -0057 expTask2.printFluxes=false; -0058 expTask2.comments=''; -0059 expTask2.inputs={'O2[s]';'glucose[s]';'NH3[s]';'Pi[s]'}; -0060 expTask2.LBin=[0;0;0;0]; -0061 expTask2.UBin=[1000;1000;1000;1000]; -0062 expTask2.outputs={'H2O[s]';'CO2[s]';'ATP[c]'}; -0063 expTask2.LBout=[0;0;1]; -0064 expTask2.UBout=[1.1;1.1;1.3]; -0065 expTask2.equations={'ATP[c] + H2O[c] <=> ADP[c] + Pi[c] + H+[c]'}; -0066 expTask2.LBequ=-1000; -0067 expTask2.UBequ=1000; -0068 expTask2.changed={}; -0069 expTask2.LBrxn=[]; -0070 expTask2.UBrxn=[]; -0071 -0072 verifyEqual(testCase,taskStruct(2),expTask2) -0073 verifyEqual(testCase,taskStructExcel(2),expTask2) -0074 -0075 %and, check that the two formats produce the same -0076 verifyEqual(testCase,taskStruct,taskStructExcel) -0077 end -0078 -0079 -0080 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -0081 % testModel +0008 gurobi_read('solverTests.m'); % Random function call +0009 catch ME +0010 if ~startsWith(ME.message,'Gurobi error 10012') % Expected error code, others may indicate problems with license +0011 solverExist(1) = false; +0012 end +0013 end +0014 end +0015 if all(~solverExist) +0016 disp('No suitable solver (gurobi or scip) was found, ftINIT tests skipped.') +0017 skipTests = contains({tests.Name},'ftinit','IgnoreCase',true); +0018 tests(skipTests) = []; +0019 end +0020 end +0021 +0022 function testparsexpTask1List(testCase) +0023 sourceDir = fileparts(which(mfilename)); +0024 taskStruct = parseTaskList(strcat(sourceDir, '/test_data/test_tasks.txt')); +0025 taskStructExcel = parseTaskList(strcat(sourceDir, '/test_data/test_tasks.xls')); +0026 %check that all fields in the first line are what we expect +0027 +0028 expTask1.id='ER'; +0029 expTask1.description='Aerobic rephosphorylation of ATP from glucose'; +0030 expTask1.shouldFail=true; +0031 expTask1.printFluxes=true; +0032 expTask1.comments='Messed up reaction'; +0033 expTask1.inputs={'O2[s]';'glucose[s]'}; +0034 expTask1.LBin=[23.6;23.6]; +0035 expTask1.UBin=[23.8;23.8]; +0036 expTask1.outputs={'H2O[s]';'CO2[s]'}; +0037 expTask1.LBout=[26.1;26.1]; +0038 expTask1.UBout=[26.2;26.2]; +0039 expTask1.equations={'ATP[c] + H2O[c] => ADP[c] + Pi[c] + H+[c]'}; +0040 expTask1.LBequ=30.2; +0041 expTask1.UBequ=30.6; +0042 expTask1.changed={'ATP[a] + H2O[a] => ADP[a] + Pi[a] + H+[a]'}; +0043 expTask1.LBrxn=56.2; +0044 %check that the check works as expected +0045 verifyNotEqual(testCase,taskStruct(1),expTask1) +0046 expTask1.UBrxn=60;%now add the last +0047 +0048 +0049 verifyEqual(testCase,taskStruct(1),expTask1) +0050 verifyEqual(testCase,taskStructExcel(1),expTask1) +0051 +0052 %check that we have 2 tasks in total +0053 verifyEqual(testCase,length(taskStruct),2) +0054 verifyEqual(testCase,length(taskStructExcel),2) +0055 +0056 expTask2.id='BS'; +0057 expTask2.description='ATP de novo synthesis'; +0058 expTask2.shouldFail=false; +0059 expTask2.printFluxes=false; +0060 expTask2.comments=''; +0061 expTask2.inputs={'O2[s]';'glucose[s]';'NH3[s]';'Pi[s]'}; +0062 expTask2.LBin=[0;0;0;0]; +0063 expTask2.UBin=[1000;1000;1000;1000]; +0064 expTask2.outputs={'H2O[s]';'CO2[s]';'ATP[c]'}; +0065 expTask2.LBout=[0;0;1]; +0066 expTask2.UBout=[1.1;1.1;1.3]; +0067 expTask2.equations={'ATP[c] + H2O[c] <=> ADP[c] + Pi[c] + H+[c]'}; +0068 expTask2.LBequ=-1000; +0069 expTask2.UBequ=1000; +0070 expTask2.changed={}; +0071 expTask2.LBrxn=[]; +0072 expTask2.UBrxn=[]; +0073 +0074 verifyEqual(testCase,taskStruct(2),expTask2) +0075 verifyEqual(testCase,taskStructExcel(2),expTask2) +0076 +0077 %and, check that the two formats produce the same +0078 verifyEqual(testCase,taskStruct,taskStructExcel) +0079 end +0080 +0081 0082 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -0083 -0084 function testModel = getTstModel() -0085 testModel = struct(); -0086 testModel.id = 'testModel'; -0087 testModel.rxns = {}; -0088 testModel.S=[]; -0089 testModel.rev=[]; -0090 testModel.mets = {'as';'ac';'bc';'cc';'dc';'ec';'es';'fc'}; -0091 testModel.metNames = {'a';'a';'b';'c';'d';'e';'e';'f'}; -0092 testModel.comps = {'s';'c'}; -0093 testModel.compNames = testModel.comps; -0094 testModel.metComps = [1;2;2;2;2;2;1;2]; -0095 testModel.genes = {'G1';'G2';'G3';'G4';'G5';'G6';'G7';'G8';'G9';'G10'}; -0096 testModel.grRules = {}; -0097 testModel.rxnGeneMat = []; -0098 -0099 rxnsToAdd = struct(); -0100 rxnsToAdd.rxns = {'R1';'R2';'R3';'R4';'R5';'R6';'R7';'R8';'R9';'R10'}; -0101 rxnsToAdd.equations = {'=> a[s]';... -0102 'a[s] <=> a[c]';... -0103 'a[c] <=> b[c] + c[c]';... -0104 'a[c] <=> 2 d[c]';... -0105 'b[c] + c[c] => e[c]';... -0106 '2 d[c] => e[c]';... -0107 'e[c] => e[s]';... -0108 'e[s] =>';... -0109 'a[c] <=> f[c]';... -0110 'f[c] <=> e[c]'}; -0111 rxnsToAdd.grRules = {'';'';'G3';'G4';'G5';'G6';'G7';'';'G9';'G10'}; -0112 testModel = addRxns(testModel,rxnsToAdd, 3); -0113 testModel.c = [0;0;0;0;0;0;0;1;0;0];%optimize for output flux, if this is used, not sure -0114 testModel.ub = repmat(1000,10,1); -0115 testModel.lb = [0;-1000;-1000;-1000;0;0;0;0;-1000;-1000]; -0116 testModel.rxnNames = testModel.rxns; -0117 testModel.b = repmat(0,8,1); -0118 end -0119 -0120 function testModelRxnScores = getTstModelRxnScores() -0121 testModelRxnScores = [-2;-2;-1;7;0.5;0.5;-1;-2;-3;3.5]; -0122 end -0123 -0124 function testModelTasks = getTstModelTasks() -0125 testModelTasks = struct(); -0126 testModelTasks.id = 'Gen e[s] from a[s]'; -0127 testModelTasks.description = 'Gen e[s] from a[s]'; -0128 testModelTasks.shouldFail = false; -0129 testModelTasks.printFluxes = false; -0130 testModelTasks.comments = ''; -0131 testModelTasks.inputs = {'a[s]'}; -0132 testModelTasks.LBin = 0; -0133 testModelTasks.UBin = inf; -0134 testModelTasks.outputs = {'e[s]'}; -0135 testModelTasks.LBout = 1; -0136 testModelTasks.UBout = 1; -0137 testModelTasks.equations = {}; -0138 testModelTasks.LBequ = []; -0139 testModelTasks.UBequ = []; -0140 testModelTasks.changed = {}; -0141 testModelTasks.LBrxn = {}; -0142 testModelTasks.UBrxn = {}; -0143 end -0144 -0145 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -0146 % testModel2 - not used directly for now, but indirectly +0083 % testModel +0084 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +0085 +0086 function testModel = getTstModel() +0087 testModel = struct(); +0088 testModel.id = 'testModel'; +0089 testModel.rxns = {}; +0090 testModel.S=[]; +0091 testModel.rev=[]; +0092 testModel.mets = {'as';'ac';'bc';'cc';'dc';'ec';'es';'fc'}; +0093 testModel.metNames = {'a';'a';'b';'c';'d';'e';'e';'f'}; +0094 testModel.comps = {'s';'c'}; +0095 testModel.compNames = testModel.comps; +0096 testModel.metComps = [1;2;2;2;2;2;1;2]; +0097 testModel.genes = {'G1';'G2';'G3';'G4';'G5';'G6';'G7';'G8';'G9';'G10'}; +0098 testModel.grRules = {}; +0099 testModel.rxnGeneMat = []; +0100 +0101 rxnsToAdd = struct(); +0102 rxnsToAdd.rxns = {'R1';'R2';'R3';'R4';'R5';'R6';'R7';'R8';'R9';'R10'}; +0103 rxnsToAdd.equations = {'=> a[s]';... +0104 'a[s] <=> a[c]';... +0105 'a[c] <=> b[c] + c[c]';... +0106 'a[c] <=> 2 d[c]';... +0107 'b[c] + c[c] => e[c]';... +0108 '2 d[c] => e[c]';... +0109 'e[c] => e[s]';... +0110 'e[s] =>';... +0111 'a[c] <=> f[c]';... +0112 'f[c] <=> e[c]'}; +0113 rxnsToAdd.grRules = {'';'';'G3';'G4';'G5';'G6';'G7';'';'G9';'G10'}; +0114 testModel = addRxns(testModel,rxnsToAdd, 3); +0115 testModel.c = [0;0;0;0;0;0;0;1;0;0];%optimize for output flux, if this is used, not sure +0116 testModel.ub = repmat(1000,10,1); +0117 testModel.lb = [0;-1000;-1000;-1000;0;0;0;0;-1000;-1000]; +0118 testModel.rxnNames = testModel.rxns; +0119 testModel.b = repmat(0,8,1); +0120 end +0121 +0122 function testModelRxnScores = getTstModelRxnScores() +0123 testModelRxnScores = [-2;-2;-1;7;0.5;0.5;-1;-2;-3;3.5]; +0124 end +0125 +0126 function testModelTasks = getTstModelTasks() +0127 testModelTasks = struct(); +0128 testModelTasks.id = 'Gen e[s] from a[s]'; +0129 testModelTasks.description = 'Gen e[s] from a[s]'; +0130 testModelTasks.shouldFail = false; +0131 testModelTasks.printFluxes = false; +0132 testModelTasks.comments = ''; +0133 testModelTasks.inputs = {'a[s]'}; +0134 testModelTasks.LBin = 0; +0135 testModelTasks.UBin = inf; +0136 testModelTasks.outputs = {'e[s]'}; +0137 testModelTasks.LBout = 1; +0138 testModelTasks.UBout = 1; +0139 testModelTasks.equations = {}; +0140 testModelTasks.LBequ = []; +0141 testModelTasks.UBequ = []; +0142 testModelTasks.changed = {}; +0143 testModelTasks.LBrxn = {}; +0144 testModelTasks.UBrxn = {}; +0145 end +0146 0147 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -0148 -0149 function testModel2 = getTstModel2() -0150 testModel2 = struct(); -0151 testModel2.id = 'testModel2'; -0152 testModel2.rxns = {}; -0153 testModel2.S=[]; -0154 testModel2.rev=[]; -0155 testModel2.mets = {'a';'b'}; -0156 testModel2.metNames = {'a';'b'}; -0157 testModel2.comps = {'s'}; -0158 testModel2.compNames = testModel2.comps; -0159 testModel2.metComps = [1;1]; -0160 testModel2.genes = {'G1';'G2';'G3';'G4'}; -0161 testModel2.grRules = {}; -0162 testModel2.rxnGeneMat = []; -0163 -0164 rxnsToAdd = struct(); -0165 rxnsToAdd.rxns = {'R1';'R2';'R3';'R4'}; -0166 rxnsToAdd.equations = {'a[s] <=>';... -0167 'a[s] => b[s]';... -0168 'a[s] <=> b[s]';... -0169 'b[s] =>'}; -0170 rxnsToAdd.grRules = testModel2.genes; -0171 testModel2 = addRxns(testModel2,rxnsToAdd,3,'',true,true); -0172 testModel2.c = [0;0;0;1];%optimize for output flux, if this is used, not sure -0173 testModel2.ub = repmat(1000,4,1); -0174 testModel2.lb = [-1000;0;-1000;0]; -0175 testModel2.rxnNames = testModel2.rxns; -0176 testModel2.b = zeros(2,1); -0177 end -0178 -0179 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -0180 % testModel4 +0148 % testModel2 - not used directly for now, but indirectly +0149 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +0150 +0151 function testModel2 = getTstModel2() +0152 testModel2 = struct(); +0153 testModel2.id = 'testModel2'; +0154 testModel2.rxns = {}; +0155 testModel2.S=[]; +0156 testModel2.rev=[]; +0157 testModel2.mets = {'a';'b'}; +0158 testModel2.metNames = {'a';'b'}; +0159 testModel2.comps = {'s'}; +0160 testModel2.compNames = testModel2.comps; +0161 testModel2.metComps = [1;1]; +0162 testModel2.genes = {'G1';'G2';'G3';'G4'}; +0163 testModel2.grRules = {}; +0164 testModel2.rxnGeneMat = []; +0165 +0166 rxnsToAdd = struct(); +0167 rxnsToAdd.rxns = {'R1';'R2';'R3';'R4'}; +0168 rxnsToAdd.equations = {'a[s] <=>';... +0169 'a[s] => b[s]';... +0170 'a[s] <=> b[s]';... +0171 'b[s] =>'}; +0172 rxnsToAdd.grRules = testModel2.genes; +0173 testModel2 = addRxns(testModel2,rxnsToAdd,3,'',true,true); +0174 testModel2.c = [0;0;0;1];%optimize for output flux, if this is used, not sure +0175 testModel2.ub = repmat(1000,4,1); +0176 testModel2.lb = [-1000;0;-1000;0]; +0177 testModel2.rxnNames = testModel2.rxns; +0178 testModel2.b = zeros(2,1); +0179 end +0180 0181 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -0182 -0183 function testModel4 = getTstModel4() -0184 testModel2 = getTstModel2(); -0185 testModel4 = testModel2; -0186 -0187 rxnsToAdd = struct(); -0188 rxnsToAdd.rxns = {'R5';'R6';'R7';'R8';'R9';'R10';'R11'}; -0189 rxnsToAdd.equations = {'5 a[s] <=> 5 d[s]';... -0190 'e[s] <=> d[s]'; -0191 'f[s] + g[s] <=> e[s]'; -0192 'b[s] <=> f[s]'; -0193 'h[s] <=> g[s]'; -0194 'h[s] =>'; -0195 'e[s] => g[s]'}; -0196 rxnsToAdd.grRules = {'G5';'G6';'G7';'G8';'G9';'G10';'G11'}; -0197 [~,testModel4] = evalc("addRxns(testModel4,rxnsToAdd, 3, [], true, true);"); -0198 end -0199 -0200 function testModel4RxnScores = getTstModel4RxnScores() -0201 testModel4RxnScores = [-1;-1;2;-1;0.5;-2;1;1.3;-0.5;-0.4;8]; -0202 end -0203 -0204 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -0205 % testModel5 +0182 % testModel4 +0183 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +0184 +0185 function testModel4 = getTstModel4() +0186 testModel2 = getTstModel2(); +0187 testModel4 = testModel2; +0188 +0189 rxnsToAdd = struct(); +0190 rxnsToAdd.rxns = {'R5';'R6';'R7';'R8';'R9';'R10';'R11'}; +0191 rxnsToAdd.equations = {'5 a[s] <=> 5 d[s]';... +0192 'e[s] <=> d[s]'; +0193 'f[s] + g[s] <=> e[s]'; +0194 'b[s] <=> f[s]'; +0195 'h[s] <=> g[s]'; +0196 'h[s] =>'; +0197 'e[s] => g[s]'}; +0198 rxnsToAdd.grRules = {'G5';'G6';'G7';'G8';'G9';'G10';'G11'}; +0199 [~,testModel4] = evalc("addRxns(testModel4,rxnsToAdd, 3, [], true, true);"); +0200 end +0201 +0202 function testModel4RxnScores = getTstModel4RxnScores() +0203 testModel4RxnScores = [-1;-1;2;-1;0.5;-2;1;1.3;-0.5;-0.4;8]; +0204 end +0205 0206 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -0207 -0208 function testModel5 = getTstModel5() -0209 testModel = getTstModel(); -0210 -0211 rxnsToAdd = struct(); -0212 rxnsToAdd.rxns = {'R11';'R12';'R13';'R14'}; -0213 rxnsToAdd.equations = {'a[c] <=> g[c]';... -0214 'a[c] <=> g[c]';... -0215 'g[c] <=> e[c]';... -0216 'g[c] <=> e[c]'}; -0217 rxnsToAdd.grRules = {'G11';'G12';'G13';'G14'}; -0218 [~,testModel5] = evalc("addRxns(testModel,rxnsToAdd, 3, [], true, true);"); -0219 end -0220 -0221 function testModel5RxnScores = getTstModel5RxnScores() -0222 testModel5RxnScores = [getTstModelRxnScores();-1;-1.5;-1;-1.5]; -0223 end -0224 -0225 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -0226 %T0001: testModel without tasks +0207 % testModel5 +0208 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +0209 +0210 function testModel5 = getTstModel5() +0211 testModel = getTstModel(); +0212 +0213 rxnsToAdd = struct(); +0214 rxnsToAdd.rxns = {'R11';'R12';'R13';'R14'}; +0215 rxnsToAdd.equations = {'a[c] <=> g[c]';... +0216 'a[c] <=> g[c]';... +0217 'g[c] <=> e[c]';... +0218 'g[c] <=> e[c]'}; +0219 rxnsToAdd.grRules = {'G11';'G12';'G13';'G14'}; +0220 [~,testModel5] = evalc("addRxns(testModel,rxnsToAdd, 3, [], true, true);"); +0221 end +0222 +0223 function testModel5RxnScores = getTstModel5RxnScores() +0224 testModel5RxnScores = [getTstModelRxnScores();-1;-1.5;-1;-1.5]; +0225 end +0226 0227 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -0228 function testftINIT_T0001(testCase) -0229 solverExist = [exist('gurobi','file'), exist('scip.mexw64','file')] == 3; -0230 currSolver = getpref('RAVEN','solver'); -0231 if solverExist(1) -0232 setRavenSolver('gurobi'); -0233 elseif solverExist(2) -0234 setRavenSolver('scip'); -0235 else -0236 error('No compatible solvers found'); -0237 end -0238 % detectedMets = {}; -0239 testParams = struct(); -0240 -0241 % params.TimeLimit = 10; +0228 %T0001: testModel without tasks +0229 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +0230 function testftINIT_T0001(testCase) +0231 solverExist = [exist('gurobi','file'), exist('scip.mexw64','file')] == 3; +0232 currSolver = getpref('RAVEN','solver'); +0233 if solverExist(1) +0234 setRavenSolver('gurobi'); +0235 elseif solverExist(2) +0236 setRavenSolver('scip'); +0237 else +0238 error('No compatible solvers found'); +0239 end +0240 % detectedMets = {}; +0241 testParams = struct(); 0242 -0243 testModel = getTstModel(); -0244 [~, prepDataTest1] = evalc('prepINITModel(testModel, {}, {}, false, {}, ''s'');'); -0245 %check some things in the prepData -0246 %1. We expect 3 rxns in origRxnsToZero: -0247 verifyTrue(testCase, all(strcmp(prepDataTest1.refModel.rxns(prepDataTest1.toIgnoreExch) , {'R1';'R8'}))) -0248 %note that R7 should not be there, since it has a GPR. -0249 -0250 arrayData1.genes = testModel.genes; -0251 arrayData1.tissues = {'a'}; -0252 arrayData1.levels = getExprForRxnScore(getTstModelRxnScores()); -0253 arrayData1.threshold = 1; -0254 -0255 [~,tst1ResModel1] = evalc('ftINIT(prepDataTest1,arrayData1.tissues{1},[],[],arrayData1,[],getINITSteps(),true,true,testParams,false);'); +0243 % params.TimeLimit = 10; +0244 +0245 testModel = getTstModel(); +0246 [~, prepDataTest1] = evalc('prepINITModel(testModel, {}, {}, false, {}, ''s'');'); +0247 %check some things in the prepData +0248 %1. We expect 3 rxns in origRxnsToZero: +0249 verifyTrue(testCase, all(strcmp(prepDataTest1.refModel.rxns(prepDataTest1.toIgnoreExch) , {'R1';'R8'}))) +0250 %note that R7 should not be there, since it has a GPR. +0251 +0252 arrayData1.genes = testModel.genes; +0253 arrayData1.tissues = {'a'}; +0254 arrayData1.levels = getExprForRxnScore(getTstModelRxnScores()); +0255 arrayData1.threshold = 1; 0256 -0257 %We expect R1 and R8 to be added since they have no GPRs and are exch rxns. The transport rxn R2 without GPR will however be removed, -0258 %since we in the standard setting run the third step with [1;0;0;0;1;0;0], meaning that such reactions will be removed -0259 %R7 however will not be added since it has a GPR -0260 verifyTrue(testCase, all(strcmp(tst1ResModel1.rxns,{'R1';'R4';'R6';'R8';'R9';'R10'}))) -0261 -0262 %also test spontaneous -0263 [~, prepDataTest1] = evalc('prepINITModel(testModel, {}, {''R7'';''R10''}, false, {}, ''s'');'); -0264 verifyTrue(testCase, all(strcmp(prepDataTest1.refModel.rxns(prepDataTest1.toIgnoreExch | prepDataTest1.toIgnoreSpont), {'R1';'R7';'R8';'R10'}))) -0265 arrayData1.genes = testModel.genes; -0266 arrayData1.tissues = {'a'}; -0267 arrayData1.levels = getExprForRxnScore(getTstModelRxnScores()); -0268 arrayData1.threshold = 1; -0269 [~,tst1ResModel1] = evalc('ftINIT(prepDataTest1,arrayData1.tissues{1},[],[],arrayData1,[],getINITSteps(),true,true,testParams,false);'); -0270 %the model should now change to include the "correct" path (including 'R2') and -0271 %skip R9/R10: -0272 verifyTrue(testCase, all(strcmp(tst1ResModel1.rxns,{'R1';'R2';'R4';'R6';'R7';'R8'})), 1) -0273 setRavenSolver(currSolver); -0274 end -0275 -0276 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -0277 %T0002: Create a task that wants to generate e[s] from a[s] for testModel +0257 [~,tst1ResModel1] = evalc('ftINIT(prepDataTest1,arrayData1.tissues{1},[],[],arrayData1,[],getINITSteps(),true,true,testParams,false);'); +0258 +0259 %We expect R1 and R8 to be added since they have no GPRs and are exch rxns. The transport rxn R2 without GPR will however be removed, +0260 %since we in the standard setting run the third step with [1;0;0;0;1;0;0], meaning that such reactions will be removed +0261 %R7 however will not be added since it has a GPR +0262 verifyTrue(testCase, all(strcmp(tst1ResModel1.rxns,{'R1';'R4';'R6';'R8';'R9';'R10'}))) +0263 +0264 %also test spontaneous +0265 [~, prepDataTest1] = evalc('prepINITModel(testModel, {}, {''R7'';''R10''}, false, {}, ''s'');'); +0266 verifyTrue(testCase, all(strcmp(prepDataTest1.refModel.rxns(prepDataTest1.toIgnoreExch | prepDataTest1.toIgnoreSpont), {'R1';'R7';'R8';'R10'}))) +0267 arrayData1.genes = testModel.genes; +0268 arrayData1.tissues = {'a'}; +0269 arrayData1.levels = getExprForRxnScore(getTstModelRxnScores()); +0270 arrayData1.threshold = 1; +0271 [~,tst1ResModel1] = evalc('ftINIT(prepDataTest1,arrayData1.tissues{1},[],[],arrayData1,[],getINITSteps(),true,true,testParams,false);'); +0272 %the model should now change to include the "correct" path (including 'R2') and +0273 %skip R9/R10: +0274 verifyTrue(testCase, all(strcmp(tst1ResModel1.rxns,{'R1';'R2';'R4';'R6';'R7';'R8'})), 1) +0275 setRavenSolver(currSolver); +0276 end +0277 0278 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -0279 function testftINIT_T0002(testCase) -0280 solverExist = [exist('gurobi','file'), exist('scip.mexw64','file')] ==3; -0281 currSolver = getpref('RAVEN','solver'); -0282 if solverExist(1) -0283 setRavenSolver('gurobi'); -0284 elseif solverExist(2) -0285 setRavenSolver('scip'); -0286 else -0287 error('No compatible solvers found'); -0288 end -0289 testModel = getTstModel(); -0290 testModelTasks = getTstModelTasks(); -0291 testRxnScores = getTstModelRxnScores(); -0292 testParams = struct(); -0293 [~, prepDataTest1] = evalc('prepINITModel(testModel, testModelTasks, {}, false, {}, ''s'');'); -0294 %We now expect to R2 and R7 to be essential. Note that R1 and R8 are not essential, -0295 %the exchange rxns are not used when checking tasks. -0296 %This is a bit complicated to check, because the essential rxns are expressed -0297 %as rxn ids of the linearly merged model. We expect those to be called R1 and R7: -0298 verifyTrue(testCase, all(strcmp(prepDataTest1.essentialRxns,{'R1';'R7'}))) -0299 -0300 arrayData1.genes = testModel.genes; -0301 arrayData1.tissues = {'a'}; -0302 arrayData1.levels = getExprForRxnScore(testRxnScores); -0303 arrayData1.threshold = 1; -0304 [~,tst1ResModel1] = evalc('ftINIT(prepDataTest1,arrayData1.tissues{1},[],[],arrayData1,[],getINITSteps(),true,true,testParams,false);'); -0305 %Since both R2 and R7 are now essential, we expect all rxns to be on except R3 and -0306 %R5 (which have a negative total score and are not needed for the task) -0307 verifyTrue(testCase, all(strcmp(tst1ResModel1.rxns,{'R1';'R2';'R4';'R6';'R7';'R8';'R9';'R10'}))) -0308 setRavenSolver(currSolver); -0309 end -0310 -0311 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -0312 %T0003: The second step - gapfilling +0279 %T0002: Create a task that wants to generate e[s] from a[s] for testModel +0280 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +0281 function testftINIT_T0002(testCase) +0282 solverExist = [exist('gurobi','file'), exist('scip.mexw64','file')] ==3; +0283 currSolver = getpref('RAVEN','solver'); +0284 if solverExist(1) +0285 setRavenSolver('gurobi'); +0286 elseif solverExist(2) +0287 setRavenSolver('scip'); +0288 else +0289 error('No compatible solvers found'); +0290 end +0291 testModel = getTstModel(); +0292 testModelTasks = getTstModelTasks(); +0293 testRxnScores = getTstModelRxnScores(); +0294 testParams = struct(); +0295 [~, prepDataTest1] = evalc('prepINITModel(testModel, testModelTasks, {}, false, {}, ''s'');'); +0296 %We now expect to R2 and R7 to be essential. Note that R1 and R8 are not essential, +0297 %the exchange rxns are not used when checking tasks. +0298 %This is a bit complicated to check, because the essential rxns are expressed +0299 %as rxn ids of the linearly merged model. We expect those to be called R1 and R7: +0300 verifyTrue(testCase, all(strcmp(prepDataTest1.essentialRxns,{'R1';'R7'}))) +0301 +0302 arrayData1.genes = testModel.genes; +0303 arrayData1.tissues = {'a'}; +0304 arrayData1.levels = getExprForRxnScore(testRxnScores); +0305 arrayData1.threshold = 1; +0306 [~,tst1ResModel1] = evalc('ftINIT(prepDataTest1,arrayData1.tissues{1},[],[],arrayData1,[],getINITSteps(),true,true,testParams,false);'); +0307 %Since both R2 and R7 are now essential, we expect all rxns to be on except R3 and +0308 %R5 (which have a negative total score and are not needed for the task) +0309 verifyTrue(testCase, all(strcmp(tst1ResModel1.rxns,{'R1';'R2';'R4';'R6';'R7';'R8';'R9';'R10'}))) +0310 setRavenSolver(currSolver); +0311 end +0312 0313 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -0314 function testftINIT_T0003(testCase) -0315 %First generate a model with gaps. We can use testModel. First we add -0316 %boundary mets. Then we remove the exchange reactions -0317 %(which is required for filling gaps) and create a gap by removing the R7 reaction. -0318 testModel = getTstModel(); -0319 testModelTasks = getTstModelTasks(); -0320 testRxnScores = getTstModelRxnScores(); -0321 -0322 mTempRef = closeModel(testModel); -0323 mTempRef = removeReactions(mTempRef, {'R1';'R8'}); -0324 mTemp = removeReactions(mTempRef, {'R7'}); -0325 mTemp.id = 'tmp'; -0326 tmpRxnScores = testRxnScores([2;3;4;5;6;7;9;10]); -0327 %now check that R7 is added back -0328 [~,outModel,addedRxnMat] = evalc('ftINITFillGapsForAllTasks(mTemp,mTempRef,[],false,min(tmpRxnScores,-0.1),testModelTasks);'); -0329 verifyTrue(testCase, all(strcmp(mTempRef.rxns(addedRxnMat),'R7')))%ok -0330 end -0331 -0332 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -0333 %T0004: MergeLinear and groupRxnScores +0314 %T0003: The second step - gapfilling +0315 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +0316 function testftINIT_T0003(testCase) +0317 %First generate a model with gaps. We can use testModel. First we add +0318 %boundary mets. Then we remove the exchange reactions +0319 %(which is required for filling gaps) and create a gap by removing the R7 reaction. +0320 testModel = getTstModel(); +0321 testModelTasks = getTstModelTasks(); +0322 testRxnScores = getTstModelRxnScores(); +0323 +0324 mTempRef = closeModel(testModel); +0325 mTempRef = removeReactions(mTempRef, {'R1';'R8'}); +0326 mTemp = removeReactions(mTempRef, {'R7'}); +0327 mTemp.id = 'tmp'; +0328 tmpRxnScores = testRxnScores([2;3;4;5;6;7;9;10]); +0329 %now check that R7 is added back +0330 [~,outModel,addedRxnMat] = evalc('ftINITFillGapsForAllTasks(mTemp,mTempRef,[],false,min(tmpRxnScores,-0.1),testModelTasks);'); +0331 verifyTrue(testCase, all(strcmp(mTempRef.rxns(addedRxnMat),'R7')))%ok +0332 end +0333 0334 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -0335 function testftINIT_T0004(testCase) -0336 %first testModel -0337 testModel = getTstModel(); -0338 testRxnScores = getTstModelRxnScores(); -0339 [reducedModel,origRxnIds,groupIds,reversedRxns]=mergeLinear(testModel, {}); -0340 %We expect mergeLinear to merge {R1,R2}, {R3,R5}, {R4,R6}, {R7,R8}, {R9,R10} -0341 verifyTrue(testCase, all(groupIds == [1;1;2;3;2;3;4;4;5;5])) -0342 %we expect R1, R3, R4, R7 to be irreversible, R9 to be reversible -0343 verifyTrue(testCase, all(reducedModel.rev == [0;0;0;0;1])) -0344 verifyTrue(testCase, all(reducedModel.lb == [0;0;0;0;-1000])) -0345 -0346 newRxnScores=groupRxnScores(reducedModel, testRxnScores, origRxnIds, groupIds, ismember(origRxnIds, {'R1';'R2';'R8'})); -0347 verifyTrue(testCase, all(newRxnScores == [0;-0.5;7.5;-1;0.5])) -0348 -0349 %then testModel4 -0350 testModel4 = getTstModel4(); -0351 [reducedModel,origRxnIds,groupIds,reversedRxns]=mergeLinear(testModel4, {}); -0352 %we expect {R5,R6},{R7,R8}, and{R9,R10} to be merged -0353 verifyTrue(testCase, all(groupIds == [0;0;0;0;1;1;2;2;3;3;0])) -0354 %check reversibility -0355 verifyTrue(testCase, all(reducedModel.rev == [1;0;1;0;1;1;0;0])) -0356 %check that some reactions have flipped direction when turned to irrev -0357 verifyTrue(testCase, strcmp(constructEquations(reducedModel, 'R9'),'g[s] => ')) -0358 verifyTrue(testCase, all(find(reversedRxns) == [6;9])) -0359 end -0360 -0361 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -0362 %T0006: reverseRxns +0335 %T0004: MergeLinear and groupRxnScores +0336 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +0337 function testftINIT_T0004(testCase) +0338 %first testModel +0339 testModel = getTstModel(); +0340 testRxnScores = getTstModelRxnScores(); +0341 [reducedModel,origRxnIds,groupIds,reversedRxns]=mergeLinear(testModel, {}); +0342 %We expect mergeLinear to merge {R1,R2}, {R3,R5}, {R4,R6}, {R7,R8}, {R9,R10} +0343 verifyTrue(testCase, all(groupIds == [1;1;2;3;2;3;4;4;5;5])) +0344 %we expect R1, R3, R4, R7 to be irreversible, R9 to be reversible +0345 verifyTrue(testCase, all(reducedModel.rev == [0;0;0;0;1])) +0346 verifyTrue(testCase, all(reducedModel.lb == [0;0;0;0;-1000])) +0347 +0348 newRxnScores=groupRxnScores(reducedModel, testRxnScores, origRxnIds, groupIds, ismember(origRxnIds, {'R1';'R2';'R8'})); +0349 verifyTrue(testCase, all(newRxnScores == [0;-0.5;7.5;-1;0.5])) +0350 +0351 %then testModel4 +0352 testModel4 = getTstModel4(); +0353 [reducedModel,origRxnIds,groupIds,reversedRxns]=mergeLinear(testModel4, {}); +0354 %we expect {R5,R6},{R7,R8}, and{R9,R10} to be merged +0355 verifyTrue(testCase, all(groupIds == [0;0;0;0;1;1;2;2;3;3;0])) +0356 %check reversibility +0357 verifyTrue(testCase, all(reducedModel.rev == [1;0;1;0;1;1;0;0])) +0358 %check that some reactions have flipped direction when turned to irrev +0359 verifyTrue(testCase, strcmp(constructEquations(reducedModel, 'R9'),'g[s] => ')) +0360 verifyTrue(testCase, all(find(reversedRxns) == [6;9])) +0361 end +0362 0363 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -0364 -0365 function testftINIT_T0006(testCase) -0366 %R1 = '=> a[s]';... -0367 %R3 = 'a[c] <=> b[c] + c[c]';... -0368 testModel = getTstModel(); -0369 -0370 tmpModel = reverseRxns(testModel, {'R1';'R3'}); -0371 res = constructEquations(tmpModel, {'R1';'R3'}); -0372 expRes = {'a[s] => ';'b[c] + c[c] <=> a[c]'}; -0373 verifyTrue(testCase, all(strcmp(res,expRes))) -0374 end -0375 -0376 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -0377 %T0007: rescaleModelForINIT +0364 %T0006: reverseRxns +0365 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +0366 +0367 function testftINIT_T0006(testCase) +0368 %R1 = '=> a[s]';... +0369 %R3 = 'a[c] <=> b[c] + c[c]';... +0370 testModel = getTstModel(); +0371 +0372 tmpModel = reverseRxns(testModel, {'R1';'R3'}); +0373 res = constructEquations(tmpModel, {'R1';'R3'}); +0374 expRes = {'a[s] => ';'b[c] + c[c] <=> a[c]'}; +0375 verifyTrue(testCase, all(strcmp(res,expRes))) +0376 end +0377 0378 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -0379 function testftINIT_T0007(testCase) -0380 miniModel = struct(); -0381 miniModel.S = [1,1000;-1,-40]; -0382 miniModel.rxns = {'1';'2'}; -0383 miniModel.mets = {'1';'2'}; -0384 res = rescaleModelForINIT(miniModel,10); -0385 verifyTrue(testCase, abs(res.S(1,2) - res.S(2,2)*-10) < 10^-6) -0386 verifyTrue(testCase, abs((abs(res.S(1,2)) + abs(res.S(2,2)))/2) - 1 < 10^-6) -0387 end -0388 -0389 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -0390 %T0008: testModel with metabolomics +0379 %T0007: rescaleModelForINIT +0380 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +0381 function testftINIT_T0007(testCase) +0382 miniModel = struct(); +0383 miniModel.S = [1,1000;-1,-40]; +0384 miniModel.rxns = {'1';'2'}; +0385 miniModel.mets = {'1';'2'}; +0386 res = rescaleModelForINIT(miniModel,10); +0387 verifyTrue(testCase, abs(res.S(1,2) - res.S(2,2)*-10) < 10^-6) +0388 verifyTrue(testCase, abs((abs(res.S(1,2)) + abs(res.S(2,2)))/2) - 1 < 10^-6) +0389 end +0390 0391 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -0392 function testftINIT_T0008(testCase) -0393 solverExist = [exist('gurobi','file'), exist('scip.mexw64','file')] ==3; -0394 currSolver = getpref('RAVEN','solver'); -0395 if solverExist(1) -0396 setRavenSolver('gurobi'); -0397 elseif solverExist(2) -0398 setRavenSolver('scip'); -0399 else -0400 error('No compatible solvers found'); -0401 end -0402 -0403 testParams = struct(); +0392 %T0008: testModel with metabolomics +0393 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +0394 function testftINIT_T0008(testCase) +0395 solverExist = [exist('gurobi','file'), exist('scip.mexw64','file')] ==3; +0396 currSolver = getpref('RAVEN','solver'); +0397 if solverExist(1) +0398 setRavenSolver('gurobi'); +0399 elseif solverExist(2) +0400 setRavenSolver('scip'); +0401 else +0402 error('No compatible solvers found'); +0403 end 0404 -0405 testModel = getTstModel(); -0406 [~, prepDataTest1] = evalc('prepINITModel(testModel, {}, {}, false, {}, ''s'');'); -0407 -0408 arrayData1.genes = testModel.genes; -0409 arrayData1.tissues = {'a'}; -0410 arrayData1.levels = getExprForRxnScore(getTstModelRxnScores()); -0411 arrayData1.threshold = 1; -0412 -0413 [~,tst1ResModel1] = evalc('ftINIT(prepDataTest1,arrayData1.tissues{1},[],[],arrayData1,[],getINITSteps(),true,true,testParams,false);'); +0405 testParams = struct(); +0406 +0407 testModel = getTstModel(); +0408 [~, prepDataTest1] = evalc('prepINITModel(testModel, {}, {}, false, {}, ''s'');'); +0409 +0410 arrayData1.genes = testModel.genes; +0411 arrayData1.tissues = {'a'}; +0412 arrayData1.levels = getExprForRxnScore(getTstModelRxnScores()); +0413 arrayData1.threshold = 1; 0414 -0415 %First the same as in T0001 (we keep them here to make the test case understandable): -0416 %We expect R1 and R8 to be added since they have no GPRs and are exch rxns. The transport rxn R2 without GPR will however be removed, -0417 %since we in the standard setting run the third step with [1;0;0;0;1;0;0], meaning that such reactions will be removed -0418 %R7 however will not be added since it has a GPR -0419 verifyTrue(testCase, all(strcmp(tst1ResModel1.rxns,{'R1';'R4';'R6';'R8';'R9';'R10'}))) -0420 -0421 %make R7 and R10 spontaneous (also same as in T0001) -0422 [~, prepDataTest1] = evalc('prepINITModel(testModel, {}, {''R7'';''R10''}, false, {}, ''s'');'); -0423 verifyTrue(testCase, all(strcmp(prepDataTest1.refModel.rxns(prepDataTest1.toIgnoreExch | prepDataTest1.toIgnoreSpont), {'R1';'R7';'R8';'R10'}))) -0424 [~,tst1ResModel1] = evalc('ftINIT(prepDataTest1,arrayData1.tissues{1},[],[],arrayData1,[],getINITSteps(),true,true,testParams,false);'); -0425 %the model should now change to include the "correct" path (including 'R2') and -0426 %skip R9/R10: -0427 verifyTrue(testCase, all(strcmp(tst1ResModel1.rxns,{'R1';'R2';'R4';'R6';'R7';'R8'}))) -0428 %now, test to add the metabolite f - this should turn back the favor to R9/R10: -0429 [~,tst1ResModel1] = evalc('ftINIT(prepDataTest1,arrayData1.tissues{1},[],[],arrayData1,{''f''},getINITSteps(),true,true,testParams,false);'); -0430 %R9 should now be included, the presence of R2 is random -0431 if length(tst1ResModel1.rxns) == 7 -0432 verifyTrue(testCase, all(strcmp(tst1ResModel1.rxns,{'R1';'R4';'R6';'R7';'R8';'R9';'R10'}))) -0433 else -0434 verifyTrue(testCase, all(strcmp(tst1ResModel1.rxns,{'R1';'R2';'R4';'R6';'R7';'R8';'R9';'R10'}))) -0435 end -0436 %now, test to add the metabolite a, e, f - this should give the same result: -0437 [~,tst1ResModel1] = evalc('ftINIT(prepDataTest1,arrayData1.tissues{1},[],[],arrayData1,{''f'';''a'';''e''},getINITSteps(),true,true,testParams,false);'); -0438 %Should be the same as above (R2 is random) -0439 if length(tst1ResModel1.rxns) == 7 -0440 verifyTrue(testCase, all(strcmp(tst1ResModel1.rxns,{'R1';'R4';'R6';'R7';'R8';'R9';'R10'}))) -0441 else -0442 verifyTrue(testCase, all(strcmp(tst1ResModel1.rxns,{'R1';'R2';'R4';'R6';'R7';'R8';'R9';'R10'}))) -0443 end -0444 -0445 %now, test to add the metabolite b - this should turn on R2 and R3/R5 and turn off R9: -0446 [~,tst1ResModel1] = evalc('ftINIT(prepDataTest1,arrayData1.tissues{1},[],[],arrayData1,{''b''},getINITSteps(),true,true,testParams,false);'); -0447 verifyTrue(testCase, all(strcmp(tst1ResModel1.rxns,{'R1';'R2';'R3';'R4';'R5';'R6';'R7';'R8'}))) -0448 -0449 %now on model 5 to test reactions that are not linearly merged (testModel has only merged rxns) -0450 testModel5 = getTstModel5(); -0451 arrayData1.genes = testModel5.genes; -0452 arrayData1.tissues = {'a'}; -0453 arrayData1.levels = getExprForRxnScore(getTstModel5RxnScores()); -0454 arrayData1.threshold = 1; -0455 -0456 [~, prepDataTest5] = evalc('prepINITModel(testModel5, {}, {''R7'';''R10''}, false, {}, ''s'');'); -0457 [~,tst1ResModel1] = evalc('ftINIT(prepDataTest5,arrayData1.tissues{1},[],[],arrayData1,{},getINITSteps(),true,true,testParams,false);'); -0458 %We expect the 'true' path, i.e. through R2, not R9/R10 or R11-R14 -0459 verifyTrue(testCase, all(strcmp(tst1ResModel1.rxns,{'R1';'R2';'R4';'R6';'R7';'R8'})), 1) -0460 -0461 %now add metabolite g -0462 %modify the scores a bit -0463 [~, prepDataTest5] = evalc('prepINITModel(testModel5, {}, {''R10''}, false, {}, ''s'');'); -0464 arrayData1.levels(7) = getExprForRxnScore(-1.1); %modify to avoid randomness -0465 [~,tst1ResModel1] = evalc('ftINIT(prepDataTest5,arrayData1.tissues{1},[],[],arrayData1,{''g''},getINITSteps(),true,true,testParams,false);'); -0466 %We expect R2 to be replaced with R11 and R13 -0467 verifyTrue(testCase, all(strcmp(tst1ResModel1.rxns,{'R1';'R4';'R6';'R8';'R11';'R13'})), 1) -0468 setRavenSolver(currSolver); -0469 end -0470 -0471 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -0472 %T0009: getExprFromRxnScore +0415 [~,tst1ResModel1] = evalc('ftINIT(prepDataTest1,arrayData1.tissues{1},[],[],arrayData1,[],getINITSteps(),true,true,testParams,false);'); +0416 +0417 %First the same as in T0001 (we keep them here to make the test case understandable): +0418 %We expect R1 and R8 to be added since they have no GPRs and are exch rxns. The transport rxn R2 without GPR will however be removed, +0419 %since we in the standard setting run the third step with [1;0;0;0;1;0;0], meaning that such reactions will be removed +0420 %R7 however will not be added since it has a GPR +0421 verifyTrue(testCase, all(strcmp(tst1ResModel1.rxns,{'R1';'R4';'R6';'R8';'R9';'R10'}))) +0422 +0423 %make R7 and R10 spontaneous (also same as in T0001) +0424 [~, prepDataTest1] = evalc('prepINITModel(testModel, {}, {''R7'';''R10''}, false, {}, ''s'');'); +0425 verifyTrue(testCase, all(strcmp(prepDataTest1.refModel.rxns(prepDataTest1.toIgnoreExch | prepDataTest1.toIgnoreSpont), {'R1';'R7';'R8';'R10'}))) +0426 [~,tst1ResModel1] = evalc('ftINIT(prepDataTest1,arrayData1.tissues{1},[],[],arrayData1,[],getINITSteps(),true,true,testParams,false);'); +0427 %the model should now change to include the "correct" path (including 'R2') and +0428 %skip R9/R10: +0429 verifyTrue(testCase, all(strcmp(tst1ResModel1.rxns,{'R1';'R2';'R4';'R6';'R7';'R8'}))) +0430 %now, test to add the metabolite f - this should turn back the favor to R9/R10: +0431 [~,tst1ResModel1] = evalc('ftINIT(prepDataTest1,arrayData1.tissues{1},[],[],arrayData1,{''f''},getINITSteps(),true,true,testParams,false);'); +0432 %R9 should now be included, the presence of R2 is random +0433 if length(tst1ResModel1.rxns) == 7 +0434 verifyTrue(testCase, all(strcmp(tst1ResModel1.rxns,{'R1';'R4';'R6';'R7';'R8';'R9';'R10'}))) +0435 else +0436 verifyTrue(testCase, all(strcmp(tst1ResModel1.rxns,{'R1';'R2';'R4';'R6';'R7';'R8';'R9';'R10'}))) +0437 end +0438 %now, test to add the metabolite a, e, f - this should give the same result: +0439 [~,tst1ResModel1] = evalc('ftINIT(prepDataTest1,arrayData1.tissues{1},[],[],arrayData1,{''f'';''a'';''e''},getINITSteps(),true,true,testParams,false);'); +0440 %Should be the same as above (R2 is random) +0441 if length(tst1ResModel1.rxns) == 7 +0442 verifyTrue(testCase, all(strcmp(tst1ResModel1.rxns,{'R1';'R4';'R6';'R7';'R8';'R9';'R10'}))) +0443 else +0444 verifyTrue(testCase, all(strcmp(tst1ResModel1.rxns,{'R1';'R2';'R4';'R6';'R7';'R8';'R9';'R10'}))) +0445 end +0446 +0447 %now, test to add the metabolite b - this should turn on R2 and R3/R5 and turn off R9: +0448 [~,tst1ResModel1] = evalc('ftINIT(prepDataTest1,arrayData1.tissues{1},[],[],arrayData1,{''b''},getINITSteps(),true,true,testParams,false);'); +0449 verifyTrue(testCase, all(strcmp(tst1ResModel1.rxns,{'R1';'R2';'R3';'R4';'R5';'R6';'R7';'R8'}))) +0450 +0451 %now on model 5 to test reactions that are not linearly merged (testModel has only merged rxns) +0452 testModel5 = getTstModel5(); +0453 arrayData1.genes = testModel5.genes; +0454 arrayData1.tissues = {'a'}; +0455 arrayData1.levels = getExprForRxnScore(getTstModel5RxnScores()); +0456 arrayData1.threshold = 1; +0457 +0458 [~, prepDataTest5] = evalc('prepINITModel(testModel5, {}, {''R7'';''R10''}, false, {}, ''s'');'); +0459 [~,tst1ResModel1] = evalc('ftINIT(prepDataTest5,arrayData1.tissues{1},[],[],arrayData1,{},getINITSteps(),true,true,testParams,false);'); +0460 %We expect the 'true' path, i.e. through R2, not R9/R10 or R11-R14 +0461 verifyTrue(testCase, all(strcmp(tst1ResModel1.rxns,{'R1';'R2';'R4';'R6';'R7';'R8'})), 1) +0462 +0463 %now add metabolite g +0464 %modify the scores a bit +0465 [~, prepDataTest5] = evalc('prepINITModel(testModel5, {}, {''R10''}, false, {}, ''s'');'); +0466 arrayData1.levels(7) = getExprForRxnScore(-1.1); %modify to avoid randomness +0467 [~,tst1ResModel1] = evalc('ftINIT(prepDataTest5,arrayData1.tissues{1},[],[],arrayData1,{''g''},getINITSteps(),true,true,testParams,false);'); +0468 %We expect R2 to be replaced with R11 and R13 +0469 verifyTrue(testCase, all(strcmp(tst1ResModel1.rxns,{'R1';'R4';'R6';'R8';'R11';'R13'})), 1) +0470 setRavenSolver(currSolver); +0471 end +0472 0473 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -0474 function testftINIT_T0009(testCase) -0475 testModel = getTstModel(); -0476 [~, prepDataTest1] = evalc('prepINITModel(testModel, {}, {}, false, {}, ''s'');'); -0477 -0478 arrayData1.genes = testModel.genes; -0479 arrayData1.tissues = {'a'}; -0480 arrayData1.levels = getExprForRxnScore(getTstModelRxnScores()); -0481 arrayData1.threshold = 1; -0482 -0483 rxnScores = scoreComplexModel(prepDataTest1.refModel,[],arrayData1,arrayData1.tissues{1},[]); -0484 expRes = getTstModelRxnScores(); -0485 verifyTrue(testCase, all(abs(rxnScores - expRes) < 10^-10)) %ok -0486 end -0487 -0488 function testModelL = getTstModelL() -0489 testModelL = struct(); -0490 testModelL.id = 'testModel'; -0491 testModelL.rxns = {}; -0492 testModelL.S=[]; -0493 testModelL.rev=[]; -0494 testModelL.metNames = {'e1';'e2';'e3';'e4';'e5';'e6';'e7';'e8';'e9';'e1';'e2';'e3';'e4';'e5';'e6';'e7';'e8';'e9';'x1';'x2';'x3';'x4';'x5';'x6';'x7';'x8';'x9';'x10';'x11'}; -0495 testModelL.comps = {'s';'c'}; -0496 testModelL.compNames = testModelL.comps; -0497 testModelL.metComps = [1;1;1;1;1;1;1;1;1;2;2;2;2;2;2;2;2;2;2;2;2;2;2;2;2;2;2;2;2]; -0498 testModelL.mets = strcat(testModelL.metNames, testModelL.comps(testModelL.metComps)); -0499 -0500 testModelL.grRules = {}; -0501 testModelL.rxnGeneMat = []; -0502 -0503 testModelL.genes = {'Ge1';'Ge2';'Ge4';'Ge5';'Ge7';'Ge9'; 'Gr1';'Gr2';'Gr3';'Gr5';'Gr6';'Gr7';'Gr8';'Gr9';'Gr10';'Gr11';'Gr12';'Gr14';'Gr15'}; +0474 %T0009: getExprFromRxnScore +0475 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +0476 function testftINIT_T0009(testCase) +0477 testModel = getTstModel(); +0478 [~, prepDataTest1] = evalc('prepINITModel(testModel, {}, {}, false, {}, ''s'');'); +0479 +0480 arrayData1.genes = testModel.genes; +0481 arrayData1.tissues = {'a'}; +0482 arrayData1.levels = getExprForRxnScore(getTstModelRxnScores()); +0483 arrayData1.threshold = 1; +0484 +0485 rxnScores = scoreComplexModel(prepDataTest1.refModel,[],arrayData1,arrayData1.tissues{1},[]); +0486 expRes = getTstModelRxnScores(); +0487 verifyTrue(testCase, all(abs(rxnScores - expRes) < 10^-10)) %ok +0488 end +0489 +0490 function testModelL = getTstModelL() +0491 testModelL = struct(); +0492 testModelL.id = 'testModel'; +0493 testModelL.rxns = {}; +0494 testModelL.S=[]; +0495 testModelL.rev=[]; +0496 testModelL.metNames = {'e1';'e2';'e3';'e4';'e5';'e6';'e7';'e8';'e9';'e1';'e2';'e3';'e4';'e5';'e6';'e7';'e8';'e9';'x1';'x2';'x3';'x4';'x5';'x6';'x7';'x8';'x9';'x10';'x11'}; +0497 testModelL.comps = {'s';'c'}; +0498 testModelL.compNames = testModelL.comps; +0499 testModelL.metComps = [1;1;1;1;1;1;1;1;1;2;2;2;2;2;2;2;2;2;2;2;2;2;2;2;2;2;2;2;2]; +0500 testModelL.mets = strcat(testModelL.metNames, testModelL.comps(testModelL.metComps)); +0501 +0502 testModelL.grRules = {}; +0503 testModelL.rxnGeneMat = []; 0504 -0505 testModelL.ub = []; -0506 testModelL.lb = []; -0507 -0508 rxnsToAdd = struct(); -0509 rxnsToAdd.rxns = { 'S1';'S2';'S3';'S4';'S5';'S6';'S7';'S8';'S9';'E1';'E2';'E2b';'E3';'E4';'E5';'E6';'E7';'E8';'E9';'R1';'R2';'R3';'R4';'R5';'R6';'R7';'R8';'R9';'R10';'R11';'R12';'R13';'R14';'R15'}; -0510 rxnsToAdd.grRules = {''; ''; ''; ''; ''; ''; ''; ''; ''; 'Ge1';'Ge2';'';'';'Ge4';'Ge5';'';'Ge7';'';'Ge9'; 'Gr1';'Gr2';'Gr3';'';'Gr5';'Gr6';'Gr7';'Gr8';'Gr9';'Gr10';'Gr11';'Gr12';'';'Gr14';'Gr15'}; -0511 rxnsToAdd.equations = {'e1[s] <=>';... -0512 'e2[s] <=>';... -0513 'e3[s] <=>';... -0514 'e4[s] <=>';... -0515 'e5[s] <=>';... -0516 'e6[s] <=>';... -0517 'e7[s] <=>';... -0518 'e8[s] <=>';... -0519 'e9[s] <=>';... -0520 'e1[s] <=> e1[c]';... -0521 'e2[s] <=> e2[c]';... -0522 'e2[s] <=> e2[c]';... %b variant -0523 'e3[s] <=> e3[c]';... -0524 'e4[s] <=> e4[c]';... -0525 'e5[s] <=> e5[c]';... -0526 'e6[s] <=> e6[c]';... -0527 'e7[s] <=> e7[c]';... -0528 'e8[s] <=> e8[c]';... -0529 'e9[s] <=> e9[c]';... -0530 'e1[c] + e2[c] <=> x1[c]';... %R1 -0531 'e1[c] + e3[c] => x2[c] + x3[c]';... %R2 -0532 'e4[c] + x3[c] => x4[c] + x5[c]';... %R3 -0533 'e5[c] + e6[c] + x4[c] => 2 x2[c] + x6[c]';... %R4 -0534 'x1[c] + x2[c] <=> x7[c] + 2 x8[c]';... %R5 -0535 'x2[c] + x8[c] => x3[c] + x9[c]';... %R6 -0536 'x4[c] <=> x9[c]';... %R7 -0537 'x5[c] <=> x9[c]';... %R8 -0538 'x6[c] <=> x10[c]';... %R9 -0539 'x6[c] <=> x11[c]';... %R10 -0540 'x10[c] + 2 x11[c] => e7[c]';... %R11 -0541 'x9[c] + x10[c] <=> e8[c]';... %R12 -0542 'x7[c] + x8[c] + x9[c] => e9[c]';... %R13 -0543 'x6[c] => x9[c]';... %R14 -0544 'x3[c] => x9[c]'... %R15 -0545 }; -0546 testModelL = addRxns(testModelL,rxnsToAdd, 3); -0547 testModelL.c = [0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0];%optimize for output flux, if this is used, not sure -0548 testModelL.rxnNames = testModelL.rxns; -0549 testModelL.b = repmat(0,length(testModelL.mets),1); -0550 end -0551 -0552 function testModelLGeneScores = getTstModelLGeneScores() -0553 %testModelL.genes = {'Ge1';'Ge2';'Ge4';'Ge5';'Ge7';'Ge9'; 'Gr1';'Gr2';'Gr3';'Gr5';'Gr6';'Gr7';'Gr8';'Gr9';'Gr10';'Gr11';'Gr12';'Gr14';'Gr15'}; -0554 testModelLGeneScores = [3; -1; 8; 6; -5; 5; 4; 5; 2; 3; 6; 1; 3; 1; -3; 1; 3; 1; 2]; -0555 end -0556 -0557 -0558 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -0559 %T0050: Test ftINIT on a slightly larger and more complex model -0560 % Specifically tests if the three-step variant and the "full" -0561 % variant gives similar results -0562 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -0563 function testftINIT_T0050(testCase) -0564 solverExist = [exist('gurobi','file'), exist('scip.mexw64','file')] ==3; -0565 currSolver = getpref('RAVEN','solver'); -0566 if solverExist(1) -0567 setRavenSolver('gurobi'); -0568 elseif solverExist(2) -0569 setRavenSolver('scip'); -0570 else -0571 error('No compatible solvers found'); -0572 end -0573 -0574 testModelL = getTstModelL(); -0575 testModelLGeneScores = getTstModelLGeneScores(); -0576 testParams = struct(); -0577 -0578 arrayDataL = struct(); -0579 arrayDataL.genes = testModelL.genes; -0580 arrayDataL.tissues = {'t1'}; -0581 arrayDataL.levels = getExprForRxnScore(testModelLGeneScores,1); -0582 arrayDataL.threshold = 1; -0583 -0584 %Run prep data -0585 [~, prepDataL] = evalc('prepINITModel(testModelL, [], {}, false, {}, ''s'');'); -0586 -0587 [~,mres] = evalc('ftINIT(prepDataL,arrayDataL.tissues{1},[],[],arrayDataL,[],getINITSteps(),true,true,testParams,false);'); -0588 [~,mres2] = evalc('ftINIT(prepDataL,arrayDataL.tissues{1},[],[],arrayDataL,[],getINITSteps([], ''full''),true,true,testParams,false);'); -0589 -0590 expResult = { 'S1';'S2';'S3';'S4';'S5';'S6';'S7';'S8';'S9';'E1';'E2';'E3';'E4';'E5';'E6';'E8';'E9';'R1';'R2';'R3';'R4';'R5';'R6';'R7';'R8';'R9';'R12';'R13';'R14';'R15'}; +0505 testModelL.genes = {'Ge1';'Ge2';'Ge4';'Ge5';'Ge7';'Ge9'; 'Gr1';'Gr2';'Gr3';'Gr5';'Gr6';'Gr7';'Gr8';'Gr9';'Gr10';'Gr11';'Gr12';'Gr14';'Gr15'}; +0506 +0507 testModelL.ub = []; +0508 testModelL.lb = []; +0509 +0510 rxnsToAdd = struct(); +0511 rxnsToAdd.rxns = { 'S1';'S2';'S3';'S4';'S5';'S6';'S7';'S8';'S9';'E1';'E2';'E2b';'E3';'E4';'E5';'E6';'E7';'E8';'E9';'R1';'R2';'R3';'R4';'R5';'R6';'R7';'R8';'R9';'R10';'R11';'R12';'R13';'R14';'R15'}; +0512 rxnsToAdd.grRules = {''; ''; ''; ''; ''; ''; ''; ''; ''; 'Ge1';'Ge2';'';'';'Ge4';'Ge5';'';'Ge7';'';'Ge9'; 'Gr1';'Gr2';'Gr3';'';'Gr5';'Gr6';'Gr7';'Gr8';'Gr9';'Gr10';'Gr11';'Gr12';'';'Gr14';'Gr15'}; +0513 rxnsToAdd.equations = {'e1[s] <=>';... +0514 'e2[s] <=>';... +0515 'e3[s] <=>';... +0516 'e4[s] <=>';... +0517 'e5[s] <=>';... +0518 'e6[s] <=>';... +0519 'e7[s] <=>';... +0520 'e8[s] <=>';... +0521 'e9[s] <=>';... +0522 'e1[s] <=> e1[c]';... +0523 'e2[s] <=> e2[c]';... +0524 'e2[s] <=> e2[c]';... %b variant +0525 'e3[s] <=> e3[c]';... +0526 'e4[s] <=> e4[c]';... +0527 'e5[s] <=> e5[c]';... +0528 'e6[s] <=> e6[c]';... +0529 'e7[s] <=> e7[c]';... +0530 'e8[s] <=> e8[c]';... +0531 'e9[s] <=> e9[c]';... +0532 'e1[c] + e2[c] <=> x1[c]';... %R1 +0533 'e1[c] + e3[c] => x2[c] + x3[c]';... %R2 +0534 'e4[c] + x3[c] => x4[c] + x5[c]';... %R3 +0535 'e5[c] + e6[c] + x4[c] => 2 x2[c] + x6[c]';... %R4 +0536 'x1[c] + x2[c] <=> x7[c] + 2 x8[c]';... %R5 +0537 'x2[c] + x8[c] => x3[c] + x9[c]';... %R6 +0538 'x4[c] <=> x9[c]';... %R7 +0539 'x5[c] <=> x9[c]';... %R8 +0540 'x6[c] <=> x10[c]';... %R9 +0541 'x6[c] <=> x11[c]';... %R10 +0542 'x10[c] + 2 x11[c] => e7[c]';... %R11 +0543 'x9[c] + x10[c] <=> e8[c]';... %R12 +0544 'x7[c] + x8[c] + x9[c] => e9[c]';... %R13 +0545 'x6[c] => x9[c]';... %R14 +0546 'x3[c] => x9[c]'... %R15 +0547 }; +0548 testModelL = addRxns(testModelL,rxnsToAdd, 3); +0549 testModelL.c = [0;0;0;0;0;0;0;1;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0];%optimize for output flux, if this is used, not sure +0550 testModelL.rxnNames = testModelL.rxns; +0551 testModelL.b = repmat(0,length(testModelL.mets),1); +0552 end +0553 +0554 function testModelLGeneScores = getTstModelLGeneScores() +0555 %testModelL.genes = {'Ge1';'Ge2';'Ge4';'Ge5';'Ge7';'Ge9'; 'Gr1';'Gr2';'Gr3';'Gr5';'Gr6';'Gr7';'Gr8';'Gr9';'Gr10';'Gr11';'Gr12';'Gr14';'Gr15'}; +0556 testModelLGeneScores = [3; -1; 8; 6; -5; 5; 4; 5; 2; 3; 6; 1; 3; 1; -3; 1; 3; 1; 2]; +0557 end +0558 +0559 +0560 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +0561 %T0050: Test ftINIT on a slightly larger and more complex model +0562 % Specifically tests if the three-step variant and the "full" +0563 % variant gives similar results +0564 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +0565 function testftINIT_T0050(testCase) +0566 solverExist = [exist('gurobi','file'), exist('scip.mexw64','file')] ==3; +0567 currSolver = getpref('RAVEN','solver'); +0568 if solverExist(1) +0569 setRavenSolver('gurobi'); +0570 elseif solverExist(2) +0571 setRavenSolver('scip'); +0572 else +0573 error('No compatible solvers found'); +0574 end +0575 +0576 testModelL = getTstModelL(); +0577 testModelLGeneScores = getTstModelLGeneScores(); +0578 testParams = struct(); +0579 +0580 arrayDataL = struct(); +0581 arrayDataL.genes = testModelL.genes; +0582 arrayDataL.tissues = {'t1'}; +0583 arrayDataL.levels = getExprForRxnScore(testModelLGeneScores,1); +0584 arrayDataL.threshold = 1; +0585 +0586 %Run prep data +0587 [~, prepDataL] = evalc('prepINITModel(testModelL, [], {}, false, {}, ''s'');'); +0588 +0589 [~,mres] = evalc('ftINIT(prepDataL,arrayDataL.tissues{1},[],[],arrayDataL,[],getINITSteps(),true,true,testParams,false);'); +0590 [~,mres2] = evalc('ftINIT(prepDataL,arrayDataL.tissues{1},[],[],arrayDataL,[],getINITSteps([], ''full''),true,true,testParams,false);'); 0591 -0592 verifyTrue(testCase, all(contains(mres.rxns,expResult))) -0593 verifyTrue(testCase, all(contains(mres2.rxns,expResult))) -0594 -0595 %run the old tINIT version (in Human-GEM) -0596 %this is just to show that they become different, not really part of the test case -0597 %paramsL2 = struct(); -0598 %paramsL2.TimeLimit = 1000; -0599 %testModelL2 = closeModel(testModelL); -0600 %init_modelOrig = getINITModel2(testModelL2,arrayDataL.tissues{1},[],[],arrayDataL,[],true,[],true,true,[],paramsL2); -0601 -0602 %in this call, I have modified the code - the possibility to turn off met secretion + don't allow flux in both directions is not possible. -0603 %The following line, around line 337, is changed -0604 %from: -0605 %[~, deletedRxnsInINIT, metProduction] = runINIT(simplifyModel(cModel),rxnScores,metabolomicsData,essentialRxnsForTasks,0,true,false,params); -0606 %to: -0607 %[~, deletedRxnsInINIT, metProduction] = runINIT(simplifyModel(cModel),rxnScores,metabolomicsData,essentialRxnsForTasks,0,false,true,params); -0608 %init_modelOrigNoSecrOneDirOnly = getINITModel2(testModelL2,arrayDataL.tissues{1},[],[],arrayDataL,[],true,[],true,true,[],paramsL2); -0609 -0610 %The models init_modelOrigNoSecrOneDirOnly and mres2 are very similar, (only one exch rxn differ, which is expected) -0611 %init_modelOrig is quite different, with a lot of gaps, and worse. So, the conclusion is that the new version does a pretty good job. -0612 setRavenSolver(currSolver); -0613 end +0592 expResult = { 'S1';'S2';'S3';'S4';'S5';'S6';'S7';'S8';'S9';'E1';'E2';'E3';'E4';'E5';'E6';'E8';'E9';'R1';'R2';'R3';'R4';'R5';'R6';'R7';'R8';'R9';'R12';'R13';'R14';'R15'}; +0593 +0594 verifyTrue(testCase, all(contains(mres.rxns,expResult))) +0595 verifyTrue(testCase, all(contains(mres2.rxns,expResult))) +0596 +0597 %run the old tINIT version (in Human-GEM) +0598 %this is just to show that they become different, not really part of the test case +0599 %paramsL2 = struct(); +0600 %paramsL2.TimeLimit = 1000; +0601 %testModelL2 = closeModel(testModelL); +0602 %init_modelOrig = getINITModel2(testModelL2,arrayDataL.tissues{1},[],[],arrayDataL,[],true,[],true,true,[],paramsL2); +0603 +0604 %in this call, I have modified the code - the possibility to turn off met secretion + don't allow flux in both directions is not possible. +0605 %The following line, around line 337, is changed +0606 %from: +0607 %[~, deletedRxnsInINIT, metProduction] = runINIT(simplifyModel(cModel),rxnScores,metabolomicsData,essentialRxnsForTasks,0,true,false,params); +0608 %to: +0609 %[~, deletedRxnsInINIT, metProduction] = runINIT(simplifyModel(cModel),rxnScores,metabolomicsData,essentialRxnsForTasks,0,false,true,params); +0610 %init_modelOrigNoSecrOneDirOnly = getINITModel2(testModelL2,arrayDataL.tissues{1},[],[],arrayDataL,[],true,[],true,true,[],paramsL2); +0611 +0612 %The models init_modelOrigNoSecrOneDirOnly and mres2 are very similar, (only one exch rxn differ, which is expected) +0613 %init_modelOrig is quite different, with a lot of gaps, and worse. So, the conclusion is that the new version does a pretty good job. +0614 setRavenSolver(currSolver); +0615 end
Generated by m2html © 2005
\ No newline at end of file diff --git a/installation/checkInstallation.m b/installation/checkInstallation.m index 3c820dc9..5f892e3b 100755 --- a/installation/checkInstallation.m +++ b/installation/checkInstallation.m @@ -126,7 +126,7 @@ try evalc('importModel(fullfile(ravenDir,''tutorial'',''empty.xml''))'); try - libSBMLver=OutputSBML; % Only works in libSBML 5.17.0+ + libSBMLver=OutputSBML_RAVEN; % Only works in libSBML 5.17.0+ fprintf([libSBMLver.libSBML_version_string '\n']); catch printOrange('Fail\n') @@ -313,21 +313,23 @@ end function status = makeBinaryExecutable(ravenDir) +% This function is required to run when RAVEN is downloaded as MATLAB +% Add-On, in which case the file permissions are not correctly set if ispc status = 0; % No need to run on Windows return; end binDir = fullfile(ravenDir,'software'); -binList = {fullfile(binDir,'blast+','blastp'); fullfile(binDir,'blast+','blastp.mac'); - fullfile(binDir,'blast+','makeblastdb'); fullfile(binDir,'blast+','makeblastdb.mac'); - fullfile(binDir,'cd-hit','cd-hit'); fullfile(binDir,'cd-hit','cd-hit.mac'); - fullfile(binDir,'diamond','diamond'); fullfile(binDir,'diamond','diamond.mac'); - fullfile(binDir,'hmmer','hmmbuild'); fullfile(binDir,'hmmer','hmmbuild.mac'); - fullfile(binDir,'hmmer','hmmsearch'); fullfile(binDir,'hmmer','hmmsearch.mac'); - fullfile(binDir,'GLPKmex','glpkcc.mexa64'); fullfile(binDir,'GLPKmex','glpkcc.mexglx'); fullfile(binDir,'GLPKmex','glpkcc.mexmaci64'); - fullfile(binDir,'libSBML','TranslateSBML.mexa64'); fullfile(binDir,'libSBML','TranslateSBML.mexglx'); fullfile(binDir,'libSBML','TranslateSBML.mexmaci64'); - fullfile(binDir,'libSBML','OutputSBML.mexa64'); fullfile(binDir,'libSBML','OutputSBML.mexglx'); fullfile(binDir,'libSBML','OutputSBML.mexmaci64'); +binList = {fullfile(binDir,'blast+','blastp'); fullfile(binDir,'blast+','blastp.mac'); + fullfile(binDir,'blast+','makeblastdb'); fullfile(binDir,'blast+','makeblastdb.mac'); + fullfile(binDir,'cd-hit','cd-hit'); fullfile(binDir,'cd-hit','cd-hit.mac'); + fullfile(binDir,'diamond','diamond'); fullfile(binDir,'diamond','diamond.mac'); + fullfile(binDir,'hmmer','hmmbuild'); fullfile(binDir,'hmmer','hmmbuild.mac'); + fullfile(binDir,'hmmer','hmmsearch'); fullfile(binDir,'hmmer','hmmsearch.mac'); + fullfile(binDir,'GLPKmex','glpkcc.mexa64'); fullfile(binDir,'GLPKmex','glpkcc.mexglx'); fullfile(binDir,'GLPKmex','glpkcc.mexmaci64'); fullfile(binDir,'GLPKmex','glpkcc.mexmaca64'); + fullfile(binDir,'libSBML','TranslateSBML_RAVEN.mexa64'); fullfile(binDir,'libSBML','TranslateSBML_RAVEN.mexglx'); fullfile(binDir,'libSBML','TranslateSBML_RAVEN.mexmaci64'); fullfile(binDir,'libSBML','TranslateSBML_RAVEN.mexmaca64'); + fullfile(binDir,'libSBML','OutputSBML_RAVEN.mexa64'); fullfile(binDir,'libSBML','OutputSBML_RAVEN.mexglx'); fullfile(binDir,'libSBML','OutputSBML_RAVEN.mexmaci64'); fullfile(binDir,'libSBML','OutputSBML_RAVEN.mexmaca64'); fullfile(binDir,'mafft','mafft-linux64','mafft.bat'); fullfile(binDir,'mafft','mafft-mac','mafft.bat');}; diff --git a/io/exportForGit.m b/io/exportForGit.m index 6e1a0d50..7fc96313 100755 --- a/io/exportForGit.m +++ b/io/exportForGit.m @@ -65,18 +65,16 @@ %Retrieve libSBML version: [ravenDir,prevDir]=findRAVENroot(); -cd(fullfile(ravenDir,'software','libSBML')); try % 5.17.0 and newer - libSBMLver=OutputSBML; + libSBMLver=OutputSBML_RAVEN; libSBMLver=libSBMLver.libSBML_version_string; catch % before 5.17.0 fid = fopen('tempModelForLibSBMLversion.xml','w+'); fclose(fid); - evalc('[~,~,libSBMLver]=TranslateSBML(''tempModelForLibSBMLversion.xml'',0,0)'); + evalc('[~,~,libSBMLver]=TranslateSBML_RAVEN(''tempModelForLibSBMLversion.xml'',0,0)'); libSBMLver=libSBMLver.libSBML_version_string; delete('tempModelForLibSBMLversion.xml'); end -cd(prevDir) % Make models folder, no warnings if folder already exists if subDirs diff --git a/io/exportModel.m b/io/exportModel.m index 84a19ace..3ac8dbc6 100755 --- a/io/exportModel.m +++ b/io/exportModel.m @@ -159,7 +159,6 @@ function exportModel(model,fileName,exportGeneComplexes,supressWarnings,sortIds) modelSBML.notes='

This file was generated using the exportModel function in RAVEN Toolbox 2 and OutputSBML in libSBML

'; end -modelSBML.annotation=['']; if isfield(model,'annotation') nameString=''; if isfield(model.annotation,'familyName') @@ -184,27 +183,22 @@ function exportModel(model,fileName,exportGeneComplexes,supressWarnings,sortIds) org=['' model.annotation.organization '']; end end - if ~isempty(nameString) || ~isempty(email) || ~isempty(org) + if ~isempty(nameString) || ~isempty(email) || ~isempty(org) % Only fill .annotation if ownership data is provided + modelSBML.annotation=['']; modelSBML.annotation=[modelSBML.annotation '']; if ~isempty(nameString) modelSBML.annotation=[modelSBML.annotation '' nameString '']; end modelSBML.annotation=[modelSBML.annotation email org '']; + modelSBML.annotation=[modelSBML.annotation ''... + '' datestr(now,'yyyy-mm-ddTHH:MM:SSZ') ''... + '' datestr(now,'yyyy-mm-ddTHH:MM:SSZ') '']; + if isfield(model.annotation,'taxonomy') + modelSBML.annotation=[modelSBML.annotation '']; + end + modelSBML.annotation=[modelSBML.annotation '']; end end -modelSBML.annotation=[modelSBML.annotation ''... - '' datestr(now,'yyyy-mm-ddTHH:MM:SSZ') ''... - ''... - ''... - '' datestr(now,'yyyy-mm-ddTHH:MM:SSZ') ''... - '']; - -if isfield(model,'annotation') - if isfield(model.annotation,'taxonomy') - modelSBML.annotation=[modelSBML.annotation '']; - end -end -modelSBML.annotation=[modelSBML.annotation '']; %Prepare compartments for i=1:numel(model.comps) @@ -672,6 +666,7 @@ function exportModel(model,fileName,exportGeneComplexes,supressWarnings,sortIds) if sbmlPackageVersions(1) == 2 modelSBML.fbc_strict=1; + modelSBML.isSetfbc_strict = 1; end modelSBML.rule=[]; @@ -679,9 +674,8 @@ function exportModel(model,fileName,exportGeneComplexes,supressWarnings,sortIds) [ravenDir,prevDir]=findRAVENroot(); fileName=checkFileExistence(fileName,1,true,false); -cd(fullfile(ravenDir,'software','libSBML')); -OutputSBML(modelSBML,fileName,1,0,[1,0]); -cd(prevDir); + +OutputSBML_RAVEN(modelSBML,fileName,1,0,[1,0]); end diff --git a/io/importModel.m b/io/importModel.m index cb591236..6bd711ff 100755 --- a/io/importModel.m +++ b/io/importModel.m @@ -129,9 +129,7 @@ %Load the model using libSBML [ravenDir,prevDir]=findRAVENroot(); fileName=checkFileExistence(fileName,1); -cd(fullfile(ravenDir,'software','libSBML')); -modelSBML = TranslateSBML(fileName,0,0,[1 1]); -cd(prevDir); +modelSBML = TranslateSBML_RAVEN(fileName,0,0,[1 1]); if isempty(modelSBML) EM='There is a problem with the SBML file. Try using the SBML Validator at http://sbml.org/Facilities/Validator'; @@ -807,6 +805,9 @@ model.annotation.note=modelSBML.notes(startString+7:endString-1); model.annotation.note=regexprep(model.annotation.note,'

|

',''); model.annotation.note=strtrim(model.annotation.note); + if regexp(model.annotation.note,'This file was generated using the exportModel function in RAVEN Toolbox \d\.\d and OutputSBML in libSBML') + model.annotation=rmfield(model.annotation,'note'); % Default note added when running exportModel + end end end diff --git a/software/libSBML/OutputSBML.m b/software/libSBML/OutputSBML_RAVEN.m similarity index 100% rename from software/libSBML/OutputSBML.m rename to software/libSBML/OutputSBML_RAVEN.m diff --git a/software/libSBML/OutputSBML.mexa64 b/software/libSBML/OutputSBML_RAVEN.mexa64 old mode 100755 new mode 100644 similarity index 100% rename from software/libSBML/OutputSBML.mexa64 rename to software/libSBML/OutputSBML_RAVEN.mexa64 diff --git a/software/libSBML/OutputSBML.mexglx b/software/libSBML/OutputSBML_RAVEN.mexglx old mode 100755 new mode 100644 similarity index 100% rename from software/libSBML/OutputSBML.mexglx rename to software/libSBML/OutputSBML_RAVEN.mexglx diff --git a/software/libSBML/OutputSBML.mexmaca64 b/software/libSBML/OutputSBML_RAVEN.mexmaca64 similarity index 100% rename from software/libSBML/OutputSBML.mexmaca64 rename to software/libSBML/OutputSBML_RAVEN.mexmaca64 diff --git a/software/libSBML/OutputSBML.mexmaci64 b/software/libSBML/OutputSBML_RAVEN.mexmaci64 old mode 100755 new mode 100644 similarity index 100% rename from software/libSBML/OutputSBML.mexmaci64 rename to software/libSBML/OutputSBML_RAVEN.mexmaci64 diff --git a/software/libSBML/OutputSBML.mexw64 b/software/libSBML/OutputSBML_RAVEN.mexw64 old mode 100755 new mode 100644 similarity index 100% rename from software/libSBML/OutputSBML.mexw64 rename to software/libSBML/OutputSBML_RAVEN.mexw64 diff --git a/software/libSBML/TranslateSBML.m b/software/libSBML/TranslateSBML_RAVEN.m similarity index 100% rename from software/libSBML/TranslateSBML.m rename to software/libSBML/TranslateSBML_RAVEN.m diff --git a/software/libSBML/TranslateSBML.mexa64 b/software/libSBML/TranslateSBML_RAVEN.mexa64 old mode 100755 new mode 100644 similarity index 100% rename from software/libSBML/TranslateSBML.mexa64 rename to software/libSBML/TranslateSBML_RAVEN.mexa64 diff --git a/software/libSBML/TranslateSBML.mexglx b/software/libSBML/TranslateSBML_RAVEN.mexglx old mode 100755 new mode 100644 similarity index 100% rename from software/libSBML/TranslateSBML.mexglx rename to software/libSBML/TranslateSBML_RAVEN.mexglx diff --git a/software/libSBML/TranslateSBML.mexmaca64 b/software/libSBML/TranslateSBML_RAVEN.mexmaca64 similarity index 100% rename from software/libSBML/TranslateSBML.mexmaca64 rename to software/libSBML/TranslateSBML_RAVEN.mexmaca64 diff --git a/software/libSBML/TranslateSBML.mexmaci64 b/software/libSBML/TranslateSBML_RAVEN.mexmaci64 old mode 100755 new mode 100644 similarity index 100% rename from software/libSBML/TranslateSBML.mexmaci64 rename to software/libSBML/TranslateSBML_RAVEN.mexmaci64 diff --git a/software/libSBML/TranslateSBML.mexw64 b/software/libSBML/TranslateSBML_RAVEN.mexw64 old mode 100755 new mode 100644 similarity index 100% rename from software/libSBML/TranslateSBML.mexw64 rename to software/libSBML/TranslateSBML_RAVEN.mexw64 diff --git a/solver/optimizeProb.m b/solver/optimizeProb.m index 4862281c..cf33d92d 100755 --- a/solver/optimizeProb.m +++ b/solver/optimizeProb.m @@ -55,7 +55,7 @@ defaultparams.MIPGap = 1e-12; defaultparams.Seed = 1; end - +res.obj=[]; switch solver %% Use whatever solver is set by COBRA Toolbox changeCobraSolver case 'cobra' diff --git a/solver/solveLP.m b/solver/solveLP.m index ba957c31..c0ae4686 100755 --- a/solver/solveLP.m +++ b/solver/solveLP.m @@ -102,6 +102,8 @@ % Parse the problem to the LP solver res = optimizeProb(prob,params); +% Swap the sign of the obj-value +res.obj = -res.obj; %Check if the problem was feasible and that the solution was optimal [isFeasible, isOptimal]=checkSolution(res); diff --git a/testing/unit_tests/fillGapsLargeTests.m b/testing/unit_tests/fillGapsLargeTests.m index 7c9f38f4..64ee554e 100755 --- a/testing/unit_tests/fillGapsLargeTests.m +++ b/testing/unit_tests/fillGapsLargeTests.m @@ -6,12 +6,14 @@ if testGurobi try gurobi_read('solverTests.m'); - catch - testGurobi = false; + catch ME + if ~startsWith(ME.message,'Gurobi error 10012') % Expected error code, others may indicate problems with license + testGurobi = false; + end end end if ~testGurobi - disp('Gurobi not installed or cannot be found in MATLAB path, some fillGapsLargeTests skipped.') + disp('Gurobi not installed or not functional, some fillGapsLargeTests skipped.') skipTests = contains({tests.Name},'gurobi','IgnoreCase',true); tests(skipTests) = []; end @@ -53,7 +55,7 @@ function testLargeGurobi(testCase) rmpref('RAVEN','solver'); end %Expect at least 5% of the original growth -verifyTrue(testCase,-sol.f>0); +verifyTrue(testCase,sol.f>0); end function testLargeSCIP(testCase) @@ -90,5 +92,5 @@ function testLargeSCIP(testCase) rmpref('RAVEN','solver'); end %Expect at least 5% of the original growth -verifyTrue(testCase,-sol.f>0); +verifyTrue(testCase,sol.f>0); end diff --git a/testing/unit_tests/fillGapsSmallTests.m b/testing/unit_tests/fillGapsSmallTests.m index 87d9f1d9..f5a63ad5 100755 --- a/testing/unit_tests/fillGapsSmallTests.m +++ b/testing/unit_tests/fillGapsSmallTests.m @@ -6,12 +6,14 @@ if testGurobi try gurobi_read('solverTests.m'); - catch - testGurobi = false; + catch ME + if ~startsWith(ME.message,'Gurobi error 10012') % Expected error code, others may indicate problems with license + testGurobi = false; + end end end if ~testGurobi - disp('Gurobi not installed or cannot be found in MATLAB path, some fillGapsLargeTests skipped.') + disp('Gurobi not installed or not functional, some fillGapsSmallTests skipped.') skipTests = contains({tests.Name},'gurobi','IgnoreCase',true); tests(skipTests) = []; end @@ -53,7 +55,7 @@ function testSmallSCIP(testCase) rmpref('RAVEN','solver'); end %Should give non-zero flux -verifyTrue(testCase,-sol.f>0); +verifyTrue(testCase,sol.f>0); end function testSmallGurobi(testCase) @@ -88,5 +90,5 @@ function testSmallGurobi(testCase) rmpref('RAVEN','solver'); end %Expect at least 5% of the original growth -verifyTrue(testCase,-sol.f>0); +verifyTrue(testCase,sol.f>0); end diff --git a/testing/unit_tests/test_data/solverTestOutput.mat b/testing/unit_tests/test_data/solverTestOutput.mat index f5c59710..a0e8dd76 100644 Binary files a/testing/unit_tests/test_data/solverTestOutput.mat and b/testing/unit_tests/test_data/solverTestOutput.mat differ diff --git a/testing/unit_tests/tinitTests.m b/testing/unit_tests/tinitTests.m index 71b9bf2b..7dc68082 100755 --- a/testing/unit_tests/tinitTests.m +++ b/testing/unit_tests/tinitTests.m @@ -5,9 +5,11 @@ solverExist = [exist('gurobi','file'), exist('scip.mexw64','file')] ==3; if solverExist(1) try - gurobi_read('solverTests.m'); - catch - solverExist(1) = false; + gurobi_read('solverTests.m'); % Random function call + catch ME + if ~startsWith(ME.message,'Gurobi error 10012') % Expected error code, others may indicate problems with license + solverExist(1) = false; + end end end if all(~solverExist)