[med-svn] [Git][med-team/q2-diversity-lib][master] 6 commits: New upstream version 2022.2.1
Andreas Tille (@tille)
gitlab at salsa.debian.org
Tue Jul 19 16:42:44 BST 2022
Andreas Tille pushed to branch master at Debian Med / q2-diversity-lib
Commits:
47fa3781 by Andreas Tille at 2022-07-19T17:36:43+02:00
New upstream version 2022.2.1
- - - - -
84e5ab17 by Andreas Tille at 2022-07-19T17:36:43+02:00
routine-update: New upstream version
- - - - -
8c5b862f by Andreas Tille at 2022-07-19T17:36:44+02:00
Update upstream source from tag 'upstream/2022.2.1'
Update to upstream version '2022.2.1'
with Debian dir 5a317d6de2b3f19566bd9cc66e1d6d7605baa61e
- - - - -
f3d61637 by Andreas Tille at 2022-07-19T17:36:44+02:00
routine-update: Standards-Version: 4.6.1
- - - - -
c8b3f3ce by Andreas Tille at 2022-07-19T17:39:05+02:00
Adjust versioned (Build-)Depends
- - - - -
4e53d8ac by Andreas Tille at 2022-07-19T17:42:01+02:00
There are some autopkgtest issues
- - - - -
17 changed files:
- .github/workflows/ci.yml
- LICENSE
- Makefile
- ci/recipe/meta.yaml
- debian/changelog
- debian/control
- q2_diversity_lib/__init__.py
- q2_diversity_lib/_util.py
- q2_diversity_lib/_version.py
- q2_diversity_lib/alpha.py
- q2_diversity_lib/beta.py
- q2_diversity_lib/plugin_setup.py
- q2_diversity_lib/tests/__init__.py
- q2_diversity_lib/tests/test_alpha.py
- q2_diversity_lib/tests/test_beta.py
- q2_diversity_lib/tests/test_util.py
- setup.py
Changes:
=====================================
.github/workflows/ci.yml
=====================================
@@ -1,14 +1,10 @@
-# This file is automatically generated by busywork.qiime2.org and
-# template-repos - any manual edits made to this file will be erased when
-# busywork performs maintenance updates.
-
name: ci
on:
pull_request:
push:
branches:
- - master
+ - 2022.2-patches
jobs:
lint:
@@ -50,6 +46,6 @@ jobs:
- uses: qiime2/action-library-packaging at alpha1
with:
package-name: q2-diversity-lib
- build-target: dev
+ build-target: release
additional-tests: py.test --pyargs q2_diversity_lib
library-token: ${{ secrets.LIBRARY_TOKEN }}
=====================================
LICENSE
=====================================
@@ -1,6 +1,6 @@
BSD 3-Clause License
-Copyright (c) 2018-2021, QIIME 2 development team.
+Copyright (c) 2018-2022, QIIME 2 development team.
All rights reserved.
Redistribution and use in source and binary forms, with or without
=====================================
Makefile
=====================================
@@ -5,6 +5,7 @@ PYTHON ?= python
all: ;
lint:
+ q2lint
flake8
test: all
=====================================
ci/recipe/meta.yaml
=====================================
@@ -18,18 +18,16 @@ requirements:
run:
- python {{ python }}
- - biom-format >=2.1.5,<2.2.0
+ - biom-format {{ biom_format }}
- decorator
- # Inherit global hard pin
- - hdf5 {{ hdf5 }}
- numpy
- - pandas
+ - pandas {{ pandas }}
- psutil
- qiime2 {{ qiime2_epoch }}.*
- q2-types {{ qiime2_epoch }}.*
- - scikit-bio
+ - scikit-bio {{ scikit_bio }}
- scipy
- - unifrac >=0.20.0
+ - unifrac {{ unifrac }}
test:
requires:
=====================================
debian/changelog
=====================================
@@ -1,3 +1,13 @@
+q2-diversity-lib (2022.2.1-1) UNRELEASED; urgency=medium
+
+ * Team upload.
+ * New upstream version
+ * Standards-Version: 4.6.1 (routine-update)
+ * Adjust versioned (Build-)Depends
+ TODO: autopkgtest issues
+
+ -- Andreas Tille <tille at debian.org> Tue, 19 Jul 2022 17:36:43 +0200
+
q2-diversity-lib (2021.8.0-3) UNRELEASED; urgency=medium
* Added full text of CC0-1.0 to d/copyright.
=====================================
debian/control
=====================================
@@ -10,8 +10,8 @@ Build-Depends: debhelper-compat (= 13),
python3-nose <!nocheck>,
python3-statsmodels <!nocheck>,
python3-unifrac <!nocheck>,
- qiime (>= 2021.8.0) <!nocheck>
-Standards-Version: 4.6.0
+ qiime (>= 2022.2.0) <!nocheck>
+Standards-Version: 4.6.1
Vcs-Browser: https://salsa.debian.org/med-team/q2-diversity-lib
Vcs-Git: https://salsa.debian.org/med-team/q2-diversity-lib.git
Homepage: https://qiime2.org/
@@ -23,9 +23,9 @@ Depends: ${shlibs:Depends},
${misc:Depends},
${python3:Depends},
python3-pandas,
- qiime (>= 2021.8.0),
- q2-emperor,
- q2-feature-table,
+ qiime (>= 2022.2.0),
+ q2-emperor (>= 2022.2.0),
+ q2-feature-table (>= 2022.2.0),
r-base-core,
r-cran-vegan,
python3-statsmodels,
=====================================
q2_diversity_lib/__init__.py
=====================================
@@ -1,5 +1,5 @@
# ----------------------------------------------------------------------------
-# Copyright (c) 2018-2021, QIIME 2 development team.
+# Copyright (c) 2018-2022, QIIME 2 development team.
#
# Distributed under the terms of the Modified BSD License.
#
=====================================
q2_diversity_lib/_util.py
=====================================
@@ -1,5 +1,5 @@
# ----------------------------------------------------------------------------
-# Copyright (c) 2018-2021, QIIME 2 development team.
+# Copyright (c) 2018-2022, QIIME 2 development team.
#
# Distributed under the terms of the Modified BSD License.
#
@@ -7,6 +7,8 @@
# ----------------------------------------------------------------------------
from inspect import signature
+from os import environ
+import subprocess
import numpy as np
from decorator import decorator
@@ -98,3 +100,19 @@ def _validate_requested_cpus(wrapped_function, *args, **kwargs):
"available to the system.")
return wrapped_function(*bound_arguments.args, **bound_arguments.kwargs)
+
+
+def _run_external_cmd(cmd, verbose=True, env=None):
+ if verbose:
+ print("Running external command line application. This may print"
+ " messages to stdout and/or stderr.\nThe command being run is"
+ " below. This command cannot be manually re-run as it will"
+ " depend on temporary files that no longer exist.\n\nCommand:\n")
+ print(" ".join(cmd), end='\n\n')
+ return subprocess.run(cmd, check=True, env=env)
+
+
+def _omp_cmd_wrapper(threads, cmd, verbose=True):
+ env = environ.copy()
+ env.update({'OMP_NUM_THREADS': str(threads)})
+ return _run_external_cmd(cmd, verbose=verbose, env=env)
=====================================
q2_diversity_lib/_version.py
=====================================
@@ -23,9 +23,9 @@ def get_keywords():
# setup.py/versioneer.py will grep for the variable names, so they must
# each be defined on a line of their own. _version.py will just call
# get_keywords().
- git_refnames = " (tag: 2021.8.0)"
- git_full = "9c30351a4ce12d4eccb94158cd808faced68fe0d"
- git_date = "2021-09-09 18:35:28 +0000"
+ git_refnames = " (tag: 2022.2.1, 2022.2-patches)"
+ git_full = "50ba304057b7d4821ed47d88417ac0f20f34c7f4"
+ git_date = "2022-05-30 21:32:17 -0700"
keywords = {"refnames": git_refnames, "full": git_full, "date": git_date}
return keywords
=====================================
q2_diversity_lib/alpha.py
=====================================
@@ -1,5 +1,5 @@
# ----------------------------------------------------------------------------
-# Copyright (c) 2018-2021, QIIME 2 development team.
+# Copyright (c) 2018-2022, QIIME 2 development team.
#
# Distributed under the terms of the Modified BSD License.
#
@@ -9,12 +9,14 @@
import pandas as pd
import skbio.diversity
import biom
-import unifrac
from q2_types.feature_table import BIOMV210Format
+from q2_types.sample_data import AlphaDiversityFormat
from q2_types.tree import NewickFormat
from ._util import (_drop_undefined_samples,
- _disallow_empty_tables)
+ _disallow_empty_tables,
+ _validate_requested_cpus,
+ _omp_cmd_wrapper)
METRICS = {
@@ -43,12 +45,13 @@ METRICS = {
# --------------------- Phylogenetic -----------------------------------------
@_disallow_empty_tables
-def faith_pd(table: BIOMV210Format, phylogeny: NewickFormat) -> pd.Series:
- table_str = str(table)
- tree_str = str(phylogeny)
- result = unifrac.faith_pd(table_str, tree_str)
- result.name = 'faith_pd'
- return result
+ at _validate_requested_cpus
+def faith_pd(table: BIOMV210Format, phylogeny: NewickFormat,
+ threads: int = 1) -> AlphaDiversityFormat:
+ vec = AlphaDiversityFormat()
+ cmd = ['faithpd', '-i', str(table), '-t', str(phylogeny), '-o', str(vec)]
+ _omp_cmd_wrapper(threads, cmd)
+ return vec
# --------------------- Non-Phylogenetic -------------------------------------
=====================================
q2_diversity_lib/beta.py
=====================================
@@ -1,13 +1,11 @@
# ----------------------------------------------------------------------------
-# Copyright (c) 2018-2021, QIIME 2 development team.
+# Copyright (c) 2018-2022, QIIME 2 development team.
#
# Distributed under the terms of the Modified BSD License.
#
# The full license is in the file LICENSE, distributed with this software.
# ----------------------------------------------------------------------------
-from functools import partial
-
import biom
import skbio.diversity
import sklearn.metrics
@@ -17,10 +15,12 @@ from scipy.spatial.distance import euclidean
from scipy.spatial.distance import jensenshannon
import numpy as np
+from q2_types.distance_matrix import LSMatFormat
from q2_types.feature_table import BIOMV210Format
from q2_types.tree import NewickFormat
from ._util import (_disallow_empty_tables,
- _validate_requested_cpus)
+ _validate_requested_cpus,
+ _omp_cmd_wrapper)
# NOTE: some phylo metrics are currently in both implemented and unimplemented
@@ -95,28 +95,47 @@ def beta_phylogenetic_passthrough(table: BIOMV210Format,
variance_adjusted: bool = False,
alpha: float = None,
bypass_tips: bool = False
- ) -> skbio.DistanceMatrix:
- unifrac_functions = {
- 'unweighted_unifrac': unifrac.unweighted,
- 'weighted_unifrac': unifrac.weighted_unnormalized,
- 'weighted_normalized_unifrac': unifrac.weighted_normalized,
- 'generalized_unifrac': unifrac.generalized}
- func = unifrac_functions[metric]
-
+ ) -> LSMatFormat:
# Ideally we remove this when we can support optional type-mapped params.
if alpha is not None and metric != 'generalized_unifrac':
raise ValueError("The alpha parameter is only allowed when the "
"selected metric is 'generalized_unifrac'")
+ method = {
+ 'unweighted_unifrac': 'unweighted',
+ 'weighted_unifrac': 'weighted_unnormalized',
+ 'weighted_normalized_unifrac': 'weighted_normalized',
+ 'generalized_unifrac': 'generalized',
+ }[metric]
+
+ result = LSMatFormat()
+
+ cmd = [
+ 'ssu',
+ '-i', str(table),
+ '-t', str(phylogeny),
+ '-m', method,
+ '-o', str(result),
+ ]
+
# handle unimplemented unifracs
if metric == 'generalized_unifrac':
alpha = 1.0 if alpha is None else alpha
- func = partial(func, alpha=alpha)
+ cmd += ['-a', str(alpha)]
+
+ if variance_adjusted:
+ cmd += ['--vaw']
+
+ if bypass_tips:
+ cmd += ['-f']
+
+ _omp_cmd_wrapper(threads, cmd)
- return func(str(table), str(phylogeny), threads=threads,
- variance_adjusted=variance_adjusted, bypass_tips=bypass_tips)
+ return result
+# Note, this method doesn't have a corresponding cli invocation, so we'll
+# just rely on unifrac doing the right thing with `threads` here.
@_disallow_empty_tables
@_validate_requested_cpus
def beta_phylogenetic_meta_passthrough(tables: BIOMV210Format,
@@ -185,17 +204,43 @@ def jaccard(table: biom.Table, n_jobs: int = 1) -> skbio.DistanceMatrix:
def unweighted_unifrac(table: BIOMV210Format,
phylogeny: NewickFormat,
threads: int = 1,
- bypass_tips: bool = False) -> skbio.DistanceMatrix:
- return unifrac.unweighted(str(table), str(phylogeny), threads=threads,
- variance_adjusted=False, bypass_tips=bypass_tips)
+ bypass_tips: bool = False) -> LSMatFormat:
+ result = LSMatFormat()
+
+ cmd = [
+ 'ssu',
+ '-i', str(table),
+ '-t', str(phylogeny),
+ '-m', 'unweighted',
+ '-o', str(result),
+ ]
+
+ if bypass_tips:
+ cmd += ['-f']
+
+ _omp_cmd_wrapper(threads, cmd)
+
+ return result
@_disallow_empty_tables
@_validate_requested_cpus
def weighted_unifrac(table: BIOMV210Format, phylogeny: NewickFormat,
threads: int = 1, bypass_tips: bool = False
- ) -> skbio.DistanceMatrix:
- return unifrac.weighted_unnormalized(str(table), str(phylogeny),
- threads=threads,
- variance_adjusted=False,
- bypass_tips=bypass_tips)
+ ) -> LSMatFormat:
+ result = LSMatFormat()
+
+ cmd = [
+ 'ssu',
+ '-i', str(table),
+ '-t', str(phylogeny),
+ '-m', 'weighted_unnormalized',
+ '-o', str(result),
+ ]
+
+ if bypass_tips:
+ cmd += ['-f']
+
+ _omp_cmd_wrapper(threads, cmd)
+
+ return result
=====================================
q2_diversity_lib/plugin_setup.py
=====================================
@@ -1,5 +1,5 @@
# ----------------------------------------------------------------------------
-# Copyright (c) 2018-2021, QIIME 2 development team.
+# Copyright (c) 2018-2022, QIIME 2 development team.
#
# Distributed under the terms of the Modified BSD License.
#
@@ -56,7 +56,7 @@ plugin.methods.register_function(
inputs={'table': FeatureTable[Frequency | RelativeFrequency
| PresenceAbsence],
'phylogeny': Phylogeny[Rooted]},
- parameters=None,
+ parameters={'threads': Int % Range(1, None) | Str % Choices(['auto'])},
outputs=[('vector', SampleData[AlphaDiversity])],
input_descriptions={
'table': "The feature table containing the samples for which Faith's "
@@ -67,7 +67,7 @@ plugin.methods.register_function(
"This tree can contain tip ids that are not present in "
"the table, but all feature ids in the table must be "
"present in this tree."},
- parameter_descriptions=None,
+ parameter_descriptions={'threads': threads_description},
output_descriptions={'vector': "Vector containing per-sample values for "
"Faith's Phylogenetic Diversity."},
name="Faith's Phylogenetic Diversity",
=====================================
q2_diversity_lib/tests/__init__.py
=====================================
@@ -1,5 +1,5 @@
# ----------------------------------------------------------------------------
-# Copyright (c) 2018-2021, QIIME 2 development team.
+# Copyright (c) 2018-2022, QIIME 2 development team.
#
# Distributed under the terms of the Modified BSD License.
#
=====================================
q2_diversity_lib/tests/test_alpha.py
=====================================
@@ -1,22 +1,22 @@
# ----------------------------------------------------------------------------
-# Copyright (c) 2018-2021, QIIME 2 development team.
+# Copyright (c) 2018-2022, QIIME 2 development team.
#
# Distributed under the terms of the Modified BSD License.
#
# The full license is in the file LICENSE, distributed with this software.
# ----------------------------------------------------------------------------
+from subprocess import CalledProcessError
+
import numpy as np
import pandas as pd
import pandas.testing as pdt
import biom
from qiime2.plugin.testing import TestPluginBase
-from q2_types.feature_table import BIOMV210Format
-from q2_types.tree import NewickFormat
from qiime2 import Artifact
-from ..alpha import (faith_pd, pielou_evenness, observed_features,
+from ..alpha import (pielou_evenness, observed_features,
shannon_entropy, METRICS)
@@ -39,77 +39,53 @@ class SmokeTests(TestPluginBase):
class FaithPDTests(TestPluginBase):
package = 'q2_diversity_lib.tests'
+ def artifact(self, semantic_type, fp):
+ return Artifact.import_data(semantic_type, self.get_data_path(fp))
+
+ @staticmethod
+ def assert_vec_equal(actual_art, expected):
+ actual = actual_art.view(pd.Series)
+ pdt.assert_series_equal(actual, expected)
+
def setUp(self):
super().setUp()
- empty_table_fp = self.get_data_path('empty_table.biom')
- self.empty_table_as_BIOMV210Format = \
- BIOMV210Format(empty_table_fp, mode='r')
- input_table_fp = self.get_data_path('faith_test_table.biom')
- self.input_table_as_BIOMV210Format = \
- BIOMV210Format(input_table_fp, mode='r')
- rf_table_fp = self.get_data_path('faith_test_table_rf.biom')
- self.rf_table_as_BIOMV210Format = BIOMV210Format(rf_table_fp, mode='r')
- pa_table_fp = self.get_data_path('faith_test_table_pa.biom')
- self.pa_table_as_BIOMV210Format = BIOMV210Format(pa_table_fp, mode='r')
-
- empty_tree_fp = self.get_data_path('empty.tree')
- self.empty_tree_as_NewickFormat = NewickFormat(empty_tree_fp, mode='r')
- input_tree_fp = self.get_data_path('faith_test.tree')
- self.input_tree_as_NewickFormat = NewickFormat(input_tree_fp, mode='r')
- root_only_tree_fp = self.get_data_path('root_only.tree')
- self.root_only_tree_as_NewickFormat = \
- NewickFormat(root_only_tree_fp, mode='r')
- missing_tip_tree_fp = self.get_data_path('missing_tip.tree')
- self.missing_tip_tree_as_NewickFormat = \
- NewickFormat(missing_tip_tree_fp, mode='r')
-
+ self.fn = self.plugin.actions['faith_pd']
+ self.tbl = self.artifact('FeatureTable[Frequency]',
+ 'faith_test_table.biom')
+ self.tre = self.artifact('Phylogeny[Rooted]', 'faith_test.tree')
self.expected = pd.Series({'S1': 0.5, 'S2': 0.7, 'S3': 1.0,
'S4': 100.5, 'S5': 101},
name='faith_pd')
def test_receives_empty_table(self):
- # empty table generated from self.empty_table with biom v2.1.7
- empty_table = self.empty_table_as_BIOMV210Format
+ table = self.artifact('FeatureTable[Frequency]', 'empty_table.biom')
with self.assertRaisesRegex(ValueError, 'empty'):
- faith_pd(table=empty_table,
- phylogeny=self.input_tree_as_NewickFormat)
+ self.fn(table=table, phylogeny=self.tre)
def test_method(self):
- actual = faith_pd(table=self.input_table_as_BIOMV210Format,
- phylogeny=self.input_tree_as_NewickFormat)
- pdt.assert_series_equal(actual, self.expected)
+ actual_art, = self.fn(table=self.tbl, phylogeny=self.tre)
+ self.assert_vec_equal(actual_art, self.expected)
def test_accepted_types_have_consistent_behavior(self):
- freq_table = self.input_table_as_BIOMV210Format
- rel_freq_table = self.rf_table_as_BIOMV210Format
- p_a_table = self.pa_table_as_BIOMV210Format
- accepted_tables = [freq_table, rel_freq_table, p_a_table]
- for table in accepted_tables:
- actual = faith_pd(table=table,
- phylogeny=self.input_tree_as_NewickFormat)
- pdt.assert_series_equal(actual, self.expected)
+ rf_tbl = self.artifact('FeatureTable[RelativeFrequency]',
+ 'faith_test_table_rf.biom')
+ pa_tbl = self.artifact('FeatureTable[PresenceAbsence]',
+ 'faith_test_table_pa.biom')
+ for table in [self.tbl, rf_tbl, pa_tbl]:
+ actual_art, = self.fn(table=table, phylogeny=self.tre)
+ self.assert_vec_equal(actual_art, self.expected)
- def test_passed_emptytree(self):
- # NOTE: different regular expressions are used here and in
- # test_beta.test_phylogenetic_measures_passed_emptytree() because
- # Unifrac reports different error messages when an empty tree is passed
- # to faith_pd than when the same is passed to the Unifrac methods.
- with self.assertRaisesRegex(ValueError,
- 'table.*not.*completely represented'):
- faith_pd(table=self.input_table_as_BIOMV210Format,
- phylogeny=self.empty_tree_as_NewickFormat)
+ def test_passed_tree_missing_tip(self):
+ tree = self.artifact('Phylogeny[Rooted]', 'missing_tip.tree')
+ with self.assertRaises(CalledProcessError):
+ obs = self.fn(table=self.tbl, phylogeny=tree)
+ self.assertTrue('not a subset of the tree tips' in obs.stderr)
def test_passed_rootonlytree(self):
- with self.assertRaisesRegex(ValueError,
- 'table.*not.*completely represented'):
- faith_pd(table=self.input_table_as_BIOMV210Format,
- phylogeny=self.root_only_tree_as_NewickFormat)
-
- def test_passed_tree_missing_tip(self):
- with self.assertRaisesRegex(ValueError,
- 'table.*not.*completely represented'):
- faith_pd(table=self.input_table_as_BIOMV210Format,
- phylogeny=self.missing_tip_tree_as_NewickFormat)
+ tree = self.artifact('Phylogeny[Rooted]', 'root_only.tree')
+ with self.assertRaises(CalledProcessError):
+ obs = self.fn(table=self.tbl, phylogeny=tree)
+ self.assertTrue('not a subset of the tree tips' in obs.stderr)
class ObservedFeaturesTests(TestPluginBase):
=====================================
q2_diversity_lib/tests/test_beta.py
=====================================
@@ -1,10 +1,13 @@
# ----------------------------------------------------------------------------
-# Copyright (c) 2018-2021, QIIME 2 development team.
+# Copyright (c) 2018-2022, QIIME 2 development team.
#
# Distributed under the terms of the Modified BSD License.
#
# The full license is in the file LICENSE, distributed with this software.
# ----------------------------------------------------------------------------
+import os
+from subprocess import CalledProcessError
+
import numpy as np
import numpy.testing as npt
import biom
@@ -12,88 +15,9 @@ import skbio
import pkg_resources
from qiime2.plugin.testing import TestPluginBase
-from q2_types.feature_table import BIOMV210Format
-from q2_types.tree import NewickFormat
from qiime2 import Artifact
-from ..beta import (bray_curtis, jaccard, unweighted_unifrac,
- weighted_unifrac, METRICS)
-
-
-nonphylogenetic_measures = [bray_curtis, jaccard]
-phylogenetic_measures = [unweighted_unifrac, weighted_unifrac]
-
-
-class SmokeTests(TestPluginBase):
- package = 'q2_diversity_lib.tests'
-
- def setUp(self):
- super().setUp()
- valid_table_fp = self.get_data_path('two_feature_table.biom')
- self.valid_table_as_BIOMV210Format = \
- BIOMV210Format(valid_table_fp, mode='r')
- # empty table fp generated from self.empty_table with biom v2.1.7
- self.empty_table = biom.Table(np.array([]), [], [])
- empty_table_fp = self.get_data_path('empty_table.biom')
- self.empty_table_as_BIOMV210Format = \
- BIOMV210Format(empty_table_fp, mode='r')
-
- empty_tree_fp = self.get_data_path('empty.tree')
- self.empty_tree_as_NewickFormat = NewickFormat(empty_tree_fp, mode='r')
- root_only_tree_fp = self.get_data_path('root_only.tree')
- self.root_only_tree_as_NewickFormat = NewickFormat(root_only_tree_fp,
- mode='r')
- missing_tip_tree_fp = self.get_data_path('missing_tip.tree')
- self.missing_tip_tree_as_NewickFormat = \
- NewickFormat(missing_tip_tree_fp, mode='r')
- two_feature_tree_fp = self.get_data_path('two_feature.tree')
- self.two_feature_tree_as_NewickFormat = \
- NewickFormat(two_feature_tree_fp, mode='r')
- extra_tip_tree_fp = self.get_data_path('extra_tip.tree')
- self.extra_tip_tree_as_NewickFormat = NewickFormat(extra_tip_tree_fp,
- mode='r')
- valid_tree_fp = self.get_data_path('three_feature.tree')
- self.valid_tree_as_NewickFormat = NewickFormat(valid_tree_fp, mode='r')
-
- def test_nonphylogenetic_measures_passed_empty_table(self):
- for measure in nonphylogenetic_measures:
- with self.assertRaisesRegex(ValueError, "empty"):
- measure(table=self.empty_table)
-
- def test_phylogenetic_measures_passed_empty_table(self):
- for measure in phylogenetic_measures:
- with self.assertRaisesRegex(ValueError, "empty"):
- measure(table=self.empty_table_as_BIOMV210Format,
- phylogeny=self.valid_tree_as_NewickFormat)
-
- def test_phylogenetic_measures_passed_empty_tree(self):
- for measure in phylogenetic_measures:
- with self.assertRaisesRegex(ValueError, "newick"):
- measure(table=self.valid_table_as_BIOMV210Format,
- phylogeny=self.empty_tree_as_NewickFormat)
-
- def test_phylogenetic_measures_passed_root_only_tree(self):
- for measure in phylogenetic_measures:
- with self.assertRaisesRegex(ValueError,
- "table.*not.*completely represented"):
- measure(table=self.valid_table_as_BIOMV210Format,
- phylogeny=self.root_only_tree_as_NewickFormat)
-
- def test_phylogenetic_measures_passed_tree_missing_tip(self):
- for measure in phylogenetic_measures:
- with self.assertRaisesRegex(ValueError,
- "table.*not.*completely represented"):
- measure(table=self.valid_table_as_BIOMV210Format,
- phylogeny=self.missing_tip_tree_as_NewickFormat)
-
- def test_phylogenetic_measure_passed_tree_w_extra_tip(self):
- for measure in phylogenetic_measures:
- matched_tree_output = measure(
- self.valid_table_as_BIOMV210Format,
- self.two_feature_tree_as_NewickFormat)
- extra_tip_tree_output = measure(self.valid_table_as_BIOMV210Format,
- self.valid_tree_as_NewickFormat)
- self.assertEqual(matched_tree_output, extra_tip_tree_output)
+from ..beta import bray_curtis, jaccard, METRICS
# ----------------------------Non-Phylogenetic---------------------------------
@@ -214,67 +138,85 @@ class JaccardTests(TestPluginBase):
class UnweightedUnifrac(TestPluginBase):
package = 'q2_diversity_lib.tests'
+ def artifact(self, semantic_type, fp):
+ return Artifact.import_data(semantic_type, self.get_data_path(fp))
+
def setUp(self):
super().setUp()
+
+ self.fn = self.plugin.actions['unweighted_unifrac']
+
# expected computed with skbio.diversity.beta_diversity
self.expected = skbio.DistanceMatrix([[0.00, 0.25, 0.25],
[0.25, 0.00, 0.00],
[0.25, 0.00, 0.00]],
ids=['S1', 'S2', 'S3'])
- table_fp = self.get_data_path('two_feature_table.biom')
- self.table_as_BIOMV210Format = BIOMV210Format(table_fp, mode='r')
- rf_table_fp = self.get_data_path('two_feature_rf_table.biom')
- self.rf_table_as_BIOMV210Format = BIOMV210Format(rf_table_fp, mode='r')
- p_a_table_fp = self.get_data_path('two_feature_p_a_table.biom')
- self.p_a_table_as_BIOMV210Format = BIOMV210Format(p_a_table_fp,
- mode='r')
- self.table_as_artifact = Artifact.import_data(
- 'FeatureTable[Frequency]', self.table_as_BIOMV210Format)
-
- tree_fp = self.get_data_path('three_feature.tree')
- self.tree_as_NewickFormat = NewickFormat(tree_fp, mode='r')
- self.tree_as_artifact = Artifact.import_data(
- 'Phylogeny[Rooted]', self.tree_as_NewickFormat)
-
- self.unweighted_unifrac_thru_framework = self.plugin.actions[
- 'unweighted_unifrac']
+ self.tbl = self.artifact('FeatureTable[Frequency]',
+ 'two_feature_table.biom')
+ self.tre = self.artifact('Phylogeny[Rooted]', 'three_feature.tree')
def test_method(self):
- actual = unweighted_unifrac(self.table_as_BIOMV210Format,
- self.tree_as_NewickFormat)
+ actual_art, = self.fn(self.tbl, self.tre)
+ actual = actual_art.view(skbio.DistanceMatrix)
self.assertEqual(actual.ids, self.expected.ids)
for id1 in actual.ids:
for id2 in actual.ids:
npt.assert_almost_equal(actual[id1, id2],
self.expected[id1, id2])
+ def test_method_bypass_tips(self):
+ actual_art, = self.fn(self.tbl, self.tre, bypass_tips=True)
+ actual = actual_art.view(skbio.DistanceMatrix)
+ self.assertEqual(actual.ids, self.expected.ids)
+
def test_accepted_types_have_consistent_behavior(self):
- freq_table = self.table_as_BIOMV210Format
- rel_freq_table = self.rf_table_as_BIOMV210Format
- p_a_table = self.p_a_table_as_BIOMV210Format
- accepted_tables = [freq_table, rel_freq_table, p_a_table]
- for table in accepted_tables:
- actual = unweighted_unifrac(table=table,
- phylogeny=self.tree_as_NewickFormat)
+ rf_tbl = self.artifact('FeatureTable[RelativeFrequency]',
+ 'two_feature_rf_table.biom')
+ pa_tbl = self.artifact('FeatureTable[PresenceAbsence]',
+ 'two_feature_p_a_table.biom')
+
+ for table in [self.tbl, rf_tbl, pa_tbl]:
+ actual_art, = self.fn(table=table, phylogeny=self.tre)
+ actual = actual_art.view(skbio.DistanceMatrix)
self.assertEqual(actual.ids, self.expected.ids)
for id1 in actual.ids:
for id2 in actual.ids:
npt.assert_almost_equal(actual[id1, id2],
self.expected[id1, id2])
- def test_does_it_run_through_framework(self):
- self.unweighted_unifrac_thru_framework(self.table_as_artifact,
- self.tree_as_artifact)
- # If we get here, then it ran without error
- self.assertTrue(True)
+ def test_missing_tips_tree(self):
+ tre = self.artifact('Phylogeny[Rooted]', 'root_only.tree')
+ with self.assertRaises(CalledProcessError):
+ obs = self.fn(self.tbl, tre)
+ self.assertTrue('not a subset of the tree tips', obs.stderr)
+
+ def test_extra_tip_tree(self):
+ tbl = self.artifact('FeatureTable[Frequency]',
+ 'two_feature_table.biom')
+
+ tre_2 = self.artifact('Phylogeny[Rooted]', 'two_feature.tree')
+ obs_2_art, = self.fn(tbl, tre_2)
+ obs_2 = obs_2_art.view(skbio.DistanceMatrix)
+
+ tre_3 = self.artifact('Phylogeny[Rooted]', 'three_feature.tree')
+ obs_3_art, = self.fn(tbl, tre_3)
+ obs_3 = obs_3_art.view(skbio.DistanceMatrix)
+
+ self.assertEqual(obs_2, obs_3)
class WeightedUnifrac(TestPluginBase):
package = 'q2_diversity_lib.tests'
+ def artifact(self, semantic_type, fp):
+ return Artifact.import_data(semantic_type, self.get_data_path(fp))
+
def setUp(self):
super().setUp()
+
+ self.fn = self.plugin.actions['weighted_unifrac']
+
# expected computed with diversity.beta_phylogenetic (weighted_unifrac)
self.expected = skbio.DistanceMatrix(
np.array([0.44656238, 0.23771096, 0.30489123, 0.23446002,
@@ -290,74 +232,99 @@ class WeightedUnifrac(TestPluginBase):
'10084.PC.355', '10084.PC.354', '10084.PC.636',
'10084.PC.635', '10084.PC.607', '10084.PC.634'))
- table_fp = self.get_data_path('crawford.biom')
- self.table_as_BIOMV210Format = BIOMV210Format(table_fp, mode='r')
- rel_freq_table_fp = self.get_data_path('crawford_rf.biom')
- self.rf_table_as_BIOMV210Format = BIOMV210Format(rel_freq_table_fp,
- mode='r')
-
- tree_fp = self.get_data_path('crawford.nwk')
- self.tree_as_NewickFormat = NewickFormat(tree_fp, mode='r')
+ self.tbl = self.artifact('FeatureTable[Frequency]', 'crawford.biom')
+ self.tre = self.artifact('Phylogeny[Rooted]', 'crawford.nwk')
def test_method(self):
- actual = weighted_unifrac(
- self.table_as_BIOMV210Format, self.tree_as_NewickFormat)
+ actual_art, = self.fn(self.tbl, self.tre)
+ actual = actual_art.view(skbio.DistanceMatrix)
self.assertEqual(actual.ids, self.expected.ids)
for id1 in actual.ids:
for id2 in actual.ids:
npt.assert_almost_equal(actual[id1, id2],
self.expected[id1, id2])
+ def test_method_bypass_tips(self):
+ actual_art, = self.fn(self.tbl, self.tre, bypass_tips=True)
+ actual = actual_art.view(skbio.DistanceMatrix)
+ self.assertEqual(actual.ids, self.expected.ids)
+
def test_accepted_types_have_consistent_behavior(self):
- freq_table = self.table_as_BIOMV210Format
- rel_freq_table = self.rf_table_as_BIOMV210Format
- accepted_tables = [freq_table, rel_freq_table]
- for table in accepted_tables:
- actual = weighted_unifrac(
- table=table, phylogeny=self.tree_as_NewickFormat)
+ tbl_rf = self.artifact('FeatureTable[RelativeFrequency]',
+ 'crawford_rf.biom')
+
+ for table in [self.tbl, tbl_rf]:
+ actual_art, = self.fn(table=table, phylogeny=self.tre)
+ actual = actual_art.view(skbio.DistanceMatrix)
self.assertEqual(actual.ids, self.expected.ids)
for id1 in actual.ids:
for id2 in actual.ids:
npt.assert_almost_equal(actual[id1, id2],
self.expected[id1, id2])
+ def test_missing_tips_tree(self):
+ tre = self.artifact('Phylogeny[Rooted]', 'root_only.tree')
+ with self.assertRaises(CalledProcessError):
+ obs = self.fn(self.tbl, tre)
+ self.assertTrue('not a subset of the tree tips', obs.stderr)
+
+ def test_extra_tip_tree(self):
+ tbl = self.artifact('FeatureTable[Frequency]',
+ 'two_feature_table.biom')
+
+ tre_2 = self.artifact('Phylogeny[Rooted]', 'two_feature.tree')
+ obs_2_art, = self.fn(tbl, tre_2)
+ obs_2 = obs_2_art.view(skbio.DistanceMatrix)
+
+ tre_3 = self.artifact('Phylogeny[Rooted]', 'three_feature.tree')
+ obs_3_art, = self.fn(tbl, tre_3)
+ obs_3 = obs_3_art.view(skbio.DistanceMatrix)
+
+ self.assertEqual(obs_2, obs_3)
+
class BetaPhylogeneticMetaPassthroughTests(TestPluginBase):
package = 'q2_diversity_lib.tests'
def setUp(self):
super().setUp()
- self.method = self.plugin.actions['beta_phylogenetic_meta_passthrough']
- empty_table = biom.Table(np.array([]), [], [])
- self.empty_table = Artifact.import_data('FeatureTable[Frequency]',
- empty_table)
+ self.fn = self.plugin.actions['beta_phylogenetic_meta_passthrough']
+
+ self.empty_tbl = Artifact.import_data(
+ 'FeatureTable[Frequency]', biom.Table(np.array([]), [], []))
# checking parity with the unifrac.meta tests
- table1 = pkg_resources.resource_filename('unifrac.tests',
- 'data/e1.biom')
- table2 = pkg_resources.resource_filename('unifrac.tests',
- 'data/e2.biom')
- self.tables = [Artifact.import_data('FeatureTable[Frequency]', table1),
- Artifact.import_data('FeatureTable[Frequency]', table2)]
-
- tree1 = pkg_resources.resource_filename('unifrac.tests',
- 'data/t1.newick')
- tree2 = pkg_resources.resource_filename('unifrac.tests',
- 'data/t2.newick')
- self.trees = [Artifact.import_data('Phylogeny[Rooted]', tree1),
- Artifact.import_data('Phylogeny[Rooted]', tree2)]
+ def unifrac_data(fn):
+ path = os.path.join('data', fn)
+ return pkg_resources.resource_filename('unifrac.tests', path)
+
+ self.tables = [
+ Artifact.import_data('FeatureTable[Frequency]',
+ unifrac_data('e1.biom')),
+ Artifact.import_data('FeatureTable[Frequency]',
+ unifrac_data('e2.biom')),
+ ]
+
+ self.trees = [
+ Artifact.import_data('Phylogeny[Rooted]',
+ unifrac_data('t1.newick')),
+ Artifact.import_data('Phylogeny[Rooted]',
+ unifrac_data('t2.newick')),
+ ]
def test_method(self):
for metric in METRICS['PHYLO']['UNIMPL']:
- self.method(tables=self.tables, phylogenies=self.trees,
- metric=metric)
- self.assertTrue(True)
+ obs_art, = self.fn(tables=self.tables, phylogenies=self.trees,
+ metric=metric)
+ obs = obs_art.view(skbio.DistanceMatrix)
+ self.assertEqual(('A', 'B', 'C'), obs.ids)
+ self.assertEqual((3, 3), obs.shape)
def test_passed_bad_metric(self):
with self.assertRaisesRegex(TypeError,
'imaginary_metric.*incompatible'):
- self.method(tables=self.tables, phylogenies=self.trees,
- metric='imaginary_metric')
+ self.fn(tables=self.tables, phylogenies=self.trees,
+ metric='imaginary_metric')
class BetaPassthroughTests(TestPluginBase):
@@ -457,44 +424,56 @@ class BetaPassthroughTests(TestPluginBase):
class BetaPhylogeneticPassthroughTests(TestPluginBase):
package = 'q2_diversity_lib.tests'
+ def artifact(self, semantic_type, fn):
+ return Artifact.import_data(semantic_type, self.get_data_path(fn))
+
def setUp(self):
super().setUp()
- self.method = self.plugin.actions['beta_phylogenetic_passthrough']
- empty_table = biom.Table(np.array([]), [], [])
- self.empty_table = Artifact.import_data('FeatureTable[Frequency]',
- empty_table)
- crawford_tbl = self.get_data_path('crawford.biom')
- self.crawford_tbl = Artifact.import_data('FeatureTable[Frequency]',
- crawford_tbl)
- crawford_tree = self.get_data_path('crawford.nwk')
- self.crawford_tree = Artifact.import_data('Phylogeny[Rooted]',
- crawford_tree)
+
+ self.fn = self.plugin.actions['beta_phylogenetic_passthrough']
+
+ self.tbl = self.artifact('FeatureTable[Frequency]', 'crawford.biom')
+ self.tre = self.artifact('Phylogeny[Rooted]', 'crawford.nwk')
def test_method(self):
for metric in METRICS['PHYLO']['UNIMPL']:
- self.method(table=self.crawford_tbl,
- phylogeny=self.crawford_tree, metric=metric)
- # If we get here, then our methods ran without error
- self.assertTrue(True)
+ obs_art, = self.fn(table=self.tbl, phylogeny=self.tre,
+ metric=metric)
+ obs = obs_art.view(skbio.DistanceMatrix)
+ self.assertEqual(9, len(obs.ids))
+ self.assertEqual((9, 9), obs.shape)
+
+ # variance adjusted
+ for metric in METRICS['PHYLO']['UNIMPL']:
+ obs_art, = self.fn(table=self.tbl, phylogeny=self.tre,
+ metric=metric, variance_adjusted=True)
+ obs = obs_art.view(skbio.DistanceMatrix)
+ self.assertEqual(9, len(obs.ids))
+ self.assertEqual((9, 9), obs.shape)
+
+ # bypass tips
+ for metric in METRICS['PHYLO']['UNIMPL']:
+ obs_art, = self.fn(table=self.tbl, phylogeny=self.tre,
+ metric=metric, bypass_tips=True)
+ obs = obs_art.view(skbio.DistanceMatrix)
+ self.assertEqual(9, len(obs.ids))
+ self.assertEqual((9, 9), obs.shape)
def test_passed_empty_table(self):
+ tbl = Artifact.import_data(
+ 'FeatureTable[Frequency]', biom.Table(np.array([]), [], []))
+
for metric in METRICS['PHYLO']['UNIMPL']:
with self.assertRaisesRegex(ValueError, 'empty'):
- self.method(table=self.empty_table,
- phylogeny=self.crawford_tree, metric=metric)
+ self.fn(table=tbl, phylogeny=self.tre, metric=metric)
def test_passed_bad_metric(self):
- with self.assertRaisesRegex(TypeError,
- 'imaginary_metric.*incompatible'):
- self.method(table=self.crawford_tbl,
- phylogeny=self.crawford_tree,
- metric='imaginary_metric')
+ with self.assertRaisesRegex(TypeError, 'imaginary.*incompatible'):
+ self.fn(table=self.tbl, phylogeny=self.tre, metric='imaginary')
def test_beta_phylogenetic_alpha_on_non_generalized(self):
with self.assertRaisesRegex(ValueError, 'The alpha parameter is only '
'allowed when the selected metric is '
'\'generalized_unifrac\''):
- self.method(table=self.crawford_tbl,
- phylogeny=self.crawford_tree,
- metric='unweighted_unifrac',
- alpha=0.11)
+ self.fn(table=self.tbl, phylogeny=self.tre,
+ metric='unweighted_unifrac', alpha=0.11)
=====================================
q2_diversity_lib/tests/test_util.py
=====================================
@@ -1,5 +1,5 @@
# ----------------------------------------------------------------------------
-# Copyright (c) 2018-2021, QIIME 2 development team.
+# Copyright (c) 2018-2022, QIIME 2 development team.
#
# Distributed under the terms of the Modified BSD License.
#
=====================================
setup.py
=====================================
@@ -1,5 +1,5 @@
# ----------------------------------------------------------------------------
-# Copyright (c) 2018-2021, QIIME 2 development team.
+# Copyright (c) 2018-2022, QIIME 2 development team.
#
# Distributed under the terms of the Modified BSD License.
#
View it on GitLab: https://salsa.debian.org/med-team/q2-diversity-lib/-/compare/4772303e0b766f4988f3617418458629a45e1f44...4e53d8accc73f83e79cc9baa157f4669c66cf475
--
View it on GitLab: https://salsa.debian.org/med-team/q2-diversity-lib/-/compare/4772303e0b766f4988f3617418458629a45e1f44...4e53d8accc73f83e79cc9baa157f4669c66cf475
You're receiving this email because of your account on salsa.debian.org.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/debian-med-commit/attachments/20220719/e15c641b/attachment-0001.htm>
More information about the debian-med-commit
mailing list