Skip to content

Commit af4801a

Browse files
authored
Merge pull request #106 from gibsramen/quiet
Suppression of warnings and (optionally) output
2 parents f4bda67 + c478fa9 commit af4801a

File tree

9 files changed

+130
-10
lines changed

9 files changed

+130
-10
lines changed

scripts/songbird

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,22 @@
11
#!/usr/bin/env python3
22
import os
3-
import tensorflow as tf
4-
from tensorboard.plugins.hparams import api as hp
53
import pandas as pd
64
import numpy as np
75
from biom import load_table
86
import click
97
from skbio.stats.composition import clr, clr_inv
108
from songbird.multinomial import MultRegression
11-
from songbird.util import read_metadata, match_and_filter, split_training
9+
from songbird.util import (read_metadata, match_and_filter, split_training,
10+
silence_output)
1211
from songbird.parameter_info import DESCS, DEFAULTS
12+
import warnings
13+
14+
with warnings.catch_warnings():
15+
warnings.filterwarnings("ignore", category=FutureWarning)
16+
from tensorboard.plugins.hparams import api as hp
17+
import tensorflow as tf
18+
19+
warnings.filterwarnings("ignore", category=RuntimeWarning)
1320

1421

1522
@click.group()
@@ -106,6 +113,12 @@ def songbird():
106113
help=DESCS["random-seed"],
107114
type=int,
108115
)
116+
@click.option(
117+
"--silent/--no-silent",
118+
default=DEFAULTS["silent"],
119+
show_default=True,
120+
help=DESCS["silent"],
121+
)
109122
def multinomial(
110123
input_biom,
111124
metadata_file,
@@ -123,7 +136,11 @@ def multinomial(
123136
summary_interval,
124137
summary_dir,
125138
random_seed,
139+
silent,
126140
):
141+
if silent:
142+
silence_output()
143+
127144
# load metadata and tables
128145
metadata = read_metadata(metadata_file)
129146
table = load_table(input_biom)
@@ -146,6 +163,7 @@ def multinomial(
146163
'learning_rate': learning_rate,
147164
'min_sample_count': min_sample_count,
148165
'min_feature_count': min_feature_count,
166+
'silent': silent,
149167
}
150168
if random_seed is not None:
151169
hparams.update({
@@ -181,6 +199,7 @@ def multinomial(
181199
epochs=epochs,
182200
summary_interval=summary_interval,
183201
checkpoint_interval=checkpoint_interval,
202+
silent=silent,
184203
)
185204

186205
summary_writer = tf.contrib.summary.create_file_writer(summary_dir)

scripts/test_songbird_cli.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,40 @@ def setUp(self) -> None:
2222
def tearDown(self) -> None:
2323
shutil.rmtree(self.path)
2424

25+
def test_cli_silent(self):
26+
runner = CliRunner()
27+
test_args = ['--input-biom', 'data/redsea/redsea.biom',
28+
'--metadata-file', 'data/redsea/redsea_metadata.txt',
29+
'--formula',
30+
'Depth+Temperature+Salinity+Oxygen+Fluorescence'
31+
'+Nitrate',
32+
'--epochs', '100',
33+
'--differential-prior', '0.5',
34+
'--summary-interval', '1',
35+
'--summary-dir', self.path,
36+
'--silent']
37+
38+
result = runner.invoke(songbird.multinomial, test_args)
39+
40+
assert result.output == ""
41+
42+
def test_cli_not_silent(self):
43+
runner = CliRunner()
44+
test_args = ['--input-biom', 'data/redsea/redsea.biom',
45+
'--metadata-file', 'data/redsea/redsea_metadata.txt',
46+
'--formula',
47+
'Depth+Temperature+Salinity+Oxygen+Fluorescence'
48+
'+Nitrate',
49+
'--epochs', '100',
50+
'--differential-prior', '0.5',
51+
'--summary-interval', '1',
52+
'--summary-dir', self.path,
53+
'--no-silent']
54+
55+
result = runner.invoke(songbird.multinomial, test_args)
56+
57+
assert result.output != ""
58+
2559
def test_cli_no_seed_set(self):
2660
runner = CliRunner()
2761
test_args = ['--input-biom', 'data/redsea/redsea.biom',

songbird/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
1+
import warnings
2+
warnings.filterwarnings("ignore", category=FutureWarning)
13
__version__ = "1.0.1"

songbird/multinomial.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import tensorflow as tf
21
import os
2+
import tensorflow as tf
33
from tensorflow.contrib.distributions import Multinomial, Normal
44
from tqdm import tqdm
55
import time
@@ -135,7 +135,8 @@ def __call__(self, session, trainX, trainY, testX, testY):
135135
self.writer = None
136136
tf.global_variables_initializer().run()
137137

138-
def fit(self, epochs=10, summary_interval=100, checkpoint_interval=3600):
138+
def fit(self, epochs=10, summary_interval=100, checkpoint_interval=3600,
139+
silent=False):
139140
""" Fits the model.
140141
141142
Parameters
@@ -146,6 +147,10 @@ def fit(self, epochs=10, summary_interval=100, checkpoint_interval=3600):
146147
Number of seconds until a summary is recorded
147148
checkpoint_interval : int
148149
Number of seconds until a checkpoint is recorded
150+
silent : bool
151+
Flag denoting whether to suppress progress bar and TensorFlow
152+
warnings. If True, show neither progress bar nor warnings. If False
153+
(default), show both.
149154
150155
Returns
151156
-------
@@ -165,7 +170,12 @@ def fit(self, epochs=10, summary_interval=100, checkpoint_interval=3600):
165170
cv = []
166171
iter_n = []
167172

168-
for i in tqdm(range(0, num_iter)):
173+
if silent:
174+
iter_range = range(0, num_iter)
175+
else:
176+
iter_range = tqdm(range(0, num_iter))
177+
178+
for i in iter_range:
169179
now = time.time()
170180

171181
if now - last_summary_time > summary_interval:

songbird/parameter_info.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,11 @@
3636
"for it to be included in the analysis."
3737
),
3838
"summary-interval": "Number of seconds before storing a summary.",
39+
"silent": (
40+
'Flag denoting whether to hide progress bar and TensorFlow warnings. '
41+
'If False, progress bar and warnings are displayed. If True, neither '
42+
'progress bar nor warnings are displayed.'
43+
),
3944
# FYI: The following parameters are exclusive to the non-Q2 Songbird script
4045
"checkpoint-interval": 'Number of seconds before a saving a checkpoint.',
4146
"summary-dir": (
@@ -65,4 +70,5 @@
6570
"summary-interval": 10,
6671
"summary-dir": "summarydir",
6772
"random-seed": 0,
73+
"silent": False,
6874
}

songbird/q2/_method.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
import biom
21
import skbio
32
import qiime2
43
import pandas as pd
54
import numpy as np
5+
import biom
66
import tensorflow as tf
77
from skbio import OrdinationResults
88
from songbird.multinomial import MultRegression
9-
from songbird.util import match_and_filter, split_training
9+
from songbird.util import match_and_filter, split_training, silence_output
1010
from songbird.parameter_info import DEFAULTS
1111
from qiime2.plugin import Metadata
1212

@@ -27,10 +27,14 @@ def multinomial(table: biom.Table,
2727
min_feature_count: int = DEFAULTS["min-feature-count"],
2828
summary_interval: int = DEFAULTS["summary-interval"],
2929
random_seed: int = DEFAULTS["random-seed"],
30+
silent: bool = DEFAULTS["silent"],
3031
) -> (
3132
pd.DataFrame, qiime2.Metadata, skbio.OrdinationResults
3233
):
3334

35+
if silent:
36+
silence_output()
37+
3438
# load metadata and tables
3539
metadata = metadata.to_dataframe()
3640
# match them
@@ -53,14 +57,16 @@ def multinomial(table: biom.Table,
5357
beta_mean=differential_prior,
5458
batch_size=batch_size,
5559
save_path=None)
60+
5661
with tf.Graph().as_default(), tf.Session() as session:
5762
tf.set_random_seed(random_seed)
5863
model(session, trainX, trainY, testX, testY)
5964

6065
loss, cv, its = model.fit(
6166
epochs=epochs,
6267
summary_interval=summary_interval,
63-
checkpoint_interval=None)
68+
checkpoint_interval=None,
69+
silent=silent)
6470

6571
md_ids = np.array(design.columns)
6672
obs_ids = table.ids(axis='observation')

songbird/q2/plugin_setup.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
import qiime2.sdk
1111
from songbird import __version__
1212

13-
from qiime2.plugin import (Str, Properties, Int, Float, Metadata)
13+
from qiime2.plugin import (Str, Properties, Int, Float, Metadata, Bool)
1414
from q2_types.feature_table import FeatureTable, Frequency
1515
from q2_types.ordination import PCoAResults
1616
from q2_types.sample_data import SampleData
@@ -51,6 +51,7 @@
5151
'min_feature_count': Int,
5252
'summary_interval': Float,
5353
'random_seed': Int,
54+
'silent': Bool,
5455
},
5556
outputs=[
5657
('differentials', FeatureData[Differential]),
@@ -81,6 +82,9 @@
8182
"min_feature_count": DESCS["min-feature-count"],
8283
"summary_interval": DESCS["summary-interval"],
8384
"random_seed": DESCS["random-seed"],
85+
"silent": (DESCS["silent"] + " (Only has an impact when using this "
86+
"command with the --verbose option or through the Qiime2 "
87+
"Artifact API)"),
8488
},
8589
name='Multinomial regression',
8690
description=("Performs multinomial regression and calculates "

songbird/q2/tests/test_method.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import qiime2
22
import unittest
33
import numpy as np
4+
import contextlib
5+
import io
46
import tensorflow as tf
57
from songbird.q2._method import multinomial
68
from songbird.util import random_multinomial_model
@@ -27,6 +29,21 @@ def setUp(self):
2729

2830
self.table, self.md, self.beta = res
2931

32+
def _silent_helper(self, silent):
33+
tf.set_random_seed(0)
34+
md = self.md
35+
36+
md.name = 'sampleid'
37+
md = qiime2.Metadata(md)
38+
39+
f = io.StringIO()
40+
with contextlib.redirect_stderr(f):
41+
res_beta, res_stats, res_biplot = multinomial(
42+
table=self.table, metadata=md,
43+
min_sample_count=0, min_feature_count=0,
44+
formula="X", epochs=1000, silent=silent)
45+
return f
46+
3047
def test_fit(self):
3148
tf.set_random_seed(0)
3249
md = self.md
@@ -51,6 +68,14 @@ def test_fit(self):
5168
npt.assert_allclose(exp_beta, res_beta.T, atol=0.6, rtol=0.6)
5269
self.assertGreater(len(res_stats.to_dataframe().index), 1)
5370

71+
def test_silent(self):
72+
f = self._silent_helper(silent=True)
73+
assert f.getvalue() == ""
74+
75+
def test_not_silent(self):
76+
f = self._silent_helper(silent=False)
77+
assert f.getvalue() != ""
78+
5479
def test_fit_consistency(self):
5580
md = self.md
5681

songbird/util.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import os
2+
import tensorflow as tf
13
import numpy as np
24
import pandas as pd
35
from sklearn.utils import check_random_state
@@ -195,3 +197,15 @@ def split_training(dense_table, metadata, design, training_column=None,
195197
testY = dense_table.loc[~train_idx].values
196198

197199
return trainX, testX, trainY, testY
200+
201+
202+
def silence_output():
203+
# suppress profiling messages & compilation warnings
204+
# taken from:
205+
# https://stackoverflow.com/questions/47068709/your-cpu-supports-
206+
# instructions-that-this-tensorflow-binary-was-not-compiled-to-u
207+
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
208+
209+
# suppress deprecation warnings
210+
# taken from https://github.com/tensorflow/tensorflow/issues/27023
211+
tf.compat.v1.logging.set_verbosity(tf.compat.v1.logging.ERROR)

0 commit comments

Comments
 (0)