diff --git a/CHANGELOG.md b/CHANGELOG.md index d5200eb8..6892c2d4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ ### Breaking changes +* `getModelFromHomology` with `preferredOrder` treats a gene of a later model that maps to a new gene an earlier model already maps as a subunit without an ortholog, and `complexPolicy` decides what happens to it (was: the gene and every part of the rule that needs it were removed). For the rule `(a and b) or x` with `a` taken by an earlier model, `flag` gives `(OLD_MODELID_a and nb) or nx`, `keep` gives `nb or nx` and `drop` gives `nx`. A reaction that has genes, none of which keeps a mapping, is not included. * `getModelFromHomology` with `complexPolicy` `drop` removes each complex that has a subunit without an ortholog, and removes the reaction only when no complex remains (was: the reaction was removed as soon as one subunit had no ortholog). For the rule `(A and B) or (C and D)` without an ortholog of `B`, the draft has the orthologs of `C` and `D`. ### Fixes diff --git a/src/reconstruction/homology/getModelFromHomology.m b/src/reconstruction/homology/getModelFromHomology.m index 4dba5084..2768b5fb 100755 --- a/src/reconstruction/homology/getModelFromHomology.m +++ b/src/reconstruction/homology/getModelFromHomology.m @@ -24,7 +24,12 @@ % the order in which reactions are added from the models, as a cell array % of model IDs. If not supplied, reactions are included from all models, % otherwise one gene results in reactions from one model only -% (default {}). +% (default {}). A gene of a later model that maps to a new gene which an +% earlier model already maps loses its mappings and counts as a subunit +% without an ortholog, so complexPolicy decides what happens to it. For +% the rule (a and b) or x with a taken by an earlier model, "flag" gives +% (OLD_MODELID_a and nb) or nx, "keep" gives nb or nx and "drop" gives nx. +% A reaction that has genes, none of which keeps a mapping, is not included. % strictness : double % integer that specifies which reactions are included (default 1): % @@ -503,16 +508,24 @@ [~, genesToDelete]=find(finalMappings{i}(usedGenes(a),:)); %IMPORTANT! IS it really correct to remove all genes that map? genesToDelete=unique(genesToDelete); %Maybe not needed, but for clarity if nothing else - %Remove all the genes that were already found and add the other - %ones to allUsedGenes - if ~isempty(genesToDelete) - models{useOrderIndexes(i)}=removeGenes(models{useOrderIndexes(i)},allGenes{i+1}(genesToDelete),true,true,false); - end + %The genes that were already found lose their mappings and are + %treated as genes without an ortholog. Add the other ones to + %allUsedGenes allUsedGenes(usedGenes)=true; %Remove the deleted genes from finalMappings and allGenes. finalMappings{i}(:,genesToDelete)=[]; allGenes{i+1}(genesToDelete)=[]; + + %Remove the reactions that have no gene with a mapping left + if ~isempty(genesToDelete) + a=ismember(models{useOrderIndexes(i)}.genes,allGenes{i+1}); + [rxnsToKeep,~] = find(models{useOrderIndexes(i)}.rxnGeneMat(:,a)); + rxnsToRemove = repmat(1,numel(models{useOrderIndexes(i)}.rxns),1); + rxnsToRemove(rxnsToKeep) = 0; + rxnsToRemove(ismember(models{useOrderIndexes(i)}.rxns,geneFreeRxns{useOrderIndexes(i)})) = 0; + models{useOrderIndexes(i)}=removeReactions(models{useOrderIndexes(i)},find(rxnsToRemove),true,true,true); + end end end @@ -606,7 +619,7 @@ else models{useOrderIndexes(i)}.genes=allGenes{1}(unique(newGenes)); end - if isfield(models{useOrderIndexes(i)},'geneComps') + if isfield(models{useOrderIndexes(i)},'geneComps') && ~isempty(models{useOrderIndexes(i)}.geneComps) geneComps=models{useOrderIndexes(i)}.geneComps(1); models{useOrderIndexes(i)}.geneComps=zeros(numel(models{useOrderIndexes(i)}.genes),1); %Assume that all genes are in the same compartment, and this @@ -616,7 +629,12 @@ end %Now merge the models. All information should be correct except for "or" -%complexes +%complexes. A model that has lost all its reactions adds nothing to the draft +modelIds=cellfun(@(m) m.id,models,'UniformOutput',false); +hasRxns=cellfun(@(m) ~isempty(m.rxns),models); +if any(hasRxns) + models=models(hasRxns); +end draftModel=mergeModels(models,'metNames'); %Remove OLD_ genes that are a member of an isozyme group (an "or" group) with @@ -659,11 +677,11 @@ %Change name of the resulting model draftModel.id=getModelFor; name='Generated by getModelFromHomology using '; -for i=1:numel(models) - if i