0001 function [outModel, geneLocalization, transportStruct, scores,...
0002 removedRxns] = predictLocalization(model, GSS,...
0003 defaultCompartment, transportCost, maxTime, plotResults)
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 if nargin<4
0066 transportCost=ones(numel(model.mets),1)*0.5;
0067 end
0068 if numel(transportCost)==1
0069 transportCost=ones(numel(model.mets),1)*transportCost;
0070 end
0071 transportCost=transportCost(:);
0072
0073 if numel(transportCost)~=numel(model.mets)
0074 EM='The vector of transport costs must have the same dimension as model.mets';
0075 dispEM(EM,true);
0076 end
0077 if nargin<5
0078 maxTime=15;
0079 end
0080 if nargin<6
0081 plotResults=false;
0082 end
0083
0084 if isfield(model,'rxnComps')
0085 model=rmfield(model,'rxnComps');
0086 EM='The model structure contains information about reaction compartmentalization. This is not supported by this function. The rxnComps field has been deleted';
0087 dispEM(EM,false);
0088 end
0089 if isfield(model,'geneComps')
0090 model=rmfield(model,'geneComps');
0091 EM='The model structure contains information about gene compartmentalization. This is not supported by this function. The geneComps field has been deleted';
0092 dispEM(EM,false);
0093 end
0094
0095 defaultCompartment=char(defaultCompartment);
0096 I=ismember(defaultCompartment,GSS.compartments);
0097 if I==false
0098 EM='defaultCompartment not found in GSS';
0099 dispEM(EM);
0100 end
0101
0102 if numel(model.comps)>1
0103 EM='The model has several compartments. All compartments will be merged';
0104 dispEM(EM,false);
0105 model=mergeCompartments(model,true,true);
0106 end
0107
0108 noGenes = ismember(model.genes,GSS.genes);
0109 if ~all(noGenes)
0110 EM=['For ' num2str(numel(find(~noGenes))) ' of ' num2str(numel(model.genes)) ' model genes no data was found in GSS'];
0111 dispEM(EM,false);
0112 end
0113
0114
0115
0116
0117 model=expandModel(model);
0118
0119
0120
0121 removedRxns={};
0122
0123
0124 originalModelMets=model.mets;
0125 while 1
0126 irrevModel=convertToIrrev(model);
0127
0128 I=sum(irrevModel.S>0,2);
0129
0130
0131 if isfield(irrevModel,'unconstrained')
0132 I(irrevModel.unconstrained~=0)=2;
0133 end
0134 metsToDelete=false(numel(model.mets),1);
0135
0136
0137
0138
0139 for i=1:numel(irrevModel.mets)
0140
0141
0142
0143 if I(i)<2
0144 if I(i)==1
0145
0146 [~, J]=find(irrevModel.S(i,:)>0);
0147
0148
0149
0150
0151 K=irrevModel.S(:,J)<0;
0152 check=find(K & I<=1);
0153
0154 for j=1:numel(check)
0155
0156 [~, L]=find(irrevModel.S(check(j),:)>0);
0157
0158 if ~isempty(L)
0159 rxn=irrevModel.rxns(J);
0160 rxnRev=irrevModel.rxns(L);
0161 if strcmp(strrep(rxn,'_REV',''),strrep(rxnRev,'_REV',''))
0162 metsToDelete(i)=true;
0163 end
0164 else
0165
0166
0167 continue;
0168 end
0169 end
0170 else
0171
0172 metsToDelete(i)=true;
0173 end
0174 end
0175 end
0176
0177 if any(metsToDelete)
0178
0179 [~, I]=find(model.S(metsToDelete,:));
0180 removedRxns=[removedRxns;model.rxns(I)];
0181 model=removeReactions(model,I,true,true);
0182 else
0183
0184 break;
0185 end
0186 end
0187
0188
0189 transportCost=transportCost(ismember(originalModelMets,model.mets));
0190
0191
0192
0193 I=find(sum(model.rxnGeneMat,2)==0);
0194 for i=1:numel(I)
0195 model.genes=[model.genes;['&&FAKE&&' num2str(i)]];
0196 if isfield(model,'geneShortNames')
0197 model.geneShortNames=[model.geneShortNames;{''}];
0198 end
0199 if isfield(model,'geneMiriams')
0200 model.geneMiriams=[model.geneMiriams;{[]}];
0201 end
0202 if isfield(model,'geneFrom')
0203 model.geneFrom=[model.geneFrom;{{'FAKE'}}];
0204 end
0205 model.rxnGeneMat(I(i),numel(model.genes))=1;
0206 model.grRules{I(i)}='';
0207 end
0208
0209
0210
0211
0212 I=setdiff(model.genes,GSS.genes);
0213 GSS.genes=[GSS.genes;I];
0214 GSS.scores=[GSS.scores;ones(numel(I),numel(GSS.compartments))*0.5];
0215
0216
0217
0218
0219
0220
0221
0222 genes=unique(model.grRules);
0223 nGenes=strrep(genes,'(','');
0224 nGenes=strrep(nGenes,')','');
0225
0226 complexes=setdiff(nGenes,model.genes);
0227 if ~isempty(complexes)
0228 if isempty(complexes{1})
0229 complexes(1)=[];
0230 end
0231 end
0232 cScores=zeros(numel(complexes),numel(GSS.compartments));
0233 for i=1:numel(complexes)
0234 genesInComplex=regexp(complexes{i},' and ','split');
0235
0236
0237 [I, J]=ismember(genesInComplex,GSS.genes);
0238
0239 if any(I)
0240
0241 mScores=mean(GSS.scores(J(I),:));
0242
0243
0244
0245 mScores=(mScores.*sum(I)+(numel(genesInComplex)-sum(I))*0.5)/numel(genesInComplex);
0246 else
0247 EM=['Could not parse grRule "' complexes{i} '". Assigning score 0.0 in all compartments'];
0248 dispEM(EM,false);
0249 mScores=ones(1,numel(genesInComplex))*0.5;
0250 end
0251 cScores(i,:)=mScores;
0252
0253
0254 model.genes=[model.genes;complexes{i}];
0255 if isfield(model,'geneMiriams')
0256 model.geneMiriams=[model.geneMiriams;{[]}];
0257 end
0258 if isfield(model,'geneShortNames')
0259 model.geneShortNames=[model.geneShortNames;{''}];
0260 end
0261 if isfield(model,'geneFrom')
0262 model.geneFrom=[model.geneFrom;{'COMPLEX'}];
0263 end
0264
0265
0266 I=ismember(model.grRules,['(' complexes{i} ')']);
0267
0268
0269 if ~isempty(I)
0270 model.rxnGeneMat(I,:)=0;
0271 model.rxnGeneMat(I,numel(model.genes))=1;
0272 end
0273 end
0274
0275
0276 GSS.genes=[GSS.genes;complexes];
0277 GSS.scores=[GSS.scores;cScores];
0278
0279
0280
0281 model=removeReactions(model,{},false,true);
0282
0283
0284
0285
0286
0287
0288 [~, I]=getExchangeRxns(model);
0289
0290
0291 J=1:numel(model.rxns);
0292 J(I)=[];
0293 model=permuteModel(model,[I;J'],'rxns');
0294
0295
0296 nER=numel(I);
0297
0298
0299 if isfield(model,'unconstrained')
0300 I=find(model.unconstrained);
0301 J=1:numel(model.mets);
0302 J(I)=[];
0303 model=permuteModel(model,[I;J'],'mets');
0304
0305 transportCost=transportCost([I;J']);
0306
0307 nEM=numel(I);
0308 else
0309 nEM=0;
0310 end
0311
0312
0313
0314 model.rxnGeneMat(1:nER,:)=0;
0315 model.grRules(1:nER)={''};
0316
0317
0318 model=removeReactions(model,{},false,true);
0319
0320
0321
0322
0323 [~, J]=ismember(model.genes,GSS.genes);
0324 GSS.genes=model.genes;
0325 GSS.scores=GSS.scores(J,:);
0326
0327
0328
0329 [~, J]=ismember(defaultCompartment,GSS.compartments);
0330 reorder=1:numel(GSS.compartments);
0331 reorder(J)=[];
0332 reorder=[J reorder];
0333 GSS.scores=GSS.scores(:,reorder);
0334 GSS.compartments=GSS.compartments(reorder);
0335
0336
0337
0338
0339 oldS=model.S;
0340 model.S(model.S>0)=1;
0341 model.S(model.S<0)=-1;
0342
0343
0344
0345
0346 model.S(:,model.rev==1)=model.S(:,model.rev==1).*10;
0347
0348
0349
0350
0351 nRxns=numel(model.rxns)-nER;
0352 nMets=numel(model.mets)-nEM;
0353 nGenes=numel(model.genes);
0354 nComps=numel(GSS.compartments);
0355
0356
0357
0358
0359
0360
0361
0362
0363
0364
0365
0366 s=repmat(eye(nMets)*0,1,nComps-1);
0367 s=[zeros(numel(model.mets)-nMets,size(s,2));s];
0368 S=[model.S sparse(numel(model.mets),nRxns*(nComps-1)) s];
0369 s=[sparse(nMets*(nComps-1),numel(model.rxns)+nRxns*(nComps-1)) eye(nMets*(nComps-1))*0];
0370 S=[S;s];
0371
0372
0373 transportCost=[transportCost(1:nEM);repmat(transportCost(nEM+1:end),nComps,1)];
0374
0375
0376
0377 g2c=false(nGenes,nComps);
0378
0379 g2c(:,1)=true;
0380
0381
0382 tic;
0383 bestScore=-inf;
0384 bestS=[];
0385 bestg2c=[];
0386
0387
0388 plotScore=[];
0389 nTrans=[];
0390 totScore=[];
0391 minScore=sum(min(GSS.scores,[],2));
0392 maxScore=sum(max(GSS.scores,[],2));
0393
0394 while toc<maxTime*60
0395
0396
0397
0398
0399
0400 [I, J]=find(g2c);
0401 geneToMove=randsample(nGenes,1,true,max(GSS.scores(I,:),[],2)-GSS.scores(sub2ind(size(g2c),I,J))+0.1);
0402
0403
0404
0405
0406 toComp=randsample(nComps,1,true,GSS.scores(geneToMove,:)+0.2);
0407
0408
0409 if toComp==find(g2c(geneToMove,:))
0410 continue;
0411 end
0412
0413
0414 [newS, newg2c]=moveGene(S,model,g2c,geneToMove,toComp,nRxns,nMets);
0415
0416
0417
0418
0419 wasConnected=false;
0420 for j=1:10
0421
0422 unconnected=findUnconnected(newS,nEM);
0423
0424
0425 if any(unconnected)
0426
0427
0428
0429 [geneIndex, moveTo, deltaConnected, deltaScore]=selectGenes(newS,nEM,nMets,nER,nRxns,model,unconnected,g2c,GSS);
0430
0431
0432
0433
0434
0435 [score, I]=max(1.5*deltaScore+deltaConnected);
0436
0437
0438
0439 hasToAddTransport=true;
0440 if ~isempty(deltaConnected)
0441 if score>0
0442 hasToAddTransport=false;
0443 end
0444 end
0445
0446
0447
0448 if hasToAddTransport==false
0449 [newS, newg2c]=moveGene(newS,model,g2c,geneIndex(I),moveTo(I),nRxns,nMets);
0450 else
0451
0452
0453 transMet=unconnected(randsample(numel(unconnected),1));
0454
0455
0456 comps=ceil((transMet-nEM)/((size(S,1)-nEM)/nComps));
0457
0458
0459
0460 dcIndex=transMet-(comps-1)*nMets;
0461
0462
0463
0464 allIndexes=dcIndex;
0465 for k=1:nComps-1
0466 allIndexes=[allIndexes;dcIndex+nMets*k];
0467 end
0468
0469
0470
0471 I=sum(newS(allIndexes,:)~=0,2)>0;
0472
0473
0474
0475
0476 connectedUsed=setdiff(allIndexes(I),unconnected);
0477
0478
0479
0480 if isempty(connectedUsed)
0481 break;
0482 end
0483
0484
0485
0486 if transMet==dcIndex
0487 newS=addTransport(newS,nRxns,nER,nMets,nEM,nComps,transMet,connectedUsed(randsample(numel(connectedUsed),1)));
0488 else
0489
0490
0491 I=connectedUsed(connectedUsed<(nMets+nEM));
0492 if any(I)
0493 newS=addTransport(newS,nRxns,nER,nMets,nEM,nComps,transMet,I(randsample(numel(I),1)));
0494 else
0495
0496
0497
0498 break;
0499 end
0500 end
0501 end
0502 else
0503 wasConnected=true;
0504 break;
0505 end
0506 end
0507
0508
0509
0510 if wasConnected==true
0511
0512 activeTransport=find(sum(newS(:,nER+nRxns*nComps+1:end),2));
0513
0514
0515 unconnected=findUnconnected(newS(:,1:nER+nRxns*nComps),nEM);
0516
0517
0518 I=setdiff(activeTransport,unconnected);
0519
0520
0521
0522 newS(:,find(sum(newS(I,nER+nRxns*nComps+1:end))==4)+nER+nRxns*nComps)=0;
0523
0524
0525
0526 [score, geneScore, trCost]=scoreModel(newS,newg2c,GSS,transportCost);
0527
0528
0529 if score>bestScore
0530 bestScore=score;
0531 bestS=newS;
0532 bestg2c=newg2c;
0533 end
0534
0535
0536 if score>=bestScore
0537 plotScore=[plotScore;geneScore];
0538 nTrans=[nTrans;trCost];
0539 totScore=[totScore;score];
0540 S=newS;
0541 g2c=newg2c;
0542
0543 if plotResults==true
0544 subplot(3,2,1);
0545 spy(S);
0546 subplot(3,2,2);
0547 plot(plotScore,'r');
0548 xlabel('Gene score');
0549 subplot(3,2,3);
0550 plot((plotScore-minScore)/(maxScore-minScore),'r');
0551 xlabel('Gene score relative to predictions');
0552 subplot(3,2,4);
0553 plot(nTrans,'g');
0554 xlabel('Transport cost');
0555 subplot(3,2,5);
0556 plot(totScore,'b');
0557 xlabel('Total score');
0558 subplot(3,2,6);
0559 pause(0.2);
0560 end
0561 end
0562 end
0563 end
0564 scores.totScore=score;
0565 scores.geneScore=geneScore;
0566 scores.transCost=trCost;
0567
0568
0569 [I, J]=find(bestS(nEM+1:nEM+nMets,end-nMets*(nComps-1)+1:end));
0570 J=ceil(J/nMets+1);
0571 transportStruct.mets=model.metNames(I+nEM);
0572 transportStruct.toComp=GSS.compartments(J);
0573
0574 [I, J]=find(bestg2c);
0575 geneLocalization.genes=GSS.genes(I);
0576 geneLocalization.comps=GSS.compartments(J);
0577
0578
0579 [~, I]=sort(geneLocalization.genes);
0580 geneLocalization.genes=geneLocalization.genes(I);
0581 geneLocalization.comps=geneLocalization.comps(I);
0582
0583
0584 I=strncmp('&&FAKE&&',geneLocalization.genes,8);
0585 geneLocalization.genes(I)=[];
0586 geneLocalization.comps(I)=[];
0587
0588
0589
0590
0591
0592
0593
0594 outModel=model;
0595 outModel.S=oldS;
0596
0597
0598 copyPart=outModel.S(nEM+1:end,nER+1:end);
0599
0600
0601 copyRxnGeneMat=outModel.rxnGeneMat(nER+1:end,:);
0602 outModel.rxnGeneMat=[outModel.rxnGeneMat;repmat(copyRxnGeneMat,nComps-1,1)];
0603
0604
0605
0606
0607 nStartComps=numel(outModel.comps);
0608 if nStartComps==1
0609 outModel.comps={'1'};
0610 outModel.compNames=GSS.compartments(1);
0611 else
0612 if model.metComps(1)==1
0613 outModel.compNames(1)=GSS.compartments(1);
0614 else
0615 outModel.compNames(2)=GSS.compartments(1);
0616 end
0617 end
0618 outModel.compNames=[outModel.compNames;GSS.compartments(2:end)'];
0619
0620
0621 for i=1:numel(GSS.compartments)-1
0622 outModel.comps=[outModel.comps;num2str(numel(outModel.comps)+1)];
0623 end
0624
0625 outModel.compOutside=cell(numel(outModel.comps),1);
0626 outModel.compOutside(:)={''};
0627
0628 for i=1:nComps-1
0629 outModel.S=[outModel.S sparse(size(outModel.S,1),nRxns)];
0630 outModel.S=[outModel.S;[sparse(nMets,nRxns*i+nER) copyPart]];
0631 outModel.rxns=[outModel.rxns;strcat(outModel.rxns(nER+1:nER+nRxns),'_',GSS.compartments{i+1})];
0632 outModel.rxnNames=[outModel.rxnNames;strcat(outModel.rxnNames(nER+1:nER+nRxns),' (',GSS.compartments{i+1},')')];
0633 outModel.lb=[outModel.lb;outModel.lb(nER+1:nER+nRxns)];
0634 outModel.ub=[outModel.ub;outModel.ub(nER+1:nER+nRxns)];
0635 outModel.rev=[outModel.rev;outModel.rev(nER+1:nER+nRxns)];
0636 outModel.c=[outModel.c;outModel.c(nER+1:nER+nRxns)];
0637 if isfield(outModel,'grRules')
0638 outModel.grRules=[outModel.grRules;outModel.grRules(nER+1:nER+nRxns)];
0639 end
0640 if isfield(outModel,'subSystems')
0641 outModel.subSystems=[outModel.subSystems;outModel.subSystems(nER+1:nER+nRxns)];
0642 end
0643 if isfield(outModel,'eccodes')
0644 outModel.eccodes=[outModel.eccodes;outModel.eccodes(nER+1:nER+nRxns)];
0645 end
0646 if isfield(outModel,'rxnFrom')
0647 outModel.rxnFrom=[outModel.rxnFrom;outModel.rxnFrom(nER+1:nER+nRxns)];
0648 end
0649 if isfield(outModel,'rxnMiriams')
0650 outModel.rxnMiriams=[outModel.rxnMiriams;outModel.rxnMiriams(nER+1:nER+nRxns)];
0651 end
0652 if isfield(outModel,'rxnNotes')
0653 outModel.rxnNotes=[outModel.rxnNotes;outModel.rxnNotes(nER+1:nER+nRxns)];
0654 end
0655 if isfield(outModel,'rxnReferences')
0656 outModel.rxnReferences=[outModel.rxnReferences;outModel.rxnReferences(nER+1:nER+nRxns)];
0657 end
0658 if isfield(outModel,'rxnConfidenceScores')
0659 outModel.rxnConfidenceScores=[outModel.rxnConfidenceScores;outModel.rxnConfidenceScores(nER+1:nER+nRxns)];
0660 end
0661 if isfield(outModel,'rxnDeltaG')
0662 outModel.rxnDeltaG=[outModel.rxnDeltaG;outModel.rxnDeltaG(nER+1:nER+nRxns)];
0663 end
0664 outModel.mets=[outModel.mets;strcat(outModel.mets(nEM+1:nEM+nMets),'_',GSS.compartments{i+1})];
0665 outModel.metNames=[outModel.metNames;outModel.metNames(nEM+1:nEM+nMets)];
0666 outModel.b=[outModel.b;outModel.b(nEM+1:nEM+nMets,:)];
0667 I=ones(nMets,1)*nStartComps+i;
0668 outModel.metComps=[outModel.metComps;I];
0669 if isfield(outModel,'inchis')
0670 outModel.inchis=[outModel.inchis;outModel.inchis(nEM+1:nEM+nMets)];
0671 end
0672 if isfield(outModel,'metSmiles')
0673 outModel.metSmiles=[outModel.metSmiles;outModel.metSmiles(nEM+1:nEM+nMets)];
0674 end
0675 if isfield(outModel,'unconstrained')
0676 outModel.unconstrained=[outModel.unconstrained;outModel.unconstrained(nEM+1:nEM+nMets)];
0677 end
0678 if isfield(outModel,'metMiriams')
0679 outModel.metMiriams=[outModel.metMiriams;outModel.metMiriams(nEM+1:nEM+nMets)];
0680 end
0681 if isfield(outModel,'metFormulas')
0682 outModel.metFormulas=[outModel.metFormulas;outModel.metFormulas(nEM+1:nEM+nMets)];
0683 end
0684 if isfield(outModel,'metFrom')
0685 outModel.metFrom=[outModel.metFrom;outModel.metFrom(nEM+1:nEM+nMets)];
0686 end
0687 if isfield(outModel,'metCharges')
0688 outModel.metCharges=[outModel.metCharges;outModel.metCharges(nEM+1:nEM+nMets)];
0689 end
0690 if isfield(outModel,'metDeltaG')
0691 outModel.metDeltaG=[outModel.metDeltaG;outModel.metDeltaG(nEM+1:nEM+nMets)];
0692 end
0693 end
0694
0695
0696 transS=bestS(:,numel(outModel.rxns)+1:end);
0697 J=sum(transS)>0;
0698
0699
0700
0701 transS(transS~=0)=1;
0702 transS(1:nEM+nMets,:)=transS(1:nEM+nMets,:)*-1;
0703 I=find(sum(transS>0,2));
0704 nTransRxns=numel(I);
0705 outModel.S=[outModel.S transS(:,J)];
0706 filler=ones(nTransRxns,1);
0707 outModel.lb=[outModel.lb;filler*-1000];
0708 outModel.ub=[outModel.ub;filler*1000];
0709 outModel.rev=[outModel.rev;filler];
0710 outModel.c=[outModel.c;filler*0];
0711 outModel.rxnGeneMat=[outModel.rxnGeneMat;sparse(nTransRxns,numel(outModel.genes))];
0712
0713 for i=1:numel(I)
0714 outModel.rxns=[outModel.rxns;strcat('transport',num2str(i))];
0715 outModel.rxnNames=[outModel.rxnNames;['Transport of ',outModel.metNames{I(i)}]];
0716 if isfield(outModel,'grRules')
0717 outModel.grRules=[outModel.grRules;{''}];
0718 end
0719 if isfield(outModel,'rxnMiriams')
0720 outModel.rxnMiriams=[outModel.rxnMiriams;{[]}];
0721 end
0722 if isfield(outModel,'subSystems')
0723 outModel.subSystems=[outModel.subSystems;{{'Inferred transport reactions'}}];
0724 end
0725 if isfield(outModel,'eccodes')
0726 outModel.eccodes=[outModel.eccodes;{''}];
0727 end
0728 if isfield(outModel,'rxnFrom')
0729 outModel.rxnFrom=[outModel.rxnFrom;{''}];
0730 end
0731 if isfield(outModel,'rxnNotes')
0732 outModel.rxnNotes=[outModel.rxnNotes;{''}];
0733 end
0734 if isfield(outModel,'rxnReferences')
0735 outModel.rxnReferences=[outModel.rxnReferences;{''}];
0736 end
0737 if isfield(outModel,'rxnConfidenceScores')
0738 outModel.rxnConfidenceScores=[outModel.rxnConfidenceScores;NaN];
0739 end
0740 if isfield(outModel,'rxnDeltaG')
0741 outModel.rxnDeltaG=[outModel.rxnDeltaG;NaN];
0742 end
0743 end
0744
0745
0746
0747 [~, J]=find(bestS(:,1:nER+nComps*nRxns));
0748 K=true(numel(outModel.rxns),1);
0749 K(J)=false;
0750 K(end-nTransRxns+1:end)=false;
0751 outModel=removeReactions(outModel,K,true);
0752
0753
0754 I=strncmp('&&FAKE&&',outModel.genes,8);
0755 outModel.genes(I)=[];
0756 if isfield(outModel,'geneMiriams')
0757 outModel.geneMiriams(I)=[];
0758 end
0759 if isfield(outModel,'geneShortNames')
0760 outModel.geneShortNames(I)=[];
0761 end
0762 outModel.rxnGeneMat(:,I)=[];
0763
0764
0765 [grRules,rxnGeneMat] = standardizeGrRules(outModel,true);
0766 outModel.grRules = grRules;
0767 outModel.rxnGeneMat = rxnGeneMat;
0768 end
0769
0770
0771 function [S, g2c]=moveGene(S,model,g2c,geneToMove,toComp,nRxns,nMets)
0772
0773 currentComp=find(g2c(geneToMove,:));
0774 g2c(geneToMove,:)=false;
0775 g2c(geneToMove,toComp)=true;
0776
0777
0778 [I, ~]=find(model.rxnGeneMat(:,geneToMove));
0779
0780
0781 oldRxns=I+(currentComp-1)*nRxns;
0782
0783
0784 newRxns=I+(toComp-1)*nRxns;
0785
0786
0787
0788 metChange=nMets*(toComp-currentComp);
0789
0790
0791 [I, J, K]=find(S(:,oldRxns));
0792 I=I+metChange;
0793
0794
0795 S(:,oldRxns)=0;
0796 S(sub2ind(size(S),I,newRxns(J)))=K;
0797 end
0798
0799
0800
0801
0802
0803
0804
0805 function unconnected=findUnconnected(S,nEM,metsToCheck)
0806 if nargin>2
0807
0808
0809 I=false(size(S,1),1);
0810 I(1:nEM)=true;
0811 I(metsToCheck)=true;
0812 S=S(I,:);
0813 end
0814
0815 em=false(size(S,1),1);
0816 em(1:nEM)=true;
0817
0818
0819 I=sum(S>2,1) | sum(S>2,1);
0820 revS=S;
0821 revS(:,I)=revS(:,I)*-1;
0822
0823
0824
0825
0826 connected=sum(S>0,2)>1 | em | sum(S~=0,2)==0 | sum(S(:,~I)>0,2)>0 | sum(S(:,I)~=0,2)>1;
0827
0828
0829 unconnected=sum(S>0 | revS>0,2)==0 & connected==false;
0830
0831
0832 maybeUnconnected=~connected & ~unconnected;
0833
0834
0835
0836
0837
0838
0839
0840 deadRxns=any(S(maybeUnconnected,:)>0) & any(S(maybeUnconnected,:)<0);
0841
0842
0843 problematic=any(S(:,deadRxns)~=0,2);
0844
0845
0846
0847 unconnected(problematic & maybeUnconnected)=true;
0848
0849
0850 if nargin>2
0851 unconnected=metsToCheck(unconnected(nEM+1:end));
0852 else
0853 unconnected=find(unconnected);
0854 end
0855 end
0856
0857
0858
0859
0860
0861
0862
0863 function [geneIndex, moveTo, deltaConnected, deltaScore]=selectGenes(S,nEM,nMets,nER,nRxns,model,unconnected,g2c,GSS)
0864
0865 moveTo=zeros(numel(model.genes),1);
0866 deltaConnected=zeros(numel(model.genes),1);
0867
0868
0869 nComps=size(g2c,2);
0870 comps=ceil((unconnected-nEM)/((size(S,1)-nEM)/nComps));
0871
0872
0873
0874 dcIndexes=unique(unconnected-(comps-1)*nMets);
0875
0876
0877 allIndexes=dcIndexes;
0878 for i=1:nComps-1
0879 allIndexes=[allIndexes;dcIndexes+nMets*i];
0880 end
0881
0882
0883 I=sum(S>2,1) | sum(S>2,1);
0884 revS=S;
0885 revS(:,I)=revS(:,I)*-1;
0886
0887
0888
0889 newMets=setdiff(allIndexes,unconnected);
0890 [~, potential]=find(S(newMets,:)>0 | revS(newMets,:)>0);
0891 potential(potential<=nER | potential>nER+nRxns*nComps)=[];
0892
0893
0894 rxnComps=ceil((potential-nER)/(nRxns));
0895
0896
0897
0898 dcRxnIndexes=potential-(rxnComps-1)*nRxns;
0899
0900
0901 genes=find(sum(model.rxnGeneMat(dcRxnIndexes,:)>0,1));
0902
0903
0904
0905
0906
0907
0908
0909
0910 [~, J]=find(g2c(genes,:));
0911
0912
0913
0914 geneScores=GSS.scores(sub2ind(size(g2c),genes(:),J));
0915 modGeneScores=1.1-geneScores;
0916 if numel(genes)>25
0917 rGenes=genes(randsample(numel(genes),min(numel(genes),25),true,modGeneScores));
0918
0919
0920 rGenes=unique(rGenes);
0921
0922
0923 [~, I]=ismember(rGenes,genes);
0924 geneScores=geneScores(I);
0925 genes=rGenes;
0926 end
0927 for i=1:numel(genes)
0928
0929
0930
0931
0932 rxns=find(model.rxnGeneMat(:,genes(i)));
0933
0934
0935 mets=find(sum(model.S(:,rxns)~=0,2)>0);
0936
0937
0938 allIndexes=mets;
0939 for j=1:nComps-1
0940 allIndexes=[allIndexes;mets+nMets*j];
0941 end
0942
0943
0944
0945
0946
0947 [I, ~]=find(model.S(:,rxns));
0948 moveToComps=unique(comps(ismember(dcIndexes,I)));
0949
0950
0951 bestMove=-inf;
0952 bestComp=[];
0953 for j=1:numel(moveToComps)
0954 newS=moveGene(S,model,g2c,genes(i),moveToComps(j),nRxns,nMets);
0955
0956
0957
0958 dConnected=numel(unconnected)-numel(findUnconnected(newS,nEM,[allIndexes;unconnected]));
0959 if dConnected>bestMove
0960 bestMove=dConnected;
0961 bestComp=moveToComps(j);
0962 end
0963 end
0964
0965
0966 moveTo(genes(i))=bestComp;
0967 deltaConnected(genes(i))=bestMove;
0968 end
0969
0970
0971 geneIndex=genes(:);
0972 moveTo=moveTo(geneIndex);
0973 deltaConnected=deltaConnected(geneIndex);
0974 deltaScore=GSS.scores(sub2ind(size(g2c),geneIndex(:),moveTo))-geneScores;
0975 end
0976
0977
0978
0979
0980
0981
0982 function S=addTransport(S,nRxns,nER,nMets,nEM,nComps,metA,metB)
0983 mets=[metA;metB];
0984
0985 comps=ceil((mets-nEM)/((size(S,1)-nEM)/nComps));
0986
0987 if sum(comps==1)~=1
0988 EM='Tried to create a transport reaction from a non-default compartment';
0989 dispEM(EM);
0990 end
0991
0992
0993 rIndex=(nER+nRxns*nComps)+mets(comps~=1)-nEM-nMets;
0994
0995 S(mets,rIndex)=2;
0996 end
0997
0998
0999
1000 function [score, geneScore, transportCost]=scoreModel(S,g2c,GSS,transportCost)
1001 [I, J]=find(g2c);
1002 geneScore=sum(GSS.scores(sub2ind(size(g2c),I,J)));
1003 [I, ~]=find(S==2);
1004 I=unique(I);
1005 transportCost=sum(transportCost(I));
1006 score=geneScore-transportCost;
1007 end
1008
1009
1010
1011
1012 function y = randsample(n, k, replace, w)
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037 if nargin < 2
1038 error('stats:randsample:TooFewInputs','Requires two input arguments.');
1039 elseif numel(n) == 1
1040 population = [];
1041 else
1042 population = n;
1043 n = numel(population);
1044 if length(population)~=n
1045 error('stats:randsample:BadPopulation','POPULATION must be a vector.');
1046 end
1047 end
1048
1049 if nargin < 3
1050 replace = false;
1051 end
1052
1053 if nargin < 4
1054 w = [];
1055 elseif ~isempty(w)
1056 if length(w) ~= n
1057 if isempty(population)
1058 error('stats:randsample:InputSizeMismatch',...
1059 'W must have length equal to N.');
1060 else
1061 error('stats:randsample:InputSizeMismatch',...
1062 'W must have the same length as the population.');
1063 end
1064 else
1065 p = w(:)' / sum(w);
1066 end
1067 end
1068
1069 switch replace
1070
1071
1072 case {true, 'true', 1}
1073 if isempty(w)
1074 y = ceil(n .* rand(k,1));
1075 else
1076 [dum, y] = histc(rand(k,1),[0 cumsum(p)]);
1077 end
1078
1079
1080 case {false, 'false', 0}
1081 if k > n
1082 if isempty(population)
1083 error('stats:randsample:SampleTooLarge',...
1084 'K must be less than or equal to N for sampling without replacement.');
1085 else
1086 error('stats:randsample:SampleTooLarge',...
1087 'K must be less than or equal to the population size.');
1088 end
1089 end
1090
1091 if isempty(w)
1092
1093
1094
1095 if 4*k > n
1096 rp = randperm(n);
1097 y = rp(1:k);
1098
1099
1100
1101
1102 else
1103 x = zeros(1,n);
1104 sumx = 0;
1105 while sumx < k
1106 x(ceil(n * rand(1,k-sumx))) = 1;
1107 sumx = sum(x);
1108 end
1109 y = find(x > 0);
1110 y = y(randperm(k));
1111 end
1112 else
1113 error('stats:randsample:NoWeighting',...
1114 'Weighted sampling without replacement is not supported.');
1115 end
1116 otherwise
1117 error('stats:randsample:BadReplaceValue',...
1118 'REPLACE must be either true or false.');
1119 end
1120
1121 if ~isempty(population)
1122 y = population(y);
1123 else
1124 y = y(:);
1125 end
1126 end