0001 function model=importExcelModel(fileName,removeExcMets,printWarnings,ignoreErrors)
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
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077 fileName=char(fileName);
0078
0079 if nargin<2
0080 removeExcMets=true;
0081 end
0082 if nargin<3
0083 printWarnings=true;
0084 end
0085 if nargin<4
0086 ignoreErrors=false;
0087 end
0088
0089 if ~isfile(fileName)
0090 error('Excel file %s cannot be found',string(fileName));
0091 end
0092
0093
0094
0095 model=[];
0096 model.id=[];
0097 model.name=[];
0098 model.annotation=[];
0099
0100 model.annotation.defaultLB=-1000;
0101 model.annotation.defaultUB=1000;
0102 model.rxns={};
0103 model.mets={};
0104 model.S=[];
0105 model.lb=[];
0106 model.ub=[];
0107 model.rev=[];
0108 model.c=[];
0109 model.b=[];
0110 model.comps={};
0111 model.compNames={};
0112 model.compOutside={};
0113 model.compMiriams={};
0114 model.rxnNames={};
0115 model.rxnComps={};
0116 model.grRules={};
0117 model.rxnGeneMat=[];
0118 model.subSystems={};
0119 model.eccodes={};
0120 model.rxnMiriams={};
0121 model.rxnNotes={};
0122 model.rxnReferences={};
0123 model.rxnConfidenceScores={};
0124 model.genes={};
0125 model.geneComps={};
0126 model.geneMiriams={};
0127 model.geneShortNames={};
0128 model.metNames={};
0129 model.metComps=[];
0130 model.inchis={};
0131 model.metFormulas={};
0132 model.metMiriams={};
0133 model.metCharges={};
0134 model.unconstrained=[];
0135
0136 workbook=loadWorkbook(fileName);
0137
0138 [raw, flag]=loadSheet(workbook,'MODEL');
0139
0140 if flag<0
0141 if printWarnings==true
0142 EM='Could not load the MODEL sheet';
0143 dispEM(EM,false);
0144 end
0145 model.id='UNKNOWN';
0146 model.name='No model details available';
0147 else
0148 raw=cleanSheet(raw);
0149
0150
0151
0152 raw(1,:)=upper(raw(1,:));
0153 raw(1,:)=strrep(raw(1,:),'MODELID','ID');
0154 raw(1,:)=strrep(raw(1,:),'MODELNAME','NAME');
0155 raw(1,:)=strrep(raw(1,:),'DESCRIPTION','NAME');
0156
0157
0158 for i=1:numel(raw(1,:))
0159 switch raw{1,i}
0160 case 'ID'
0161 if any(raw{2,i})
0162 model.id=toStr(raw{2,i});
0163 else
0164 EM='No model ID supplied';
0165 dispEM(EM);
0166 end
0167 case 'NAME'
0168 if any(raw{2,i})
0169 model.name=toStr(raw{2,i});
0170 else
0171 EM='No model name supplied';
0172 dispEM(EM);
0173 end
0174 case 'DEFAULT LOWER'
0175 if ~isempty(raw{2,i})
0176 try
0177 model.annotation.defaultLB=toDouble(raw{2,i},NaN);
0178 catch
0179 EM='DEFAULT LOWER must be numeric';
0180 dispEM(EM);
0181 end
0182 else
0183 if printWarnings==true
0184 fprintf('NOTE: DEFAULT LOWER not supplied. Uses -1000\n');
0185 end
0186 model.annotation.defaultLB=-1000;
0187 end
0188 case 'DEFAULT UPPER'
0189 if ~isempty(raw{2,i})
0190 try
0191 model.annotation.defaultUB=toDouble(raw{2,i},NaN);
0192 catch
0193 EM='DEFAULT UPPER must be numeric';
0194 dispEM(EM);
0195 end
0196 else
0197 if printWarnings==true
0198 fprintf('NOTE: DEFAULT UPPER not supplied. Uses 1000\n');
0199 end
0200 model.annotation.defaultUB=1000;
0201 end
0202 case 'TAXONOMY'
0203 if any(raw{2,i})
0204 model.annotation.taxonomy=toStr(raw{2,i});
0205 end
0206 case 'CONTACT GIVEN NAME'
0207 if any(raw{2,i})
0208 model.annotation.givenName=toStr(raw{2,i});
0209 end
0210 case 'CONTACT FAMILY NAME'
0211 if any(raw{2,i})
0212 model.annotation.familyName=toStr(raw{2,i});
0213 end
0214 case 'CONTACT EMAIL'
0215 if any(raw{2,i})
0216 model.annotation.email=toStr(raw{2,i});
0217 end
0218 case 'ORGANIZATION'
0219 if any(raw{2,i})
0220 model.annotation.organization=toStr(raw{2,i});
0221 end
0222 case 'NOTES'
0223 if any(raw{2,i})
0224 model.annotation.note=toStr(raw{2,i});
0225 end
0226 end
0227 end
0228 end
0229
0230
0231 [raw, flag]=loadSheet(workbook,'COMPS');
0232
0233 if flag<0
0234 if printWarnings==true
0235 EM='Could not load the COMPS sheet. All elements will be assigned to a compartment "s" for "System"';
0236 dispEM(EM,false);
0237 end
0238 model.comps={'s'};
0239 model.compNames={'System'};
0240 else
0241 raw=cleanSheet(raw);
0242
0243
0244 raw(1,:)=upper(raw(1,:));
0245 raw(1,:)=strrep(raw(1,:),'COMPABBREV','ABBREVIATION');
0246 raw(1,:)=strrep(raw(1,:),'COMPNAME','NAME');
0247
0248
0249 for i=1:numel(raw(1,:))
0250 switch raw{1,i}
0251 case 'ABBREVIATION'
0252 model.comps=cellfun(@toStr,raw(2:end,i),'UniformOutput',false);
0253 case 'NAME'
0254 model.compNames=cellfun(@toStr,raw(2:end,i),'UniformOutput',false);
0255 case 'INSIDE'
0256 model.compOutside=cellfun(@toStr,raw(2:end,i),'UniformOutput',false);
0257 case 'MIRIAM'
0258 model.compMiriams=raw(2:end,i);
0259 end
0260 end
0261
0262
0263 if isempty(model.comps)
0264 EM='There must be a column named ABBREVIATION in the COMPS sheet';
0265 dispEM(EM);
0266 end
0267 if isempty(model.compNames)
0268 model.compNames=model.comps;
0269 if printWarnings==true
0270 EM='There is no column named NAME in the COMPS sheet. ABBREVIATION will be used as name';
0271 dispEM(EM,false);
0272 end
0273 end
0274 model.compMiriams=parseMiriam(model.compMiriams);
0275 end
0276
0277
0278 [raw, flag]=loadSheet(workbook,'GENES');
0279
0280 if flag<0
0281 if printWarnings==true
0282 EM='There is no spreadsheet named GENES';
0283 dispEM(EM,false)
0284 end
0285 else
0286 raw=cleanSheet(raw);
0287
0288
0289 raw(1,:)=upper(raw(1,:));
0290 raw(1,:)=strrep(raw(1,:),'GENE NAME','NAME');
0291
0292
0293 foundGenes=false;
0294 for i=1:numel(raw(1,:))
0295 switch raw{1,i}
0296 case 'NAME'
0297 model.genes=cellfun(@toStr,raw(2:end,i),'UniformOutput',false);
0298 foundGenes=true;
0299 case 'MIRIAM'
0300 model.geneMiriams=cellfun(@toStr,raw(2:end,i),'UniformOutput',false);
0301 case 'SHORT NAME'
0302 model.geneShortNames=cellfun(@toStr,raw(2:end,i),'UniformOutput',false);
0303 case 'COMPARTMENT'
0304 model.geneComps=cellfun(@toStr,raw(2:end,i),'UniformOutput',false);
0305 end
0306 end
0307
0308 if foundGenes==false
0309 EM='There must be a column named NAME in the GENES sheet';
0310 dispEM(EM);
0311 end
0312
0313
0314 if all(cellfun(@isempty,model.geneComps))
0315 model.geneComps=[];
0316 end
0317
0318
0319 if ~iscellstr(model.genes)
0320 EM='All gene names have to be strings';
0321 dispEM(EM);
0322 else
0323 if any(strcmp('',model.genes))
0324 EM='There can be no empty strings in gene names';
0325 dispEM(EM);
0326 end
0327 end
0328
0329
0330 if ~isempty(model.geneComps)
0331 if ~iscellstr(model.geneComps)
0332 EM='All gene compartments have to be strings';
0333 dispEM(EM);
0334 else
0335 if any(strcmp('',model.geneComps))
0336 EM='There can be no empty strings in gene compartments';
0337 dispEM(EM);
0338 end
0339 end
0340 [I, model.geneComps]=ismember(model.geneComps,model.comps);
0341 EM='The following genes have compartment abbreviations which could not be found:';
0342 dispEM(EM,true,model.genes(~I));
0343 end
0344 end
0345
0346 model.geneMiriams=parseMiriam(model.geneMiriams);
0347
0348
0349 [raw, flag]=loadSheet(workbook,'RXNS');
0350
0351 if flag<0
0352 EM='Could not load the RXNS sheet';
0353 dispEM(EM);
0354 end
0355
0356 raw=cleanSheet(raw);
0357
0358
0359 raw(1,:)=upper(raw(1,:));
0360 raw(1,:)=strrep(raw(1,:),'RXNID','ID');
0361
0362
0363 equations={};
0364 reactionReplacement={};
0365 for i=1:numel(raw(1,:))
0366 switch raw{1,i}
0367 case 'ID'
0368 model.rxns=cellfun(@toStr,raw(2:end,i),'UniformOutput',false);
0369 case 'NAME'
0370 model.rxnNames=cellfun(@toStr,raw(2:end,i),'UniformOutput',false);
0371 case 'EQUATION'
0372 equations=cellfun(@toStr,raw(2:end,i),'UniformOutput',false);
0373 case 'EC-NUMBER'
0374 model.eccodes=cellfun(@toStr,raw(2:end,i),'UniformOutput',false);
0375 case 'GENE ASSOCIATION'
0376 model.grRules=cellfun(@toStr,raw(2:end,i),'UniformOutput',false);
0377 case 'LOWER BOUND'
0378 try
0379 model.lb=cellfun(@(x) toDouble(x,NaN),raw(2:end,i));
0380 catch
0381 EM='The lower bounds must be numerical values';
0382 dispEM(EM);
0383 end
0384 case 'UPPER BOUND'
0385 try
0386 model.ub=cellfun(@(x) toDouble(x,NaN),raw(2:end,i));
0387 catch
0388 EM='The upper bounds must be numerical values';
0389 dispEM(EM);
0390 end
0391 case 'OBJECTIVE'
0392 try
0393 model.c=cellfun(@(x) toDouble(x,0),raw(2:end,i));
0394 catch
0395 EM='The objective coefficients must be numerical values';
0396 dispEM(EM);
0397 end
0398 case 'COMPARTMENT'
0399 model.rxnComps=cellfun(@toStr,raw(2:end,i),'UniformOutput',false);
0400 case 'SUBSYSTEM'
0401 subsystems=cellfun(@toStr,raw(2:end,i),'UniformOutput',false);
0402 case 'REPLACEMENT ID'
0403 reactionReplacement=cellfun(@toStr,raw(2:end,i),'UniformOutput',false);
0404 case 'MIRIAM'
0405 model.rxnMiriams=cellfun(@toStr,raw(2:end,i),'UniformOutput',false);
0406 case 'NOTE'
0407 model.rxnNotes=cellfun(@toStr,raw(2:end,i),'UniformOutput',false);
0408 case 'REFERENCE'
0409 model.rxnReferences=cellfun(@toStr,raw(2:end,i),'UniformOutput',false);
0410 case 'CONFIDENCE SCORE'
0411 model.rxnConfidenceScores=cellfun(@toStr,raw(2:end,i),'UniformOutput',false);
0412 end
0413 end
0414
0415 if ~isempty(model.rxnConfidenceScores)
0416 model.rxnConfidenceScores=str2double(model.rxnConfidenceScores);
0417 end
0418 for i=1:numel(subsystems)
0419 model.subSystems{i,1}=cellstr(strsplit(subsystems{i,1},';'));
0420 end
0421
0422
0423 if isempty(equations)
0424 EM='There must be a column named EQUATION in the RXNS sheet';
0425 dispEM(EM);
0426 end
0427 if isempty(model.rxns)
0428 if printWarnings==true
0429 EM='There is no column named ID in the RXNS sheet. The reactions will be named as "r1", "r2"...';
0430 dispEM(EM,false);
0431 end
0432 I=num2cell((1:numel(equations))');
0433 model.rxns=strcat('r',cellfun(@num2str,I,'UniformOutput',false));
0434 end
0435
0436
0437
0438 if isempty(model.rxnNames)
0439 model.rxnNames=cell(numel(model.rxns),1);
0440 model.rxnNames(:)={''};
0441 if printWarnings==true
0442 EM='There is no column named NAME in the RXNS sheet. Empty strings will be used as reaction names';
0443 dispEM(EM,false);
0444 end
0445 end
0446 if isempty(model.lb)
0447
0448 model.lb=nan(numel(model.rxns),1);
0449 if printWarnings==true
0450 EM='There is no column named LOWER BOUND in the RXNS sheet. Default bounds will be used';
0451 dispEM(EM,false);
0452 end
0453 end
0454 if isempty(model.ub)
0455 model.ub=nan(numel(model.rxns),1);
0456 if printWarnings==true
0457 EM='There is no column named UPPER BOUND in the RXNS sheet. Default bounds will be used';
0458 dispEM(EM,false);
0459 end
0460 end
0461 if isempty(model.c)
0462 model.c=zeros(numel(model.rxns),1);
0463 if printWarnings==true
0464 EM='There is no column named OBJECTIVE in the RXNS sheet';
0465 dispEM(EM,false);
0466 end
0467 end
0468
0469
0470
0471 if ~isempty(model.rxnComps)
0472 if all(cellfun(@isempty,model.rxnComps))
0473 model.rxnComps=[];
0474 end
0475 end
0476
0477
0478 model.rxnMiriams=parseMiriam(model.rxnMiriams);
0479
0480
0481
0482 I=cellfun(@any,reactionReplacement);
0483 model.rxns(I)=reactionReplacement(I);
0484
0485
0486 if any(strcmp('',model.rxns))
0487 EM='There are empty reaction IDs';
0488 dispEM(EM);
0489 end
0490
0491 if any(strcmp('',equations))
0492 EM='There are empty equations';
0493 dispEM(EM);
0494 end
0495
0496 if ~isempty(model.rxnComps)
0497 if any(strcmp('',model.rxnComps))
0498 EM='Either all reactions must have an associated compartment string or none of them';
0499 dispEM(EM);
0500 end
0501 end
0502
0503 if ~isempty(model.grRules)
0504 tempRules=model.grRules;
0505 for i=1:length(model.rxns)
0506
0507 if ~isempty(model.grRules{i})
0508 tempRules{i}=regexprep(tempRules{i},' and | or ','>');
0509 tempRules{i}=regexprep(tempRules{i},'(','');
0510 tempRules{i}=regexprep(tempRules{i},')','');
0511 indexesNew=strfind(tempRules{i},'>');
0512 indexes=strfind(tempRules{i},':');
0513 indexes=unique([indexesNew indexes strfind(tempRules{i},';')]);
0514 if isempty(indexes)
0515
0516 I=find(strcmp(tempRules{i},model.genes));
0517 if isempty(I)
0518 EM=['The gene association in reaction ' model.rxns{i} ' (' tempRules{i} ') is not present in the gene list'];
0519 dispEM(EM);
0520 end
0521 else
0522 temp=[0 indexes numel(tempRules{i})+1];
0523 for j=1:numel(indexes)+1
0524
0525 geneName=tempRules{i}(temp(j)+1:temp(j+1)-1);
0526 I=find(strcmp(geneName,model.genes));
0527 if isempty(I)
0528 EM=['The gene association in reaction ' model.rxns{i} ' (' geneName ') is not present in the gene list'];
0529 dispEM(EM);
0530 end
0531 end
0532 end
0533
0534
0535
0536
0537
0538
0539 aSign=strfind(model.grRules{i},':');
0540 oSign=strfind(model.grRules{i},';');
0541 if isempty(aSign) && isempty(oSign)
0542 model.grRules{i}=model.grRules{i};
0543 else
0544 if isempty(aSign)
0545 model.grRules{i}=['(' strrep(model.grRules{i},';',' or ') ')'];
0546 else
0547 if isempty(oSign)
0548 model.grRules{i}=['(' strrep(model.grRules{i},':',' and ') ')'];
0549 else
0550 model.grRules{i}=['((' strrep(model.grRules{i},';',') or (') '))'];
0551 model.grRules{i}=strrep(model.grRules{i},':',' and ');
0552 end
0553 end
0554 end
0555 end
0556 end
0557 end
0558
0559
0560 if ~isempty(model.rxnComps)
0561 [I, model.rxnComps]=ismember(model.rxnComps,model.comps);
0562 EM='The following reactions have compartment abbreviations which could not be found:';
0563 dispEM(EM,true,model.rxns(~I));
0564 end
0565
0566
0567 [raw, flag]=loadSheet(workbook,'METS');
0568
0569 if flag<0
0570 if printWarnings==true
0571 EM='There is no spreadsheet named METS. The metabolites will be named "m1", "m2"... and assigned to the first compartment';
0572 dispEM(EM,false);
0573 end
0574
0575 metsForParsing=parseRxnEqu(equations);
0576 I=num2cell((1:numel(metsForParsing))');
0577 model.mets=strcat('m',cellfun(@num2str,I,'UniformOutput',false));
0578 model.metComps=ones(numel(model.mets),1);
0579 model.unconstrained=zeros(numel(model.mets),1);
0580 model.metNames=metsForParsing;
0581 else
0582 raw=cleanSheet(raw);
0583
0584
0585 raw(1,:)=upper(raw(1,:));
0586 raw(1,:)=strrep(raw(1,:),'METID','ID');
0587 raw(1,:)=strrep(raw(1,:),'METNAME','NAME');
0588
0589
0590 metReplacement={};
0591 for i=1:numel(raw(1,:))
0592 switch raw{1,i}
0593 case 'ID'
0594 model.mets=cellfun(@toStr,raw(2:end,i),'UniformOutput',false);
0595 case 'NAME'
0596 model.metNames=cellfun(@toStr,raw(2:end,i),'UniformOutput',false);
0597 case 'UNCONSTRAINED'
0598 model.unconstrained=cellfun(@boolToDouble,raw(2:end,i));
0599
0600 EM='The UNCONSTRAINED property for the following metabolites must be "true"/"false", 1/0, TRUE/FALSE or not set:';
0601 dispEM(EM,true,model.mets(isnan(model.unconstrained)));
0602 case 'MIRIAM'
0603 model.metMiriams=cellfun(@toStr,raw(2:end,i),'UniformOutput',false);
0604 case 'COMPOSITION'
0605 model.metFormulas=cellfun(@toStr,raw(2:end,i),'UniformOutput',false);
0606 case 'INCHI'
0607 model.inchis=cellfun(@toStr,raw(2:end,i),'UniformOutput',false);
0608 case 'COMPARTMENT'
0609 model.metComps=cellfun(@toStr,raw(2:end,i),'UniformOutput',false);
0610
0611
0612 if any(strcmp('',model.metComps))
0613 EM='All metabolites must have an associated compartment string';
0614 dispEM(EM);
0615 end
0616 case 'REPLACEMENT ID'
0617 metReplacement=cellfun(@toStr,raw(2:end,i),'UniformOutput',false);
0618 case 'CHARGE'
0619 model.metCharges=cellfun(@toStr,raw(2:end,i),'UniformOutput',false);
0620 end
0621 end
0622
0623
0624 if isempty(model.mets)
0625 EM='There must be a column named ID in the METS sheet';
0626 dispEM(EM);
0627 end
0628
0629
0630 if isempty(model.metNames)
0631 model.metNames=cell(numel(model.mets),1);
0632 if printWarnings==true
0633 EM='There is no column named NAME in the METS sheet. ID will be used as name';
0634 dispEM(EM,false);
0635 end
0636 end
0637 if isempty(model.unconstrained)
0638 model.unconstrained=zeros(numel(model.mets),1);
0639 if printWarnings==true
0640 EM='There is no column named UNCONSTRAINED in the METS sheet. All metabolites will be constrained';
0641 dispEM(EM,false);
0642 end
0643 end
0644
0645 if isempty(model.metComps)
0646 model.metComps=cell(numel(model.mets),1);
0647 model.metComps(:)=model.comps(1);
0648 if printWarnings==true
0649 EM='There is no column named COMPARTMENT in the METS sheet. All metabolites will be assigned to the first compartment in COMPS. Note that RAVEN makes extensive use of metabolite names and compartments. Some features will therefore not function correctly if metabolite compartments are not correctly assigned';
0650 dispEM(EM,false);
0651 end
0652 end
0653
0654
0655 I=find(~cellfun(@isempty,model.inchis));
0656 for i=1:numel(I)
0657 S=regexp(model.inchis(I(i)),'/','split');
0658 S=S{1};
0659 if numel(S)>=2
0660
0661 model.metFormulas(I(i))=S(2);
0662 end
0663 end
0664
0665
0666
0667 [I, model.metComps]=ismember(model.metComps,model.comps);
0668 EM='The following metabolites have compartment abbreviations which could not be found:';
0669 dispEM(EM,true,model.mets(~I));
0670
0671
0672
0673
0674 I=false(numel(model.mets),1);
0675 [J, K]=unique(model.mets);
0676 if numel(J)~=numel(model.mets)
0677 L=1:numel(model.mets);
0678 L(K)=[];
0679 I(L)=true;
0680 end
0681 EM='The following metabolites are duplicates:';
0682 dispEM(EM,~ignoreErrors,model.mets(I));
0683
0684
0685
0686 I=cellfun(@str2double,model.mets);
0687 EM='The following metabolites have names which cannot be distinguished from numbers:';
0688 dispEM(EM,~ignoreErrors,model.mets(~isnan(I)));
0689 I=cellfun(@str2double,metReplacement);
0690 EM='The following metabolites have names which cannot be distinguished from numbers:';
0691 dispEM(EM,~ignoreErrors,metReplacement(~isnan(I)));
0692
0693
0694
0695
0696 metsForParsing=model.mets;
0697 I=cellfun(@any,metReplacement);
0698 model.mets(I)=metReplacement(I);
0699
0700
0701 I=~cellfun(@any,model.metNames);
0702 model.metNames(I)=model.mets(I);
0703
0704
0705 model.metMiriams=parseMiriam(model.metMiriams);
0706
0707
0708
0709 if ~isempty(model.metCharges)
0710 if all(cellfun(@isempty,model.metCharges))
0711 model.metCharges=[];
0712 end
0713 end
0714 if ~isempty(model.metCharges)
0715 model.metCharges=str2double(model.metCharges);
0716 end
0717 end
0718
0719
0720
0721
0722
0723 [model.S, mets, badRxns, model.rev]=constructS(equations,metsForParsing,model.rxns);
0724 model.rev=model.rev*1;
0725
0726
0727 model.lb(isnan(model.lb))=model.annotation.defaultLB.*model.rev(isnan(model.lb));
0728 model.ub(isnan(model.ub))=model.annotation.defaultUB;
0729
0730
0731
0732 [~, I]=ismember(mets,metsForParsing);
0733 model.S=model.S(I,:);
0734
0735
0736
0737 EM='The following reactions have metabolites which are present more than once. Only the net reactions will be exported:';
0738 dispEM(EM,false,model.rxns(badRxns));
0739
0740 model.b=zeros(numel(model.mets),1);
0741
0742
0743 [grRules,rxnGeneMat] = standardizeGrRules(model,true);
0744 model.grRules = grRules;
0745 model.rxnGeneMat = rxnGeneMat;
0746
0747
0748 if all(cellfun(@isempty,model.compOutside))
0749 model=rmfield(model,'compOutside');
0750 end
0751 if all(cellfun(@isempty,model.compMiriams))
0752 model=rmfield(model,'compMiriams');
0753 end
0754 if all(cellfun(@isempty,model.rxnNames))
0755 model=rmfield(model,'rxnNames');
0756 end
0757 if isempty(model.rxnComps)
0758 model=rmfield(model,'rxnComps');
0759 end
0760 if all(cellfun(@isempty,model.grRules))
0761 model=rmfield(model,'grRules');
0762 end
0763 if isfield(model,'rxnGeneMat') && isempty(model.rxnGeneMat)
0764 model=rmfield(model,'rxnGeneMat');
0765 end
0766 if all(cellfun(@isempty,model.subSystems))
0767 model=rmfield(model,'subSystems');
0768 end
0769 if all(cellfun(@isempty,model.eccodes))
0770 model=rmfield(model,'eccodes');
0771 end
0772 if all(cellfun(@isempty,model.rxnMiriams))
0773 model=rmfield(model,'rxnMiriams');
0774 end
0775 if all(cellfun(@isempty,model.rxnNotes))
0776 model=rmfield(model,'rxnNotes');
0777 end
0778 if all(cellfun(@isempty,model.rxnReferences))
0779 model=rmfield(model,'rxnReferences');
0780 end
0781 if isempty(model.rxnConfidenceScores)
0782 model=rmfield(model,'rxnConfidenceScores');
0783 end
0784 if isempty(model.genes)
0785 model=rmfield(model,'genes');
0786 end
0787 if isempty(model.geneComps)
0788 model=rmfield(model,'geneComps');
0789 end
0790 if isempty(model.geneMiriams)
0791 model=rmfield(model,'geneMiriams');
0792 end
0793 if all(cellfun(@isempty,model.geneShortNames))
0794 model=rmfield(model,'geneShortNames');
0795 end
0796 if all(cellfun(@isempty,model.inchis))
0797 model=rmfield(model,'inchis');
0798 end
0799 if all(cellfun(@isempty,model.metFormulas))
0800 model=rmfield(model,'metFormulas');
0801 end
0802 if all(cellfun(@isempty,model.metMiriams))
0803 model=rmfield(model,'metMiriams');
0804 end
0805 if isempty(model.metCharges)
0806 model=rmfield(model,'metCharges');
0807 end
0808
0809
0810
0811
0812 checkModelStruct(model,~ignoreErrors);
0813
0814 if removeExcMets==true
0815 model=simplifyModel(model);
0816 end
0817 end
0818
0819 function miriamStruct=parseMiriam(strings,miriamStruct)
0820
0821
0822
0823
0824
0825 if nargin<2
0826 miriamStruct=cell(numel(strings),1);
0827 end
0828 for i=1:numel(strings)
0829 if any(strings{i})
0830
0831
0832
0833 I=regexp(strings{i},';','split');
0834 if isfield(miriamStruct{i},'name')
0835 startIndex=numel(miriamStruct{i}.name);
0836 miriamStruct{i}.name=[miriamStruct{i}.name;cell(numel(I),1)];
0837 miriamStruct{i}.value=[miriamStruct{i}.value;cell(numel(I),1)];
0838 else
0839 startIndex=0;
0840 miriamStruct{i}.name=cell(numel(I),1);
0841 miriamStruct{i}.value=cell(numel(I),1);
0842 end
0843
0844 for j=1:numel(I)
0845 if any(strfind(I{j},'/'))
0846 index=max(strfind(I{j},'/'));
0847 elseif any(strfind(I{j},':'))
0848 index=max(strfind(I{j},':'));
0849 end
0850 if exist('index','var') & any(index)
0851 miriamStruct{i}.name{startIndex+j}=I{j}(1:index-1);
0852 miriamStruct{i}.value{startIndex+j}=I{j}(index+1:end);
0853 else
0854 EM=['"' I{j} '" is not a valid MIRIAM string. The format must be "identifier/value" or identifier:value'];
0855 dispEM(EM);
0856 end
0857 end
0858 end
0859 end
0860 end
0861
0862
0863
0864 function y=toStr(x)
0865
0866
0867 if isempty(x)
0868 y='';
0869 else
0870 y=num2str(x);
0871 end
0872 end
0873
0874
0875
0876
0877
0878 function y=toDouble(x,default)
0879 if isempty(x)
0880 y=default;
0881 else
0882 if isnumeric(x)
0883 y=x;
0884 else
0885 y=str2double(x);
0886
0887
0888
0889 if isnan(y)
0890 EM=['Cannot convert the string "' x '" to double'];
0891 dispEM(EM);
0892 end
0893 end
0894 end
0895 end
0896
0897
0898
0899 function y=boolToDouble(x)
0900 if isempty(x)
0901 y=0;
0902 return;
0903 end
0904 if islogical(x)
0905 y=x*1;
0906 return;
0907 end
0908 if isnumeric(x)
0909 if x~=0
0910 y=1;
0911 return;
0912 else
0913 y=0;
0914 return;
0915 end
0916 end
0917 if ischar(x)
0918 if strcmpi(x,'TRUE')
0919 y=1;
0920 return;
0921 end
0922 if strcmpi(x,'FALSE')
0923 y=0;
0924 return;
0925 end
0926 end
0927 y=NaN;
0928 end