0001 function balanceStructure=getElementalBalance(model,rxns,printUnbalanced,printUnparsable)
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032 if nargin<2
0033 rxns=[];
0034 end
0035
0036 if nargin<3
0037 printUnbalanced=false;
0038 end
0039
0040 if nargin<4
0041 printUnparsable=false;
0042 end
0043
0044 if ~isempty(rxns)
0045 indexes=~getIndexes(model,rxns,'rxns',true);
0046 model=removeRxns(model,indexes,true);
0047 end
0048
0049 balanceStructure.balanceStatus=nan(numel(model.rxns),1);
0050
0051
0052 if isfield(model,'metFormulas')
0053 [balanceStructure.elements, useMat, exitFlag]=parseFormulas(model.metFormulas, true);
0054 else
0055 if isfield(model,'inchis')
0056 [balanceStructure.elements, useMat, exitFlag]=parseFormulas(model.inchis, true,true);
0057 else
0058 dispEM('The model must contain either the "metFormulas" or the "inchis" field in order to test for elemental balancing');
0059 end
0060 end
0061
0062 balanceStructure.leftComp=zeros(numel(model.rxns),numel(balanceStructure.elements.names));
0063 balanceStructure.rightComp=balanceStructure.leftComp;
0064
0065
0066 S{1}=model.S;
0067 S{2}=model.S;
0068 S{1}(S{1}>0)=0;
0069 S{2}(S{2}<0)=0;
0070 S{1}=abs(S{1});
0071
0072
0073 for i=1:2
0074 for j=1:numel(model.rxns)
0075
0076 I=exitFlag(S{i}(:,j)~=0);
0077 if any(I==-1)
0078 balanceStructure.balanceStatus(j)=-2;
0079 end
0080 if any(I==0)
0081
0082 balanceStructure.balanceStatus(j)=min(-1,balanceStructure.balanceStatus(j));
0083 end
0084
0085 for k=1:numel(balanceStructure.elements.names)
0086 if i==1
0087 balanceStructure.leftComp(j,k)=sum(S{i}(:,j).*useMat(:,k));
0088 else
0089 balanceStructure.rightComp(j,k)=sum(S{i}(:,j).*useMat(:,k));
0090 end
0091 end
0092 end
0093 end
0094
0095
0096
0097 total=abs(balanceStructure.rightComp-balanceStructure.leftComp)>10^-8;
0098
0099
0100
0101 balanceStructure.balanceStatus(any(total,2))=min(balanceStructure.balanceStatus(any(total,2)),0);
0102
0103
0104 balanceStructure.balanceStatus(isnan(balanceStructure.balanceStatus))=1;
0105
0106
0107 toPrint=[];
0108 if printUnbalanced==true
0109 toPrint=[toPrint;find(balanceStructure.balanceStatus==0)];
0110 end
0111 if printUnparsable==true
0112 toPrint=[toPrint;find(balanceStructure.balanceStatus<0)];
0113 end
0114
0115 toPrint=sort(toPrint);
0116 for i=1:numel(toPrint)
0117 if balanceStructure.balanceStatus(toPrint(i))<0
0118 if balanceStructure.balanceStatus(toPrint(i))==-1
0119 dispEM(['The reaction ' model.rxns{toPrint(i)} ' could not be balanced due to missing information'],false);
0120 else
0121 dispEM(['The reaction ' model.rxns{toPrint(i)} ' could not be balanced due to a parsing error'],false);
0122 end
0123 else
0124
0125 notBalanced=find(total(toPrint(i),:));
0126 for j=1:numel(notBalanced)
0127 dispEM(['The reaction ' model.rxns{toPrint(i)} ' is not balanced with respect to ' balanceStructure.elements.names{notBalanced(j)}],false);
0128 end
0129 end
0130 end
0131 end