From 216fd8c57acca5f5ff1fdbe7f3e2c183f679f8d3 Mon Sep 17 00:00:00 2001 From: Jai Ram Rideout Date: Tue, 20 Oct 2015 13:39:01 -0700 Subject: [PATCH] REF: remove biom script; make commands importable and tab-completable Fixes #283. Changes also necessary for #656. --- .travis.yml | 2 +- MANIFEST.in | 1 - biom/cli/__init__.py | 32 +- biom/cli/installation_informer.py | 22 ++ biom/cli/metadata_adder.py | 111 +++++- biom/cli/table_converter.py | 109 +++++- biom/cli/table_head.py | 46 +++ biom/cli/table_normalizer.py | 52 ++- biom/cli/table_subsetter.py | 77 +++- biom/cli/table_summarizer.py | 46 ++- biom/cli/table_validator.py | 39 +- biom/cli/util.py | 2 + doc/index.rst | 4 + scripts/biom | 460 ----------------------- setup.py | 15 +- tests/test_cli/test_add_metadata.py | 4 +- tests/test_cli/test_data/test.json | 1 + tests/test_cli/test_show_install_info.py | 4 +- tests/test_cli/test_subset_table.py | 16 +- tests/test_cli/test_summarize_table.py | 6 +- tests/test_cli/test_table_converter.py | 5 +- tests/test_cli/test_table_normalizer.py | 11 +- 22 files changed, 547 insertions(+), 518 deletions(-) create mode 100644 biom/cli/table_head.py delete mode 100755 scripts/biom create mode 100644 tests/test_cli/test_data/test.json diff --git a/.travis.yml b/.travis.yml index 9c61745f..488be128 100644 --- a/.travis.yml +++ b/.travis.yml @@ -24,7 +24,7 @@ install: - pip install -e . --no-deps script: - nosetests --with-doctest --with-coverage - - flake8 biom setup.py scripts + - flake8 biom setup.py - biom show-install-info - make -C doc html # we can only validate the tables if we have H5PY diff --git a/MANIFEST.in b/MANIFEST.in index 5e27d9a6..7f908c96 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -5,7 +5,6 @@ include ChangeLog.md graft biom graft support_files graft examples -graft scripts graft doc prune docs/_build diff --git a/biom/cli/__init__.py b/biom/cli/__init__.py index b0e2baf6..9eaecf3a 100644 --- a/biom/cli/__init__.py +++ b/biom/cli/__init__.py @@ -6,15 +6,25 @@ # The full license is in the file COPYING.txt, distributed with this software. # ---------------------------------------------------------------------------- -from .installation_informer import show_install_info -from .table_subsetter import subset_table -from .table_summarizer import summarize_table -from .table_normalizer import normalize_table -from .metadata_adder import add_metadata -from .table_validator import validate_table -from .table_converter import convert -from .util import write_biom_table +from __future__ import division -__all__ = ['validate_table', 'summarize_table', 'add_metadata', - 'show_install_info', 'normalize_table', 'subset_table', - 'convert', 'write_biom_table'] +from importlib import import_module + +import click +import biom + + +@click.group() +@click.version_option(version=biom.__version__) +def cli(): + pass + + +import_module('biom.cli.table_summarizer') +import_module('biom.cli.metadata_adder') +import_module('biom.cli.table_converter') +import_module('biom.cli.installation_informer') +import_module('biom.cli.table_subsetter') +import_module('biom.cli.table_normalizer') +import_module('biom.cli.table_head') +import_module('biom.cli.table_validator') diff --git a/biom/cli/installation_informer.py b/biom/cli/installation_informer.py index 2e31908b..9e3a9991 100644 --- a/biom/cli/installation_informer.py +++ b/biom/cli/installation_informer.py @@ -10,8 +10,30 @@ import sys +import click +from biom.cli import cli + + +@cli.command(name='show-install-info') def show_install_info(): + """Provide information about the biom-format installation. + + Provide information about the biom-format installation, including settings + pulled from the configuration file. For more details, see + http://biom-format.org + + Example usage: + + Display biom-format installation information: + + $ biom show-install-info + + """ + click.echo(_show_install_info()) + + +def _show_install_info(): lines = [] lines.extend(_get_formatted_system_info()) lines.extend(_get_formatted_dependency_version_info()) diff --git a/biom/cli/metadata_adder.py b/biom/cli/metadata_adder.py index 7b685c0e..96e26606 100644 --- a/biom/cli/metadata_adder.py +++ b/biom/cli/metadata_adder.py @@ -8,7 +8,110 @@ from __future__ import division +import click + +from biom import load_table +from biom.cli import cli +from biom.cli.util import write_biom_table from biom.parse import MetadataMap +from biom.util import HAVE_H5PY + + +@cli.command(name='add-metadata') +@click.option('-i', '--input-fp', required=True, + type=click.Path(exists=True, dir_okay=False), + help='The input BIOM table') +@click.option('-o', '--output-fp', required=True, + type=click.Path(exists=False, dir_okay=False), + help='The output BIOM table') +@click.option('-m', '--sample-metadata-fp', required=False, + type=click.Path(exists=True, dir_okay=False), + help='The sample metadata mapping file (will add sample ' + 'metadata to the input BIOM table, if provided).') +@click.option('--observation-metadata-fp', required=False, + type=click.Path(exists=True, dir_okay=False), + help='The observation metadata mapping file (will add ' + 'observation metadata to the input BIOM table, if ' + 'provided).') +@click.option('--sc-separated', required=False, type=click.STRING, + help='Comma-separated list of the metadata fields to split ' + 'on semicolons. This is useful for hierarchical data such ' + 'as taxonomy or functional categories.') +@click.option('--sc-pipe-separated', required=False, type=click.STRING, + help='Comma-separated list of the metadata fields to split ' + 'on semicolons and pipes ("|"). This is useful for ' + 'hierarchical data such as functional categories with ' + 'one-to-many mappings (e.g. x;y;z|x;y;w)).') +@click.option('--int-fields', required=False, type=click.STRING, + help='Comma-separated list of the metadata fields to cast ' + 'to integers. This is useful for integer data such as ' + '"DaysSinceStart".') +@click.option('--float-fields', required=False, type=click.STRING, + help='Comma-separated list of the metadata fields to cast ' + 'to floating point numbers. This is useful for real number ' + 'data such as "pH".') +@click.option('--sample-header', required=False, type=click.STRING, + help='Comma-separated list of the sample metadata field ' + 'names. This is useful if a header line is not provided ' + 'with the metadata, if you want to rename the fields, or ' + 'if you want to include only the first n fields where n is ' + 'the number of entries provided here.') +@click.option('--observation-header', required=False, type=click.STRING, + help='Comma-separated list of the observation metadata ' + 'field names. This is useful if a header line is not ' + 'provided with the metadata, if you want to rename the ' + 'fields, or if you want to include only the first n fields ' + 'where n is the number of entries provided here.') +@click.option('--output-as-json', default=not HAVE_H5PY, is_flag=True, + help='Write the output file in JSON format.') +def add_metadata(input_fp, output_fp, sample_metadata_fp, + observation_metadata_fp, sc_separated, sc_pipe_separated, + int_fields, float_fields, sample_header, observation_header, + output_as_json): + """Add metadata to a BIOM table. + + Add sample and/or observation metadata to BIOM-formatted files. See + examples here: http://biom-format.org/documentation/adding_metadata.html + + Example usage: + + Add sample metadata to a BIOM table: + + $ biom add-metadata -i otu_table.biom -o table_with_sample_metadata.biom + -m sample_metadata.txt + """ + table = load_table(input_fp) + if sample_metadata_fp is not None: + sample_metadata_f = open(sample_metadata_fp, 'U') + else: + sample_metadata_f = None + if observation_metadata_fp is not None: + observation_metadata_f = open(observation_metadata_fp, 'U') + else: + observation_metadata_f = None + if sc_separated is not None: + sc_separated = sc_separated.split(',') + if sc_pipe_separated is not None: + sc_pipe_separated = sc_pipe_separated.split(',') + if int_fields is not None: + int_fields = int_fields.split(',') + if float_fields is not None: + float_fields = float_fields.split(',') + if sample_header is not None: + sample_header = sample_header.split(',') + if observation_header is not None: + observation_header = observation_header.split(',') + + result = _add_metadata(table, sample_metadata_f, observation_metadata_f, + sc_separated, sc_pipe_separated, int_fields, + float_fields, sample_header, observation_header) + + if output_as_json: + fmt = 'json' + else: + fmt = 'hdf5' + + write_biom_table(result, fmt, output_fp) def _split_on_semicolons(x): @@ -33,10 +136,10 @@ def _float(x): return x -def add_metadata(table, sample_metadata=None, observation_metadata=None, - sc_separated=None, sc_pipe_separated=None, int_fields=None, - float_fields=None, sample_header=None, - observation_header=None): +def _add_metadata(table, sample_metadata=None, observation_metadata=None, + sc_separated=None, sc_pipe_separated=None, int_fields=None, + float_fields=None, sample_header=None, + observation_header=None): if sample_metadata is None and observation_metadata is None: raise ValueError('Must specify sample_metadata and/or ' diff --git a/biom/cli/table_converter.py b/biom/cli/table_converter.py index c0497740..59129708 100644 --- a/biom/cli/table_converter.py +++ b/biom/cli/table_converter.py @@ -8,7 +8,13 @@ from __future__ import division +import click + +from biom import load_table +from biom.cli import cli from biom.cli.util import write_biom_table +from biom.parse import MetadataMap + table_types = ["OTU table", "Pathway table", @@ -32,12 +38,103 @@ } -def convert(table, output_filepath, sample_metadata=None, - observation_metadata=None, - to_json=False, to_hdf5=False, to_tsv=False, - collapsed_samples=False, collapsed_observations=False, - header_key=None, output_metadata_id=None, table_type=None, - process_obs_metadata=None, tsv_metadata_formatter='sc_separated'): +@cli.command(name='convert') +@click.option('-i', '--input-fp', required=True, + type=click.Path(exists=True, dir_okay=False), + help='The input BIOM table') +@click.option('-o', '--output-fp', required=True, + type=click.Path(exists=False, dir_okay=False), + help='The output BIOM table') +@click.option('-m', '--sample-metadata-fp', required=False, + type=click.Path(exists=True, dir_okay=False), + help='The sample metadata mapping file (will add sample ' + 'metadata to the input BIOM table, if provided).') +@click.option('--observation-metadata-fp', required=False, + type=click.Path(exists=True, dir_okay=False), + help='The observation metadata mapping file (will add ' + 'observation metadata to the input BIOM table, if ' + 'provided).') +@click.option('--to-json', default=False, is_flag=True, + help='Output as JSON-formatted table.') +@click.option('--to-hdf5', default=False, is_flag=True, + help='Output as HDF5-formatted table.') +@click.option('--to-tsv', default=False, is_flag=True, + help='Output as TSV-formatted (classic) table.') +@click.option('--collapsed-samples', default=False, is_flag=True, + help='If --to_hdf5 is passed and the original table is a ' + 'BIOM table with collapsed samples, this will ' + 'update the sample metadata of the table to ' + 'the supported HDF5 collapsed format.') +@click.option('--collapsed-observations', default=False, is_flag=True, + help='If --to_hdf5 is passed and the original table is a ' + 'BIOM table with collapsed observations, this will ' + 'update the observation metadata of the table ' + 'to the supported HDF5 collapsed format.') +@click.option('--header-key', required=False, type=click.STRING, + help='The observation metadata to include from the input ' + 'BIOM table file when creating a tsv table file. ' + 'By default no observation metadata will be included.') +@click.option('--output-metadata-id', required=False, type=click.STRING, + help='The name to be given to the observation metadata ' + 'column when creating a tsv table file if the column ' + 'should be renamed.') +@click.option('--table-type', required=False, + type=click.Choice(table_types), + help='The type of the table.') +@click.option('--process-obs-metadata', required=False, + type=click.Choice( + observation_metadata_types), + help='Process metadata associated with observations when ' + 'converting from a classic table.') +@click.option('--tsv-metadata-formatter', required=False, + default='sc_separated', + type=click.Choice( + observation_metadata_formatters), + help='Method for formatting the observation metadata.') +def convert(input_fp, output_fp, sample_metadata_fp, observation_metadata_fp, + to_json, to_hdf5, to_tsv, collapsed_samples, + collapsed_observations, header_key, output_metadata_id, table_type, + process_obs_metadata, tsv_metadata_formatter): + """Convert to/from the BIOM table format. + + Convert between BIOM table formats. See examples here: + http://biom-format.org/documentation/biom_conversion.html + + Example usage: + + Convert a "classic" BIOM file (tab-separated text) to an HDF5 BIOM + formatted OTU table: + + $ biom convert -i table.txt -o table.biom --to-hdf5 + """ + if sum([to_tsv, to_hdf5, to_json]) > 1: + raise ValueError("--to-tsv, --to-json, and --to-hdf5 are mutually " + "exclusive. You can only pass one of these options.") + + table = load_table(input_fp) + if sample_metadata_fp is not None: + with open(sample_metadata_fp, 'U') as f: + sample_metadata_f = MetadataMap.from_file(f) + else: + sample_metadata_f = None + if observation_metadata_fp is not None: + with open(observation_metadata_fp, 'U') as f: + observation_metadata_f = MetadataMap.from_file(f) + else: + observation_metadata_f = None + + _convert(table, output_fp, sample_metadata_f, observation_metadata_f, + to_json, to_hdf5, to_tsv, collapsed_samples, + collapsed_observations, header_key, output_metadata_id, + table_type, process_obs_metadata, tsv_metadata_formatter) + + +def _convert(table, output_filepath, sample_metadata=None, + observation_metadata=None, to_json=False, to_hdf5=False, + to_tsv=False, collapsed_samples=False, + collapsed_observations=False, header_key=None, + output_metadata_id=None, table_type=None, + process_obs_metadata=None, tsv_metadata_formatter='sc_separated'): if sum([to_tsv, to_hdf5, to_json]) == 0: raise ValueError("Must specify an output format") diff --git a/biom/cli/table_head.py b/biom/cli/table_head.py new file mode 100644 index 00000000..9d924c7a --- /dev/null +++ b/biom/cli/table_head.py @@ -0,0 +1,46 @@ +# ---------------------------------------------------------------------------- +# Copyright (c) 2011-2013, The BIOM Format Development Team. +# +# Distributed under the terms of the Modified BSD License. +# +# The full license is in the file COPYING.txt, distributed with this software. +# ---------------------------------------------------------------------------- + +from __future__ import division + +import click + +from biom import load_table +from biom.cli import cli + + +@cli.command() +@click.option('-i', '--input-fp', required=True, + type=click.Path(exists=True, dir_okay=False), + help='The input BIOM table') +@click.option('-o', '--output-fp', default=None, + type=click.Path(writable=True), + help='An output file-path', required=False) +@click.option('-n', '--n-obs', default=5, type=int, + help="The number of observations to show", + required=False) +@click.option('-m', '--n-samp', default=5, type=int, + help="The number of samples to show", + required=False) +def head(input_fp, output_fp, n_obs, n_samp): + """Dump the first bit of a table. + + Example usage: + + Print out the upper left corner of a BIOM table to standard out: + + $ biom head -i table.biom + + """ + table = load_table(input_fp).head(n=n_obs, m=n_samp) + + if output_fp is None: + click.echo(str(table)) + else: + with open(output_fp, 'w') as fp: + fp.write(str(table)) diff --git a/biom/cli/table_normalizer.py b/biom/cli/table_normalizer.py index faa46e98..cad6ebf0 100755 --- a/biom/cli/table_normalizer.py +++ b/biom/cli/table_normalizer.py @@ -10,9 +10,57 @@ from __future__ import division +import click -def normalize_table(table, relative_abund=False, presence_absence=False, - axis='sample'): +from biom import load_table +from biom.cli import cli +from biom.cli.util import write_biom_table +from biom.util import HAVE_H5PY + + +@cli.command(name='normalize-table') +@click.option('-i', '--input-fp', required=True, + type=click.Path(exists=True, dir_okay=False), + help='The input BIOM table') +@click.option('-o', '--output-fp', default=None, + type=click.Path(writable=True), + help='An output file-path') +@click.option('-r', '--relative-abund', default=False, is_flag=True, + help='convert table to relative abundance', + required=False) +@click.option('-p', '--presence-absence', default=False, is_flag=True, + help='convert table to presence/absence', + required=False) +@click.option('-a', '--axis', default='sample', + type=click.Choice(['sample', 'observation']), + help='The axis to normalize over') +def normalize_table(input_fp, output_fp, relative_abund, presence_absence, + axis): + """Normalize a BIOM table. + + Normalize the values of a BIOM table through various methods. Relative + abundance will take the relative abundance of each observation in terms of + samples or observations. Presence absensece will convert observations to + 1's and 0's based on presence of the observation. + + Example usage: + + Normalizing a BIOM table to relative abundnace: + + $ biom normalize-table -i table.biom -r -o normalized_table.biom + + Converting a BIOM table to a presence/absence table: + + $ biom normalize-table -i table.biom -p -o converted_table.biom + """ + table = load_table(input_fp) + result = _normalize_table(table, relative_abund, presence_absence, axis) + + write_biom_table(result, 'hdf5' if HAVE_H5PY else 'json', output_fp) + + +def _normalize_table(table, relative_abund=False, presence_absence=False, + axis='sample'): if relative_abund is False and presence_absence is False: raise ValueError("Must specifiy a normalization type") elif relative_abund is True and presence_absence is True: diff --git a/biom/cli/table_subsetter.py b/biom/cli/table_subsetter.py index 99ba7f75..fa056f25 100644 --- a/biom/cli/table_subsetter.py +++ b/biom/cli/table_subsetter.py @@ -8,12 +8,83 @@ from __future__ import division -from biom.parse import get_axis_indices, direct_slice_data, direct_parse_key +import click + +from biom.cli import cli +from biom.parse import (get_axis_indices, direct_slice_data, direct_parse_key, + generatedby) from biom.table import Table -from biom.util import biom_open +from biom.util import biom_open, HAVE_H5PY + + +@cli.command(name='subset-table') +@click.option('-i', '--input-hdf5-fp', default=None, + type=click.Path(exists=True, dir_okay=False), + help='the input hdf5 BIOM table filepath to subset') +@click.option('-j', '--input-json-fp', default=None, + type=click.Path(exists=True, dir_okay=False), + help='the input json BIOM table filepath to subset') +@click.option('-a', '--axis', required=True, + type=click.Choice(['sample', 'observation']), + help='the axis to subset over, either sample or observation') +@click.option('-s', '--ids', required=True, + type=click.Path(exists=True, dir_okay=False), + help='a file containing a single column of IDs to retain ' + '(either sample IDs or observation IDs, depending on the ' + 'axis)') +@click.option('-o', '--output-fp', required=True, + type=click.Path(writable=True, dir_okay=False), + help='the output BIOM table filepath') +def subset_table(input_hdf5_fp, input_json_fp, axis, ids, output_fp): + """Subset a BIOM table. + + Subset a BIOM table, over either observations or samples, without fully + parsing it. This command is intended to assist in working with very large + tables when tight on memory, or as a lightweight way to subset a full + table. Currently, it is possible to produce tables with rows or columns + (observations or samples) that are fully zeroed. + + Example usage: + + Choose a subset of the observations in table.biom (JSON) and write them to + subset.biom: + + $ biom subset-table -j table.biom -a observations -s observation_ids.txt \ + -o subset.biom + + Choose a subset of the observations in table.biom (HDF5) and write them to + subset.biom: + + $ biom subset-table -i table.biom -a observations -s observation_ids.txt \ + -o subset.biom + + """ + if input_json_fp is not None: + with open(input_json_fp, 'U') as f: + input_json_fp = f.read() + + with open(ids, 'U') as f: + ids = [line.strip() for line in f] + + table, format_ = _subset_table(input_hdf5_fp, input_json_fp, axis, ids) + + if format_ == 'json': + with open(output_fp, 'w') as f: + for line in table: + f.write(line) + f.write('\n') + else: + if HAVE_H5PY: + import h5py + else: + # This should never be raised here + raise ImportError("h5py is not available, cannot write HDF5!") + + with h5py.File(output_fp, 'w') as f: + table.to_hdf5(f, generatedby()) -def subset_table(hdf5_biom, json_table_str, axis, ids): +def _subset_table(hdf5_biom, json_table_str, axis, ids): if axis not in ['sample', 'observation']: raise ValueError("Invalid axis '%s'. Must be either 'sample' or " "'observation'." % axis) diff --git a/biom/cli/table_summarizer.py b/biom/cli/table_summarizer.py index 08c46825..e3bc46e6 100644 --- a/biom/cli/table_summarizer.py +++ b/biom/cli/table_summarizer.py @@ -8,12 +8,52 @@ from __future__ import division -from biom.util import compute_counts_per_sample_stats -from numpy import std from operator import itemgetter +import click +from numpy import std + +from biom import load_table +from biom.cli import cli +from biom.util import compute_counts_per_sample_stats + + +@cli.command(name='summarize-table') +@click.option('-i', '--input-fp', required=True, + type=click.Path(exists=True, dir_okay=False), + help='The input BIOM table') +@click.option('-o', '--output-fp', default=None, + type=click.Path(writable=True, dir_okay=False), + help='An output file-path') +@click.option('--qualitative', default=False, is_flag=True, + help="Present counts as number of unique observation ids per" + " sample, rather than counts of observations per sample.") +@click.option('--observations', default=False, is_flag=True, + help="Summarize over observations") +def summarize_table(input_fp, output_fp, qualitative, observations): + """Summarize sample or observation data in a BIOM table. + + Provides details on the observation counts per sample, including summary + statistics, as well as metadata categories associated with samples and + observations. + + Example usage: + + Write a summary of table.biom to table_summary.txt: + + $ biom summarize-table -i table.biom -o table_summary.txt + + """ + table = load_table(input_fp) + result = _summarize_table(table, qualitative, observations) + if output_fp: + with open(output_fp, 'w') as fh: + fh.write(result) + else: + click.echo(result) + -def summarize_table(table, qualitative=False, observations=False): +def _summarize_table(table, qualitative=False, observations=False): lines = [] if observations: diff --git a/biom/cli/table_validator.py b/biom/cli/table_validator.py index 55bf1245..82c581d4 100644 --- a/biom/cli/table_validator.py +++ b/biom/cli/table_validator.py @@ -15,12 +15,49 @@ from operator import and_ from functools import reduce +import click import numpy as np +from biom.cli import cli from biom.util import HAVE_H5PY, biom_open, is_hdf5_file -def validate_table(input_fp, format_version=None, detailed_report=False): +@cli.command(name='validate-table') +@click.option('-i', '--input-fp', required=True, + type=click.Path(exists=True, dir_okay=False), + help='The input filpath to validate against the BIOM format' + ' specification') +@click.option('-f', '--format-version', default=None, + help='The specific format version to validate against') +@click.option('--detailed-report', is_flag=True, default=False, + help='Include more details in the output report') +def validate_table(input_fp, format_version, detailed_report): + """Validate a BIOM-formatted file. + + Test a file for adherence to the Biological Observation Matrix (BIOM) + format specification. This specification is defined at + http://biom-format.org + + Example usage: + + Validate the contents of table.biom for adherence to the BIOM format + specification + + $ biom validate-table -i table.biom + + """ + valid, report = _validate_table(input_fp, format_version, detailed_report) + click.echo("\n".join(report)) + if valid: + # apparently silence is too quiet to be golden. + click.echo("The input file is a valid BIOM-formatted file.") + sys.exit(0) + else: + click.echo("The input file is not a valid BIOM-formatted file.") + sys.exit(1) + + +def _validate_table(input_fp, format_version=None, detailed_report=False): result = TableValidator()(table=input_fp, format_version=format_version, detailed_report=detailed_report) return result['valid_table'], result['report_lines'] diff --git a/biom/cli/util.py b/biom/cli/util.py index 18d7602f..8b5c9725 100644 --- a/biom/cli/util.py +++ b/biom/cli/util.py @@ -6,6 +6,8 @@ # The full license is in the file COPYING.txt, distributed with this software. # ---------------------------------------------------------------------------- +from __future__ import division + import biom.util import biom.parse diff --git a/doc/index.rst b/doc/index.rst index 2dfd8640..45b8ac4c 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -67,6 +67,10 @@ To see a list of all ``biom`` commands, run:: biom +To enable Bash tab completion of ``biom`` commands, add the following line to ``$HOME/.bashrc`` (if on Linux) or ``$HOME/.bash_profile`` (if on Mac OS X):: + + eval "$(_BIOM_COMPLETE=source biom)" + Installing the ``biom`` R package ================================= diff --git a/scripts/biom b/scripts/biom deleted file mode 100755 index 085ad85f..00000000 --- a/scripts/biom +++ /dev/null @@ -1,460 +0,0 @@ -#!/usr/bin/env python - -#----------------------------------------------------------------------------- -# Copyright (c) 2011-2015, The BIOM Format Development Team. -# -# Distributed under the terms of the Modified BSD License. -# -# The full license is in the file COPYING.txt, distributed with this software. -#----------------------------------------------------------------------------- - -import click -import biom -import sys -import biom.cli -import biom.cli.table_converter -from biom.util import HAVE_H5PY -import biom.parse -import biom.util - - -@click.group() -@click.version_option(version=biom.__version__) -def cli(): - pass - -@cli.command(name='summarize-table') -@click.option('-i', '--input-fp', required=True, - type=click.Path(exists=True, dir_okay=False), - help='The input BIOM table') -@click.option('-o', '--output-fp', default=None, - type=click.Path(writable=True, dir_okay=False), - help='An output file-path') -@click.option('--qualitative', default=False, is_flag=True, - help="Present counts as number of unique observation ids per" - " sample, rather than counts of observations per sample.") -@click.option('--observations', default=False, is_flag=True, - help="Summarize over observations") -def summarize_table(input_fp, output_fp, qualitative, observations): - """Summarize sample or observation data in a BIOM table - - Provides details on the observation counts per sample, including summary - statistics, as well as metadata categories associated with samples and - observations. - - Example usage: - - Write a summary of table.biom to table_summary.txt: - - $ biom summarize-table -i table.biom -o table_summary.txt - - """ - table = biom.load_table(input_fp) - result = biom.cli.summarize_table(table, qualitative, observations) - if output_fp: - with open(output_fp, 'w') as fh: - fh.write(result) - else: - click.echo(result) - -@cli.command(name='add-metadata') -@click.option('-i', '--input-fp', required=True, - type=click.Path(exists=True, dir_okay=False), - help='The input BIOM table') -@click.option('-o', '--output-fp', required=True, - type=click.Path(exists=False, dir_okay=False), - help='The output BIOM table') -@click.option('-m', '--sample-metadata-fp', required=False, - type=click.Path(exists=True, dir_okay=False), - help='The sample metadata mapping file (will add sample ' - 'metadata to the input BIOM table, if provided).') -@click.option('--observation-metadata-fp', required=False, - type=click.Path(exists=True, dir_okay=False), - help='The observation metadata mapping file (will add ' - 'observation metadata to the input BIOM table, if ' - 'provided).') -@click.option('--sc-separated', required=False, type=click.STRING, - help='Comma-separated list of the metadata fields to split ' - 'on semicolons. This is useful for hierarchical data such ' - 'as taxonomy or functional categories.') -@click.option('--sc-pipe-separated', required=False, type=click.STRING, - help='Comma-separated list of the metadata fields to split ' - 'on semicolons and pipes ("|"). This is useful for ' - 'hierarchical data such as functional categories with ' - 'one-to-many mappings (e.g. x;y;z|x;y;w)).') -@click.option('--int-fields', required=False, type=click.STRING, - help='Comma-separated list of the metadata fields to cast ' - 'to integers. This is useful for integer data such as ' - '"DaysSinceStart".') -@click.option('--float-fields', required=False, type=click.STRING, - help='Comma-separated list of the metadata fields to cast ' - 'to floating point numbers. This is useful for real number ' - 'data such as "pH".') -@click.option('--sample-header', required=False, type=click.STRING, - help='Comma-separated list of the sample metadata field ' - 'names. This is useful if a header line is not provided ' - 'with the metadata, if you want to rename the fields, or ' - 'if you want to include only the first n fields where n is ' - 'the number of entries provided here.') -@click.option('--observation-header', required=False, type=click.STRING, - help='Comma-separated list of the observation metadata ' - 'field names. This is useful if a header line is not ' - 'provided with the metadata, if you want to rename the ' - 'fields, or if you want to include only the first n fields ' - 'where n is the number of entries provided here.') -@click.option('--output-as-json', default=not HAVE_H5PY, is_flag=True, - help='Write the output file in JSON format.') -def add_metadata(input_fp, output_fp, sample_metadata_fp, - observation_metadata_fp, sc_separated, sc_pipe_separated, - int_fields, float_fields, sample_header, observation_header, - output_as_json): - """Add metadata to a BIOM table - - Add sample and/or observation metadata to BIOM-formatted files. See - examples here: http://biom-format.org/documentation/adding_metadata.html - - Example usage: - - Add sample metadata to a BIOM table: - - $ biom add-metadata -i otu_table.biom -o table_with_sample_metadata.biom - -m sample_metadata.txt - """ - table = biom.load_table(input_fp) - if sample_metadata_fp is not None: - sample_metadata_f = open(sample_metadata_fp, 'U') - else: - sample_metadata_f = None - if observation_metadata_fp is not None: - observation_metadata_f = open(observation_metadata_fp, 'U') - else: - observation_metadata_f = None - if sc_separated is not None: - sc_separated = sc_separated.split(',') - if sc_pipe_separated is not None: - sc_pipe_separated = sc_pipe_separated.split(',') - if int_fields is not None: - int_fields = int_fields.split(',') - if float_fields is not None: - float_fields = float_fields.split(',') - if sample_header is not None: - sample_header = sample_header.split(',') - if observation_header is not None: - observation_header = observation_header.split(',') - - result = biom.cli.add_metadata(table, sample_metadata_f, - observation_metadata_f, - sc_separated, - sc_pipe_separated, - int_fields, - float_fields, - sample_header, - observation_header) - - if output_as_json: - fmt = 'json' - else: - fmt = 'hdf5' - - biom.cli.write_biom_table(result, fmt, output_fp) - - -@cli.command(name='convert') -@click.option('-i', '--input-fp', required=True, - type=click.Path(exists=True, dir_okay=False), - help='The input BIOM table') -@click.option('-o', '--output-fp', required=True, - type=click.Path(exists=False, dir_okay=False), - help='The output BIOM table') -@click.option('-m', '--sample-metadata-fp', required=False, - type=click.Path(exists=True, dir_okay=False), - help='The sample metadata mapping file (will add sample ' - 'metadata to the input BIOM table, if provided).') -@click.option('--observation-metadata-fp', required=False, - type=click.Path(exists=True, dir_okay=False), - help='The observation metadata mapping file (will add ' - 'observation metadata to the input BIOM table, if ' - 'provided).') -@click.option('--to-json', default=False, is_flag=True, - help='Output as JSON-formatted table.') -@click.option('--to-hdf5', default=False, is_flag=True, - help='Output as HDF5-formatted table.') -@click.option('--to-tsv', default=False, is_flag=True, - help='Output as TSV-formatted (classic) table.') -@click.option('--collapsed-samples', default=False, is_flag=True, - help='If --to_hdf5 is passed and the original table is a ' - 'BIOM table with collapsed samples, this will ' - 'update the sample metadata of the table to ' - 'the supported HDF5 collapsed format.') -@click.option('--collapsed-observations', default=False, is_flag=True, - help='If --to_hdf5 is passed and the original table is a ' - 'BIOM table with collapsed observations, this will ' - 'update the observation metadata of the table ' - 'to the supported HDF5 collapsed format.') -@click.option('--header-key', required=False, type=click.STRING, - help='The observation metadata to include from the input ' - 'BIOM table file when creating a tsv table file. ' - 'By default no observation metadata will be included.') -@click.option('--output-metadata-id', required=False, type=click.STRING, - help='The name to be given to the observation metadata ' - 'column when creating a tsv table file if the column ' - 'should be renamed.') -@click.option('--table-type', required=False, - type=click.Choice(biom.cli.table_converter.table_types), - help='The type of the table.') -@click.option('--process-obs-metadata', required=False, - type=click.Choice( - biom.cli.table_converter.observation_metadata_types), - help='Process metadata associated with observations when ' - 'converting from a classic table.') -@click.option('--tsv-metadata-formatter', required=False, - default='sc_separated', - type=click.Choice( - biom.cli.table_converter.observation_metadata_formatters), - help='Method for formatting the observation metadata.') -def convert(input_fp, output_fp, sample_metadata_fp, observation_metadata_fp, - to_json, to_hdf5, to_tsv, collapsed_samples, - collapsed_observations, header_key, output_metadata_id, table_type, - process_obs_metadata, tsv_metadata_formatter): - """Convert to/from the BIOM table format - - Convert between BIOM table formats. See examples here: - http://biom-format.org/documentation/biom_conversion.html - - Example usage: - - Convert a "classic" BIOM file (tab-separated text) to an HDF5 BIOM - formatted OTU table: - - $ biom convert -i table.txt -o table.biom --to-hdf5 - """ - if to_json: - fmt = 'json' - elif to_hdf5: - fmt = 'hdf5' - elif to_tsv: - fmt = 'tsv' - else: - raise ValueError("Must provide one of --to-tsv, --to-json, or " - "--to-hdf5.") - if sum([to_tsv, to_hdf5, to_json]) > 1: - raise ValueError("--to-tsv, --to-json, and --to-hdf5 are mutually " - "exclusive. You can only pass one of these options.") - - table = biom.load_table(input_fp) - if sample_metadata_fp is not None: - with open(sample_metadata_fp, 'U') as f: - sample_metadata_f = biom.parse.MetadataMap.from_file(f) - else: - sample_metadata_f = None - if observation_metadata_fp is not None: - with open(observation_metadata_fp, 'U') as f: - observation_metadata_f = biom.parse.MetadataMap.from_file(f) - else: - observation_metadata_f = None - - biom.cli.convert(table, output_fp, sample_metadata_f, - observation_metadata_f, - to_json, to_hdf5, to_tsv, collapsed_samples, - collapsed_observations, header_key, - output_metadata_id, table_type, - process_obs_metadata, tsv_metadata_formatter) - -@cli.command(name='show-install-info') -def show_install_info(): - """Provide information about the biom-format installation - - Provide information about the biom-format installation, including settings - pulled from the configuration file. For more details, see - http://biom-format.org - - Example usage: - - Display biom-format installation information: - - $ biom show-install-info - - """ - click.echo(biom.cli.show_install_info()) - - -@cli.command(name='subset-table') -@click.option( '-i', '--input-hdf5-fp', default=None, - type=click.Path(exists=True, dir_okay=False), - help='the input hdf5 BIOM table filepath to subset') -@click.option( '-j', '--input-json-fp', default=None, - type=click.Path(exists=True, dir_okay=False), - help='the input json BIOM table filepath to subset') -@click.option( '-a', '--axis', required=True, - type=click.Choice(['sample', 'observation']), - help='the axis to subset over, either sample or observation') -@click.option( '-s', '--ids', required=True, - type=click.Path(exists=True, dir_okay=False), - help='a file containing a single column of IDs to retain ' - '(either sample IDs or observation IDs, depending on the ' - 'axis)') -@click.option('-o', '--output-fp', required=True, - type=click.Path(writable=True, dir_okay=False), - help='the output BIOM table filepath') -def subset_table(input_hdf5_fp, input_json_fp, axis, ids, output_fp): - """Subset a BIOM table - - Subset a BIOM table, over either observations or samples, without fully - parsing it. This command is intended to assist in working with very large - tables when tight on memory, or as a lightweight way to subset a full - table. Currently, it is possible to produce tables with rows or columns - (observations or samples) that are fully zeroed. - - Example usage: - - Choose a subset of the observations in table.biom (JSON) and write them to - subset.biom: - - $ biom subset-table -j table.biom -a observations -s observation_ids.txt \ - -o subset.biom - - Choose a subset of the observations in table.biom (HDF5) and write them to - subset.biom: - - $ biom subset-table -i table.biom -a observations -s observation_ids.txt \ - -o subset.biom - - """ - if input_json_fp is not None: - with open(input_json_fp, 'U') as f: - input_json_fp = f.read() - - with open(ids, 'U') as f: - ids = [line.strip() for line in f] - - table, format_ = biom.cli.subset_table(input_hdf5_fp, input_json_fp, axis, - ids) - - if format_ == 'json': - with open(output_fp, 'w') as f: - for line in table: - f.write(line) - f.write('\n') - else: - if biom.util.HAVE_H5PY: - import h5py - else: - # This should never be raised here - raise ImportError("h5py is not available, cannot write HDF5!") - - with h5py.File(output_fp, 'w') as f: - table.to_hdf5(f, biom.parse.generatedby()) - - -@cli.command(name='normalize-table') -@click.option( '-i', '--input-fp', required=True, - type=click.Path(exists=True, dir_okay=False), - help='The input BIOM table') -@click.option('-o', '--output-fp', default=None, - type=click.Path(writable=True), - help='An output file-path') -@click.option('-r', '--relative-abund', default=False, is_flag=True, - help='convert table to relative abundance', - required=False) -@click.option('-p', '--presence-absence', default=False, is_flag=True, - help='convert table to presence/absence', - required=False) -@click.option('-a', '--axis', default='sample', - type=click.Choice(['sample', 'observation']), - help='The axis to normalize over') -def normalize_table(input_fp, output_fp, relative_abund, presence_absence, - axis): - """Normalize a BIOM table - - Normalize the values of a BIOM table through various methods. Relative - abundance will take the relative abundance of each observation in terms of - samples or observations. Presence absensece will convert observations to - 1's and 0's based on presence of the observation. - - Example usage: - - Normalizing a BIOM table to relative abundnace: - - $ biom normalize-table -i table.biom -r -o normalized_table.biom - - Converting a BIOM table to a presence/absence table: - - $ biom normalize-table -i table.biom -p -o converted_table.biom - """ - table = biom.load_table(input_fp) - result = biom.cli.normalize_table(table, relative_abund, presence_absence, - axis) - - biom.cli.write_biom_table(result, 'hdf5' if HAVE_H5PY else 'json', - output_fp) - - -@cli.command() -@click.option('-i', '--input-fp', required=True, - type=click.Path(exists=True, dir_okay=False), - help='The input BIOM table') -@click.option('-o', '--output-fp', default=None, - type=click.Path(writable=True), - help='An output file-path', required=False) -@click.option('-n', '--n-obs', default=5, type=int, - help="The number of observations to show", - required=False) -@click.option('-m', '--n-samp', default=5, type=int, - help="The number of samples to show", - required=False) -def head(input_fp, output_fp, n_obs, n_samp): - """Dump the first bit of a table - - Example usage: - - Print out the upper left corner of a BIOM table to standard out: - - $ biom head -i table.biom - """ - table = biom.load_table(input_fp).head(n=n_obs, m=n_samp) - - if output_fp is None: - click.echo(str(table)) - else: - with open(output_fp, 'w') as fp: - fp.write(str(table)) - - -@cli.command(name='validate-table') -@click.option('-i', '--input-fp', required=True, - type=click.Path(exists=True, dir_okay=False), - help='The input filpath to validate against the BIOM format' - ' specification') -@click.option('-f', '--format-version', default=None, - help='The specific format version to validate against') -@click.option('--detailed-report', is_flag=True, default=False, - help='Include more details in the output report') -def validate_table(input_fp, format_version, detailed_report): - """Validate a BIOM-formatted file - - Test a file for adherence to the Biological Observation Matrix (BIOM) - format specification. This specification is defined at - http://biom-format.org - - Example usage: - - Validate the contents of table.biom for adherence to the BIOM format - specification - - $ biom validate-table -i table.biom - - """ - valid, report = biom.cli.validate_table(input_fp, format_version, - detailed_report) - click.echo("\n".join(report)) - if valid: - # apparently silence is too quiet to be golden. - click.echo("The input file is a valid BIOM-formatted file.") - sys.exit(0) - else: - click.echo("The input file is not a valid BIOM-formatted file.") - sys.exit(1) - - -if __name__ == '__main__': - cli() diff --git a/setup.py b/setup.py index 8ce7e2f2..468599c3 100644 --- a/setup.py +++ b/setup.py @@ -10,7 +10,7 @@ # ---------------------------------------------------------------------------- import os -from setuptools import setup +from setuptools import setup, find_packages from setuptools.extension import Extension try: @@ -89,17 +89,18 @@ maintainer_email=__email__, url='http://www.biom-format.org', test_suite='nose.collector', - packages=['biom', - 'biom/cli' - ], + packages=find_packages(), + include_package_data=True, ext_modules=extensions, include_dirs=[np.get_include()], - scripts=['scripts/biom'], install_requires=["click", "numpy >= 1.3.0", "scipy >= 0.13.0"], extras_require={'test': ["nose >= 0.10.1", "flake8"], 'hdf5': ["h5py >= 2.2.0"] }, - classifiers=classifiers - ) + classifiers=classifiers, + entry_points=''' + [console_scripts] + biom=biom.cli:cli + ''') diff --git a/tests/test_cli/test_add_metadata.py b/tests/test_cli/test_add_metadata.py index 9ca126e7..c862b540 100644 --- a/tests/test_cli/test_add_metadata.py +++ b/tests/test_cli/test_add_metadata.py @@ -12,14 +12,14 @@ from unittest import TestCase, main import biom -from biom.cli import add_metadata +from biom.cli.metadata_adder import _add_metadata class TestAddMetadata(TestCase): def setUp(self): """Set up data for use in unit tests.""" - self.cmd = add_metadata + self.cmd = _add_metadata with tempfile.NamedTemporaryFile() as fh: fh.write(biom1) fh.flush() diff --git a/tests/test_cli/test_data/test.json b/tests/test_cli/test_data/test.json new file mode 100644 index 00000000..74cd4d3f --- /dev/null +++ b/tests/test_cli/test_data/test.json @@ -0,0 +1 @@ +{"id": "No Table ID","format": "Biological Observation Matrix 1.0.0","format_url": "http://biom-format.org","generated_by": "BIOM-Format 2.0.0-dev","date": "2014-06-02T10:08:43.174137", "type": "OTU table", "matrix_element_type": "float","shape": [5, 6],"data": [[0,2,1.0],[1,0,5.0],[1,1,1.0],[1,3,2.0],[1,4,3.0],[1,5,1.0],[2,2,1.0],[2,3,4.0],[2,5,2.0],[3,0,2.0],[3,1,1.0],[3,2,1.0],[3,5,1.0],[4,1,1.0],[4,2,1.0]],"rows": [{"id": "GG_OTU_1", "metadata": {"taxonomy": ["k__Bacteria", "p__Proteobacteria", "c__Gammaproteobacteria", "o__Enterobacteriales", "f__Enterobacteriaceae", "g__Escherichia", "s__"]}},{"id": "GG_OTU_2", "metadata": {"taxonomy": ["k__Bacteria", "p__Cyanobacteria", "c__Nostocophycideae", "o__Nostocales", "f__Nostocaceae", "g__Dolichospermum", "s__"]}},{"id": "GG_OTU_3", "metadata": {"taxonomy": ["k__Archaea", "p__Euryarchaeota", "c__Methanomicrobia", "o__Methanosarcinales", "f__Methanosarcinaceae", "g__Methanosarcina", "s__"]}},{"id": "GG_OTU_4", "metadata": {"taxonomy": ["k__Bacteria", "p__Firmicutes", "c__Clostridia", "o__Halanaerobiales", "f__Halanaerobiaceae", "g__Halanaerobium", "s__Halanaerobiumsaccharolyticum"]}},{"id": "GG_OTU_5", "metadata": {"taxonomy": ["k__Bacteria", "p__Proteobacteria", "c__Gammaproteobacteria", "o__Enterobacteriales", "f__Enterobacteriaceae", "g__Escherichia", "s__"]}}],"columns": [{"id": "Sample1", "metadata": {"LinkerPrimerSequence": "CATGCTGCCTCCCGTAGGAGT", "BarcodeSequence": "CGCTTATCGAGA", "Description": "human gut", "BODY_SITE": "gut"}},{"id": "Sample2", "metadata": {"LinkerPrimerSequence": "CATGCTGCCTCCCGTAGGAGT", "BarcodeSequence": "CATACCAGTAGC", "Description": "human gut", "BODY_SITE": "gut"}},{"id": "Sample3", "metadata": {"LinkerPrimerSequence": "CATGCTGCCTCCCGTAGGAGT", "BarcodeSequence": "CTCTCTACCTGT", "Description": "human gut", "BODY_SITE": "gut"}},{"id": "Sample4", "metadata": {"LinkerPrimerSequence": "CATGCTGCCTCCCGTAGGAGT", "BarcodeSequence": "CTCTCGGCCTGT", "Description": "human skin", "BODY_SITE": "skin"}},{"id": "Sample5", "metadata": {"LinkerPrimerSequence": "CATGCTGCCTCCCGTAGGAGT", "BarcodeSequence": "CTCTCTACCAAT", "Description": "human skin", "BODY_SITE": "skin"}},{"id": "Sample6", "metadata": {"LinkerPrimerSequence": "CATGCTGCCTCCCGTAGGAGT", "BarcodeSequence": "CTAACTACCAAT", "Description": "human skin", "BODY_SITE": "skin"}}]} diff --git a/tests/test_cli/test_show_install_info.py b/tests/test_cli/test_show_install_info.py index 37ac1d1c..35cd63a1 100644 --- a/tests/test_cli/test_show_install_info.py +++ b/tests/test_cli/test_show_install_info.py @@ -8,7 +8,7 @@ import unittest -from biom.cli import show_install_info +from biom.cli.installation_informer import _show_install_info class TestShowInstallInfo(unittest.TestCase): @@ -16,7 +16,7 @@ def test_default(self): # Not really sure what to specifically test here, as this information # will change on a per-install basis. Just make sure the code is being # exercised and we have some output. - obs = show_install_info() + obs = _show_install_info() self.assertTrue(len(obs) > 0) diff --git a/tests/test_cli/test_subset_table.py b/tests/test_cli/test_subset_table.py index 59f104b4..945f8053 100644 --- a/tests/test_cli/test_subset_table.py +++ b/tests/test_cli/test_subset_table.py @@ -11,7 +11,7 @@ import numpy.testing as npt -from biom.cli import subset_table +from biom.cli.table_subsetter import _subset_table from biom.parse import parse_biom_table from biom.util import HAVE_H5PY @@ -23,7 +23,7 @@ def setUp(self): def test_subset_samples(self): """Correctly subsets samples in a table.""" - obs = subset_table(json_table_str=self.biom_str1, axis='sample', + obs = _subset_table(json_table_str=self.biom_str1, axis='sample', ids=['f4', 'f2'], hdf5_biom=None) obs = parse_biom_table(list(obs[0])) self.assertEqual(len(obs.ids()), 2) @@ -33,7 +33,7 @@ def test_subset_samples(self): def test_subset_observations(self): """Correctly subsets observations in a table.""" - obs = subset_table(json_table_str=self.biom_str1, axis='observation', + obs = _subset_table(json_table_str=self.biom_str1, axis='observation', ids=['None2', '879972'], hdf5_biom=None) obs = parse_biom_table(list(obs[0])) self.assertEqual(len(obs.ids()), 9) @@ -44,14 +44,14 @@ def test_subset_observations(self): def test_invalid_input(self): """Correctly raises politically correct error upon invalid input.""" with self.assertRaises(ValueError): - subset_table(hdf5_biom=None, json_table_str=self.biom_str1, axis='foo', + _subset_table(hdf5_biom=None, json_table_str=self.biom_str1, axis='foo', ids=['f2', 'f4']) with self.assertRaises(ValueError): - subset_table(hdf5_biom=None, json_table_str=None, axis='sample', ids=['f2', 'f4']) + _subset_table(hdf5_biom=None, json_table_str=None, axis='sample', ids=['f2', 'f4']) with self.assertRaises(ValueError): - subset_table(json_table_str=self.biom_str1, hdf5_biom='foo', + _subset_table(json_table_str=self.biom_str1, hdf5_biom='foo', axis='sample', ids=['f2', 'f4']) @npt.dec.skipif(HAVE_H5PY is False, msg='H5PY is not installed') @@ -60,7 +60,7 @@ def test_subset_samples_hdf5(self): cwd = os.getcwd() if '/' in __file__: os.chdir(__file__.rsplit('/', 1)[0]) - obs = subset_table(hdf5_biom='test_data/test.biom', axis='sample', + obs = _subset_table(hdf5_biom='test_data/test.biom', axis='sample', ids=['Sample1', 'Sample2', 'Sample3'], json_table_str=None) os.chdir(cwd) @@ -77,7 +77,7 @@ def test_subset_observations_hdf5(self): cwd = os.getcwd() if '/' in __file__: os.chdir(__file__.rsplit('/', 1)[0]) - obs = subset_table(hdf5_biom='test_data/test.biom', axis='observation', + obs = _subset_table(hdf5_biom='test_data/test.biom', axis='observation', ids=['GG_OTU_1', 'GG_OTU_3', 'GG_OTU_5'], json_table_str=None) os.chdir(cwd) diff --git a/tests/test_cli/test_summarize_table.py b/tests/test_cli/test_summarize_table.py index 22902029..e7ad0455 100644 --- a/tests/test_cli/test_summarize_table.py +++ b/tests/test_cli/test_summarize_table.py @@ -8,7 +8,7 @@ # The full license is in the file COPYING.txt, distributed with this software. # ----------------------------------------------------------------------------- -from biom.cli import summarize_table +from biom.cli.table_summarizer import _summarize_table from biom.parse import load_table import tempfile @@ -27,14 +27,14 @@ def test_default(self): """ TableSummarizer functions as expected """ - result = summarize_table(self.biom1) + result = _summarize_table(self.biom1) self.assertEqual(result, summary_default) def test_qualitative(self): """ TableSummarizer functions as expected with qualitative=True """ - result = summarize_table(self.biom1, qualitative=True) + result = _summarize_table(self.biom1, qualitative=True) self.assertEqual(result, summary_qualitative) biom1 = ('{"id": "None","format": "Biological Observation Matrix 1.0.0",' diff --git a/tests/test_cli/test_table_converter.py b/tests/test_cli/test_table_converter.py index 8a092298..8448be2f 100644 --- a/tests/test_cli/test_table_converter.py +++ b/tests/test_cli/test_table_converter.py @@ -13,7 +13,8 @@ import numpy as np -from biom.cli import convert, write_biom_table +from biom.cli.table_converter import _convert +from biom.cli.util import write_biom_table from biom.parse import MetadataMap, load_table from biom.table import Table from biom import load_table @@ -26,7 +27,7 @@ class TableConverterTests(TestCase): def setUp(self): """Set up data for use in unit tests.""" - self.cmd = convert + self.cmd = _convert self.output_filepath = tempfile.NamedTemporaryFile().name with tempfile.NamedTemporaryFile('w') as fh: diff --git a/tests/test_cli/test_table_normalizer.py b/tests/test_cli/test_table_normalizer.py index 169ec34f..8e4feaf8 100755 --- a/tests/test_cli/test_table_normalizer.py +++ b/tests/test_cli/test_table_normalizer.py @@ -10,8 +10,10 @@ from unittest import TestCase, main +import os + import biom -from biom.cli.table_normalizer import normalize_table +from biom.cli.table_normalizer import _normalize_table from biom.parse import parse_biom_table from biom.util import HAVE_H5PY from biom.exception import UnknownAxisError @@ -21,8 +23,13 @@ class TableNormalizerTests(TestCase): def setUp(self): """initialize objects for use in tests""" - self.cmd = normalize_table + self.cmd = _normalize_table + + cwd = os.getcwd() + if '/' in __file__: + os.chdir(__file__.rsplit('/', 1)[0]) self.table = biom.load_table('test_data/test.json') + os.chdir(cwd) def test_bad_inputs(self): # relative_abund and pa