From a357083591200cbc2fbf86b7852445d66264834d Mon Sep 17 00:00:00 2001 From: Eduard Kerkhoven Date: Fri, 17 Jul 2026 22:52:30 +0200 Subject: [PATCH 1/2] chore: remove legacy getINITModel2 gene-essentiality code Gene essentiality now runs the Python ftINIT (tINIT2) pipeline (code/test/geneEssentiality.py + estimateEssentialGenes.py + evaluateHart2015Essentiality.py). Remove the superseded MATLAB implementation: - tINIT/getINITModel2.m old INIT algorithm; RAVEN ftINIT is its successor - tINIT/restoreModelGrRules.m orphan; restored grRules the old tINIT stripped - test/estimateEssentialGenes.m MATLAB; only caller of getINITModel2 - test/evaluateHart2015Essentiality.m MATLAB The Python equivalents, the Hart2015 data/results and the (already-Python) gene-essentiality workflow are the current pipeline and are untouched. --- code/tINIT/getINITModel2.m | 464 ----------------------- code/tINIT/restoreModelGrRules.m | 41 -- code/test/estimateEssentialGenes.m | 107 ------ code/test/evaluateHart2015Essentiality.m | 156 -------- 4 files changed, 768 deletions(-) delete mode 100644 code/tINIT/getINITModel2.m delete mode 100644 code/tINIT/restoreModelGrRules.m delete mode 100644 code/test/estimateEssentialGenes.m delete mode 100644 code/test/evaluateHart2015Essentiality.m diff --git a/code/tINIT/getINITModel2.m b/code/tINIT/getINITModel2.m deleted file mode 100644 index 5fe3b508..00000000 --- a/code/tINIT/getINITModel2.m +++ /dev/null @@ -1,464 +0,0 @@ -function [model, metProduction, essentialRxnsForTasks, addedRxnsForTasks, deletedDeadEndRxns, deletedRxnsInINIT, taskReport] = getINITModel2(refModel, tissue, celltype, hpaData, arrayData, metabolomicsData, removeGenes, taskFile, useScoresForTasks, printReport, taskStructure, params, paramsFT) -% getINITModel2 -% Note: There is a newer improved version of this function in RAVEN Toolbox -% called ftINIT that can be used together with the helper functions in this repo. -% -% Generates a model using the INIT algorithm, based on proteomics and/or -% transcriptomics and/or metabolomics and/or metabolic tasks. -% This is the newer version, which has updated handling of gene rules to -% differentiate between isozymes and enzyme complexes. -% -% refModel a model structure. The model should be in the -% closed form (no exchange reactions open). Import -% using import(filename,false). If the model is not -% loaded using importModel, it might be that there -% is no "unconstrained" field. In that case, -% manually add the field like: -% model.unconstrained = false(numel(model.mets),1); -% tissue tissue to score for. Should exist in either -% hpaData.tissues or arrayData.tissues -% celltype cell type to score for. Should exist in either -% hpaData.celltypes or arrayData.celltypes for this -% tissue (opt, default is to use the max values -% among all the cell types for the tissue. -% hpaData HPA data structure from parseHPA (opt if arrayData -% is supplied, default []) -% arrayData gene expression data structure (opt if hpaData is -% supplied, default []) -% genes cell array with the unique gene names -% tissues cell array with the tissue names. The list may not -% be unique, as there can be multiple cell types per -% tissue -% celltypes cell array with the cell type names for each tissue -% levels GENESxTISSUES array with the expression level for -% each gene in each tissue/celltype. NaN should be -% used when no measurement was performed -% threshold a single value or a vector of gene expression -% thresholds, above which genes are considered to be -% "expressed". (opt, by default, the mean expression -% levels of each gene across all tissues in arrayData -% will be used as the threshold values) -% singleCells binary value selecting whether to use the -% single-cell algorithm to identify expressed genes. -% If used, specify cell subpopulations in CELLTYPES -% (opt, default []) -% plotResults true if single cell probability distributions -% should be plotted (opt, default = false) -% metabolomicsData cell array with metabolite names that the model -% should produce (opt, default []) -% removeGenes if true, low-abundance genes will be removed from -% grRules, unless they are the only gene associated -% with a reaction, or a subunit of an enzyme complex -% (see "removeLowScoreGenes" function for details). -% If false, grRules will not be modified; however, -% genes that were associated only with removed -% reactions will not be present in the final model. -% (opt, default true). -% taskFile a task list in Excel format. See parseTaskList for -% details (opt, default []) -% useScoresForTasks true if the calculated reaction scored should be -% used as weights when fitting to tasks (opt, default -% true) -% printReport true if a report should be printed to the screen -% (opt, default true) -% taskStructure task structure generated from parseTaskList. Can be -% used as an alternative way to define tasks when Excel -% sheets are not suitable. Overrides taskFile (opt, -% default []) -% params parameter structure as used by getMILPParams. This -% is for the INIT algorithm. For the the MILP -% problems solved to fit tasks, see paramsFT (opt, -% default []) -% paramsFT parameter structure as used by getMILPParams. This -% is for the fitTasks step. For the INIT algorithm, -% see params (opt, default []) -% -% model the resulting model structure -% metProduction array that indicates which of the -% metabolites in metabolomicsData that could be -% produced. Note that this is before the -% gap-filling process to enable defined tasks. To -% see which metabolites that can be produced in -% the final model, use canProduce. -% -2: metabolite name not found in model -% -1: metabolite found, but it could not be produced -% 1: metabolite could be produced -% essentialRxnsForTasks cell array of the reactions which were -% essential to perform the tasks -% addedRxnsForTasks cell array of the reactions which were added in -% order to perform the tasks -% deletedDeadEndRxns cell array of reactions deleted because they -% could not carry flux (INIT requires a -% functional input model) -% deletedRxnsInINIT cell array of the reactions which were deleted by -% the INIT algorithm -% taskReport structure with the results for each task -% id cell array with the id of the task -% description cell array with the description of the task -% ok boolean array with true if the task was successful -% essential cell array with cell arrays of essential -% reactions for the task -% gapfill cell array of cell arrays of reactions included -% in the gap-filling for the task -% -% This is the main function for automatic reconstruction of models based -% on the INIT algorithm (PLoS Comput Biol. 2012;8(5):e1002518). Not all -% settings are possible using this function, and you may want to call the -% functions scoreComplexModel, runINIT and fitTasks individually instead. -% -% NOTE: Boundary metabolites should normally not be removed from the model -% when using this approach, since checkTasks/fitTasks rely on putting specific -% constraints for each task. The INIT algorithm will remove boundary metabolites -% if any are present. Use the closeModel function to add boundary -% metabolites to a model. -% -% Usage: [model, metProduction, essentialRxnsForTasks, addedRxnsForTasks,... -% deletedDeadEndRxns, deletedRxnsInINIT, taskReport] = ... -% getINITModel2(refModel, tissue, celltype, hpaData, arrayData,... -% metabolomicsData, removeGenes, taskFile, useScoresForTasks, ... -% printReport, taskStructure, params, paramsFT); -% - - -if nargin < 5 - arrayData = []; -end -if nargin < 6 - metabolomicsData = []; -end -if nargin < 7 || isempty(removeGenes) - removeGenes = true; -end -if nargin < 8 - taskFile = []; -end -if nargin < 9 || isempty(useScoresForTasks) - useScoresForTasks = true; -end -if nargin < 10 || isempty(printReport) - printReport = true; -end -if nargin < 11 - taskStructure = []; -end -if nargin < 12 - params = []; -end -if nargin < 13 - paramsFT = []; -end - -%Check that the model is in the closed form -if ~isfield(refModel,'unconstrained') - EM = 'Boundary metabolites should normally be present in the model when using getINITModel2. Use closeModel(model) to add boundary metabolites to a model'; - dispEM(EM); -end - -%Create the task structure if not supplied -if any(taskFile) && isempty(taskStructure) - taskStructure = parseTaskList(taskFile); -end - -% sc-tINIT to identify confidence levels of gene expression -if isfield(arrayData,'singleCells') - if arrayData.singleCells == 1 - % Check to ensure cell type is defined - if ~isfield(arrayData,'celltypes') - dispEM('arrayData must contain cell type information if sc-tINIT is to be used','false'); - end - if ~ismember(upper(celltype),upper(arrayData.celltypes)) - dispEM('The cell type name does not match'); - end - - % Analyze only cell type of interest - J = strcmpi(arrayData.celltypes,celltype); - - % Analyze only genes included in the reference model - I = ismember(arrayData.genes,refModel.genes); - - % Convert expression data to population fractions - binary_levels = arrayData.levels(I,J) ~= 0; % Classify each gene as detected (1) or not (0) in each cell - cell_count_levels = sum(binary_levels,2); % Number of cells expressing each transcript - cell_frac_levels = cell_count_levels/size(binary_levels,2); % Number of cells expressing each transcript - - % Bin cell_frac_counts manually - x = 0:.01:1; - for i = 1:length(x) - cell_frac_count(i) = sum(round(cell_frac_levels,2) == x(i)); - end - - % Fit four beta distributions - cell_frac_count(cell_frac_count == 0) = NaN; % Remove zeros from optimization - cell_frac_count(1) = NaN; % Remove non-expressed genes from optimization - x_lim = 1; % Somewhat arbitrary parameter to fit left tail of distr. - myfun = @(par) nansum((cell_frac_count(1:find(x >= x_lim,1)) - ... - abs(par(1))*betapdf(x(1:find(x >= x_lim,1)),abs(par(2)),abs(par(3))) - ... - abs(par(4))*betapdf(x(1:find(x >= x_lim,1)),abs(par(5)),abs(par(6))) - ... - abs(par(7))*betapdf(x(1:find(x >= x_lim,1)),abs(par(8)),abs(par(9))) - ... - abs(par(10))*betapdf(x(1:find(x >= x_lim,1)),abs(par(11)),abs(par(12)))).^2); - - par0 = [4,2,100,7,2,30,7,5,20,5,15,20]; - opts = optimset('Display','off'); - [par,f_val] = fminsearch(myfun,par0,opts); - par = abs(par); - - % Plot results - if (isfield(arrayData,'plotResults')) - if arrayData.plotResults == true - figure(); hold on; plot(x,cell_frac_count,'ko','MarkerSize',5); - plot(x,abs(par(1))*betapdf(x,abs(par(2)),abs(par(3))),'b-','LineWidth',1) - plot(x,abs(par(4))*betapdf(x,abs(par(5)),abs(par(6))),'b-','LineWidth',1) - plot(x,abs(par(7))*betapdf(x,abs(par(8)),abs(par(9))),'b-','LineWidth',1) - plot(x,abs(par(10))*betapdf(x,abs(par(11)),abs(par(12))),'b-','LineWidth',1) - plot(x,abs(par(1))*betapdf(x,abs(par(2)),abs(par(3))) + ... - abs(par(4))*betapdf(x,abs(par(5)),abs(par(6))) + ... - abs(par(7))*betapdf(x,abs(par(8)),abs(par(9))) + ... - abs(par(10))*betapdf(x,abs(par(11)),abs(par(12))),'-','Color',[.5 .5 .5],'LineWidth',2) - xlabel('Expression Probability');ylabel('# of genes');set(gca,'FontSize',14,'LineWidth',1.25); - title('Expression prediction','FontSize',18,'FontWeight','bold') - end - end - - % Score genes based on population expression (p = .05) - exprs_cutoff_1 = find(cdf('beta',x,par(2),par(3)) >.95,1)-1; % Find index of no confidence genes - exprs_cutoff_2 = find(cdf('beta',x,par(5),par(6)) >.95,1)-1; % Find index of low confidence genes - exprs_cutoff_3 = find(cdf('beta',x,par(8),par(9)) >.95,1)-1; % Find index of low confidence genes - exprs_cutoffs = sort([exprs_cutoff_1,exprs_cutoff_2,exprs_cutoff_3]); - gene_scores = cell_frac_levels*0; - gene_scores(cell_frac_levels <= x(exprs_cutoffs(1))) = 4; % Not detected - gene_scores(logical((cell_frac_levels >= x(exprs_cutoffs(1))).*(cell_frac_levels < x(exprs_cutoffs(2))))) = 3; % Low detection - gene_scores(logical((cell_frac_levels >= x(exprs_cutoffs(2))).*(cell_frac_levels < x(exprs_cutoffs(3))))) = 2; % Medium detection - gene_scores(cell_frac_levels > x(exprs_cutoffs(3))) = 1; % High detection - - % Replace hpaData with singleCellData - if printReport == true - dispEM('Single cell data is not currently compatible with HPA data. \n Replacing hpaData with single cell-based scoring.',false); - end - hpaData.genes = arrayData.genes; - hpaData.tissues = arrayData.tissues; - hpaData.celltypes = arrayData.celltypes; - hpaData.levels = [{'High'},{'Medium'},{'Low'},{'None'}]; - hpaData.gene2Level = zeros(length(arrayData.genes),length(arrayData.celltypes)); - for i = 1:length(find(J)) - find_var = find(J,i); - hpaData.gene2Level(I,find_var(end)) = gene_scores; - end - - % Remove arrayData from the analysis (Might be a bad idea) - clear arrayData - arrayData = []; - end -end - - -if printReport == true - if any(celltype) - fprintf(['***Generating model for: ' tissue ' - ' celltype '\n']); - else - fprintf(['***Generating model for: ' tissue '\n']); - end - if ~isempty(hpaData) - fprintf('-Using HPA data\n'); - end - if ~isempty(arrayData) - fprintf('-Using array data\n'); - end - if ~isempty(metabolomicsData) - fprintf('-Using metabolomics data\n'); - end - if ~isempty(taskFile) || ~isempty(taskStructure) - fprintf('-Using metabolic tasks\n'); - end - fprintf('\n'); - - printScores(refModel,'Reference model statistics',hpaData,arrayData,tissue,celltype); -end - -%Remove dead-end reactions to speed up the optimization and to -%differentiate between reactions removed by INIT and those that are -%dead-end -if isfield(arrayData,'deletedDeadEndRxns') % temporary shortcut, should be revised. - deletedDeadEndRxns = arrayData.deletedDeadEndRxns; % temporary shortcut, should be revised. -elseif isfield(hpaData,'deletedDeadEndRxns') % temporary shortcut, should be revised. - deletedDeadEndRxns = hpaData.deletedDeadEndRxns; % temporary shortcut, should be revised. -else % temporary shortcut, should be revised. - [~, deletedDeadEndRxns]=simplifyModel(refModel,true,false,true,true,true); -end % temporary shortcut, should be revised. -cModel = removeReactions(refModel,deletedDeadEndRxns,false,true); - -%Store the connected model like this to keep track of stuff -if printReport == true - printScores(cModel,'Pruned model statistics',hpaData,arrayData,tissue,celltype); -end - -%If tasks have been defined, then go through them and get essential -%reactions -if ~isempty(taskStructure) - - if isfield(arrayData,'taskReport') && isfield(arrayData,'essentialRxnMat') % temporary shortcut, should be revised. - taskReport = arrayData.taskReport; % temporary shortcut, should be revised. - essentialRxnMat = arrayData.essentialRxnMat; % temporary shortcut, should be revised. - elseif isfield(hpaData,'taskReport') && isfield(hpaData,'essentialRxnMat') % temporary shortcut, should be revised. - taskReport = hpaData.taskReport; % temporary shortcut, should be revised. - essentialRxnMat = hpaData.essentialRxnMat; % temporary shortcut, should be revised. - else % temporary shortcut, should be revised. - [taskReport, essentialRxnMat]=checkTasks(cModel,[],printReport,true,true,taskStructure); - end % temporary shortcut, should be revised. - - essentialRxnsForTasks = cModel.rxns(any(essentialRxnMat,2)); - - %Find metabolites present in taskStruct. We want to avoid removing - %these metabolites from the final model (even though they may no longer - %participate in any reacitons) so that the final model is still able to - %complete all of the tasks without any errors. - taskMets = union(vertcat(taskStructure.inputs),vertcat(taskStructure.outputs)); - taskMets = union(taskMets, parseRxnEqu(vertcat(taskStructure.equations))); - modelMets = strcat(cModel.metNames,'[',cModel.comps(cModel.metComps),']'); - [inModel,metInd] = ismember(taskMets,modelMets); - essentialMetsForTasks = cModel.mets(metInd(inModel)); - - %Remove tasks that cannot be performed - taskStructure(taskReport.ok == false) = []; - if printReport == true - printScores(removeReactions(cModel,setdiff(cModel.rxns,essentialRxnsForTasks),true,true),'Reactions essential for tasks',hpaData,arrayData,tissue,celltype); - end -else - essentialRxnsForTasks = {}; - essentialMetsForTasks = {}; -end - -% Score the connected model -rxnScores = scoreComplexModel(cModel,hpaData,arrayData,tissue,celltype); - -%Run the INIT algorithm. The exchange reactions that are used in the final -%model will be open, which doesn't fit with the last step. Therefore -%delete reactions from the original model instead of taking the output. The -%default implementation does not constrain reversible reactions to only -%carry flux in one direction. Runs without the constraints on reversibility -%and with all output allowed. This is to reduce the complexity of the -%problem. -[~, deletedRxnsInINIT, metProduction] = runINIT(simplifyModel(cModel),rxnScores,metabolomicsData,essentialRxnsForTasks,0,true,false,params); -initModel = removeReactions(cModel,deletedRxnsInINIT,false,true); - -% remove metabolites separately to avoid removing those needed for tasks -unusedMets = initModel.mets(all(initModel.S == 0,2)); -initModel = removeMets(initModel, setdiff(unusedMets,essentialMetsForTasks)); - -if printReport == true - printScores(initModel,'INIT model statistics',hpaData,arrayData,tissue,celltype); - printScores(removeReactions(cModel,setdiff(cModel.rxns,deletedRxnsInINIT),true,true),'Reactions deleted by INIT',hpaData,arrayData,tissue,celltype); -end - -%The full model has exchange reactions in it. fitTasks calls on fillGaps, -%which automatically removes exchange (boundary) metabolites (because it -%assumes that the reactions are constrained when appropriate). In this case -%the uptakes/outputs are retrieved from the task sheet instead. To prevent -%exchange reactions being used to fill gaps, they are delete from the -%reference model here. -initModel.id = 'INITModel'; - -%If gaps in the model should be filled using a task list -if ~isempty(taskStructure) - %Remove exchange reactions and reactions already included in the INIT - %model - refModelNoExc = removeReactions(refModel,union(initModel.rxns,getExchangeRxns(refModel)),true,true); - - %At this stage the model is fully connected and most of the genes with - %good scores should have been included. The final gap-filling should - %take the scores of the genes into account, so that "rather bad" - %reactions are preferred to "very bad" reactions. However, reactions - %with positive scores will be included even if they are not connected - %in the current formulation. Therefore, such reactions will have to be - %assigned a small negative score instead. - if useScoresForTasks == true - refRxnScores = scoreComplexModel(refModelNoExc,hpaData,arrayData,tissue,celltype); - [outModel,addedRxnMat] = fitTasks(initModel,refModelNoExc,[],true,min(refRxnScores,-0.1),taskStructure,paramsFT); - else - [outModel,addedRxnMat] = fitTasks(initModel,refModelNoExc,[],true,[],taskStructure,paramsFT); - end - if printReport == true - printScores(outModel,'Functional model statistics',hpaData,arrayData,tissue,celltype); - printScores(removeReactions(outModel,intersect(outModel.rxns,initModel.rxns),true,true),'Reactions added to perform the tasks',hpaData,arrayData,tissue,celltype); - end - - addedRxnsForTasks = refModelNoExc.rxns(any(addedRxnMat,2)); -else - outModel = initModel; - addedRxnMat = []; - addedRxnsForTasks = {}; -end - -% The model can now perform all the tasks defined in the task list. -model = outModel; - -% If requested, attempt to remove negative-score genes from the model, -% depending on their role (isozyme or complex subunit) in each grRule. -% See the "removeLowScoreGenes" function more more details, and to adjust -% any default parameters therein. -if ( removeGenes ) - [~, geneScores] = scoreComplexModel(model,hpaData,arrayData,tissue,celltype); - model = removeLowScoreGenes(model,geneScores); -end - - -% At this stage the model will contain some exchange reactions but probably -% not all (and maybe zero). This can be inconvenient, so all exchange -% reactions from the reference model are added, except for those which -% involve metabolites that are not in the model. - -% First delete any included exchange reactions in order to prevent the order -% from changing -model = removeReactions(model,getExchangeRxns(model)); - -% Create a model with only the exchange reactions in refModel -excModel = removeReactions(refModel,setdiff(refModel.rxns,getExchangeRxns(refModel)),true,true); - -% Find the metabolites there which are not boundary metabolites and which do -% not exist in the output model -I = ~ismember(excModel.mets,model.mets) & excModel.unconstrained == 0; - -% Then find those reactions and delete them -[~, J] = find(excModel.S(I,:)); -excModel = removeReactions(excModel,J,true,true); - -% Merge with the output model -model = mergeModels({model;excModel},'metNames'); -model.id = 'INITModel'; -model.description = ['Automatically generated model for ' tissue]; -if any(celltype) - model.description = [model.description ' - ' celltype]; -end - -if printReport == true - printScores(model,'Final model statistics',hpaData,arrayData,tissue,celltype); -end - -% Add information about essential reactions and reactions included for -% gap-filling and return a taskReport -if ~isempty(taskStructure) - I = find(taskReport.ok); %Ignore failed tasks - for i = 1:numel(I) - taskReport.essential{I(i),1} = cModel.rxns(essentialRxnMat(:,I(i))); - taskReport.gapfill{I(i),1} = refModelNoExc.rxns(addedRxnMat(:,i)); - end -else - taskReport = []; -end - -%Fix grRules and reconstruct rxnGeneMat -[grRules,rxnGeneMat] = standardizeGrRules(model,true); -model.grRules = grRules; -model.rxnGeneMat = rxnGeneMat; -end - -%This is for printing a summary of a model -function [rxnS, geneS] = printScores(model,name,hpaData,arrayData,tissue,celltype) -[a, b] = scoreComplexModel(model,hpaData,arrayData,tissue,celltype); -rxnS = mean(a); -geneS = mean(b,'omitnan'); -fprintf([name ':\n']); -fprintf(['\t' num2str(numel(model.rxns)) ' reactions, ' num2str(numel(model.genes)) ' genes\n']); -fprintf(['\tMean reaction score: ' num2str(rxnS) '\n']); -fprintf(['\tMean gene score: ' num2str(geneS) '\n']); -fprintf(['\tReactions with positive scores: ' num2str(100*sum(a>0)/numel(a)) '%%\n\n']); -end diff --git a/code/tINIT/restoreModelGrRules.m b/code/tINIT/restoreModelGrRules.m deleted file mode 100644 index 66c5edc8..00000000 --- a/code/tINIT/restoreModelGrRules.m +++ /dev/null @@ -1,41 +0,0 @@ -function restoredModel = restoreModelGrRules(model,refModel) -%restoreModelGrRules Recover grRules (and genes) from reference model. -% -% The current implementation of tINIT removes genes from grRules, and will -% eliminate enzyme complex information from grRules (i.e., all rules will -% become "OR" expressions). -% -% This function will replace the input MODEL grRules with the corresponding -% original grRule from the reference model (refModel). In addition, the -% function will regenerate the "genes" and "rxnGeneMat" fields based on the -% restored grRules. -% -% USAGE: -% -% restoredModel = restoreModelGrRules(model,refModel); -% -% INPUTS: -% -% model Model structure with grRules needing restoration. -% -% refModel Reference model from which the input MODEL was derived. -% -% OUTPUTS: -% -% restoredModel Input MODEL returned with grRules retrieved from -% refModel, as well as updated genes and geneRxnMat -% fields. -% - - -% restore model grRules with those in refModel -[~,ind] = ismember(model.rxns,refModel.rxns); -model.grRules = refModel.grRules(ind); - -% regenerate "genes" and "rxnGeneMat" fields -[genes,rxnGeneMat] = getGenesFromGrRules(model.grRules); -model.genes = genes; -model.rxnGeneMat = rxnGeneMat; - -% assign output -restoredModel = model; diff --git a/code/test/estimateEssentialGenes.m b/code/test/estimateEssentialGenes.m deleted file mode 100644 index 78db25e9..00000000 --- a/code/test/estimateEssentialGenes.m +++ /dev/null @@ -1,107 +0,0 @@ -function [eGenes, INIT_output] = estimateEssentialGenes(model, dataFile, taskStruct, useGeneSymbol) -% generate tINIT models and estimate essential genes -% -% Input: -% -% model reference human or animal model -% -% dataFile (opt, default Hart2015_RNAseq.txt) -% -% taskStruct metabolic task structure (opt, default is Essential tasks) -% -% useGeneSymbol use gene symbols as ids and in grRules (opt, default TRUE) -% -% Output: -% -% eGenes results structure with the following fields: -% taskList list of metabolic tasks that were tested -% tissues list of tissues (model IDs) corresponding to each model -% geneList cell array of the list of genes from each model -% essentialGenes cell array with one entry per model, where each -% entry is a logical matrix with rows corresponding -% to genes (in geneList) and columns to tasks (in -% taskList). Entries in the matrix are true when a -% gene is essential for a task, and false otherwise. -% -% INIT_output structure containing tINIT models (or information -% necessary to regenerate tINIT models) for which gene -% essentiality will be evaluated. -% -% Note: This function may take long computation time. -% - - -if nargin < 2 - % load Hart et al. RNA-Seq cell line data - dataFile = 'Hart2015_RNAseq.txt'; -end - -if nargin < 3 - taskStruct = parseTaskList('metabolicTasks_Essential.txt'); -end - -if nargin < 4 - useGeneSymbol = true; -end - -% replace gene IDs with gene symbols -if useGeneSymbol - idMapping = [model.genes, model.geneShortNames]; - [grRules,genes,rxnGeneMat] = replaceGrRules(model.grRules,idMapping); - model.grRules = grRules; - model.genes = genes; - model.rxnGeneMat = rxnGeneMat; -end - -% pre-process RNA-Seq data -disp('Step 1: preprocess and preliminary step') -tmp = readtable(dataFile); -arrayData.genes = tmp.gene; -arrayData.tissues = tmp.Properties.VariableNames(2:end)'; -arrayData.levels = table2array(tmp(:,2:end)); - - -% Run some preliminary steps -[~,deletedDeadEndRxns] = simplifyModel(model,true,false,true,true,true); -cModel = removeReactions(model,deletedDeadEndRxns,false,true); -[taskReport, essentialRxnMat] = checkTasks(cModel,[],true,false,true,taskStruct); - - -% add pre-processing results to arrayData structure -arrayData.deletedDeadEndRxns = deletedDeadEndRxns; -arrayData.taskReport = taskReport; -arrayData.essentialRxnMat = essentialRxnMat; -arrayData.threshold = 1; - - -% run tINIT -disp('Step 2: get tissue models') -model = closeModel(model); -params = {}; -INIT_output = {}; - -for i = 1:length(arrayData.tissues) - disp(['Tissue ', num2str(i), ' out of ', num2str(length(arrayData.tissues)),': ', arrayData.tissues{i}]) - - % First try to run tINIT with shorter time limit. If it fails, then - % try again with a longer time limit. - try - params.TimeLimit = 1000; - init_model = getINITModel2(model,arrayData.tissues{i},[],[],arrayData,[],true,[],true,true,taskStruct,params); - catch - params.TimeLimit = 5000; - init_model = getINITModel2(model,arrayData.tissues{i},[],[],arrayData,[],true,[],true,true,taskStruct,params); - end - - init_model.id = arrayData.tissues{i}; - INIT_output.id{i,1} = init_model.id; - INIT_output.model{i,1} = init_model; - -end - -disp('Step 3: get essential genes') -% get essential genes for each model and task -eGenes = getTaskEssentialGenes(INIT_output, model, taskStruct); -eGenes.refModel = model; - -end diff --git a/code/test/evaluateHart2015Essentiality.m b/code/test/evaluateHart2015Essentiality.m deleted file mode 100644 index 8fd1cb02..00000000 --- a/code/test/evaluateHart2015Essentiality.m +++ /dev/null @@ -1,156 +0,0 @@ -function results = evaluateHart2015Essentiality(eGenes) -% Evaluate and compare experimental fitness genes with essentiality results -% predicted from 5 cell-line specific GEMs from Hart 2015 datasets -% -% Input: -% -% eGenes results structure with the following fields: -% taskList list of metabolic tasks that were tested -% tissues list of tissues (model IDs) corresponding to each model -% geneList cell array of the list of genes from each model -% essentialGenes cell array with one entry per model, where each -% entry is a logical matrix with rows corresponding -% to genes (in geneList) and columns to tasks (in -% taskList). Entries in the matrix are true when a -% gene is essential for a task, and false otherwise. -% -% Output: -% -% -% results evaluation with values of TP, TN, FP, FN, accuracy, -% sensitivity, specificity, F1, MCC -% -% Example usage: -% -% results = evaluateEssentialityHart2015(eGenes) -% - - -%% load Hart2015 essentiality data - -% Table S2 from the Hart2015 datasets: -% In this study, essential genes are, by definition, a subset of fitness genes -x = readtable('Hart2015_TableS2.xlsx'); - -% remove duplicated rows (MARCH1 and MARCH2 genes) -ind1 = find(ismember(x.Gene,'MARCH1'),1,'last'); -ind2 = find(ismember(x.Gene,'MARCH2'),1,'last'); -x([ind1;ind2],:) = []; - -% extract gene list and cell types -genes = x.Gene; -celltypes = regexprep(upper(x.Properties.VariableNames(3:7)'),'BF_',''); - -% for each cell type, determine the "fitness" genes, defined as those with -% a 5% FDRs were chosen as thresholds (the values are extracted from the -% supporting information of the Hart 2015 paper. Genes observed in 3 or more -% of the 5 TKO screens (n=1,580) were considered as core fitness genes -bf_data = table2array(x(:,3:7)); -bf_thresh = {'HCT116', 1.57 - 'HELA', 15.47 - 'GBM', 3.20 - 'RPE1', 6.84 - 'DLD1', 3.57}; - -% construct fitness matrix according to threshold values -fitness_mat = zeros(numel(genes),numel(celltypes)); -for i = 1:numel(celltypes) - [~,ind] = ismember(celltypes{i},bf_thresh(:,1)); - fitness_mat(:,i) = bf_data(:,i) > bf_thresh{ind,2}; -end -fitness_mat(isnan(bf_data)) = NaN; % mark missing values differently than non-hits - -% also get the genes that were essential in all 5 cell lines ("all") -celltypes(end+1) = {'all'}; -fitness_mat(:,end+1) = all(fitness_mat == 1,2); - -% put Hart2015 essentiality data into data structure for comparison -expdata = {}; -expdata.genes = genes; -expdata.tissues = celltypes; -expdata.essential = fitness_mat; - - -%% Load and organize model-predicted gene essentiality results - -% re-organize essentialGenes logical matrices into a uniform 3D matrix, -% where rows represent genes, columns are tasks, and the 3rd dimension is -% different cell lines. -eGenes.essentialMat = false(numel(eGenes.refModel.genes), numel(eGenes.taskList), numel(eGenes.tissues)); -for i = 1:numel(eGenes.tissues) - [hasMatch,ind] = ismember(eGenes.refModel.genes,eGenes.geneList{i}); - eGenes.essentialMat(hasMatch,:,i) = eGenes.essentialGenes{i}(ind(hasMatch),:); -end - - -%% compare model predictions to experimental essentiality data - -% specify model-determined essential genes -modelPred = squeeze(any(eGenes.essentialMat,2)); % essential for any task - -tissues = eGenes.tissues; -tissues(end+1) = {'all'}; % also include "all" category for Hart2015 dataset - -% calculate true and false positives and negatives -[TP,TN,FP,FN,Penr] = deal(nan(numel(tissues),1)); % initialize variables -for i = 1:numel(tissues) - - [~,tissue_ind] = ismember(tissues(i), expdata.tissues); - if tissue_ind == 0 - continue % a few tissues are missing from the DepMap dataset - end - - modelGenes = eGenes.refModel.genes; - if strcmpi(tissues{i},'all') - modelEssential = modelGenes(sum(modelPred,2) == size(modelPred,2)); - else - modelEssential = modelGenes(modelPred(:,i)); - end - modelNonEssential = setdiff(modelGenes,modelEssential); - - expGenes = expdata.genes(~isnan(expdata.essential(:,tissue_ind))); - expEssential = expdata.genes(expdata.essential(:,tissue_ind) == 1); - expNonEssential = setdiff(expGenes,expEssential); - - TP(i) = sum(ismember(modelEssential, expEssential)); % true positives - TN(i) = sum(ismember(modelNonEssential, expNonEssential)); % true negatives - FP(i) = sum(ismember(modelEssential, expNonEssential)); % false positives - FN(i) = sum(ismember(modelNonEssential, expEssential)); % false negatives - - % Requires Statistics and Machine Learning Toolbox - %Penr(i) = EnrichmentTest(intersect(modelGenes,expGenes), intersect(modelEssential,expGenes), intersect(expEssential,modelGenes)); -end - -% calculate some metrics -sensitivity = TP./(TP + FN); -specificity = TN./(TN + FP); -accuracy = (TP + TN)./(TP + TN + FP + FN); -F1 = 2*TP./(2*TP + FP + FN); -MCC = ((TP.*TN) - (FP.*FN))./sqrt((TP+FP).*(TP+FN).*(TN+FP).*(TN+FN)); % Matthews correlation coefficient -%PenrAdj = adjust_pvalues(Penr,'Benjamini'); - -% get results for cell types -results = [{'cellLine','TP','TN','FP','FN','accuracy','sensitivity','specificity','F1','MCC'}; - [tissues, num2cell([TP, TN, FP, FN, accuracy, sensitivity, specificity, F1, MCC])]]; - -% Including Penr results -%results = [{'cellLine','TP','TN','FP','FN','accuracy','sensitivity','specificity','F1','MCC','Penr','logPenr','PenrAdj','logPenrAdj'}; -% [tissues, num2cell([TP, TN, FP, FN, accuracy, sensitivity, specificity, F1, MCC, Penr, -log10(Penr), PenrAdj, -log10(PenrAdj)])]]; -end - -function [penr,pdep] = EnrichmentTest(pop,sample,successes) -% Caculates p-value of enrichment of successes in a sample. -% -% Evaluates the significance of enrichment (and depletion) of SUCCESSES in -% a SAMPLE drawn from population POP using the hypergeometric test. - -x = numel(intersect(successes,sample)); % calc # of successes in sample -m = numel(pop); % calc size of population -k = numel(intersect(successes,pop)); -n = numel(sample); - -penr = hygecdf(x-1,m,k,n,'upper'); -pdep = hygecdf(x,m,k,n); - -end - From 3c1a85e7a24db086cbb2fc39397470e1b55a4073 Mon Sep 17 00:00:00 2001 From: edkerk <7326655+edkerk@users.noreply.github.com> Date: Fri, 17 Jul 2026 21:21:47 +0000 Subject: [PATCH 2/2] chore: update model QC results [skip ci] --- data/testResults/README.md | 10 ++-- data/testResults/model_qc_summary.md | 72 ++++++++++++++-------------- 2 files changed, 41 insertions(+), 41 deletions(-) diff --git a/data/testResults/README.md b/data/testResults/README.md index 6ed6d67d..182c2f3d 100644 --- a/data/testResults/README.md +++ b/data/testResults/README.md @@ -21,11 +21,11 @@ own files. The pull request in each row is the one whose run last wrote those fi | Result file(s) | Produced by | Last updated by | | --- | --- | --- | -| `qc_duplicate_keys.csv`, `qc_empty_reactions.csv`, `qc_annotation_consistency.csv`, `qc_deprecation_completeness.csv`, `qc_metabolite_completeness.csv`, `qc_reaction_sanity.csv`, `qc_duplicate_reactions.csv`, `qc_unused_entities.csv`, `qc_growth_blockers.csv` | `qcModelChecks.py` | **PR #1061** (model QC checks) | -| `qc_annotation_issues.csv` | `annotationTest.py` | **PR #1061** (model QC checks) | -| `qc_status.tsv` (round-trip, YAML lint, metabolic tasks, growth) | `testYamlConversion.py`, `testMetabolicTasks.py`, `action-yamllint`, `qcModelChecks.py` (via `qcStatus.py`) | **PR #1061** (model QC checks) | -| `macaw_results.csv`, `balance_results.csv`, `qc_structure_consistency.csv` | `macawTests.py`, `balanceTest.py`, `structureConsistencyTest.py` | **PR #1061** (MACAW and balance) | -| `memote_score.md` | `memoteSnapshot.py` (fast subset every PR; full suite via `/run memote`) | **PR #1061** (MEMOTE) | +| `qc_duplicate_keys.csv`, `qc_empty_reactions.csv`, `qc_annotation_consistency.csv`, `qc_deprecation_completeness.csv`, `qc_metabolite_completeness.csv`, `qc_reaction_sanity.csv`, `qc_duplicate_reactions.csv`, `qc_unused_entities.csv`, `qc_growth_blockers.csv` | `qcModelChecks.py` | **PR #1068** (model QC checks) | +| `qc_annotation_issues.csv` | `annotationTest.py` | **PR #1068** (model QC checks) | +| `qc_status.tsv` (round-trip, YAML lint, metabolic tasks, growth) | `testYamlConversion.py`, `testMetabolicTasks.py`, `action-yamllint`, `qcModelChecks.py` (via `qcStatus.py`) | **PR #1068** (model QC checks) | +| `macaw_results.csv`, `balance_results.csv`, `qc_structure_consistency.csv` | `macawTests.py`, `balanceTest.py`, `structureConsistencyTest.py` | **PR #1068** (MACAW and balance) | +| `memote_score.md` | `memoteSnapshot.py` (fast subset every PR; full suite via `/run memote`) | **PR #1068** (MEMOTE) | | `gene-essential.csv`, `gene-essential_summary.md` | `geneEssentiality.py` via `/run gene-essentiality` | **PR #1027** (gene essentiality) | ## 2. What each check means diff --git a/data/testResults/model_qc_summary.md b/data/testResults/model_qc_summary.md index fdac8f39..0b48ec4a 100644 --- a/data/testResults/model_qc_summary.md +++ b/data/testResults/model_qc_summary.md @@ -1,59 +1,59 @@ ## Model quality report -:warning: **6 pre-existing finding(s), no regressions vs `main`.** Non-blocking. +:warning: **6 pre-existing finding(s), no regressions vs `develop`.** Non-blocking. -_Each check name links to its explanation in the [testResults README](https://github.com/SysBioChalmers/Human-GEM/blob/develop/data/testResults/README.md)._ +_Each check name links to its explanation in the [testResults README](https://github.com/SysBioChalmers/Human-GEM/blob/chore/remove-legacy-getinitmodel2/data/testResults/README.md)._ ### Model checks _Duplicate keys (model unloadable) and no growth block the merge; every other row is a non-blocking report._ -| Check | Result | Δ vs `main` | | +| Check | Result | Δ vs `develop` | | | --- | ---: | ---: | :---: | -| [Duplicate `!!omap` keys](https://github.com/SysBioChalmers/Human-GEM/blob/develop/data/testResults/README.md#duplicate-omap-keys) | 0 | new | :white_check_mark: | -| [Growth (biomass producible)](https://github.com/SysBioChalmers/Human-GEM/blob/develop/data/testResults/README.md#growth-biomass-producible) | 125 | new | :white_check_mark: | -| [Reactions with no metabolites](https://github.com/SysBioChalmers/Human-GEM/blob/develop/data/testResults/README.md#reactions-with-no-metabolites) | 0 | new | :white_check_mark: | -| [Model / annotation-table inconsistencies](https://github.com/SysBioChalmers/Human-GEM/blob/develop/data/testResults/README.md#model--annotation-table-inconsistencies) | 0 | new | :white_check_mark: | -| [Removed reactions or metabolites not deprecated](https://github.com/SysBioChalmers/Human-GEM/blob/develop/data/testResults/README.md#removed-reactions-or-metabolites-not-deprecated) | 0 | new | :white_check_mark: | -| [Metabolites missing formula](https://github.com/SysBioChalmers/Human-GEM/blob/develop/data/testResults/README.md#metabolites-missing-formula) | 0 | new | :white_check_mark: | -| [Metabolites missing charge](https://github.com/SysBioChalmers/Human-GEM/blob/develop/data/testResults/README.md#metabolites-missing-charge) | 0 | new | :white_check_mark: | -| [Reaction bound / GPR issues](https://github.com/SysBioChalmers/Human-GEM/blob/develop/data/testResults/README.md#reaction-bound--gpr-issues) | 0 | new | :white_check_mark: | -| [Exact-duplicate reaction groups](https://github.com/SysBioChalmers/Human-GEM/blob/develop/data/testResults/README.md#exact-duplicate-reaction-groups) | 0 | new | :white_check_mark: | -| [Unused metabolites](https://github.com/SysBioChalmers/Human-GEM/blob/develop/data/testResults/README.md#unused-metabolites) | 0 | new | :white_check_mark: | -| [Unused genes](https://github.com/SysBioChalmers/Human-GEM/blob/develop/data/testResults/README.md#unused-genes) | 0 | new | :white_check_mark: | -| [Malformed cross-references](https://github.com/SysBioChalmers/Human-GEM/blob/develop/data/testResults/README.md#malformed-cross-references) | 0 | new | :white_check_mark: | -| [Cross-refs inconsistent across compartments](https://github.com/SysBioChalmers/Human-GEM/blob/develop/data/testResults/README.md#cross-refs-inconsistent-across-compartments) | [3](https://github.com/SysBioChalmers/Human-GEM/blob/develop/data/testResults/qc_annotation_issues.csv) | new | :warning: | +| [Duplicate `!!omap` keys](https://github.com/SysBioChalmers/Human-GEM/blob/chore/remove-legacy-getinitmodel2/data/testResults/README.md#duplicate-omap-keys) | 0 | 0 | :white_check_mark: | +| [Growth (biomass producible)](https://github.com/SysBioChalmers/Human-GEM/blob/chore/remove-legacy-getinitmodel2/data/testResults/README.md#growth-biomass-producible) | 125 | 0 | :white_check_mark: | +| [Reactions with no metabolites](https://github.com/SysBioChalmers/Human-GEM/blob/chore/remove-legacy-getinitmodel2/data/testResults/README.md#reactions-with-no-metabolites) | 0 | 0 | :white_check_mark: | +| [Model / annotation-table inconsistencies](https://github.com/SysBioChalmers/Human-GEM/blob/chore/remove-legacy-getinitmodel2/data/testResults/README.md#model--annotation-table-inconsistencies) | 0 | 0 | :white_check_mark: | +| [Removed reactions or metabolites not deprecated](https://github.com/SysBioChalmers/Human-GEM/blob/chore/remove-legacy-getinitmodel2/data/testResults/README.md#removed-reactions-or-metabolites-not-deprecated) | 0 | 0 | :white_check_mark: | +| [Metabolites missing formula](https://github.com/SysBioChalmers/Human-GEM/blob/chore/remove-legacy-getinitmodel2/data/testResults/README.md#metabolites-missing-formula) | 0 | 0 | :white_check_mark: | +| [Metabolites missing charge](https://github.com/SysBioChalmers/Human-GEM/blob/chore/remove-legacy-getinitmodel2/data/testResults/README.md#metabolites-missing-charge) | 0 | 0 | :white_check_mark: | +| [Reaction bound / GPR issues](https://github.com/SysBioChalmers/Human-GEM/blob/chore/remove-legacy-getinitmodel2/data/testResults/README.md#reaction-bound--gpr-issues) | 0 | 0 | :white_check_mark: | +| [Exact-duplicate reaction groups](https://github.com/SysBioChalmers/Human-GEM/blob/chore/remove-legacy-getinitmodel2/data/testResults/README.md#exact-duplicate-reaction-groups) | 0 | 0 | :white_check_mark: | +| [Unused metabolites](https://github.com/SysBioChalmers/Human-GEM/blob/chore/remove-legacy-getinitmodel2/data/testResults/README.md#unused-metabolites) | 0 | 0 | :white_check_mark: | +| [Unused genes](https://github.com/SysBioChalmers/Human-GEM/blob/chore/remove-legacy-getinitmodel2/data/testResults/README.md#unused-genes) | 0 | 0 | :white_check_mark: | +| [Malformed cross-references](https://github.com/SysBioChalmers/Human-GEM/blob/chore/remove-legacy-getinitmodel2/data/testResults/README.md#malformed-cross-references) | 0 | 0 | :white_check_mark: | +| [Cross-refs inconsistent across compartments](https://github.com/SysBioChalmers/Human-GEM/blob/chore/remove-legacy-getinitmodel2/data/testResults/README.md#cross-refs-inconsistent-across-compartments) | [3](https://github.com/SysBioChalmers/Human-GEM/blob/chore/remove-legacy-getinitmodel2/data/testResults/qc_annotation_issues.csv) | 0 | :warning: | ### MACAW and mass/charge balance -| Check | Result | Δ vs `main` | | +| Check | Result | Δ vs `develop` | | | --- | ---: | ---: | :---: | -| [Reactions flagged by MACAW dead-end test](https://github.com/SysBioChalmers/Human-GEM/blob/develop/data/testResults/README.md#reactions-flagged-by-macaw-dead-end-test) | [2510](https://github.com/SysBioChalmers/Human-GEM/blob/develop/data/testResults/macaw_results.csv) | -703 | :warning: | -| [Reactions flagged as MACAW duplicates](https://github.com/SysBioChalmers/Human-GEM/blob/develop/data/testResults/README.md#reactions-flagged-as-macaw-duplicates) | [377](https://github.com/SysBioChalmers/Human-GEM/blob/develop/data/testResults/macaw_results.csv) | -2 | :warning: | -| [Mass-imbalanced reactions](https://github.com/SysBioChalmers/Human-GEM/blob/develop/data/testResults/README.md#mass-imbalanced-reactions) | [87](https://github.com/SysBioChalmers/Human-GEM/blob/develop/data/testResults/balance_results.csv) | new | :warning: | -| [Charge-imbalanced reactions](https://github.com/SysBioChalmers/Human-GEM/blob/develop/data/testResults/README.md#charge-imbalanced-reactions) | [234](https://github.com/SysBioChalmers/Human-GEM/blob/develop/data/testResults/balance_results.csv) | new | :warning: | -| [Structure vs formula/charge inconsistencies](https://github.com/SysBioChalmers/Human-GEM/blob/develop/data/testResults/README.md#structure-vs-formulacharge-inconsistencies) | [397](https://github.com/SysBioChalmers/Human-GEM/blob/develop/data/testResults/qc_structure_consistency.csv) | new | :warning: | +| [Reactions flagged by MACAW dead-end test](https://github.com/SysBioChalmers/Human-GEM/blob/chore/remove-legacy-getinitmodel2/data/testResults/README.md#reactions-flagged-by-macaw-dead-end-test) | [2510](https://github.com/SysBioChalmers/Human-GEM/blob/chore/remove-legacy-getinitmodel2/data/testResults/macaw_results.csv) | 0 | :warning: | +| [Reactions flagged as MACAW duplicates](https://github.com/SysBioChalmers/Human-GEM/blob/chore/remove-legacy-getinitmodel2/data/testResults/README.md#reactions-flagged-as-macaw-duplicates) | [377](https://github.com/SysBioChalmers/Human-GEM/blob/chore/remove-legacy-getinitmodel2/data/testResults/macaw_results.csv) | 0 | :warning: | +| [Mass-imbalanced reactions](https://github.com/SysBioChalmers/Human-GEM/blob/chore/remove-legacy-getinitmodel2/data/testResults/README.md#mass-imbalanced-reactions) | [87](https://github.com/SysBioChalmers/Human-GEM/blob/chore/remove-legacy-getinitmodel2/data/testResults/balance_results.csv) | 0 | :warning: | +| [Charge-imbalanced reactions](https://github.com/SysBioChalmers/Human-GEM/blob/chore/remove-legacy-getinitmodel2/data/testResults/README.md#charge-imbalanced-reactions) | [234](https://github.com/SysBioChalmers/Human-GEM/blob/chore/remove-legacy-getinitmodel2/data/testResults/balance_results.csv) | 0 | :warning: | +| [Structure vs formula/charge inconsistencies](https://github.com/SysBioChalmers/Human-GEM/blob/chore/remove-legacy-getinitmodel2/data/testResults/README.md#structure-vs-formulacharge-inconsistencies) | [397](https://github.com/SysBioChalmers/Human-GEM/blob/chore/remove-legacy-getinitmodel2/data/testResults/qc_structure_consistency.csv) | 0 | :warning: | ### Model file and metabolic tasks | Check | Result | | | --- | ---: | :---: | -| [YAML round-trip (cobrapy)](https://github.com/SysBioChalmers/Human-GEM/blob/develop/data/testResults/README.md#yaml-round-trip-cobrapy) | pass | :white_check_mark: | -| [YAML round-trip (RAVEN)](https://github.com/SysBioChalmers/Human-GEM/blob/develop/data/testResults/README.md#yaml-round-trip-raven) | pass | :white_check_mark: | -| [YAML lint](https://github.com/SysBioChalmers/Human-GEM/blob/develop/data/testResults/README.md#yaml-lint) | pass | :white_check_mark: | -| [Essential metabolic tasks](https://github.com/SysBioChalmers/Human-GEM/blob/develop/data/testResults/README.md#essential-metabolic-tasks) | 57 passed | :white_check_mark: | -| [Verification metabolic tasks](https://github.com/SysBioChalmers/Human-GEM/blob/develop/data/testResults/README.md#verification-metabolic-tasks) | 21 passed | :white_check_mark: | +| [YAML round-trip (cobrapy)](https://github.com/SysBioChalmers/Human-GEM/blob/chore/remove-legacy-getinitmodel2/data/testResults/README.md#yaml-round-trip-cobrapy) | pass | :white_check_mark: | +| [YAML round-trip (RAVEN)](https://github.com/SysBioChalmers/Human-GEM/blob/chore/remove-legacy-getinitmodel2/data/testResults/README.md#yaml-round-trip-raven) | pass | :white_check_mark: | +| [YAML lint](https://github.com/SysBioChalmers/Human-GEM/blob/chore/remove-legacy-getinitmodel2/data/testResults/README.md#yaml-lint) | pass | :white_check_mark: | +| [Essential metabolic tasks](https://github.com/SysBioChalmers/Human-GEM/blob/chore/remove-legacy-getinitmodel2/data/testResults/README.md#essential-metabolic-tasks) | 57 passed | :white_check_mark: | +| [Verification metabolic tasks](https://github.com/SysBioChalmers/Human-GEM/blob/chore/remove-legacy-getinitmodel2/data/testResults/README.md#verification-metabolic-tasks) | 21 passed | :white_check_mark: | -### [MEMOTE](https://github.com/SysBioChalmers/Human-GEM/blob/develop/data/testResults/README.md#memote) +### [MEMOTE](https://github.com/SysBioChalmers/Human-GEM/blob/chore/remove-legacy-getinitmodel2/data/testResults/README.md#memote) -**Total score: 63.2%** (core subset)   +**Total score: 63.2%** (core subset)   0 | Section | Score | Δ vs base | | --- | ---: | ---: | -| consistency | 42.4% | | -| annotation_met | 73.0% | | -| annotation_rxn | 72.7% | | -| annotation_gene | 46.7% | | -| annotation_sbo | 81.7% | | +| consistency | 42.4% | 0 | +| annotation_met | 73.0% | 0 | +| annotation_rxn | 72.7% | 0 | +| annotation_gene | 46.7% | 0 | +| annotation_sbo | 81.7% | 0 |
Per-test scores @@ -89,11 +89,11 @@ _Duplicate keys (model unloadable) and no growth block the merge; every other ro
-**Full suite: 64.2%**   · _from the last_ `/run memote`. +**Full suite: 64.2%**   0 · _from the last_ `/run memote`. _The score above is the fast core subset. Comment_ `/run memote` _to run the full suite on this pull request; the score updates here when it finishes._ -### [Gene essentiality (Hart 2015)](https://github.com/SysBioChalmers/Human-GEM/blob/develop/data/testResults/README.md#gene-essentiality-hart-2015) +### [Gene essentiality (Hart 2015)](https://github.com/SysBioChalmers/Human-GEM/blob/chore/remove-legacy-getinitmodel2/data/testResults/README.md#gene-essentiality-hart-2015) _Not run automatically (it takes hours). Comment_ `/run gene-essentiality` _to run it on this pull request; the result posts as its own comment._