Skip to content
Open
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
27 changes: 27 additions & 0 deletions gridData/OpenDX.py
Original file line number Diff line number Diff line change
Expand Up @@ -523,6 +523,33 @@ def __init__(self,classid='0',components=None,comments=None):
self.components = components
self.comments= comments

@staticmethod
def from_grid(grid, type=None, typequote='"', **kwargs):
comments = [
"OpenDX density file written by gridDataFormats.Grid.export()",
"File format: http://opendx.sdsc.edu/docs/html/pages/usrgu068.htm#HDREDF",
"Data are embedded in the header and tied to the grid positions.",
"Data is written in C array order: In grid[x,y,z] the axis z is fastest",
"varying, then y, then finally x, i.e. z is the innermost loop.",
]
if grid.metadata:
comments.append("Meta data stored with the python Grid object:")
for k in grid.metadata:
comments.append(" " + str(k) + " = " + str(grid.metadata[k]))
comments.append("(Note: the VMD dx-reader chokes on comments below this line)")

components = dict(
positions=gridpositions(1, grid.grid.shape, grid.origin, grid.delta),
connections=gridconnections(2, grid.grid.shape),
data=array(3, grid.grid, type=type, typequote=typequote),
)
dx_field = field('density', components=components, comments=comments)
return dx_field

@property
def native(self):
return self

def _openfile_writing(self, filename):
"""Returns a regular or gz file stream for writing"""
if filename.endswith('.gz'):
Expand Down
68 changes: 35 additions & 33 deletions gridData/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,12 @@ class Grid(object):

#: Default format for exporting with :meth:`export`.
default_format = 'DX'

converter = {
'MRC': mrc.MRC.from_grid,
'VDB': None,
'DX': OpenDX.field.from_grid,
}

