From fb6a866d3e3a87c4fc597418ac57ccd5f74b9d2d Mon Sep 17 00:00:00 2001 From: Brian Skinn Date: Sun, 21 Aug 2016 00:25:29 -0400 Subject: [PATCH 01/12] DEV: Created arg parser, fleshed out a bit Seems to be working fine. Need to implement the decompression. --- .gitignore | 9 ++++ h5cube/h5cube.py | 120 ++++++++++++++++++++++++++++++++++++----------- 2 files changed, 101 insertions(+), 28 deletions(-) diff --git a/.gitignore b/.gitignore index 7aa4ac9..f872f80 100644 --- a/.gitignore +++ b/.gitignore @@ -92,3 +92,12 @@ ENV/ *.cube *.h5 +# gedit temp/bak files +*.rst~ +*.py~ +.gitignore~ + +# Misc .bak files +*.bak + + diff --git a/h5cube/h5cube.py b/h5cube/h5cube.py index 370c7bc..cd1503c 100644 --- a/h5cube/h5cube.py +++ b/h5cube/h5cube.py @@ -1,19 +1,26 @@ import os import sys -COMMENT1 = 'COMMENT1' -COMMENT2 = 'COMMENT2' -NATOMS = 'NATOMS' -ORIGIN = 'ORIGIN' -XAXIS = 'XAXIS' -YAXIS = 'YAXIS' -ZAXIS = 'ZAXIS' -GEOM = 'GEOM' -SIGNS = 'SIGNS' -LOGDATA = 'LOGDATA' - - -def cube_to_h5(cubepath): +# Argparse constants +AP_PATH = 'path' +AP_DELETE = 'delete' +AP_COMPRESS = 'compress' +AP_TRUNC = 'truncate' + +# h5py constants +H5_COMMENT1 = 'COMMENT1' +H5_COMMENT2 = 'COMMENT2' +H5_NATOMS = 'NATOMS' +H5_ORIGIN = 'ORIGIN' +H5_XAXIS = 'XAXIS' +H5_YAXIS = 'YAXIS' +H5_ZAXIS = 'ZAXIS' +H5_GEOM = 'GEOM' +H5_SIGNS = 'SIGNS' +H5_LOGDATA = 'LOGDATA' + + +def cube_to_h5(cubepath, delsrc, comp, trunc): import h5py as h5 import itertools as itt @@ -32,19 +39,19 @@ def cube_to_h5(cubepath): hf = h5.File(h5path) # Comment lines - hf.create_dataset(COMMENT1, data=next(datalines)) - hf.create_dataset(COMMENT2, data=next(datalines)) + hf.create_dataset(H5_COMMENT1, data=next(datalines)) + hf.create_dataset(H5_COMMENT2, data=next(datalines)) # Number of atoms and origin elements = iter(next(datalines).split()) natoms = abs(int(next(elements))) - hf.create_dataset(NATOMS, data=natoms) - hf.create_dataset(ORIGIN, data=np.array([float(next(elements)) + hf.create_dataset(H5_NATOMS, data=natoms) + hf.create_dataset(H5_ORIGIN, data=np.array([float(next(elements)) for i in range(3)])) # Dimensions and vectors dims = [] - for dsname in [XAXIS, YAXIS, ZAXIS]: + for dsname in [H5_XAXIS, H5_YAXIS, H5_ZAXIS]: elements = iter(next(datalines).split()) hf.create_dataset(dsname, data=np.array([float(next(elements)) for i in range(4)])) @@ -58,7 +65,7 @@ def cube_to_h5(cubepath): for j in range(5): geom[i, j] = elements[j] - hf.create_dataset(GEOM, data=geom) + hf.create_dataset(H5_GEOM, data=geom) # Volumetric field data # Create one big iterator over a scientific notation regular @@ -76,7 +83,8 @@ def cube_to_h5(cubepath): """, re.X | re.I) # Agglomerated iterator - dataiter = itt.chain(*(p_scinot.finditer(l) for l in datalines)) + dataiter = itt.chain.from_iterable([p_scinot.finditer(l) + for l in datalines]) # Initialize the numpy objects logdataarr = np.zeros(dims) @@ -103,26 +111,82 @@ def cube_to_h5(cubepath): raise ValueError("CUBE file dataset not exhausted") # Store the arrays, compressed - hf.create_dataset(LOGDATA, data=logdataarr, compression="gzip", - compression_opts=9, shuffle=True, scaleoffset=5) - hf.create_dataset(SIGNS, data=signsarr, compression="gzip", - compression_opts=9, shuffle=True) + hf.create_dataset(H5_LOGDATA, data=logdataarr, compression="gzip", + compression_opts=comp, shuffle=True, scaleoffset=trunc) + hf.create_dataset(H5_SIGNS, data=signsarr, compression="gzip", + compression_opts=comp, shuffle=True) # Close the h5 file hf.close() + # If indicated, delete the source file + if delsrc: + os.remove(cubepath) + -def h5_to_cube(path): +def h5_to_cube(h5path, delsrc): pass +def get_parser(): + + import argparse as ap + + prs = ap.ArgumentParser(description="CUBE (de)compression via h5py", + epilog="When decompressing, all parameters but " + "'{0}' and '{1}' are ignored." + .format(AP_PATH, AP_DELETE)) + + # Argument for the filename + prs.add_argument(AP_PATH, action='store', + help="Path to file to be (de)compressed") + + # Argument to delete the source file; default is to keep + prs.add_argument('-{0}'.format(AP_DELETE[0]), '--{0}'.format(AP_DELETE), + action='store_true', + help="Delete the source file after (de)compression") + + # gzip compression level + prs.add_argument('-{0}'.format(AP_COMPRESS[0]), + '--{0}'.format(AP_COMPRESS), + action='store', default=9, type=int, + choices=list(range(10)), + help="gzip compression level (default 9)") + + # gzip truncation level + prs.add_argument('-{0}'.format(AP_TRUNC[0]), + '--{0}'.format(AP_TRUNC), + action='store', default=5, type=int, + choices=list(range(1,10)), + help="gzip truncation width (default 5)") + + return prs + + if __name__ == '__main__': - path = sys.argv[1] + prs = get_parser() + + # Parse known args, convert to dict, and leave unknown args in sys.argv + ns, args_left = prs.parse_known_args() + params = vars(ns) + sys.argv = sys.argv[:1] + args_left + + # Retrieve path and file extension + path = params[AP_PATH] ext = os.path.splitext(path)[1] + # Retrieve other parameters + delsrc = params[AP_DELETE] + comp = params[AP_COMPRESS] + trunc = params[AP_TRUNC] + if ext == '.h5': - h5_to_cube(path) + h5_to_cube(path, delsrc) elif ext == '.cube': - cube_to_h5(path) + cube_to_h5(path, delsrc, comp, trunc) + else: + print("File extension not recognized. Exiting...") + + From 5282806c41d50a0785ebab9c013530498108a6e9 Mon Sep 17 00:00:00 2001 From: Brian Skinn Date: Sun, 21 Aug 2016 23:57:17 -0400 Subject: [PATCH 02/12] DEV: First decompress capability; other tweaks * First-completed version of the decompression function - DATA VALIDATION TESTING CRUCIAL. A test suite would probably be warranted...? - Option implemented to allow user-defined precision in data block output to .cube * Imports pulled to narrowest scopes * Compressed files now have .h5cube extension (mandatory) * Pulled (de)compression-specific commandline args into groups * Source file header added --- .gitignore | 1 + h5cube/h5cube.py | 171 +++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 144 insertions(+), 28 deletions(-) diff --git a/.gitignore b/.gitignore index f872f80..cd124a7 100644 --- a/.gitignore +++ b/.gitignore @@ -91,6 +91,7 @@ ENV/ # CUBE and h5 files *.cube *.h5 +*.h5cube # gedit temp/bak files *.rst~ diff --git a/h5cube/h5cube.py b/h5cube/h5cube.py index cd1503c..6c694c4 100644 --- a/h5cube/h5cube.py +++ b/h5cube/h5cube.py @@ -1,11 +1,26 @@ -import os -import sys +# ------------------------------------------------------------------------------ +# Name: h5cube +# Purpose: Script for h5py (de)compression of Gaussian CUBE files +# +# Author: Brian Skinn +# bskinn@alum.mit.edu +# +# Created: 20 Aug 2016 +# Copyright: (c) Brian Skinn 2016 +# License: The MIT License; see "license.txt" for full license terms +# and contributor agreement. +# +# http://www.github.com/bskinn/h5cube +# +# ------------------------------------------------------------------------------ + # Argparse constants AP_PATH = 'path' AP_DELETE = 'delete' AP_COMPRESS = 'compress' AP_TRUNC = 'truncate' +AP_PREC = 'precision' # h5py constants H5_COMMENT1 = 'COMMENT1' @@ -20,7 +35,28 @@ H5_LOGDATA = 'LOGDATA' +def exp_format(val, prec): + """ [Docstring] + + """ + + # Convert val using string formatting: Always a leading space; + # positive values with another leading space; negatives with the negative + # sign; one digit in front of the decimal, 'dec' digits after. + # Capital 'E' for the exponent. + out = " {{: #1.{0}E}}".format(prec).format(val) + + # Insert zeros as needed to make a three-digit exponent + out = out[:(6 + prec)] + "".zfill(9 + prec - len(out)) + out[(6 + prec):] + + # Return the results + return out + + def cube_to_h5(cubepath, delsrc, comp, trunc): + """ [Docstring] + + """ import h5py as h5 import itertools as itt @@ -32,7 +68,7 @@ def cube_to_h5(cubepath, delsrc, comp, trunc): datalines = iter(filedata.splitlines()) - h5path = "{0}.h5".format(cubepath) + h5path = cubepath[:-4] + 'h5' + cubepath[-4:] if os.path.isfile(h5path): os.remove(h5path) @@ -76,7 +112,7 @@ def cube_to_h5(cubepath, delsrc, comp, trunc): -? # Optional leading negative sign \\d # Single leading digit \\. # Decimal point - \\d+ # Multiple digits + \\d* # Digits (could be none, zero precision) [de] # Accept either 0.000d00 or 0.000e00 [+-] # Sign of the exponent \\d+ # Digits of the exponent @@ -124,47 +160,125 @@ def cube_to_h5(cubepath, delsrc, comp, trunc): os.remove(cubepath) -def h5_to_cube(h5path, delsrc): - pass +def h5_to_cube(h5path, delsrc, prec): + """ [Docstring] + + Less error/syntax checking here since presumably the data was + parsed for validity when the .h5cube file was created. + """ + + import h5py as h5 + import os + + # Define the header block substitution strings + hdr_3val = "{:5d} {: 1.6f} {: 1.6f} {: 1.6f}" + hdr_4val = "{:5d} {: 1.6f} {: 1.6f} {: 1.6f} {: 1.6f}" + + # Define the uncompressed filename + cubepath = h5path[:-6] + h5path[-4:] + + # Open the source file + hf = h5.File(h5path) + + # Delete any existing output file + if os.path.isfile(cubepath): + os.remove(cubepath) + + # Open the output file for writing as a context manager + with open(cubepath, 'w') as f: + # Write the two comment lines + f.write(hf[H5_COMMENT1].value + os.linesep) + f.write(hf[H5_COMMENT2].value + os.linesep) + + # Write the number-of-atoms and system origin line + natoms = hf[H5_NATOMS].value + f.write(hdr_3val.format(natoms, *(hf[H5_ORIGIN].value)) + os.linesep) + + # Write the three axes lines + dims = [] + for dsname in [H5_XAXIS, H5_YAXIS, H5_ZAXIS]: + ds = hf[dsname].value + f.write(hdr_3val.format(int(ds[0]), *ds[1:]) + os.linesep) + dims.append(int(ds[0])) + + # Write the geometry + geom = hf[H5_GEOM].value + for i in range(natoms): + f.write(hdr_4val.format(int(geom[i,0]), *geom[i,1:]) + os.linesep) + + # Write the data blocks + signs = hf[H5_SIGNS].value + logvals = hf[H5_LOGDATA].value + for x in range(dims[0]): + for y in range(dims[1]): + for z in range(dims[2]): + f.write(exp_format(signs[x, y, z] * + 10.**logvals[x, y, z], prec)) + if z % 6 == 5: + f.write(os.linesep) + + f.write(os.linesep) + + # Close the h5 file + hf.close() + + # If indicated, delete the source file + if delsrc: + os.remove(h5path) def get_parser(): + """ [Docstring] + + """ import argparse as ap - prs = ap.ArgumentParser(description="CUBE (de)compression via h5py", - epilog="When decompressing, all parameters but " - "'{0}' and '{1}' are ignored." - .format(AP_PATH, AP_DELETE)) + # Core parser + prs = ap.ArgumentParser(description="Gaussian CUBE (de)compression " + "via h5py") + + # Compression and decompression groups + gp_comp = prs.add_argument_group(title="compression options") + gp_decomp = prs.add_argument_group(title="decompression options") - # Argument for the filename + # Argument for the filename (core parser) prs.add_argument(AP_PATH, action='store', help="Path to file to be (de)compressed") - # Argument to delete the source file; default is to keep + # Argument to delete the source file; default is to keep (core) prs.add_argument('-{0}'.format(AP_DELETE[0]), '--{0}'.format(AP_DELETE), action='store_true', help="Delete the source file after (de)compression") - # gzip compression level - prs.add_argument('-{0}'.format(AP_COMPRESS[0]), - '--{0}'.format(AP_COMPRESS), - action='store', default=9, type=int, - choices=list(range(10)), - help="gzip compression level (default 9)") - - # gzip truncation level - prs.add_argument('-{0}'.format(AP_TRUNC[0]), - '--{0}'.format(AP_TRUNC), - action='store', default=5, type=int, - choices=list(range(1,10)), - help="gzip truncation width (default 5)") - + # gzip compression level (compress) + gp_comp.add_argument('-{0}'.format(AP_COMPRESS[0]), + '--{0}'.format(AP_COMPRESS), + action='store', default=9, type=int, + choices=list(range(10)), + help="gzip compression level (default 9)") + + # gzip truncation level (compress) + gp_comp.add_argument('-{0}'.format(AP_TRUNC[0]), + '--{0}'.format(AP_TRUNC), + action='store', default=5, type=int, + choices=list(range(1,10)), + help="gzip truncation width (default 5)") + + # Data block output precision (decompress) + gp_decomp.add_argument('-{0}'.format(AP_PREC[0]), + '--{0}'.format(AP_PREC), + action='store', default=5, type=int, + choices=list(range(16)), + help="Data block output precision (default 5)") return prs if __name__ == '__main__': + import os + import sys + prs = get_parser() # Parse known args, convert to dict, and leave unknown args in sys.argv @@ -180,9 +294,10 @@ def get_parser(): delsrc = params[AP_DELETE] comp = params[AP_COMPRESS] trunc = params[AP_TRUNC] + prec = params[AP_PREC] - if ext == '.h5': - h5_to_cube(path, delsrc) + if ext == '.h5cube': + h5_to_cube(path, delsrc, prec) elif ext == '.cube': cube_to_h5(path, delsrc, comp, trunc) else: From d98068a3740765080243a23c1e5ef58c1ec55fb8 Mon Sep 17 00:00:00 2001 From: Brian Skinn Date: Tue, 23 Aug 2016 00:20:45 -0400 Subject: [PATCH 03/12] DEV: Add __init__.py, misc development * Add __init__.py primarily to enable automatic script generation via setuptools / setup.py. Also will allow API access (and thus require API documentation... which I probably would've written anyways). * Convert internal constants to classes, for a cleaner namespace, and roll out to (presumably?) all usages within the code * Add default (de)compression parameter values class, and integrate with the argparse parser setup, and as default values for h5_to_cube and cube_to_h5 * Strip the printing of extra zeros in the volumetric data block. Totally not necessary for a functional CUBE. * Enable compression of .cub files (compression still always to .h5cube, and decompression always to .cube) * Change path processing from magic number indexing to that based on os.path.splitext * Fix EOL bug -- f.write() handles the native EOL characters automatically! * Pull core script actions into main() --- h5cube/__init__.py | 21 +++++++ h5cube/h5cube.py | 147 ++++++++++++++++++++++++--------------------- 2 files changed, 100 insertions(+), 68 deletions(-) create mode 100644 h5cube/__init__.py diff --git a/h5cube/__init__.py b/h5cube/__init__.py new file mode 100644 index 0000000..c7496d4 --- /dev/null +++ b/h5cube/__init__.py @@ -0,0 +1,21 @@ +# ------------------------------------------------------------------------------ +# Name: init +# Purpose: Package information for h5cube +# +# Author: Brian Skinn +# bskinn@alum.mit.edu +# +# Created: 22 Aug 2016 +# Copyright: (c) Brian Skinn 2016 +# License: The MIT License; see "license.txt" for full license terms +# and contributor agreement. +# +# http://www.github.com/bskinn/h5cube +# +# ------------------------------------------------------------------------------ + +from __future__ import absolute_import + +from .h5cube import cube_to_h5, h5_to_cube, H5 + +__version__ = '0.1' diff --git a/h5cube/h5cube.py b/h5cube/h5cube.py index 6c694c4..dc0eba6 100644 --- a/h5cube/h5cube.py +++ b/h5cube/h5cube.py @@ -16,23 +16,32 @@ # Argparse constants -AP_PATH = 'path' -AP_DELETE = 'delete' -AP_COMPRESS = 'compress' -AP_TRUNC = 'truncate' -AP_PREC = 'precision' +class AP(object): + PATH = 'path' + DELETE = 'delete' + COMPRESS = 'compress' + TRUNC = 'truncate' + PREC = 'precision' # h5py constants -H5_COMMENT1 = 'COMMENT1' -H5_COMMENT2 = 'COMMENT2' -H5_NATOMS = 'NATOMS' -H5_ORIGIN = 'ORIGIN' -H5_XAXIS = 'XAXIS' -H5_YAXIS = 'YAXIS' -H5_ZAXIS = 'ZAXIS' -H5_GEOM = 'GEOM' -H5_SIGNS = 'SIGNS' -H5_LOGDATA = 'LOGDATA' +class H5(object): + COMMENT1 = 'COMMENT1' + COMMENT2 = 'COMMENT2' + NATOMS = 'NATOMS' + ORIGIN = 'ORIGIN' + XAXIS = 'XAXIS' + YAXIS = 'YAXIS' + ZAXIS = 'ZAXIS' + GEOM = 'GEOM' + SIGNS = 'SIGNS' + LOGDATA = 'LOGDATA' + +# Default values +class DEF(object): + TRUNC = 5 + PREC = 5 + COMP = 9 + DEL = False def exp_format(val, prec): @@ -46,14 +55,11 @@ def exp_format(val, prec): # Capital 'E' for the exponent. out = " {{: #1.{0}E}}".format(prec).format(val) - # Insert zeros as needed to make a three-digit exponent - out = out[:(6 + prec)] + "".zfill(9 + prec - len(out)) + out[(6 + prec):] - # Return the results return out -def cube_to_h5(cubepath, delsrc, comp, trunc): +def cube_to_h5(cubepath, *, delsrc=DEF.DEL, comp=DEF.COMP, trunc=DEF.TRUNC): """ [Docstring] """ @@ -61,6 +67,7 @@ def cube_to_h5(cubepath, delsrc, comp, trunc): import h5py as h5 import itertools as itt import numpy as np + import os import re with open(cubepath) as f: @@ -68,26 +75,26 @@ def cube_to_h5(cubepath, delsrc, comp, trunc): datalines = iter(filedata.splitlines()) - h5path = cubepath[:-4] + 'h5' + cubepath[-4:] + h5path = os.path.splitext(cubepath)[0] + '.h5cube' if os.path.isfile(h5path): os.remove(h5path) hf = h5.File(h5path) # Comment lines - hf.create_dataset(H5_COMMENT1, data=next(datalines)) - hf.create_dataset(H5_COMMENT2, data=next(datalines)) + hf.create_dataset(H5.COMMENT1, data=next(datalines)) + hf.create_dataset(H5.COMMENT2, data=next(datalines)) # Number of atoms and origin elements = iter(next(datalines).split()) natoms = abs(int(next(elements))) - hf.create_dataset(H5_NATOMS, data=natoms) - hf.create_dataset(H5_ORIGIN, data=np.array([float(next(elements)) + hf.create_dataset(H5.NATOMS, data=natoms) + hf.create_dataset(H5.ORIGIN, data=np.array([float(next(elements)) for i in range(3)])) # Dimensions and vectors dims = [] - for dsname in [H5_XAXIS, H5_YAXIS, H5_ZAXIS]: + for dsname in [H5.XAXIS, H5.YAXIS, H5.ZAXIS]: elements = iter(next(datalines).split()) hf.create_dataset(dsname, data=np.array([float(next(elements)) for i in range(4)])) @@ -101,7 +108,7 @@ def cube_to_h5(cubepath, delsrc, comp, trunc): for j in range(5): geom[i, j] = elements[j] - hf.create_dataset(H5_GEOM, data=geom) + hf.create_dataset(H5.GEOM, data=geom) # Volumetric field data # Create one big iterator over a scientific notation regular @@ -147,9 +154,9 @@ def cube_to_h5(cubepath, delsrc, comp, trunc): raise ValueError("CUBE file dataset not exhausted") # Store the arrays, compressed - hf.create_dataset(H5_LOGDATA, data=logdataarr, compression="gzip", + hf.create_dataset(H5.LOGDATA, data=logdataarr, compression="gzip", compression_opts=comp, shuffle=True, scaleoffset=trunc) - hf.create_dataset(H5_SIGNS, data=signsarr, compression="gzip", + hf.create_dataset(H5.SIGNS, data=signsarr, compression="gzip", compression_opts=comp, shuffle=True) # Close the h5 file @@ -160,10 +167,10 @@ def cube_to_h5(cubepath, delsrc, comp, trunc): os.remove(cubepath) -def h5_to_cube(h5path, delsrc, prec): +def h5_to_cube(h5path, *, delsrc=DEF.DEL, prec=DEF.PREC): """ [Docstring] - Less error/syntax checking here since presumably the data was + Less error/syntax checking here since presumably the data was parsed for validity when the .h5cube file was created. """ @@ -175,7 +182,7 @@ def h5_to_cube(h5path, delsrc, prec): hdr_4val = "{:5d} {: 1.6f} {: 1.6f} {: 1.6f} {: 1.6f}" # Define the uncompressed filename - cubepath = h5path[:-6] + h5path[-4:] + cubepath = os.path.splitext(h5path)[0] + '.cube' # Open the source file hf = h5.File(h5path) @@ -187,37 +194,37 @@ def h5_to_cube(h5path, delsrc, prec): # Open the output file for writing as a context manager with open(cubepath, 'w') as f: # Write the two comment lines - f.write(hf[H5_COMMENT1].value + os.linesep) - f.write(hf[H5_COMMENT2].value + os.linesep) + f.write(hf[H5.COMMENT1].value + '\n') + f.write(hf[H5.COMMENT2].value + '\n') # Write the number-of-atoms and system origin line - natoms = hf[H5_NATOMS].value - f.write(hdr_3val.format(natoms, *(hf[H5_ORIGIN].value)) + os.linesep) + natoms = hf[H5.NATOMS].value + f.write(hdr_3val.format(natoms, *(hf[H5.ORIGIN].value)) + '\n') # Write the three axes lines dims = [] - for dsname in [H5_XAXIS, H5_YAXIS, H5_ZAXIS]: + for dsname in [H5.XAXIS, H5.YAXIS, H5.ZAXIS]: ds = hf[dsname].value - f.write(hdr_3val.format(int(ds[0]), *ds[1:]) + os.linesep) + f.write(hdr_3val.format(int(ds[0]), *ds[1:]) + '\n') dims.append(int(ds[0])) # Write the geometry - geom = hf[H5_GEOM].value + geom = hf[H5.GEOM].value for i in range(natoms): - f.write(hdr_4val.format(int(geom[i,0]), *geom[i,1:]) + os.linesep) + f.write(hdr_4val.format(int(geom[i,0]), *geom[i,1:]) + '\n') # Write the data blocks - signs = hf[H5_SIGNS].value - logvals = hf[H5_LOGDATA].value + signs = hf[H5.SIGNS].value + logvals = hf[H5.LOGDATA].value for x in range(dims[0]): for y in range(dims[1]): for z in range(dims[2]): - f.write(exp_format(signs[x, y, z] * + f.write(exp_format(signs[x, y, z] * 10.**logvals[x, y, z], prec)) if z % 6 == 5: - f.write(os.linesep) + f.write('\n') - f.write(os.linesep) + f.write('\n') # Close the h5 file hf.close() @@ -243,38 +250,41 @@ def get_parser(): gp_decomp = prs.add_argument_group(title="decompression options") # Argument for the filename (core parser) - prs.add_argument(AP_PATH, action='store', - help="Path to file to be (de)compressed") + prs.add_argument(AP.PATH, action='store', + help="path to .(h5)cube file to be (de)compressed") # Argument to delete the source file; default is to keep (core) - prs.add_argument('-{0}'.format(AP_DELETE[0]), '--{0}'.format(AP_DELETE), + prs.add_argument('-{0}'.format(AP.DELETE[0]), '--{0}'.format(AP.DELETE), action='store_true', - help="Delete the source file after (de)compression") + help="delete the source file after (de)compression") # gzip compression level (compress) - gp_comp.add_argument('-{0}'.format(AP_COMPRESS[0]), - '--{0}'.format(AP_COMPRESS), - action='store', default=9, type=int, + gp_comp.add_argument('-{0}'.format(AP.COMPRESS[0]), + '--{0}'.format(AP.COMPRESS), + action='store', default=DEF.COMP, type=int, choices=list(range(10)), - help="gzip compression level (default 9)") + help="gzip compression level for volumetric " + "data (default {0})".format(DEF.COMP)) # gzip truncation level (compress) - gp_comp.add_argument('-{0}'.format(AP_TRUNC[0]), - '--{0}'.format(AP_TRUNC), - action='store', default=5, type=int, + gp_comp.add_argument('-{0}'.format(AP.TRUNC[0]), + '--{0}'.format(AP.TRUNC), + action='store', default=DEF.TRUNC, type=int, choices=list(range(1,10)), - help="gzip truncation width (default 5)") + help="gzip truncation width for volumetric " + "data (default {0})".format(DEF.TRUNC)) # Data block output precision (decompress) - gp_decomp.add_argument('-{0}'.format(AP_PREC[0]), - '--{0}'.format(AP_PREC), - action='store', default=5, type=int, + gp_decomp.add_argument('-{0}'.format(AP.PREC[0]), + '--{0}'.format(AP.PREC), + action='store', default=DEF.PREC, type=int, choices=list(range(16)), - help="Data block output precision (default 5)") + help="volumetric data block output " + "precision (default {0})".format(DEF.PREC)) return prs -if __name__ == '__main__': +def main(): import os import sys @@ -287,21 +297,22 @@ def get_parser(): sys.argv = sys.argv[:1] + args_left # Retrieve path and file extension - path = params[AP_PATH] + path = params[AP.PATH] ext = os.path.splitext(path)[1] # Retrieve other parameters - delsrc = params[AP_DELETE] - comp = params[AP_COMPRESS] - trunc = params[AP_TRUNC] - prec = params[AP_PREC] + delsrc = params[AP.DELETE] + comp = params[AP.COMPRESS] + trunc = params[AP.TRUNC] + prec = params[AP.PREC] if ext == '.h5cube': h5_to_cube(path, delsrc, prec) - elif ext == '.cube': + elif ext in ['.cube', '.cub']: cube_to_h5(path, delsrc, comp, trunc) else: print("File extension not recognized. Exiting...") - +if __name__ == '__main__': + main() From 93fdad1e294622529a9810cf7a8b285632dab1f2 Mon Sep 17 00:00:00 2001 From: Brian Skinn Date: Tue, 23 Aug 2016 12:50:41 -0400 Subject: [PATCH 04/12] DEV: Start of argparse for thresholding Partial implementation; help for nested parameters is not displaying. --- h5cube/h5cube.py | 39 +++++++++++++++++++++++++++++++++------ 1 file changed, 33 insertions(+), 6 deletions(-) diff --git a/h5cube/h5cube.py b/h5cube/h5cube.py index dc0eba6..e888867 100644 --- a/h5cube/h5cube.py +++ b/h5cube/h5cube.py @@ -22,6 +22,8 @@ class AP(object): COMPRESS = 'compress' TRUNC = 'truncate' PREC = 'precision' + ABSMODE = 'absolute' + SIGNMODE = 'signed' # h5py constants class H5(object): @@ -249,6 +251,13 @@ def get_parser(): gp_comp = prs.add_argument_group(title="compression options") gp_decomp = prs.add_argument_group(title="decompression options") + # Thresholding subgroup within compression + gp_thresh = gp_comp.add_argument_group(title="thresholding options") + + # Mutually exclusive subgroups for the compression operation + meg_threshmode = gp_thresh.add_mutually_exclusive_group() +# meg_threshvals = gp_comp.add_mutually_exclusive_group() + # Argument for the filename (core parser) prs.add_argument(AP.PATH, action='store', help="path to .(h5)cube file to be (de)compressed") @@ -263,24 +272,41 @@ def get_parser(): '--{0}'.format(AP.COMPRESS), action='store', default=DEF.COMP, type=int, choices=list(range(10)), + metavar='#', help="gzip compression level for volumetric " - "data (default {0})".format(DEF.COMP)) + "data (0-9, default {0})".format(DEF.COMP)) # gzip truncation level (compress) gp_comp.add_argument('-{0}'.format(AP.TRUNC[0]), '--{0}'.format(AP.TRUNC), action='store', default=DEF.TRUNC, type=int, - choices=list(range(1,10)), + choices=list(range(1,16)), + metavar='#', help="gzip truncation width for volumetric " - "data (default {0})".format(DEF.TRUNC)) + "data (1-15, default {0})".format(DEF.TRUNC)) + + # Absolute thresholding mode (compress -- threshold) + meg_threshmode.add_argument('-{0}'.format(AP.ABSMODE[0]), + '--{0}'.format(AP.ABSMODE), + action='store_true', + help="absolute-value thresholding " + "mode") + # Signed thresholding mode (compress -- threshold) + meg_threshmode.add_argument('-{0}'.format(AP.SIGNMODE[0]), + '--{0}'.format(AP.SIGNMODE), + action='store_true', + help="signed-value thresholding " + "mode") # Data block output precision (decompress) gp_decomp.add_argument('-{0}'.format(AP.PREC[0]), '--{0}'.format(AP.PREC), action='store', default=DEF.PREC, type=int, choices=list(range(16)), + metavar='#', help="volumetric data block output " - "precision (default {0})".format(DEF.PREC)) + "precision (0-15, " + "default {0})".format(DEF.PREC)) return prs @@ -307,12 +333,13 @@ def main(): prec = params[AP.PREC] if ext == '.h5cube': - h5_to_cube(path, delsrc, prec) + h5_to_cube(path, delsrc=delsrc, prec=prec) elif ext in ['.cube', '.cub']: - cube_to_h5(path, delsrc, comp, trunc) + cube_to_h5(path, delsrc=delsrc, comp=comp, trunc=trunc) else: print("File extension not recognized. Exiting...") if __name__ == '__main__': main() + From 0cd63e03dd5918e61b18b46ce4bd4a75771384a0 Mon Sep 17 00:00:00 2001 From: Brian Skinn Date: Tue, 23 Aug 2016 16:02:14 -0400 Subject: [PATCH 05/12] DEV: Implement thresholding Still needs aggressive shakedown, incl. probably some automated testing. First trial of `isofactor` thresholding mode worked fine, though. --- h5cube/h5cube.py | 140 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 129 insertions(+), 11 deletions(-) diff --git a/h5cube/h5cube.py b/h5cube/h5cube.py index e888867..6f99060 100644 --- a/h5cube/h5cube.py +++ b/h5cube/h5cube.py @@ -24,6 +24,9 @@ class AP(object): PREC = 'precision' ABSMODE = 'absolute' SIGNMODE = 'signed' + NOTHRESH = 'nothresh' + MINMAX = 'minmax' + ISOFACTOR = 'isofactor' # h5py constants class H5(object): @@ -44,6 +47,7 @@ class DEF(object): PREC = 5 COMP = 9 DEL = False + THRESH = False def exp_format(val, prec): @@ -61,7 +65,8 @@ def exp_format(val, prec): return out -def cube_to_h5(cubepath, *, delsrc=DEF.DEL, comp=DEF.COMP, trunc=DEF.TRUNC): +def cube_to_h5(cubepath, *, delsrc=DEF.DEL, comp=DEF.COMP, trunc=DEF.TRUNC, + thresh=DEF.THRESH, signed=None, minmax=None, isofactor=None): """ [Docstring] """ @@ -135,6 +140,15 @@ def cube_to_h5(cubepath, *, delsrc=DEF.DEL, comp=DEF.COMP, trunc=DEF.TRUNC): logdataarr = np.zeros(dims) signsarr = np.zeros(dims) + # Preassign the calculated minmax values if isofactored thresh + # is enabled + if thresh and isofactor is not None: + # Populate minmax with the isovalue/factor based + # threshold values + minmax = np.zeros((2,)) + minmax[0] = isofactor[0] / isofactor[1] + minmax[1] = isofactor[0] * isofactor[1] + # Loop over the respective dimensions for x in range(dims[0]): for y in range(dims[1]): @@ -144,6 +158,19 @@ def cube_to_h5(cubepath, *, delsrc=DEF.DEL, comp=DEF.COMP, trunc=DEF.TRUNC): except StopIteration as e: raise ValueError("Insufficient data in CUBE file") from e + # Threshold, if indicated + if thresh: + if signed: + if val < minmax[0]: + val = minmax[0] + elif val > minmax[1]: + val = minmax[1] + else: + if np.abs(val) < minmax[0]: + val = np.sign(val) * minmax[0] + elif np.abs(val) > minmax[1]: + val = np.sign(val) * minmax[1] + signsarr[x, y, z] = np.sign(val) logdataarr[x, y, z] = np.log10(np.abs(val)) @@ -235,6 +262,37 @@ def h5_to_cube(h5path, *, delsrc=DEF.DEL, prec=DEF.PREC): if delsrc: os.remove(h5path) +def validate_minmax(minmax, signed): + """ [Docstring] + + """ + + import argparse as ap + + if minmax[0] >= minmax[1]: + raise ap.ArgumentTypeError("'max' is not greater than 'min'") + + if not signed and minmax[0] < 0: + raise ap.ArgumentTypeError("Negative 'min' in absolute " + "thresholding mode") + +def validate_isofactor(isofactor, signed): + """ [Docstring] + + """ + + import argparse as ap + + if isofactor[0] == 0.0: + raise ap.ArgumentTypeError("'isovalue' cannot be zero") + + if isofactor[1] <= 1.0: + raise ap.ArgumentTypeError("'factor' must be greater than one") + + if not signed and isofactor[0] < 0: + raise ap.ArgumentTypeError("Negative 'isovalue' in absolute " + "thresholding mode") + def get_parser(): """ [Docstring] @@ -247,16 +305,21 @@ def get_parser(): prs = ap.ArgumentParser(description="Gaussian CUBE (de)compression " "via h5py") - # Compression and decompression groups + # Compression group gp_comp = prs.add_argument_group(title="compression options") + + # Thresholding "subgroups" within compression + gp_threshmode = prs.add_argument_group(title="compression thresholding mode") + gp_threshvals = prs.add_argument_group(title="compression thresholding values") + + # Decompression group gp_decomp = prs.add_argument_group(title="decompression options") - # Thresholding subgroup within compression - gp_thresh = gp_comp.add_argument_group(title="thresholding options") + # Mutually exclusive subgroups for the compression operation - meg_threshmode = gp_thresh.add_mutually_exclusive_group() -# meg_threshvals = gp_comp.add_mutually_exclusive_group() + meg_threshmode = gp_threshmode.add_mutually_exclusive_group() + meg_threshvals = gp_threshvals.add_mutually_exclusive_group() # Argument for the filename (core parser) prs.add_argument(AP.PATH, action='store', @@ -285,19 +348,48 @@ def get_parser(): help="gzip truncation width for volumetric " "data (1-15, default {0})".format(DEF.TRUNC)) - # Absolute thresholding mode (compress -- threshold) + # Absolute thresholding mode (compress -- threshold mode) meg_threshmode.add_argument('-{0}'.format(AP.ABSMODE[0]), '--{0}'.format(AP.ABSMODE), action='store_true', help="absolute-value thresholding " "mode") - # Signed thresholding mode (compress -- threshold) + + # Signed thresholding mode (compress -- threshold mode) meg_threshmode.add_argument('-{0}'.format(AP.SIGNMODE[0]), '--{0}'.format(AP.SIGNMODE), action='store_true', help="signed-value thresholding " "mode") + # Thresholding mode disabled (compress -- threshold mode) + meg_threshmode.add_argument('-{0}'.format(AP.NOTHRESH[0]), + '--{0}'.format(AP.NOTHRESH), + action='store_true', + help="thresholding disabled (default)") + + + # Min/max threshold specification (compress -- threshold values) + meg_threshvals.add_argument('-{0}'.format(AP.MINMAX[0]), + '--{0}'.format(AP.MINMAX), + action='store', + default=None, + nargs=2, + metavar='#', + help="min and max values for " + "threshold specification") + + # Isovalue/factor threshold specification (compress -- threshold values) + meg_threshvals.add_argument('-{0}'.format(AP.ISOFACTOR[0]), + '--{0}'.format(AP.ISOFACTOR), + action='store', + default=None, + nargs=2, + metavar='#', + help="Isovalue and multiplicative " + "factor values for " + "threshold specification") + # Data block output precision (decompress) gp_decomp.add_argument('-{0}'.format(AP.PREC[0]), '--{0}'.format(AP.PREC), @@ -312,6 +404,8 @@ def get_parser(): def main(): + import argparse as ap + import numpy as np import os import sys @@ -331,15 +425,39 @@ def main(): comp = params[AP.COMPRESS] trunc = params[AP.TRUNC] prec = params[AP.PREC] - + signed = params[AP.SIGNMODE] + minmax = params[AP.MINMAX] + isofactor = params[AP.ISOFACTOR] + + if minmax: + minmax = np.float_(minmax) + validate_minmax(minmax, signed) + if isofactor: + isofactor = np.float_(isofactor) + validate_isofactor(isofactor, signed) + + # Check file extension as indication of execution mode if ext == '.h5cube': + # Decompression mode h5_to_cube(path, delsrc=delsrc, prec=prec) + elif ext in ['.cube', '.cub']: - cube_to_h5(path, delsrc=delsrc, comp=comp, trunc=trunc) + # Compression mode + if minmax is not None: + # Min/max thresholding + cube_to_h5(path, delsrc=delsrc, comp=comp, trunc=trunc, + thresh=True, signed=signed, minmax=minmax) + elif isofactor is not None: + # Isovalue thresholding + cube_to_h5(path, delsrc=delsrc, comp=comp, trunc=trunc, + thresh=True, signed=signed, isofactor=isofactor) + else: + # No thresholding + cube_to_h5(path, delsrc=delsrc, comp=comp, trunc=trunc) + else: print("File extension not recognized. Exiting...") if __name__ == '__main__': main() - From 970e67904a1846238abe76606e5fb9a2838ee96d Mon Sep 17 00:00:00 2001 From: Brian Skinn Date: Tue, 23 Aug 2016 23:05:23 -0400 Subject: [PATCH 06/12] DOC: Bourke CUBE PDF --- .../_static/Bourke_Gaussian_Cube_Files.pdf | Bin 0 -> 148399 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 doc/source/_static/Bourke_Gaussian_Cube_Files.pdf diff --git a/doc/source/_static/Bourke_Gaussian_Cube_Files.pdf b/doc/source/_static/Bourke_Gaussian_Cube_Files.pdf new file mode 100644 index 0000000000000000000000000000000000000000..fc931578f505c21ba1325af813f468477d05ff42 GIT binary patch literal 148399 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�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

