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

Writes compressed output of given format #2221

Merged
merged 22 commits into from
Apr 5, 2019
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
3 changes: 2 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,11 @@ matrix:
- env: NAME="Doc"
MAIN_CMD="cd package && python setup.py"
SETUP_CMD="build_sphinx"
PYTHON_VERSION=3.7
BUILD_DOCS=true
BUILD_CMD="cd ${TRAVIS_BUILD_DIR}/package && python setup.py build_ext --inplace"
INSTALL_HOLE="false"
PIP_DEPENDENCIES="${PIP_DEPENDENCIES} sphinx-sitemap"
PIP_DEPENDENCIES="${PIP_DEPENDENCIES} sphinx==1.8.5 sphinx-sitemap"

- env: NAME="Lint"
PYLINTRC="${TRAVIS_BUILD_DIR}/package/.pylintrc"
Expand Down
1 change: 1 addition & 0 deletions package/AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ Chronological list of authors
- Daniele Padula
2019
- Ninad Bhat
- Fenil Suchak

External code
-------------
Expand Down
4 changes: 4 additions & 0 deletions package/CHANGELOG
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ Enhancements
distance_array. (Issue #2103, PR #2209)
* updated analysis.distances.contact_matrix to use capped_distance. (Issue #2102,
PR #2215)
* added functionality to write files in compressed form(gz,bz2). (Issue #2216,
PR #2221)

Changes
* added official support for Python 3.7 (PR #1963)
Expand Down Expand Up @@ -91,6 +93,8 @@ Fixes
* Fixed documentation of MDAnalysis.analysis.contacts
* Enforced consistent dtype (numpy.float32) of Universe.dimensions and
Timestep.dimensions for all Universes and Readers (Issue #2190, PR #2213)
* Fixed analysis.nucleic.hydroxyl() function: correctly recognize the
2'-hydroxyl hydrogen H2'; gave wrong results (Issue #2218)

Deprecations
* analysis.polymer.PersistenceLength no longer requires the perform_fit()
Expand Down
8 changes: 4 additions & 4 deletions package/MDAnalysis/analysis/nuclinfo.py
Original file line number Diff line number Diff line change
Expand Up @@ -704,10 +704,10 @@ def hydroxyl(universe, seg, i):
.. versionadded:: 0.7.6

"""
h = universe.select_atoms(" atom {0!s} {1!s} C1\' ".format(seg, i),
" atom {0!s} {1!s} C2\' ".format(seg, i),
" atom {0!s} {1!s} O2\' ".format(seg, i),
" atom {0!s} {1!s} H2\'\' ".format(seg, i))
h = universe.select_atoms("atom {0!s} {1!s} C1'".format(seg, i),
"atom {0!s} {1!s} C2'".format(seg, i),
"atom {0!s} {1!s} O2'".format(seg, i),
"atom {0!s} {1!s} H2'".format(seg, i))
try:
hydr = h.dihedral.value() % 360
except ValueError:
Expand Down
2 changes: 1 addition & 1 deletion package/MDAnalysis/coordinates/GRO.py
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,7 @@ def __init__(self, filename, convert_units=None, n_atoms=None, **kwargs):
w.write(u.atoms)

"""
self.filename = util.filename(filename, ext='gro')
self.filename = util.filename(filename, ext='gro', keep=True)
self.n_atoms = n_atoms
self.reindex = kwargs.pop('reindex', True)

Expand Down
19 changes: 7 additions & 12 deletions package/MDAnalysis/core/groups.py
Original file line number Diff line number Diff line change
Expand Up @@ -2975,7 +2975,7 @@ def improper(self):
"improper only makes sense for a group with exactly 4 atoms")
return topologyobjects.ImproperDihedral(self.ix, self.universe)

def write(self, filename=None, file_format="PDB",
def write(self, filename=None, file_format=None,
filenamefmt="{trjname}_{frame}", frames=None, **kwargs):
"""Write `AtomGroup` to a file.

Expand Down Expand Up @@ -3054,8 +3054,9 @@ def write(self, filename=None, file_format="PDB",
if filename is None:
trjname, ext = os.path.splitext(os.path.basename(trj.filename))
filename = filenamefmt.format(trjname=trjname, frame=trj.frame)
filename = util.filename(filename, ext=file_format.lower(), keep=True)

filename = util.filename(filename,
ext=file_format if file_format is not None else 'PDB',
keep=True)
# Some writer behave differently when they are given a "multiframe"
# argument. It is the case of the PDB writer tht writes models when
# "multiframe" is True.
Expand All @@ -3080,14 +3081,7 @@ def write(self, filename=None, file_format="PDB",
# Try and select a Class using get_ methods (becomes `writer`)
# Once (and if!) class is selected, use it in with block
try:
# format keyword works differently in get_writer and get_selection_writer
# here it overrides everything, in get_sel it is just a default
# apply sparingly here!
format = os.path.splitext(filename)[1][1:] # strip initial dot!
format = format or file_format
format = format.strip().upper()

writer = get_writer_for(filename, format=format, multiframe=multiframe)
writer = get_writer_for(filename, format=file_format, multiframe=multiframe)
except (ValueError, TypeError):
pass
else:
Expand All @@ -3106,7 +3100,8 @@ def write(self, filename=None, file_format="PDB",
try:
# here `file_format` is only used as default,
# anything pulled off `filename` will be used preferentially
writer = get_selection_writer_for(filename, file_format)
writer = get_selection_writer_for(filename,
file_format if file_format is not None else 'PDB')
except (TypeError, NotImplementedError):
pass
else:
Expand Down
1 change: 1 addition & 0 deletions package/MDAnalysis/lib/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,7 @@ def filename(name, ext=None, keep=False):
Also permits :class:`NamedStream` to pass through.
"""
if ext is not None:
ext = ext.lower()
if not ext.startswith(os.path.extsep):
ext = os.path.extsep + ext
root, origext = os.path.splitext(name)
Expand Down
72 changes: 38 additions & 34 deletions testsuite/MDAnalysisTests/analysis/test_nuclinfo.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
import MDAnalysis as mda
import pytest
from MDAnalysis.analysis import nuclinfo
from MDAnalysisTests.datafiles import NUCL
from MDAnalysisTests.datafiles import RNA_PSF, RNA_PDB
from numpy.testing import (
assert_almost_equal,
assert_allclose,
Expand All @@ -34,140 +34,144 @@

@pytest.fixture(scope='module')
def u():
return mda.Universe(NUCL)
return mda.Universe(RNA_PSF, RNA_PDB)


@pytest.mark.parametrize('i, bp, seg1, seg2, expected_value', (
(1, 2, 'RNAA', 'RNAA', 4.449),
(22, 23, 'RNAA', 'RNAA', 4.601)
( 1, 2, 'RNAA', 'RNAA', 4.3874702),
(22, 23, 'RNAA', 'RNAA', 4.1716404),
))
def test_wc_pair(u, i, bp, seg1, seg2, expected_value):
val = nuclinfo.wc_pair(u, i, bp, seg1=seg1, seg2=seg2)
assert_almost_equal(val, expected_value, decimal=3)


@pytest.mark.parametrize('i, bp, seg1, seg2, expected_value', (
(3, 17, 'RNAA', 'RNAA', 16.649),
(20, 5, 'RNAA', 'RNAA', 4.356)
( 3, 17, 'RNAA', 'RNAA', 15.06506),
(20, 5, 'RNAA', 'RNAA', 3.219116),
))
def test_minor_pair(u, i, bp, seg1, seg2, expected_value):
val = nuclinfo.minor_pair(u, i, bp, seg1=seg1, seg2=seg2)
assert_almost_equal(val, expected_value, decimal=3)


@pytest.mark.parametrize('i, bp, seg1, seg2, expected_value', (
(2, 12, 'RNAA', 'RNAA', 30.001),
(5, 9, 'RNAA', 'RNAA', 12.581)
(2, 12, 'RNAA', 'RNAA', 26.884272),
(5, 9, 'RNAA', 'RNAA', 13.578535),
))
def test_major_pair(u, i, bp, seg1, seg2, expected_value):
val = nuclinfo.major_pair(u, i, bp, seg1=seg1, seg2=seg2)
assert_almost_equal(val, expected_value, decimal=3)


@pytest.mark.parametrize('seg, i, expected_value', (
('RNAA', 9, 14.846),
('RNAA', 21, 16.199)
('RNAA', 9, 3.16497),
('RNAA', 21, 22.07721),
))
def test_phase_cp(u, seg, i, expected_value):
val = nuclinfo.phase_cp(u, seg=seg, i=i)
assert_almost_equal(val, expected_value, decimal=3)


@pytest.mark.parametrize('seg, i, expected_value', (
('RNAA', 1, 8.565),
('RNAA', 11, 151.397)
('RNAA', 1, 359.57580),
('RNAA', 11, 171.71645),
))
def test_phase_as(u, seg, i, expected_value):
val = nuclinfo.phase_as(u, seg=seg, i=i)
assert_almost_equal(val, expected_value, decimal=3)


@pytest.mark.parametrize('seg, i, expected_value', (
('RNAA', 5, [296.103016, 179.084427, 47.712818, 81.49588, 205.350479,
284.046562, 198.58165]),
('RNAA', 21, [300.047634, 172.476593, 50.744877, 82.144211, 206.106445,
286.208565, 195.652176])
('RNAA', 5, [302.203802, 179.043077, 35.271411, 79.499729, 201.000393,
282.14321 , 210.709327]),
('RNAA', 21, [280.388619, 185.12919 , 56.616215, 64.87354 , 187.153367,
279.340915, 215.332144]),
))
def test_tors(u, seg, i, expected_value):
val = nuclinfo.tors(u, seg=seg, i=i)
assert_allclose(val, expected_value, rtol=1e-03)


@pytest.mark.parametrize('seg, i, expected_value', (
('RNAA', 6, 299.278),
('RNAA', 18, 304.093)
('RNAA', 6, 279.15103),
('RNAA', 18, 298.09936),
))
def test_tors_alpha(u, seg, i, expected_value):
val = nuclinfo.tors_alpha(u, seg=seg, i=i)
assert_almost_equal(val, expected_value, decimal=3)


@pytest.mark.parametrize('seg, i, expected_value', (
('RNAA', 7, 177.041),
('RNAA', 15, 162.441)
('RNAA', 7, 184.20501),
('RNAA', 15, 169.70042),
))
def test_tors_beta(u, seg, i, expected_value):
val = nuclinfo.tors_beta(u, seg=seg, i=i)
assert_almost_equal(val, expected_value, decimal=3)


@pytest.mark.parametrize('seg, i, expected_value', (
('RNAA', 7, 47.201),
('RNAA', 15, 64.276)
('RNAA', 7, 52.72022),
('RNAA', 15, 54.59684),
))
def test_tors_gamma(u, seg, i, expected_value):
val = nuclinfo.tors_gamma(u, seg=seg, i=i)
assert_almost_equal(val, expected_value, decimal=3)


@pytest.mark.parametrize('seg, i, expected_value', (
('RNAA', 7, 80.223),
('RNAA', 15, 81.553)
('RNAA', 7, 84.80554),
('RNAA', 15, 82.00043),
))
def test_tors_delta(u, seg, i, expected_value):
val = nuclinfo.tors_delta(u, seg=seg, i=i)
assert_almost_equal(val, expected_value, decimal=3)


@pytest.mark.parametrize('seg, i, expected_value', (
('RNAA', 7, 207.476),
('RNAA', 15, 202.352)
('RNAA', 7, 200.40990),
('RNAA', 15, 210.96953),
))
def test_tors_eps(u, seg, i, expected_value):
val = nuclinfo.tors_eps(u, seg=seg, i=i)
assert_almost_equal(val, expected_value, decimal=3)


@pytest.mark.parametrize('seg, i, expected_value', (
('RNAA', 7, 289.429),
('RNAA', 15, 289.318)
('RNAA', 7, 297.84736),
('RNAA', 15, 330.24898)
))
def test_tors_zeta(u, seg, i, expected_value):
val = nuclinfo.tors_zeta(u, seg=seg, i=i)
assert_almost_equal(val, expected_value, decimal=3)


@pytest.mark.parametrize('seg, i, expected_value', (
('RNAA', 1, 198.601),
('RNAA', 2, 198.932)
('RNAA', 1, 177.12643),
('RNAA', 2, 212.08998),
('RNAA', 7, 209.56533),
('RNAA', 15, 209.32109),
))
def test_tors_chi(u, seg, i, expected_value):
val = nuclinfo.tors_chi(u, seg=seg, i=i)
assert_almost_equal(val, expected_value, decimal=3)


@pytest.mark.parametrize('seg, i, expected_value', (
('RNAA', 20, 122.689),
('RNAA', 5, 122.965)
('RNAA', 20, 103.07024),
('RNAA', 5, 156.62223),
('RNAA', 7 , 77.94538),
('RNAA', 15, 130.18539),
))
def test_hydroxyl(u, seg, i, expected_value):
val = nuclinfo.hydroxyl(u, seg=seg, i=i)
assert_almost_equal(val, expected_value, decimal=3)


@pytest.mark.parametrize('bp1, bp2, i, seg1, seg2, seg3, expected_value', (
(16, 2, 3, 'RNAA', 'RNAA', 'RNAA', 308.244),
(8, 9, 10, 'RNAA', 'RNAA', 'RNAA', 25.224),
(16, 2, 3, 'RNAA', 'RNAA', 'RNAA', 314.69804),
(8, 9, 10, 'RNAA', 'RNAA', 'RNAA', 34.50106),
))
def test_pseudo_dihe_baseflip(u, bp1, bp2, i, seg1, seg2, seg3, expected_value):
val = nuclinfo.pseudo_dihe_baseflip(u, bp1, bp2, i, seg1, seg2, seg3)
Expand Down
32 changes: 31 additions & 1 deletion testsuite/MDAnalysisTests/core/test_atomgroup.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ def test_write_frame_iterator(self, u, tmpdir, frames):

assert_array_almost_equal(new_positions, ref_positions)

@pytest.mark.parametrize('extension', ('xtc', 'dcd', 'pdb', 'xyz'))
@pytest.mark.parametrize('extension', ('xtc', 'dcd', 'pdb', 'xyz', 'PDB'))
def test_write_frame_none(self, u, tmpdir, extension):
destination = str(tmpdir / 'test.' + extension)
u.atoms.write(destination, frames=None)
Expand All @@ -167,6 +167,26 @@ def test_write_frame_none(self, u, tmpdir, extension):
u.atoms.positions[None, ...], new_positions, decimal=2
)

@pytest.mark.parametrize('extension', ('xtc', 'dcd', 'pdb', 'xyz', 'PDB'))
def test_compressed_write_frame_none(self, u, tmpdir, extension):
for ext in ('.gz', '.bz2'):
destination = str(tmpdir / 'test.' + extension + ext)
u.atoms.write(destination, frames=None)
u_new = mda.Universe(destination)
new_positions = np.stack([ts.positions for ts in u_new.trajectory])
assert_array_almost_equal(
u.atoms.positions[None, ...], new_positions, decimal=2
fenilsuchak marked this conversation as resolved.
Show resolved Hide resolved
)

def test_compressed_write_frames_all(self, u, tmpdir):
for ext in ('.gz', '.bz2'):
destination = str(tmpdir / 'test.dcd') + ext
u.atoms.write(destination, frames='all')
u_new = mda.Universe(destination)
ref_positions = np.stack([ts.positions for ts in u.trajectory])
new_positions = np.stack([ts.positions for ts in u_new.trajectory])
assert_array_almost_equal(new_positions, ref_positions)

def test_write_frames_all(self, u, tmpdir):
destination = str(tmpdir / 'test.dcd')
u.atoms.write(destination, frames='all')
Expand Down Expand Up @@ -238,6 +258,16 @@ def test_write_atoms(self, universe, outfile):
err_msg=("atom coordinate mismatch between original and {0!s} file"
"".format(self.ext)))

def test_compressed_write_atoms(self, universe, outfile):
for compressed_ext in ('.gz', '.bz2'):
universe.atoms.write(outfile + compressed_ext)
u2 = self.universe_from_tmp(outfile + compressed_ext)
assert_almost_equal(
universe.atoms.positions, u2.atoms.positions,
self.precision,
err_msg=("atom coordinate mismatch between original and {0!s} file"
"".format(self.ext)))

def test_write_empty_atomgroup(self, universe, outfile):
sel = universe.select_atoms('name doesntexist')
with pytest.raises(IndexError):
Expand Down
18 changes: 10 additions & 8 deletions testsuite/MDAnalysisTests/core/test_atomselections.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
PSF, DCD,
PRMpbc, TRJpbc_bz2,
PSF_NAMD, PDB_NAMD,
GRO, NUCL, NUCLsel, TPR, XTC,
GRO, RNA_PSF, NUCLsel, TPR, XTC,
TRZ_psf, TRZ,
PDB_icodes,
PDB_HOLE,
Expand Down Expand Up @@ -449,20 +449,22 @@ def test_molnum(self, universe, selection_string, reference):


class TestSelectionsNucleicAcids(object):
@pytest.fixture()
@pytest.fixture(scope='class')
def universe(self):
return MDAnalysis.Universe(NUCL)
return MDAnalysis.Universe(RNA_PSF)

@pytest.fixture(scope='class')
def universe2(self):
return MDAnalysis.Universe(NUCLsel)


def test_nucleic(self, universe):
rna = universe.select_atoms("nucleic")
assert_equal(rna.n_atoms, 739)
assert_equal(rna.n_residues, 23)

def test_nucleic_all(self, universe):
u = mda.Universe(NUCLsel)

sel = u.select_atoms('nucleic')

def test_nucleic_all(self, universe2):
sel = universe2.select_atoms('nucleic')
assert len(sel) == 34

def test_nucleicbackbone(self, universe):
Expand Down
Loading