Skip to content

Commit

Permalink
fix(memh5): json serialize numpy ndarray
Browse files Browse the repository at this point in the history
Some old data format may have numpy.ndarray's in history["acq"]. To be
able to write these (for backwards compatibility) we need to add a json
decoder for numpy.ndarray. Note that reading the files again will show
list's instead of ndarray's.
  • Loading branch information
nritsche authored and jrs65 committed May 7, 2020
1 parent e7409e9 commit e8156da
Showing 1 changed file with 18 additions and 4 deletions.
22 changes: 18 additions & 4 deletions caput/memh5.py
Original file line number Diff line number Diff line change
Expand Up @@ -2197,18 +2197,32 @@ def _map_unicode(value):
def _map_json(value):
# Serialize/deserialize "special" json values

# Datetimes often appear in the configs (as they are parsed by PyYAML),
# so we need to serialise them back to strings
class DatetimeJSONEncoder(json.JSONEncoder):
class Memh5JSONEncoder(json.JSONEncoder):
"""
- Datetimes often appear in the configs (as they are parsed by PyYAML),
so we need to serialise them back to strings.
- Some old data format may have numpy arrays in `history["acq"]`. We have to convert
those to lists and decode byte objects.
"""

def default(self, v):
if isinstance(v, datetime.datetime):
return v.isoformat()
elif isinstance(v, np.number):
return v.data
elif isinstance(v, np.ndarray):
if len(v) == 1:
return v.tolist()[0]
return v.tolist()
elif isinstance(v, bytes): # pragma: py3
return v.decode()

# Let the default method raise the TypeError
return json.JSONEncoder.default(self, v)

if isinstance(value, dict) and isinstance(a2, h5py.AttributeManager):
# Save to JSON converting datetimes.
encoder = DatetimeJSONEncoder()
encoder = Memh5JSONEncoder()
value = json_prefix + encoder.encode(value)
elif isinstance(value, str) and value.startswith(json_prefix):
# Read from JSON, keep serialised datetimes as strings
Expand Down

0 comments on commit e8156da

Please sign in to comment.