diff --git a/q2_annotate/kraken2/bracken.py b/q2_annotate/kraken2/bracken.py index 40a4fd23..b82f5301 100644 --- a/q2_annotate/kraken2/bracken.py +++ b/q2_annotate/kraken2/bracken.py @@ -6,6 +6,7 @@ # The full license is in the file LICENSE, distributed with this software. # ---------------------------------------------------------------------------- import os +import platform import re import subprocess import tempfile @@ -167,6 +168,14 @@ def estimate_bracken( level: str = 'S', include_unclassified: bool = True ) -> (Kraken2ReportDirectoryFormat, pd.DataFrame, pd.DataFrame): + + # Check for macOS and raise an error if detected + if platform.system() == "Darwin": + raise RuntimeError( + "The estimate_bracken action is currently not supported on macOS " + "due to the unavailability of the Bracken package. Please try it on Linux." + ) + _assert_read_lens_available(bracken_db, read_len) table, reports = _estimate_bracken( diff --git a/q2_annotate/kraken2/tests/test_bracken.py b/q2_annotate/kraken2/tests/test_bracken.py index d7022c63..0b0a30ad 100644 --- a/q2_annotate/kraken2/tests/test_bracken.py +++ b/q2_annotate/kraken2/tests/test_bracken.py @@ -6,6 +6,7 @@ # The full license is in the file LICENSE, distributed with this software. # ---------------------------------------------------------------------------- import os +import platform import shutil import tempfile import unittest @@ -164,9 +165,10 @@ def test_estimate_bracken(self, p1): assert_frame_equal(obs_table, exp_table) self.assertIsInstance(obs_reports, Kraken2ReportDirectoryFormat) + @patch('platform.system', return_value='Linux') @patch('q2_annotate.kraken2.bracken._assert_read_lens_available') @patch('q2_annotate.kraken2.bracken._estimate_bracken') - def test_estimate_bracken_with_unclassified(self, p1, p2): + def test_estimate_bracken_with_unclassified(self, p1, p2, p3): kraken_reports = Kraken2ReportDirectoryFormat( self.get_data_path('bracken-report-with-unclassified/' 'kraken-reports'), 'r' @@ -204,6 +206,16 @@ def test_estimate_bracken_with_unclassified(self, p1, p2): assert_frame_equal(obs_taxonomy, exp_taxonomy) self.assertIsInstance(obs_reports, Kraken2ReportDirectoryFormat) + def test_estimate_bracken_linux_vs_osx(self): + from qiime2.plugins import annotate + try: + annotate.methods.estimate_bracken + except AttributeError: + if platform.system() == "Darwin": + pass + else: + raise + if __name__ == "__main__": unittest.main() diff --git a/q2_annotate/plugin_setup.py b/q2_annotate/plugin_setup.py index 01056427..fad03719 100644 --- a/q2_annotate/plugin_setup.py +++ b/q2_annotate/plugin_setup.py @@ -6,6 +6,7 @@ # The full license is in the file LICENSE, distributed with this software. # ---------------------------------------------------------------------------- import importlib +import platform from q2_quality_control.plugin_setup import ( filter_parameters, filter_parameter_descriptions @@ -284,45 +285,47 @@ description="Collates kraken2 outputs" ) -plugin.methods.register_function( - function=q2_annotate.kraken2.bracken.estimate_bracken, - inputs={ - "kraken_reports": SampleData[Kraken2Reports % Properties('reads')], - "bracken_db": BrackenDB - }, - parameters={ - 'threshold': Int % Range(0, None), - 'read_len': Int % Range(0, None), - 'level': Str % Choices(['D', 'P', 'C', 'O', 'F', 'G', 'S']), - 'include_unclassified': Bool - }, - outputs=[ - ('reports', SampleData[Kraken2Reports % Properties('bracken')]), - ('taxonomy', FeatureData[Taxonomy]), - ('table', FeatureTable[Frequency]) - ], - input_descriptions={ - "kraken_reports": "Reports produced by Kraken2.", - "bracken_db": "Bracken database." - }, - parameter_descriptions={ - 'threshold': 'Bracken: number of reads required PRIOR to abundance ' - 'estimation to perform re-estimation.', - 'read_len': ('Bracken: read length to get all classifications for. ' - 'For paired end data (e.g., 2x150) this should be set ' - 'to the length of the single-end reads (e.g., 150).'), - 'level': 'Bracken: taxonomic level to estimate abundance at.', - 'include_unclassified': 'Bracken does not include the unclassified ' - 'read counts in the feature table. Set this ' - 'to True to include those regardless.' - }, - output_descriptions={ - 'reports': 'Reports modified by Bracken.', - }, - name='Perform read abundance re-estimation using Bracken.', - description='This method uses Bracken to re-estimate read abundances.', - citations=[citations["wood2019"]] -) +if platform.system() != "Darwin": + plugin.methods.register_function( + function=q2_annotate.kraken2.bracken.estimate_bracken, + inputs={ + "kraken_reports": SampleData[Kraken2Reports % Properties('reads')], + "bracken_db": BrackenDB + }, + parameters={ + 'threshold': Int % Range(0, None), + 'read_len': Int % Range(0, None), + 'level': Str % Choices(['D', 'P', 'C', 'O', 'F', 'G', 'S']), + 'include_unclassified': Bool + }, + outputs=[ + ('reports', SampleData[Kraken2Reports % Properties('bracken')]), + ('taxonomy', FeatureData[Taxonomy]), + ('table', FeatureTable[Frequency]) + ], + input_descriptions={ + "kraken_reports": "Reports produced by Kraken2.", + "bracken_db": "Bracken database." + }, + parameter_descriptions={ + 'threshold': 'Bracken: number of reads required PRIOR to abundance ' + 'estimation to perform re-estimation.', + 'read_len': ('Bracken: read length to get all classifications for. ' + 'For paired end data (e.g., 2x150) this should be set ' + 'to the length of the single-end reads (e.g., 150).'), + 'level': 'Bracken: taxonomic level to estimate abundance at.', + 'include_unclassified': 'Bracken does not include the unclassified ' + 'read counts in the feature table. Set this ' + 'to True to include those regardless.' + }, + output_descriptions={ + 'reports': 'Reports modified by Bracken.', + }, + name='Perform read abundance re-estimation using Bracken.', + description='This method uses Bracken to re-estimate read abundances. ' + 'Only available on Linux platforms.', + citations=[citations["wood2019"]] + ) plugin.methods.register_function( function=q2_annotate.kraken2.build_kraken_db, diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 00000000..086d8175 --- /dev/null +++ b/setup.cfg @@ -0,0 +1,6 @@ +[flake8] +max-line-length = 88 +extend-ignore = E203 + +[tool.isort] +profile = "black"