Skip to content

Commit 5364981

Browse files
Merge pull request #995 from A-Baji/fix-mym-#86
Fix issue with reading 32 bit blobs
2 parents 8115393 + 4b49864 commit 5364981

File tree

6 files changed

+68
-6
lines changed

6 files changed

+68
-6
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
## Release notes
22

3+
### 0.13.4 -- TBA
4+
* Add - Allow reading blobs produced by legacy 32-bit compiled mYm library for matlab. PR #995
5+
36
### 0.13.3 -- Feb 9, 2022
47
* Bugfix - Fix error in listing ancestors, descendants with part tables.
58
* Bugfix - Fix Python 3.10 compatibility (#983) PR #972

datajoint/blob.py

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@
4444

4545
bypass_serialization = False # runtime setting to bypass blob (en|de)code
4646

47+
# runtime setting to read integers as 32-bit to read blobs created by the 32-bit
48+
# version of the mYm library for MATLAB
49+
use_32bit_dims = False
50+
4751

4852
def len_u64(obj):
4953
return np.uint64(len(obj)).tobytes()
@@ -96,7 +100,7 @@ def unpack(self, blob):
96100
pass # assume uncompressed but could be unrecognized compression
97101
else:
98102
self._pos += len(prefix)
99-
blob_size = self.read_value('uint64')
103+
blob_size = self.read_value()
100104
blob = compression[prefix](self._blob[self._pos:])
101105
assert len(blob) == blob_size
102106
self._blob = blob
@@ -191,8 +195,8 @@ def pack_blob(self, obj):
191195
raise DataJointError("Packing object of type %s currently not supported!" % type(obj))
192196

193197
def read_array(self):
194-
n_dims = int(self.read_value('uint64'))
195-
shape = self.read_value('uint64', count=n_dims)
198+
n_dims = int(self.read_value())
199+
shape = self.read_value(count=n_dims)
196200
n_elem = np.prod(shape, dtype=int)
197201
dtype_id, is_complex = self.read_value('uint32', 2)
198202
dtype = dtype_list[dtype_id]
@@ -365,7 +369,7 @@ def read_struct(self):
365369
return np.array(None) # empty array
366370
field_names = [self.read_zero_terminated_string() for _ in range(n_fields)]
367371
raw_data = [
368-
tuple(self.read_blob(n_bytes=int(self.read_value('uint64'))) for _ in range(n_fields))
372+
tuple(self.read_blob(n_bytes=int(self.read_value())) for _ in range(n_fields))
369373
for __ in range(n_elem)]
370374
data = np.array(raw_data, dtype=list(zip(field_names, repeat(object))))
371375
return self.squeeze(data.reshape(shape, order="F"), convert_to_scalar=False).view(MatStruct)
@@ -431,7 +435,9 @@ def read_zero_terminated_string(self):
431435
self._pos = target + 1
432436
return data
433437

434-
def read_value(self, dtype='uint64', count=1):
438+
def read_value(self, dtype=None, count=1):
439+
if dtype is None:
440+
dtype = 'uint32' if use_32bit_dims else 'uint64'
435441
data = np.frombuffer(self._blob, dtype=dtype, count=count, offset=self._pos)
436442
self._pos += data.dtype.itemsize * data.size
437443
return data[0] if count == 1 else data

datajoint/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
__version__ = "0.13.3"
1+
__version__ = "0.13.4"
22

33
assert len(__version__) <= 10 # The log table limits version to the 10 characters

docs-parts/intro/Releases_lang1.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
0.13.4 -- TBA
2+
----------------------
3+
* Add - Allow reading blobs produced by legacy 32-bit compiled mYm library for matlab. PR #995
4+
15
0.13.3 -- Feb 9, 2022
26
----------------------
37
* Bugfix - Fix error in listing ancestors, descendants with part tables.

tests/schema.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -449,3 +449,12 @@ class Stimulus(dj.Lookup):
449449
contrast: int
450450
brightness: int
451451
"""
452+
453+
454+
@schema
455+
class Longblob(dj.Manual):
456+
definition = """
457+
id: int
458+
---
459+
data: longblob
460+
"""

tests/test_blob.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1+
import datajoint as dj
12
import numpy as np
23
import uuid
4+
from . import schema
35
from decimal import Decimal
46
from datetime import datetime
57
from datajoint.blob import pack, unpack
@@ -129,3 +131,41 @@ def test_complex():
129131

130132
x = np.int16(np.random.randn(1, 2, 3)) + 1j*np.int16(np.random.randn(1, 2, 3))
131133
assert_array_equal(x, unpack(pack(x)), "Arrays do not match!")
134+
135+
136+
def test_insert_longblob():
137+
insert_dj_blob = {'id': 1, 'data': [1, 2, 3]}
138+
schema.Longblob.insert1(insert_dj_blob)
139+
assert (schema.Longblob & 'id=1').fetch1() == insert_dj_blob
140+
(schema.Longblob & 'id=1').delete()
141+
142+
query_mym_blob = {'id': 1, 'data': np.array([1, 2, 3])}
143+
schema.Longblob.insert1(query_mym_blob)
144+
assert (schema.Longblob & 'id=1').fetch1()['data'].all() == query_mym_blob['data'].all()
145+
(schema.Longblob & 'id=1').delete()
146+
147+
query_32_blob = ("INSERT INTO djtest_test1.longblob (id, data) VALUES (1, "
148+
"X'6D596D00530200000001000000010000000400000068697473007369646573007461736B73007374"
149+
"616765004D000000410200000001000000070000000600000000000000000000000000F8FF00000000"
150+
"0000F03F000000000000F03F0000000000000000000000000000F03F00000000000000000000000000"
151+
"00F8FF230000004102000000010000000700000004000000000000006C006C006C006C00720072006C"
152+
"0023000000410200000001000000070000000400000000000000640064006400640064006400640025"
153+
"00000041020000000100000008000000040000000000000053007400610067006500200031003000')")
154+
dj.conn().query(query_32_blob).fetchall()
155+
dj.blob.use_32bit_dims = True
156+
assert (schema.Longblob & 'id=1').fetch1() == {
157+
'id': 1, 'data':
158+
np.rec.array(
159+
[[
160+
(
161+
np.array([[np.nan, 1., 1., 0., 1., 0., np.nan]]),
162+
np.array(['llllrrl'], dtype='<U7'),
163+
np.array(['ddddddd'], dtype='<U7'),
164+
np.array(['Stage 10'], dtype='<U8')
165+
)
166+
]],
167+
dtype=[('hits', 'O'), ('sides', 'O'), ('tasks', 'O'), ('stage', 'O')]
168+
)
169+
}
170+
(schema.Longblob & 'id=1').delete()
171+
dj.blob.use_32bit_dims = False

0 commit comments

Comments
 (0)