Skip to content

Latest commit

 

History

History
69 lines (48 loc) · 4.44 KB

README.md

File metadata and controls

69 lines (48 loc) · 4.44 KB

Test Suite

zfpc: zfp container format

An unofficial project unaffiliated with the zfp project.

An exerimental container format for zfp encoded vector fields. As described in the zfp documentation, datasets such as vector fields are not optimally compressed within a single zfp stream. This is due to the uncorrelated X and Y components. Compress the X and Y components as separate zfp arrays and you will yield a higher compression ratio.

However, this method of separate files is cumbersome, must be maintained per a project, and is not compatible with existing data viewers (such as Neuroglancer) that expect to download a single file per an image tile. zfpc provides a means for splitting up a 1-4D array based on their (user specified) uncorrelated dimensions, compressing those slices into separate zfp streams, and encoding them into a single file. This file can then be decompressed back into its original form seamlessly using zfpc. In the future, it may be possible to automatically determine which dimensions are uncorrelated using statistical tests.

In fixed rate mode, it should still be possible to perform random access though this feature is not available yet.

import zfpc

# example shape: (1202, 1240, 64, 2)
vector_field = np.array(...) # dtype must be float or int, 32 or 64-bit

# For data that are arranged as a Z stack of planar XY vectors
# e.g. arr[x,y,z,channel] mostly smoothly vary in the XY plane
# per a channel. Therefore, we set correlated_dims as 
# [True,True,False,False] as the z and channel dimensions
# do not smoothly vary to obtain optimal compression.
#
# tolerance, rate, and precision are supported modes.
# By default, lossless compression is used.
correlated_dims = [True, True, False, False]
binary = zfpc.compress(
	vector_field, 
	tolerance=0.01,
	correlated_dims=correlated_dims,
)
recovered_img = zfpc.decompress(binary)

header = zfpc.header(binary)

Container Format

header,index,streams

Header

The header is 15 bytes long in the following format written in little endian.

Field Type Description
magic char[4] "zfpc" magic number for file format.
format version uint8 Always version 0 (for now).
dtype,mode,order uint8 bits 1-3: zfp data type; bits 4-6: zfp mode; bit 7: unused; bit 8: true indicates c order (bits: DDDMMMUC)
nx uint32 Size of x axis.
ny uint32 Size of y axis.
nz uint32 Size of z axis.
nw uint32 Number of channels.
correlated dims uint8 Bottom 4 bits are a bitfield with 1 indicating correlated, 0 uncorrelated. Top 4 bits unused. (xyzw0000)

Index

All entries in the index are uint64 (8 bytes) little endian.

Stream offset followed by the size of each stream. The number of streams is calculated by the product of all the uncorrelated dimension sizes.

The stream offset is not a strictly necessary element, but will allow the format to be changed while allowing older decompressors to still function.

Streams

All zfp streams are concatenated together in Fortran order. The streams are written with a full header so that they can be decompressed independently.

In the future, it might make sense to get savings by condensing them into a single header and writing headerless streams. However, writing full headers presents the possibility of using different compression settings for each stream which could pay off for different components.