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

Fix FileNotFoundErrors to support windows #1

Open
wants to merge 14 commits into
base: windows
Choose a base branch
from
2 changes: 2 additions & 0 deletions ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ biom 2.1.15-dev

Performance improvements:

* Add Windows support. PR[#951](https://github.com/biocore/biom-format/pull/951) revises codebase to be Windows compatible and adds this support to the CI testing matrix.
* Add NumPy 2.0 support. PR [#950](https://github.com/biocore/biom-format/pull/950) ensures code compatibility with NumPy 2.0. This support is yet to be added to the CI testing matrix.
* Revise `Table._fast_merge` to use COO directly. For very large tables, this reduces runtime by ~50x and memory by ~5x. See PR [#913](https://github.com/biocore/biom-format/pull/933).
* Drastically reduce the memory needs of subsampling when sums are large. Also adds 64-bit support. See PR [#935](https://github.com/biocore/biom-format/pull/935).
* Improve handling of not-perfectly-integer inputs. See PR [#938](https://github.com/biocore/biom-format/pull/938).
Expand Down
1 change: 1 addition & 0 deletions biom/_filter.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ from types import FunctionType

import numpy as np
cimport numpy as cnp
cnp.import_array()


cdef cnp.ndarray[cnp.uint8_t, ndim=1] \
Expand Down
2 changes: 2 additions & 0 deletions biom/_subsample.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

import numpy as np
cimport numpy as cnp
cnp.import_array()


cdef _subsample_with_replacement(cnp.ndarray[cnp.float64_t, ndim=1] data,
cnp.ndarray[cnp.int32_t, ndim=1] indptr,
Expand Down
1 change: 1 addition & 0 deletions biom/_transform.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

import numpy as np
cimport numpy as cnp
cnp.import_array()


def _transform(arr, ids, metadata, function, axis):
Expand Down
7 changes: 6 additions & 1 deletion biom/tests/test_cli/test_add_metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
# -----------------------------------------------------------------------------

import tempfile
import os
from unittest import TestCase, main

import biom
Expand All @@ -20,13 +21,17 @@ class TestAddMetadata(TestCase):
def setUp(self):
"""Set up data for use in unit tests."""
self.cmd = _add_metadata
with tempfile.NamedTemporaryFile('w') as fh:
with tempfile.NamedTemporaryFile('w', delete=False) as fh:
fh.write(biom1)
fh.flush()
self.biom_table1 = biom.load_table(fh.name)
self.temporary_fh_name = fh.name
self.sample_md_lines1 = sample_md1.split('\n')
self.obs_md_lines1 = obs_md1.split('\n')

def tearDown(self):
os.unlink(self.temporary_fh_name)

def test_add_sample_metadata_no_casting(self):
"""Correctly adds sample metadata without casting it."""
# Add a subset of sample metadata to a table that doesn't have any
Expand Down
13 changes: 7 additions & 6 deletions biom/tests/test_cli/test_subset_table.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,10 @@ def test_invalid_input(self):
def test_subset_samples_hdf5(self):
"""Correctly subsets samples in a hdf5 table"""
cwd = os.getcwd()
if '/' in __file__:
os.chdir(__file__.rsplit('/', 1)[0])
obs = _subset_table(hdf5_biom='test_data/test.biom', axis='sample',
if os.path.sep in __file__:
os.chdir(os.path.dirname(__file__))
obs = _subset_table(hdf5_biom=os.path.join('test_data', 'test.biom'),
axis='sample',
ids=['Sample1', 'Sample2', 'Sample3'],
json_table_str=None)
os.chdir(cwd)
Expand All @@ -71,9 +72,9 @@ def test_subset_samples_hdf5(self):
def test_subset_observations_hdf5(self):
"""Correctly subsets samples in a hdf5 table"""
cwd = os.getcwd()
if '/' in __file__:
os.chdir(__file__.rsplit('/', 1)[0])
obs = _subset_table(hdf5_biom='test_data/test.biom',
if os.path.sep in __file__:
os.chdir(os.path.dirname(__file__))
obs = _subset_table(hdf5_biom=os.path.join('test_data', 'test.biom'),
axis='observation',
ids=['GG_OTU_1', 'GG_OTU_3', 'GG_OTU_5'],
json_table_str=None)
Expand Down
7 changes: 6 additions & 1 deletion biom/tests/test_cli/test_summarize_table.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,21 @@
from biom.parse import load_table

import tempfile
import os
from unittest import TestCase, main


class TestSummarizeTable(TestCase):

def setUp(self):
with tempfile.NamedTemporaryFile(mode='w') as fh:
with tempfile.NamedTemporaryFile(mode='w', delete=False) as fh:
fh.write(biom1)
fh.flush()
self.biom1 = load_table(fh.name)
self.temporary_fh_name = fh.name

def tearDown(self):
os.unlink(self.temporary_fh_name)

def test_default(self):
""" TableSummarizer functions as expected
Expand Down
11 changes: 9 additions & 2 deletions biom/tests/test_cli/test_table_converter.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
# The full license is in the file COPYING.txt, distributed with this software.
# -----------------------------------------------------------------------------

import os
from os.path import abspath, dirname, join
import tempfile

Expand All @@ -28,16 +29,18 @@ def setUp(self):
self.cmd = _convert
self.output_filepath = tempfile.NamedTemporaryFile().name

with tempfile.NamedTemporaryFile('w') as fh:
with tempfile.NamedTemporaryFile('w', delete=False) as fh:
fh.write(biom1)
fh.flush()
self.biom_table1 = load_table(fh.name)
self.temporary_fh_table_name = fh.name

self.biom_lines1 = biom1.split('\n')
with tempfile.NamedTemporaryFile('w') as fh:
with tempfile.NamedTemporaryFile('w', delete=False) as fh:
fh.write(classic1)
fh.flush()
self.classic_biom1 = load_table(fh.name)
self.temporary_fh_classic_name = fh.name

self.sample_md1 = MetadataMap.from_file(sample_md1.split('\n'))

Expand All @@ -47,6 +50,10 @@ def setUp(self):
self.json_collapsed_samples = join(test_data_dir,
'json_sample_collapsed.biom')

def tearDown(self):
os.unlink(self.temporary_fh_classic_name)
os.unlink(self.temporary_fh_table_name)

def test_classic_to_biom(self):
"""Correctly converts classic to biom."""
self.cmd(table=self.classic_biom1,
Expand Down
6 changes: 3 additions & 3 deletions biom/tests/test_cli/test_table_normalizer.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ def setUp(self):
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')
if os.path.sep in __file__:
os.chdir(os.path.dirname(__file__))
self.table = biom.load_table(os.path.join('test_data', 'test.json'))
os.chdir(cwd)

def test_bad_inputs(self):
Expand Down
3 changes: 2 additions & 1 deletion biom/tests/test_cli/test_validate_table.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ def setUp(self):
self.to_remove = []

cur_path = os.path.split(os.path.abspath(__file__))[0]
examples_path = os.path.join(cur_path.rsplit('/', 3)[0], 'examples')
examples_path = os.path.join(cur_path.rsplit(os.path.sep, 3)[0],
'examples')
self.hdf5_file_valid = os.path.join(examples_path,
'min_sparse_otu_table_hdf5.biom')
self.hdf5_file_valid_md = os.path.join(examples_path,
Expand Down
42 changes: 25 additions & 17 deletions biom/tests/test_parse.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,19 @@ def setUp(self):
self.legacy_otu_table1 = legacy_otu_table1
self.otu_table1 = otu_table1
self.otu_table1_floats = otu_table1_floats
self.files_to_remove = []
self.to_remove = []
self.biom_minimal_sparse = biom_minimal_sparse

self.classic_otu_table1_w_tax = classic_otu_table1_w_tax.split('\n')
self.classic_otu_table1_no_tax = classic_otu_table1_no_tax.split('\n')
self.classic_table_with_complex_metadata = \
classic_table_with_complex_metadata.split('\n')

def tearDown(self):
if self.to_remove:
for f in self.to_remove:
os.remove(f)

def test_from_tsv_bug_854(self):
data = StringIO('#FeatureID\tSample1')
exp = Table([], [], ['Sample1'])
Expand Down Expand Up @@ -281,38 +286,40 @@ def test_parse_adjacency_table_no_header(self):
def test_parse_biom_table_hdf5(self):
"""Make sure we can parse a HDF5 table through the same loader"""
cwd = os.getcwd()
if '/' in __file__[1:]:
os.chdir(__file__.rsplit('/', 1)[0])
Table.from_hdf5(h5py.File('test_data/test.biom', 'r'))
if os.path.sep in __file__[1:]:
os.chdir(os.path.dirname(__file__))
Table.from_hdf5(h5py.File(os.path.join('test_data', 'test.biom'),
'r'))
os.chdir(cwd)

def test_save_table_filepath(self):
t = Table(np.array([[0, 1, 2], [3, 4, 5]]), ['a', 'b'],
['c', 'd', 'e'])
with NamedTemporaryFile() as tmpfile:
with NamedTemporaryFile(delete=False) as tmpfile:
save_table(t, tmpfile.name)
obs = load_table(tmpfile.name)
self.assertEqual(obs, t)
self.to_remove.append(tmpfile.name)

def test_load_table_filepath(self):
cwd = os.getcwd()
if '/' in __file__[1:]:
os.chdir(__file__.rsplit('/', 1)[0])
load_table('test_data/test.biom')
if os.path.sep in __file__[1:]:
os.chdir(os.path.dirname(__file__))
load_table(os.path.join('test_data', 'test.biom'))
os.chdir(cwd)

def test_load_table_inmemory(self):
cwd = os.getcwd()
if '/' in __file__[1:]:
os.chdir(__file__.rsplit('/', 1)[0])
load_table(h5py.File('test_data/test.biom', 'r'))
if os.path.sep in __file__[1:]:
os.chdir(os.path.dirname(__file__))
load_table(h5py.File(os.path.join('test_data', 'test.biom'), 'r'))
os.chdir(cwd)

def test_load_table_inmemory_json(self):
cwd = os.getcwd()
if '/' in __file__[1:]:
os.chdir(__file__.rsplit('/', 1)[0])
load_table(open('test_data/test.json'))
if os.path.sep in __file__[1:]:
os.chdir(os.path.dirname(__file__))
load_table(open(os.path.join('test_data', 'test.json')))
os.chdir(cwd)

def test_load_table_inmemory_stringio(self):
Expand Down Expand Up @@ -350,10 +357,11 @@ def test_parse_biom_table_with_hdf5(self):
"""tests for parse_biom_table when we have h5py"""
# We will round-trip the HDF5 file to several different formats, and
# make sure we can recover the same table using parse_biom_table
if '/' in __file__[1:]:
os.chdir(__file__.rsplit('/', 1)[0])
if os.path.sep in __file__[1:]:
os.chdir(os.path.dirname(__file__))

t = parse_biom_table(h5py.File('test_data/test.biom', 'r'))
t = parse_biom_table(h5py.File(os.path.join('test_data', 'test.biom'),
'r'))

# These things are not round-trippable using the general-purpose
# parse_biom_table function
Expand Down
Loading