L7jfYpF|G{g!m4X#V%m1A#Zc5;yx56*& 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 literal 0 HcmV?d00001 From 4b2bc1192def641351f0115d3a911ddcc6e53b95 Mon Sep 17 00:00:00 2001 From: Brian Skinn Date: Tue, 23 Aug 2016 23:57:27 -0400 Subject: [PATCH 07/12] DEV: New setup.py, argparse tweak Should be pretty representative. Just need README to make a first beta push to PyPI. Also tweaked the descriptions of the thresholding options in the argparse constructor. --- h5cube/h5cube.py | 6 ++++-- setup.py | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 2 deletions(-) create mode 100644 setup.py diff --git a/h5cube/h5cube.py b/h5cube/h5cube.py index 6f99060..6f19e2a 100644 --- a/h5cube/h5cube.py +++ b/h5cube/h5cube.py @@ -309,8 +309,10 @@ def get_parser(): gp_comp = prs.add_argument_group(title="compression options") # Thresholding "subgroups" within compression - gp_threshmode = prs.add_argument_group(title="compression thresholding mode") - gp_threshvals = prs.add_argument_group(title="compression thresholding values") + gp_threshmode = prs.add_argument_group(title="compression thresholding " + "mode (mutually exclusive)") + gp_threshvals = prs.add_argument_group(title="compression thresholding " + "values (mutually exclusive)") # Decompression group gp_decomp = prs.add_argument_group(title="decompression options") diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..eeda59e --- /dev/null +++ b/setup.py @@ -0,0 +1,32 @@ +from setuptools import setup + +setup( + name='h5cube', + version='0.1', +# requires='h5py something, pending tox', + packages=['h5cube'], + url='https://www.github.com/bskinn/h5cube', + license='MIT License', + author='Brian Skinn', + author_email='bskinn@alum.mit.edu', + description='Gaussian CUBE File Compression Utility', + classifiers=['License :: OSI Approved :: MIT License', + 'Natural Language :: English', + 'Environment :: Console', + 'Intended Audience :: Science/Research', + 'Operating System :: OS Independent', + 'Programming Language :: Python :: 3 :: Only', +# 'Programming Language :: Python :: 3.2', +# 'Programming Language :: Python :: 3.3', +# 'Programming Language :: Python :: 3.4', +# 'Programming Language :: Python :: 3.5', + 'Topic :: Scientific/Engineering', + 'Topic :: System :: Archiving :: Compression', + 'Topic :: Utilities', + 'Development Status :: 4 - Beta'], + entry_points={ + 'console_scripts': [ + 'h5cube = h5cube.h5cube:main' + ] + } +) From d2811fe3059c6e80347b2a9748ce2c8115d84763 Mon Sep 17 00:00:00 2001 From: Brian Skinn Date: Wed, 24 Aug 2016 10:08:06 -0400 Subject: [PATCH 08/12] ADMIN: Swap to rst README --- README.md | 2 -- README.rst | 19 +++++++++++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) delete mode 100644 README.md create mode 100644 README.rst diff --git a/README.md b/README.md deleted file mode 100644 index d5135dd..0000000 --- a/README.md +++ /dev/null @@ -1,2 +0,0 @@ -# h5cube -Gaussian CUBE file compression via h5py binary storage diff --git a/README.rst b/README.rst new file mode 100644 index 0000000..7c0fcac --- /dev/null +++ b/README.rst @@ -0,0 +1,19 @@ +Gaussian CUBE Compression via h5py +================================== + +Compression/decompression command-line tool and Python package for +Gaussian CUBE files, exploiting the capabilities of the HDF5 binary +format via ``h5py``. + +Available on `PyPI `__ +(``pip install h5cube``). + +Source on `GitHub `__. + +Documentation at Read the Docs: + +.. image:: https://readthedocs.org/projects/h5cube/badge/?version=latest + :target: http://h5cube.readthedocs.io/en/latest/?badge=latest + :alt: Documentation Status + + From f84587f9e07278e0a52dc282676fa22bf65caa7c Mon Sep 17 00:00:00 2001 From: Brian Skinn Date: Wed, 24 Aug 2016 22:47:01 -0400 Subject: [PATCH 09/12] ADMIN: Cull .cube, .h5, .h5cube from .gitignore Now that setup.py develop is working, there's no need to house random test files inside the project folder structure, and eventually there's probably going to be test data with these extensions that I *will* want in source control. --- .gitignore | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.gitignore b/.gitignore index cd124a7..f386bf2 100644 --- a/.gitignore +++ b/.gitignore @@ -88,11 +88,6 @@ ENV/ # Rope project settings .ropeproject -# CUBE and h5 files -*.cube -*.h5 -*.h5cube - # gedit temp/bak files *.rst~ *.py~ From c4573b0cafebf89a614ac1c0dbf5550acbf67ec1 Mon Sep 17 00:00:00 2001 From: Brian Skinn Date: Thu, 25 Aug 2016 17:13:04 -0400 Subject: [PATCH 10/12] DEV: Argument parsing * -n now complains if -i or -m also given (addresses one bullet of #23.) * Robustified checking of minmax and isofactor values * Added check for existing file, with exit if not existing --- h5cube/h5cube.py | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/h5cube/h5cube.py b/h5cube/h5cube.py index 6f19e2a..c98f05b 100644 --- a/h5cube/h5cube.py +++ b/h5cube/h5cube.py @@ -422,19 +422,33 @@ def main(): path = params[AP.PATH] ext = os.path.splitext(path)[1] + # Check for existence + if not os.path.isfile(path): + print("File not found. Exiting...") + sys.exit(1) + # Retrieve other parameters delsrc = params[AP.DELETE] comp = params[AP.COMPRESS] trunc = params[AP.TRUNC] prec = params[AP.PREC] + absolute = params[AP.ABSMODE] signed = params[AP.SIGNMODE] + nothresh = params[AP.NOTHRESH] minmax = params[AP.MINMAX] isofactor = params[AP.ISOFACTOR] - if minmax: + # Complain if nothresh specified but minmax or isofactor provided + if nothresh and not (minmax is None and isofactor is None): + raise ap.ArgumentTypeError("Invalid: Thresholding parameter specified " + "with --nothresh") + + + # Convert and validate the thresholding inputs + if minmax is not None: minmax = np.float_(minmax) validate_minmax(minmax, signed) - if isofactor: + if isofactor is not None: isofactor = np.float_(isofactor) validate_isofactor(isofactor, signed) @@ -459,7 +473,9 @@ def main(): else: print("File extension not recognized. Exiting...") + sys.exit(1) if __name__ == '__main__': main() + From d6ae9b5a88c6ec94fc87a6475f8eb88d129d967a Mon Sep 17 00:00:00 2001 From: Brian Skinn Date: Sat, 27 Aug 2016 23:51:22 -0400 Subject: [PATCH 11/12] ADMIN/DEV: Mostly commandline handling stuff ADMIN: * Renamed LICENSE to LICENSE.txt * Added link to h5py site to README.rst * Added leading underscore to nonpublic functions * Add note to '--absolute' that it's the default if '--minmax' or '--isofactor' is passed DEV: * Change commandline error exits to print/sys.exit call combos, instead of raising argparse.ArgumentTypeError, since ap.ATE only really helps inside the parse_args call (Issue #27) * Add EXIT class with sys.exit codes; added EXIT to public members of package in __init__.py * Switch most argument defaults to None, for more ready detection of whether a thing was passed or not. * Addressed the remaining four cmdline parsing problems listed in Issue #23 --- LICENSE => LICENSE.txt | 0 README.rst | 4 +- h5cube/__init__.py | 2 +- h5cube/h5cube.py | 116 ++++++++++++++++++++++++++++++----------- 4 files changed, 90 insertions(+), 32 deletions(-) rename LICENSE => LICENSE.txt (100%) diff --git a/LICENSE b/LICENSE.txt similarity index 100% rename from LICENSE rename to LICENSE.txt diff --git a/README.rst b/README.rst index 7c0fcac..38ad5ea 100644 --- a/README.rst +++ b/README.rst @@ -2,8 +2,8 @@ Gaussian CUBE Compression via h5py ================================== Compression/decompression command-line tool and Python package for -Gaussian CUBE files, exploiting the capabilities of the HDF5 binary -format via ``h5py``. +Gaussian CUBE files, exploiting the capabilities of the +`HDF5 `__ binary format via ``h5py``. Available on `PyPI `__ (``pip install h5cube``). diff --git a/h5cube/__init__.py b/h5cube/__init__.py index c7496d4..dab2d7c 100644 --- a/h5cube/__init__.py +++ b/h5cube/__init__.py @@ -16,6 +16,6 @@ from __future__ import absolute_import -from .h5cube import cube_to_h5, h5_to_cube, H5 +from .h5cube import cube_to_h5, h5_to_cube, H5, EXIT __version__ = '0.1' diff --git a/h5cube/h5cube.py b/h5cube/h5cube.py index c98f05b..e45d352 100644 --- a/h5cube/h5cube.py +++ b/h5cube/h5cube.py @@ -49,8 +49,14 @@ class DEF(object): DEL = False THRESH = False - -def exp_format(val, prec): +# Exit codes +class EXIT(object): + GENERIC = 1 + CMDLINE = 2 + FILEREAD = 4 + FILEWRITE = 8 + +def _exp_format(val, prec): """ [Docstring] """ @@ -77,15 +83,23 @@ def cube_to_h5(cubepath, *, delsrc=DEF.DEL, comp=DEF.COMP, trunc=DEF.TRUNC, import os import re + # Default compression and truncations, if no value(s) passed on commandline + if comp is None: + comp = DEF.COMP + if trunc is None: + trunc = DEF.TRUNC + + # Pull the file contents and make an iterator with open(cubepath) as f: filedata = f.read() - datalines = iter(filedata.splitlines()) + # Construct the .h5cube path h5path = os.path.splitext(cubepath)[0] + '.h5cube' + + # Clobber to new file if os.path.isfile(h5path): os.remove(h5path) - hf = h5.File(h5path) # Comment lines @@ -206,6 +220,10 @@ def h5_to_cube(h5path, *, delsrc=DEF.DEL, prec=DEF.PREC): import h5py as h5 import os + # Default precision value, if no value passed on commandline + if prec is None: + prec = DEF.PREC + # Define the header block substitution strings hdr_3val = "{:5d} {: 1.6f} {: 1.6f} {: 1.6f}" hdr_4val = "{:5d} {: 1.6f} {: 1.6f} {: 1.6f} {: 1.6f}" @@ -248,7 +266,7 @@ def h5_to_cube(h5path, *, delsrc=DEF.DEL, prec=DEF.PREC): for x in range(dims[0]): for y in range(dims[1]): for z in range(dims[2]): - f.write(exp_format(signs[x, y, z] * + f.write(_exp_format(signs[x, y, z] * 10.**logvals[x, y, z], prec)) if z % 6 == 5: f.write('\n') @@ -262,39 +280,45 @@ def h5_to_cube(h5path, *, delsrc=DEF.DEL, prec=DEF.PREC): if delsrc: os.remove(h5path) -def validate_minmax(minmax, signed): +def _validate_minmax(minmax, signed): """ [Docstring] """ import argparse as ap + import sys if minmax[0] >= minmax[1]: - raise ap.ArgumentTypeError("'max' is not greater than 'min'") + print("Error: 'max' is not greater than 'min'") + sys.exit(EXIT.CMDLINE) if not signed and minmax[0] < 0: - raise ap.ArgumentTypeError("Negative 'min' in absolute " - "thresholding mode") + print("Error: Negative 'min' in absolute thresholding mode") + sys.exit(EXIT.CMDLINE) -def validate_isofactor(isofactor, signed): + +def _validate_isofactor(isofactor, signed): """ [Docstring] """ import argparse as ap + import sys if isofactor[0] == 0.0: - raise ap.ArgumentTypeError("'isovalue' cannot be zero") + print("Error: 'isovalue' cannot be zero") + sys.exit(EXIT.CMDLINE) if isofactor[1] <= 1.0: - raise ap.ArgumentTypeError("'factor' must be greater than one") + print("Error: 'factor' must be greater than one") + sys.exit(EXIT.CMDLINE) if not signed and isofactor[0] < 0: - raise ap.ArgumentTypeError("Negative 'isovalue' in absolute " - "thresholding mode") - + print("Error: Negative 'isovalue' in absolute thresholding mode") + sys.exit(EXIT.CMDLINE) -def get_parser(): + +def _get_parser(): """ [Docstring] """ @@ -335,7 +359,7 @@ def get_parser(): # gzip compression level (compress) gp_comp.add_argument('-{0}'.format(AP.COMPRESS[0]), '--{0}'.format(AP.COMPRESS), - action='store', default=DEF.COMP, type=int, + action='store', default=None, type=int, choices=list(range(10)), metavar='#', help="gzip compression level for volumetric " @@ -344,7 +368,7 @@ def get_parser(): # gzip truncation level (compress) gp_comp.add_argument('-{0}'.format(AP.TRUNC[0]), '--{0}'.format(AP.TRUNC), - action='store', default=DEF.TRUNC, type=int, + action='store', default=None, type=int, choices=list(range(1,16)), metavar='#', help="gzip truncation width for volumetric " @@ -355,7 +379,9 @@ def get_parser(): '--{0}'.format(AP.ABSMODE), action='store_true', help="absolute-value thresholding " - "mode") + "mode (default if -{0} or -{1} " + "specified".format(AP.MINMAX[0], + AP.ISOFACTOR[0])) # Signed thresholding mode (compress -- threshold mode) meg_threshmode.add_argument('-{0}'.format(AP.SIGNMODE[0]), @@ -395,7 +421,7 @@ def get_parser(): # Data block output precision (decompress) gp_decomp.add_argument('-{0}'.format(AP.PREC[0]), '--{0}'.format(AP.PREC), - action='store', default=DEF.PREC, type=int, + action='store', default=None, type=int, choices=list(range(16)), metavar='#', help="volumetric data block output " @@ -411,7 +437,8 @@ def main(): import os import sys - prs = get_parser() + # Retrieve the argument parser + prs = _get_parser() # Parse known args, convert to dict, and leave unknown args in sys.argv ns, args_left = prs.parse_known_args() @@ -425,7 +452,7 @@ def main(): # Check for existence if not os.path.isfile(path): print("File not found. Exiting...") - sys.exit(1) + sys.exit(EXIT.FILEREAD) # Retrieve other parameters delsrc = params[AP.DELETE] @@ -438,27 +465,57 @@ def main(): minmax = params[AP.MINMAX] isofactor = params[AP.ISOFACTOR] + # Composite indicators for which types of arguments passed + def notNoneFalse(x): + return x is not None and x is not False + + compargs = any(map(notNoneFalse, [comp, trunc, absolute, + signed, nothresh, + minmax, isofactor])) + + decompargs = any(map(notNoneFalse, [prec])) + # Complain if nothresh specified but minmax or isofactor provided if nothresh and not (minmax is None and isofactor is None): - raise ap.ArgumentTypeError("Invalid: Thresholding parameter specified " - "with --nothresh") + print("Error: Thresholding parameter specified with --nothresh") + sys.exit(EXIT.CMDLINE) + # Complain if compression and decompression arguments mixed + if compargs and decompargs: + print("Error: Both compression and decompression options specified") + sys.exit(EXIT.CMDLINE) # Convert and validate the thresholding inputs if minmax is not None: minmax = np.float_(minmax) - validate_minmax(minmax, signed) + _validate_minmax(minmax, signed) if isofactor is not None: isofactor = np.float_(isofactor) - validate_isofactor(isofactor, signed) - + _validate_isofactor(isofactor, signed) + + # Complain if a thresholding mode is indicated but no + # threshold values are provided + if (absolute or signed) and (minmax is None and isofactor is None): + print("Error: Thresholding mode specified but no values provided") + sys.exit(EXIT.CMDLINE) + # Check file extension as indication of execution mode if ext == '.h5cube': # Decompression mode + if compargs: + print("Error: compression arguments passed to " + "decompression operation") + sys.exit(EXIT.CMDLINE) + h5_to_cube(path, delsrc=delsrc, prec=prec) elif ext in ['.cube', '.cub']: # Compression mode + if decompargs: + print("Error: decompression arguments passed to " + "compression operation") + sys.exit(EXIT.CMDLINE) + if minmax is not None: # Min/max thresholding cube_to_h5(path, delsrc=delsrc, comp=comp, trunc=trunc, @@ -469,11 +526,12 @@ def main(): thresh=True, signed=signed, isofactor=isofactor) else: # No thresholding - cube_to_h5(path, delsrc=delsrc, comp=comp, trunc=trunc) + cube_to_h5(path, thresh=False, delsrc=delsrc, comp=comp, + trunc=trunc) else: print("File extension not recognized. Exiting...") - sys.exit(1) + sys.exit(EXIT.CMDLINE) if __name__ == '__main__': From f3679a08fc452f6bac021f8f4d031633d25ae477 Mon Sep 17 00:00:00 2001 From: Brian Skinn Date: Sun, 28 Aug 2016 08:18:10 -0400 Subject: [PATCH 12/12] REL: Should be good for v0.1 --- CHANGELOG.txt | 34 ++++++++++++++++++++++++++++++++++ doc/source/conf.py | 13 +++++++------ doc/source/index.rst | 2 ++ setup.py | 2 +- 4 files changed, 44 insertions(+), 7 deletions(-) create mode 100644 CHANGELOG.txt diff --git a/CHANGELOG.txt b/CHANGELOG.txt new file mode 100644 index 0000000..87dd704 --- /dev/null +++ b/CHANGELOG.txt @@ -0,0 +1,34 @@ +Changelog for h5cube + + +v0.1 +================================================================================ + +Initial beta release, without documentation or a test suite. Below functionality +believed functional and substantially bug-free + +File extensions are fixed: + + - .h5cube files (case insensitive) are decompressed + - .cube and .cub files (case insensitive) are compressed + +Clobber of an existing output file always occurs. No options are available for +selecting/changing the name of the output file. + +* General options + --delete, optionally delete the source file after (de)compression + +* Compression options + --compress, gzip compression level within the HDF5 file + --truncate, truncated precision of the log-10 mantissa of each data value + * Thresholding options + --absolute / --signed, whether indicated threshold values are applied to + the signed value or the absolute magnitude + --minmax / --isofactor, whether the threshold values are specified by + explicit min/max values, or a central isovalue + and a multiplicative factor + +* Decompression options + --precision, the significant figures past the decimal point output for + each data point + diff --git a/doc/source/conf.py b/doc/source/conf.py index 5869742..24c35f6 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -25,7 +25,7 @@ # If your documentation needs a minimal Sphinx version, state it here. # -# needs_sphinx = '1.0' +needs_sphinx = '1.0' # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom @@ -65,9 +65,9 @@ # built documents. # # The short X.Y version. -version = '0.0' +version = '0.1' # The full version, including alpha/beta/rc tags. -release = '0.0' +release = '0.1' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. @@ -127,7 +127,7 @@ # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. # -html_theme = 'alabaster' +html_theme = 'sphinx_rtd_theme' # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the @@ -325,7 +325,7 @@ # dir menu entry, description, category) texinfo_documents = [ (master_doc, 'h5cube', 'h5cube Documentation', - author, 'h5cube', 'One line description of project.', + author, 'h5cube', 'Gaussian CUBE file compression via h5py', 'Miscellaneous'), ] @@ -347,4 +347,5 @@ # Example configuration for intersphinx: refer to the Python standard library. -intersphinx_mapping = {'https://docs.python.org/': None} +intersphinx_mapping = {'python': ('https://docs.python.org/3.5', None)} + diff --git a/doc/source/index.rst b/doc/source/index.rst index 51e28ff..233c9d1 100644 --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -6,6 +6,8 @@ Welcome to h5cube's documentation! ================================== +*Pending...* + Contents: .. toctree:: diff --git a/setup.py b/setup.py index eeda59e..3ead813 100644 --- a/setup.py +++ b/setup.py @@ -3,7 +3,7 @@ setup( name='h5cube', version='0.1', -# requires='h5py something, pending tox', + requires='h5py (>=2.4)', packages=['h5cube'], url='https://www.github.com/bskinn/h5cube', license='MIT License',