def __init__(self, grid=None, edges=None, origin=None, delta=None,
metadata=None, interpolation_spline_order=3,
Expand Down Expand Up @@ -598,6 +604,32 @@ def _load_plt(self, filename, **kwargs):
grid, edges = g.histogramdd()
self._load(grid=grid, edges=edges, metadata=self.metadata)

def convert_to(self, format_specifier, tolerance=None, **kwargs):
"""Generates an instance of the native object for a given format

Implemented formats:

DX
:mod:`OpenDX`
MRC
:mod:`mrc` MRC/CCP4 format

Parameters
----------
format_specifier : str

tolerance : float (default is None)

Returns
-------
native object

"""
fmt_upper = format_specifier.upper()

wrapper = self.converter[fmt_upper](self, **kwargs)
return wrapper.native

def export(self, filename, file_format=None, type=None, typequote='"'):
"""export density to file using the given format.

Expand Down Expand Up @@ -673,29 +705,8 @@ def _export_dx(self, filename, type=None, typequote='"', **kwargs):
"""
root, ext = os.path.splitext(filename)
filename = root + '.dx'

comments = [
'OpenDX density file written by gridDataFormats.Grid.export()',
'File format: http://opendx.sdsc.edu/docs/html/pages/usrgu068.htm#HDREDF',
'Data are embedded in the header and tied to the grid positions.',
'Data is written in C array order: In grid[x,y,z] the axis z is fastest',
'varying, then y, then finally x, i.e. z is the innermost loop.']

# write metadata in comments section
if self.metadata:
comments.append('Meta data stored with the python Grid object:')
for k in self.metadata:
comments.append(' ' + str(k) + ' = ' + str(self.metadata[k]))
comments.append(
'(Note: the VMD dx-reader chokes on comments below this line)')

components = dict(
positions=OpenDX.gridpositions(1, self.grid.shape, self.origin,
self.delta),
connections=OpenDX.gridconnections(2, self.grid.shape),
data=OpenDX.array(3, self.grid, type=type, typequote=typequote),
)
dx = OpenDX.field('density', components=components, comments=comments)
dx = OpenDX.field.from_grid(self, type=type, typequote=typequote, **kwargs)

if ext == '.gz':
filename = root + ext
dx.write(filename)
Expand All @@ -721,16 +732,7 @@ def _export_mrc(self, filename, **kwargs):

.. versionadded:: 1.1.0
"""
# Create MRC object and populate with Grid data
mrc_file = mrc.MRC()
mrc_file.array = self.grid
mrc_file.delta = numpy.diag(self.delta)
mrc_file.origin = self.origin
mrc_file.rank = 3

# Transfer header if it exists (preserves axis ordering and other metadata)
if hasattr(self, '_mrc_header'):
mrc_file.header = self._mrc_header
mrc_file = mrc.MRC.from_grid(self, **kwargs)

# Write to file
mrc_file.write(filename)
Expand Down
19 changes: 19 additions & 0 deletions gridData/mrc.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,25 @@ def __init__(self, filename=None, assume_volumetric=False):
self.filename = filename
if filename is not None:
self.read(filename, assume_volumetric=assume_volumetric)

@staticmethod
def from_grid(grid, **kwargs):
mrc_obj = MRC()

mrc_obj.array = grid.grid
mrc_obj.delta = np.diag(grid.delta)
mrc_obj.origin = grid.origin
mrc_obj.rank = 3

if hasattr(grid, "_mrc_header"):
mrc_obj.header = grid._mrc_header

return mrc_obj

@property
def native(self):
"""Native object is the MRC wrapper itself."""
return self

def read(self, filename, assume_volumetric=False):
"""Populate the instance from the MRC/CCP4 file *filename*."""
Expand Down
23 changes: 23 additions & 0 deletions gridData/tests/test_dx.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,3 +90,26 @@ def test_delta_precision(tmpdir):
g.delta, g2.delta,
decimal=7,
err_msg="deltas of written grid do not match original")

def test_dx_from_grid():
data = np.ones((5, 5, 5), dtype=np.float32)
g = Grid(data, origin=[1.0, 2.0, 3.0], delta=[0.5, 0.5, 0.5])
g.metadata['name'] = 'test_density'
g.metadata['author'] = 'test_user'

dx_field = gridData.OpenDX.field.from_grid(g)

assert isinstance(dx_field, gridData.OpenDX.field)

assert any('test_density' and 'test_user' in str(c) for c in dx_field.comments)
# assert any('test_user' in str(c) for c in dx_field.comments)

assert_equal(dx_field.components['data'].array, data)
assert_equal(dx_field.components['positions'].origin, g.origin)

def test_dx_native():
data = np.ones((5, 5, 5))
g = Grid(data, origin=[0, 0, 0], delta=[1, 1, 1])

dx_field = gridData.OpenDX.field.from_grid(g)
assert dx_field.native is dx_field
21 changes: 21 additions & 0 deletions gridData/tests/test_mrc.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,27 @@ def test_origin(self, grid, ccp4data):

def test_data(self, grid, ccp4data):
assert_allclose(grid.grid, ccp4data.array)

def test_mrc_from_grid(self):
data = np.arange(27, dtype=np.float32).reshape((3, 3, 3))
g = Grid(data, origin=[1.0, 2.0, 3.0], delta=[0.5, 0.5, 0.5])

mrc_obj = mrc.MRC.from_grid(g)

assert isinstance(mrc_obj, mrc.MRC)

assert_equal(mrc_obj.array, data)
assert_allclose(mrc_obj.delta, np.diag(g.delta))
assert_allclose(mrc_obj.origin, g.origin)
assert mrc_obj.rank == 3

def test_mrc_native_property(self):
data = np.ones((3, 3, 3))
g = Grid(data, origin=[0, 0, 0], delta=[1, 1, 1])

mrc_obj = mrc.MRC.from_grid(g)

assert mrc_obj.native is mrc_obj

class TestMRCWrite:
"""Tests for MRC write functionality"""
Expand Down
Loading