Skip to content

Commit a405729

Browse files
MRC: force read as volume
1 parent f391ee3 commit a405729

File tree

5 files changed

+36
-13
lines changed

5 files changed

+36
-13
lines changed

gridData/core.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ class Grid(object):
196196

197197
def __init__(self, grid=None, edges=None, origin=None, delta=None,
198198
metadata=None, interpolation_spline_order=3,
199-
file_format=None):
199+
file_format=None, **kwargs):
200200
# file formats are guessed from extension == lower case key
201201
self._exporters = {
202202
'DX': self._export_dx,
@@ -238,7 +238,7 @@ def __init__(self, grid=None, edges=None, origin=None, delta=None,
238238
filename = str(grid)
239239

240240
if filename is not None:
241-
self.load(filename, file_format=file_format)
241+
self.load(filename, file_format=file_format, **kwargs)
242242
else:
243243
self._load(grid, edges, metadata, origin, delta)
244244

@@ -532,7 +532,7 @@ def _load(
532532
"grid={0} edges={1} origin={2} delta={3}".format(
533533
grid, edges, origin, delta))
534534

535-
def load(self, filename, file_format=None):
535+
def load(self, filename, file_format=None, **kwargs):
536536
"""Load saved grid and edges from `filename`
537537
538538
The :meth:`load` method calls the class's constructor method and
@@ -545,32 +545,32 @@ def load(self, filename, file_format=None):
545545
# are not really a file
546546
raise IOError(errno.ENOENT, "file not found", filename)
547547
loader = self._get_loader(filename, file_format=file_format)
548-
loader(filename)
548+
loader(filename, **kwargs)
549549

550-
def _load_python(self, filename):
550+
def _load_python(self, filename, **kwargs):
551551
with open(filename, 'rb') as f:
552552
saved = pickle.load(f)
553553
self._load(grid=saved['grid'],
554554
edges=saved['edges'],
555555
metadata=saved['metadata'])
556556

557-
def _load_mrc(self, filename):
557+
def _load_mrc(self, filename, **kwargs):
558558
"""Initializes Grid from a MRC/CCP4 file."""
559-
mrcfile = mrc.MRC(filename)
559+
mrcfile = mrc.MRC(filename, **kwargs)
560560
grid, edges = mrcfile.histogramdd()
561561
self._load(grid=grid, edges=edges, metadata=self.metadata)
562562
# Store header for access from Grid object (undocumented)
563563
# https://github.com/MDAnalysis/GridDataFormats/pull/100#discussion_r782604833
564564
self._mrc_header = mrcfile.header.copy()
565565

566-
def _load_dx(self, filename):
566+
def _load_dx(self, filename, **kwargs):
567567
"""Initializes Grid from a OpenDX file."""
568568
dx = OpenDX.field(0)
569569
dx.read(filename)
570570
grid, edges = dx.histogramdd()
571571
self._load(grid=grid, edges=edges, metadata=self.metadata)
572572

573-
def _load_plt(self, filename):
573+
def _load_plt(self, filename, **kwargs):
574574
"""Initialize Grid from gOpenMol plt file."""
575575
g = gOpenMol.Plt()
576576
g.read(filename)

gridData/mrc.py

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,12 @@ class MRC(object):
4343
----------
4444
filename : str (optional)
4545
input file (or stream), can be compressed
46+
is_volume : bool (optional)
47+
Force input file to be interpreted as a volume. If None (default),
48+
use the MRC file header. If True, force the file to be read as a
49+
volume. If False, the file is intepreted as a 2D image stack and
50+
raise a ValueError.
51+
4652
4753
Raises
4854
------
@@ -86,17 +92,22 @@ class MRC(object):
8692
8793
"""
8894

89-
def __init__(self, filename=None):
95+
def __init__(self, filename=None, is_volume=None):
9096
self.filename = filename
9197
if filename is not None:
92-
self.read(filename)
98+
self.read(filename, is_volume)
9399

94-
def read(self, filename):
100+
def read(self, filename, is_volume=None):
95101
"""Populate the instance from the MRC/CCP4 file *filename*."""
96102
if filename is not None:
97103
self.filename = filename
98104
with mrcfile.open(filename) as mrc:
99-
if mrc.data is None or len(mrc.data.shape) != 3: #pragma: no cover
105+
if is_volume is None:
106+
is_volume = mrc.is_volume()
107+
elif is_volume:
108+
# non 3D volumes should always fail, regardless of is_volume value
109+
is_volume = mrc.data is not None and len(mrc.data.shape) == 3
110+
if not is_volume: #pragma: no cover
100111
raise ValueError(
101112
"MRC file {} is not a volumetric density.".format(filename))
102113
self.header = h = mrc.header.copy()

gridData/tests/datafiles/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
DX = importlib_resources.files(__name__) / 'test.dx'
88
DXGZ = importlib_resources.files(__name__) / 'test.dx.gz'
99
CCP4 = importlib_resources.files(__name__) / 'test.ccp4'
10+
ISPG_0 = importlib_resources.files(__name__) / "ispg_0.mrc"
1011
# from http://www.ebi.ac.uk/pdbe/coordinates/files/1jzv.ccp4
1112
# (see issue #57)
1213
CCP4_1JZV = importlib_resources.files(__name__) / '1jzv.ccp4'
3.48 MB
Binary file not shown.

gridData/tests/test_mrc.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,17 @@ def test_triclinic_ValueError():
113113
"supported, not"):
114114
Grid(datafiles.MRC_EMD3001, file_format="MRC")
115115

116+
def test_mrcfile_volume_check():
117+
with pytest.raises(ValueError, match="is not a volumetric density"):
118+
Grid(datafiles.ISPG_0)
119+
120+
def test_mrcfile_volume_force():
121+
Grid(datafiles.ISPG_0, is_volume=True)
122+
123+
def test_mrcfile_force_fail():
124+
with pytest.raises(ValueError, match="is not a volumetric density"):
125+
Grid(datafiles.CCP4_1JZV, is_volume=False)
126+
116127
class TestGridMRC():
117128
@pytest.fixture(scope="class")
118129
def grid(self):

0 commit comments

Comments
 (0)