Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

REF: remove biom script; make commands importable and tab-completable #672

Merged
merged 3 commits into from
Oct 20, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 3 additions & 5 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,15 @@ language: python
env:
- PYTHON_VERSION=2.7 USE_H5PY=True NOSE_ARGS="--with-doctest --with-coverage"
- PYTHON_VERSION=2.7 USE_CYTHON=True NOSE_ARGS="--with-doctest --with-coverage"
- PYTHON_VERSION=3.4 USE_H5PY=True
- PYTHON_VERSION=3.4 USE_H5PY=True
- PYTHON_VERSION=3.4 USE_CYTHON=True
- PYTHON_VERSION=3.5 USE_H5PY=True
- PYTHON_VERSION=3.5 USE_CYTHON=True
before_install:
- wget http://repo.continuum.io/miniconda/Miniconda3-3.7.3-Linux-x86_64.sh -O miniconda.sh
- wget https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh -O miniconda.sh
- chmod +x miniconda.sh
- ./miniconda.sh -b
- export PATH=/home/travis/miniconda3/bin:$PATH
# Update conda itself
- conda update --yes conda
install:
- conda create --yes -n env_name python=$PYTHON_VERSION pip click numpy scipy nose pep8 flake8 coverage future
- if [ ${USE_CYTHON} ]; then conda install --yes -n env_name cython; fi
Expand All @@ -24,7 +22,7 @@ install:
- pip install -e . --no-deps
script:
- nosetests ${NOSE_ARGS}
- flake8 biom setup.py scripts
- flake8 biom setup.py
- biom show-install-info
- if [ ${PYTHON_VERSION} = "2.7" ]; then make -C doc html; fi
# we can only validate the tables if we have H5PY
Expand Down
1 change: 0 additions & 1 deletion MANIFEST.in
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ include ChangeLog.md
graft biom
graft support_files
graft examples
graft scripts
graft doc

prune docs/_build
Expand Down
32 changes: 21 additions & 11 deletions biom/cli/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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')
22 changes: 22 additions & 0 deletions biom/cli/installation_informer.py
Original file line number Diff line number Diff line change
Expand Up @@ -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())
Expand Down
111 changes: 107 additions & 4 deletions biom/cli/metadata_adder.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand All @@ -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 '
Expand Down
109 changes: 103 additions & 6 deletions biom/cli/table_converter.py
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -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")
Expand Down
Loading