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

Work around more DX parsing issues by other apps #58

Merged
merged 7 commits into from
Apr 8, 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 AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,5 @@ Contributors:
* Max Linke <kain88-de>
* Jan Domanski <jandom>
* Dominik Mierzejewski <rathann>
* Tyler Luchko <tluchko>
* Tyler Luchko <tluchko>
* Giacomo Fiorin <giacomofiorin>
9 changes: 9 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,15 @@ The rules for this file:
* accompany each entry with github issue/PR number (Issue #xyz)

------------------------------------------------------------------------------
??/??/2019 giacomofiorin

* 0.5.0

Fixes

* Allow parsing DX files by NAMD's GridForces module (typequote keyword, #58)
* Allow parsing DX files by Pymol's buggy floating-point parser (#58)

04/06/2019 rathann, tluchko, orbeckst

* 0.4.1
Expand Down
15 changes: 11 additions & 4 deletions gridData/OpenDX.py
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,8 @@ class array(DXclass):
# "string" not automatically supported
}

def __init__(self, classid, array=None, type=None, **kwargs):
def __init__(self, classid, array=None, type=None, typequote='"',
**kwargs):
"""
Parameters
----------
Expand Down Expand Up @@ -347,6 +348,7 @@ def __init__(self, classid, array=None, type=None, **kwargs):
"types are: {1}".format(type,
list(self.dx_types.values()))))
self.type = type
self.typequote = typequote

def write(self, file):
"""Write the *class array* section.
Expand All @@ -367,18 +369,23 @@ def write(self, file):
"Supported valus are: {}\n"
"Use the type=<type> keyword argument.").format(
self.type, list(self.dx_types.keys())))
typelabel = (self.typequote+self.type+self.typequote)
DXclass.write(self,file,
'type "{0}" rank 0 items {1} data follows'.format(
self.type, self.array.size))
'type {0} rank 0 items {1} data follows'.format(
typelabel, self.array.size))
# grid data, serialized as a C array (z fastest varying)
# (flat iterator is equivalent to: for x: for y: for z: grid[x,y,z])
# VMD's DX reader requires exactly 3 values per line
fmt_string = "{:d}"
if (self.array.dtype.kind == 'f' or self.array.dtype.kind == 'c'):
precision = numpy.finfo(self.array.dtype).precision
fmt_string = "{:."+"{:d}".format(precision)+"f}"
values_per_line = 3
values = self.array.flat
while 1:
try:
for i in range(values_per_line):
file.write(str(next(values)) + "\t")
file.write(fmt_string.format(next(values)) + "\t")
file.write('\n')
except StopIteration:
file.write('\n')
Expand Down
29 changes: 19 additions & 10 deletions gridData/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -407,7 +407,7 @@ def _load_plt(self, filename):
grid, edges = g.histogramdd()
self.__init__(grid=grid, edges=edges, metadata=self.metadata)

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

The format can also be deduced from the suffix of the filename
Expand All @@ -426,25 +426,34 @@ def export(self, filename, file_format=None, type=None):

Parameters
----------

filename : str
name of the output file

file_format : {'dx', 'pickle', None} (optional)
output file format, the default is "dx"

type : str (optional)
for DX, set the output DX array type, e.g., "double" or
"float"; note that PyMOL only understands "double" (see
issue `#35`_). By default (``None``), the DX type is
determined from the numpy dtype of the array of the grid
(and this will typically result in "double").
for DX, set the output DX array type, e.g., "double" or "float".
By default (``None``), the DX type is determined from the numpy
dtype of the array of the grid (and this will typically result in
"double").

.. versionadded:: 0.4.0


.. _`#35`: https://github.com/MDAnalysis/GridDataFormats/issues/35

typequote : str (optional)
For DX, set the character used to quote the type string;
by default this is a double-quote character, '"'.
Custom parsers like the one from NAMD-GridForces (backend for MDFF)
expect no quotes, and typequote='' may be used to appease them.

.. versionadded:: 0.5.0

"""
exporter = self._get_exporter(filename, file_format=file_format)
exporter(filename, type=type)
exporter(filename, type=type, typequote=typequote)

# note: the _export_FORMAT() methods all take the filename as a mandatory
# argument. They can process kwargs but they are not required to do
Expand All @@ -460,7 +469,7 @@ def _export_python(self, filename, **kwargs):
with open(filename, 'wb') as f:
cPickle.dump(data, f, cPickle.HIGHEST_PROTOCOL)

def _export_dx(self, filename, type=None, **kwargs):
def _export_dx(self, filename, type=None, typequote='"', **kwargs):
"""Export the density grid to an OpenDX file.

The file format is the simplest regular grid array and it is
Expand Down Expand Up @@ -494,7 +503,7 @@ def _export_dx(self, filename, type=None, **kwargs):
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),
data=OpenDX.array(3, self.grid, type=type, typequote=typequote),
)
dx = OpenDX.field('density', components=components, comments=comments)
dx.write(filename)
Expand Down