From 40ea7101a133af99bfd842efd5d5461f9c4b4643 Mon Sep 17 00:00:00 2001 From: dvklopfenstein Date: Fri, 13 Mar 2020 13:33:55 -0400 Subject: [PATCH] Add quiet mode to run_goea https://github.com/tanghaibao/goatools/issues/133#issuecomment-598334391 --- goatools/go_enrichment.py | 15 ++++++-- goatools/goea/go_enrichment_ns.py | 4 +- tests/test_goea_quiet.py | 63 +++++++++++++++++++++++++++++++ 3 files changed, 77 insertions(+), 5 deletions(-) create mode 100755 tests/test_goea_quiet.py diff --git a/goatools/go_enrichment.py b/goatools/go_enrichment.py index e8f3de13..994d2923 100755 --- a/goatools/go_enrichment.py +++ b/goatools/go_enrichment.py @@ -292,14 +292,15 @@ def _remove_assc_goids(self, assoc, broad_goids): def run_study(self, study, **kws): """Run Gene Ontology Enrichment Study (GOEA) on study ids.""" study_name = kws.get('name', 'current') - print('\nRun {OBJNAME} Gene Ontology Analysis: {STU} study set of {N} IDs ...'.format( - OBJNAME=self.name, N=len(study), STU=study_name)) + log = self._get_log_or_prt(kws) + if log: + log.write('\nRun {OBJNAME} Gene Ontology Analysis: {STU} study set of {N} IDs ...'.format( + OBJNAME=self.name, N=len(study), STU=study_name)) if not study: return [] # Key-word arguments: methods = Methods(kws['methods']) if 'methods' in kws else self.methods alpha = kws['alpha'] if 'alpha' in kws else self.alpha - log = kws['log'] if 'log' in kws else self.log # Calculate uncorrected pvalues results = self.get_pval_uncorr(study, log) if not results: @@ -326,6 +327,14 @@ def run_study(self, study, **kws): results.sort(key=lambda r: [r.enrichment, r.NS, r.p_uncorrected]) return results # list of GOEnrichmentRecord objects + def _get_log_or_prt(self, kws): + """Allow either keyword, 'log', or 'prt' to be used to suppress or redirect printing""" + if 'log' in kws: + return kws['log'] + if 'prt' in kws: + return kws['prt'] + return self.log + def run_study_nts(self, study, **kws): """Run GOEA on study ids. Return results as a list of namedtuples.""" goea_results = self.run_study(study, **kws) diff --git a/goatools/goea/go_enrichment_ns.py b/goatools/goea/go_enrichment_ns.py index fbc941ea..d83b35b1 100755 --- a/goatools/goea/go_enrichment_ns.py +++ b/goatools/goea/go_enrichment_ns.py @@ -15,9 +15,9 @@ class GOEnrichmentStudyNS: def __init__(self, pop, ns2assoc, godag, propagate_counts=True, alpha=.05, methods=None, **kws): self.ns2objgoea = self._ns2o(pop, ns2assoc, godag, propagate_counts, alpha, methods, **kws) - def run_study(self, study_ids): + def run_study(self, study_ids, **kws): """Run GOEAs for each namespace, BP MF CC""" - ns2results = {ns:o.run_study(study_ids) for ns, o in sorted(self.ns2objgoea.items())} + ns2results = {ns:o.run_study(study_ids, **kws) for ns, o in sorted(self.ns2objgoea.items())} return list(itertools.chain.from_iterable(ns2results.values())) def wr_xlsx(self, fout_xlsx, goea_results, **kws): diff --git a/tests/test_goea_quiet.py b/tests/test_goea_quiet.py new file mode 100755 index 00000000..bef96a6b --- /dev/null +++ b/tests/test_goea_quiet.py @@ -0,0 +1,63 @@ +"""Test that a Gene Ontology Enrichement Analysis can be run quietly""" + +import os +from goatools.goea.go_enrichment_ns import GOEnrichmentStudyNS +from goatools.anno.idtogos_reader import IdToGosReader +from goatools.base import get_godag + +__copyright__ = "Copyright (C) 2010-present, H Tang et al., All rights reserved." + +REPO = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..") + + +def test_goea_quiet(): + """Test that a Gene Ontology Enrichement Analysis can be run quietly""" + goeaobj = _get_goeaobj() + study_fin = "{REPO}/tests/data/small_study".format(REPO=REPO) + study_ids = [line.rstrip() for line in open(study_fin)] + print('\nTEST 1: GOEA run_study(study_ids)') + goea_results1 = goeaobj.run_study(study_ids) + print('{N} GOEA results for verbose GOEA'.format(N=len(goea_results1))) + + print('\nTEST 2: GOEA run_study(study_ids, prt=None)') + goea_results2 = goeaobj.run_study(study_ids, prt=None) + print('{N} GOEA results for quiet GOEA'.format(N=len(goea_results2))) + + # Original keyword is 'log' + print('\nTEST 3: GOEA run_study(study_ids, log=None)') + goea_results3 = goeaobj.run_study(study_ids, log=None) + print('{N} GOEA results for quiet GOEA'.format(N=len(goea_results3))) + + + _chk_results(goea_results1, goea_results2) + _chk_results(goea_results1, goea_results3) + + +def _get_goeaobj(methods=None): + """Test GOEA with method, fdr.""" + # REad GODag + obo_fin = os.path.join(REPO, "go-basic.obo") + obo_dag = get_godag(obo_fin, loading_bar=None) + # Read association + fin_assc = "{REPO}/tests/data/small_association".format(REPO=REPO) + objanno = IdToGosReader(fin_assc, godag=obo_dag) + ns2assc = objanno.get_ns2assc() + popul_fin = "{REPO}/tests/data/small_population".format(REPO=REPO) + popul_ids = [line.rstrip() for line in open(popul_fin)] + goeaobj = GOEnrichmentStudyNS(popul_ids, ns2assc, obo_dag, methods=methods) + return goeaobj + +def _chk_results(results1, results2): + """Check that results match""" + # pylint: disable=line-too-long + for res1, res2 in zip(results1, results2): + assert res1.GO == res2.GO, '\nRES1: {R1}\nRES2: {R2}\n\n'.format(R1=res1, R2=res2) + assert res1.p_bonferroni == res2.p_bonferroni, '\nRES1: {R1}\nRES2: {R2}\n\n'.format(R1=res1, R2=res2) + assert res1.p_sidak == res2.p_sidak, '\nRES1: {R1}\nRES2: {R2}\n\n'.format(R1=res1, R2=res2) + assert res1.p_holm == res2.p_holm, '\nRES1: {R1}\nRES2: {R2}\n\n'.format(R1=res1, R2=res2) + + +if __name__ == '__main__': + test_goea_quiet() + +# Copyright (C) 2010-present, H Tang et al., All rights reserved.