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

adds round_to_int boolean argument to FixedScaleOffset #558

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
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
12 changes: 8 additions & 4 deletions numcodecs/fixedscaleoffset.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
class FixedScaleOffset(Codec):
"""Simplified version of the scale-offset filter available in HDF5.
Applies the transformation `(x - offset) * scale` to all chunks. Results
are rounded to the nearest integer but are not packed according to the
are optionally rounded to the nearest integer but are not packed according to the
minimum number of bits.

Parameters
Expand All @@ -21,6 +21,8 @@ class FixedScaleOffset(Codec):
Data type to use for decoded data.
astype : dtype, optional
Data type to use for encoded data.
round_to_int : boolean
Flag to control rounding encoded data to integers after applying scale and offset

Notes
-----
Expand Down Expand Up @@ -70,10 +72,11 @@ class FixedScaleOffset(Codec):

codec_id = 'fixedscaleoffset'

def __init__(self, offset, scale, dtype, astype=None):
def __init__(self, offset, scale, dtype, astype=None, round_to_int=True):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
def __init__(self, offset, scale, dtype, astype=None, round_to_int=True):
def __init__(self, offset, scale, dtype, astype=None, *, round_to_int=True):

self.offset = offset
self.scale = scale
self.dtype = np.dtype(dtype)
self.round_to_int = round_to_int
if astype is None:
self.astype = self.dtype
else:
Expand All @@ -91,8 +94,9 @@ def encode(self, buf):
# compute scale offset
enc = (arr - self.offset) * self.scale

# round to nearest integer
enc = np.around(enc)
if self.round_to_int:
# round to nearest integer
enc = np.around(enc)

# convert dtype
enc = enc.astype(self.astype, copy=False)
Expand Down
13 changes: 12 additions & 1 deletion numcodecs/tests/test_fixedscaleoffset.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@


import numpy as np
from numpy.testing import assert_array_equal
from numpy.testing import assert_array_equal, assert_allclose
import pytest


Expand Down Expand Up @@ -30,6 +30,7 @@
FixedScaleOffset(offset=1000, scale=10**6, dtype='<f8', astype='<i4'),
FixedScaleOffset(offset=1000, scale=10**12, dtype='<f8', astype='<i8'),
FixedScaleOffset(offset=1000, scale=10**12, dtype='<f8'),
FixedScaleOffset(offset=1000, scale=10**12, dtype='<f8', round_to_int=False),
]


Expand All @@ -50,6 +51,16 @@ def test_encode():
assert np.dtype(astype) == actual.dtype


def test_encode_no_round():
dtype = '<f8'
astype = dtype
codec = FixedScaleOffset(scale=1, offset=1000, dtype=dtype, astype=astype, round_to_int=False)
arr = np.linspace(1000, 1001, 10, dtype=dtype)
expect = np.linspace(0, 1, 10, dtype=dtype)
actual = codec.encode(arr)
assert_allclose(expect, actual)


def test_config():
codec = FixedScaleOffset(dtype='<f8', astype='<i4', scale=10, offset=100)
check_config(codec)
Expand Down