12
12
from zarr .compression import get_compressor_cls
13
13
from zarr .util import is_total_slice , normalize_array_selection , \
14
14
get_chunk_range , human_readable_size , normalize_shape , normalize_chunks , \
15
- normalize_resize_args
15
+ normalize_resize_args , normalize_order
16
16
from zarr .meta import decode_metadata , encode_metadata
17
17
from zarr .attrs import Attributes , SynchronizedAttributes
18
18
from zarr .compat import itervalues
19
19
from zarr .errors import ReadOnlyError
20
20
21
21
22
22
def init_store (store , shape , chunks , dtype = None , compression = 'blosc' ,
23
- compression_opts = None , fill_value = None , overwrite = False ):
23
+ compression_opts = None , fill_value = None ,
24
+ order = 'C' , overwrite = False ):
24
25
"""Initialise an array store with the given configuration."""
25
26
26
27
# guard conditions
@@ -36,14 +37,15 @@ def init_store(store, shape, chunks, dtype=None, compression='blosc',
36
37
compression_opts = compressor_cls .normalize_opts (
37
38
compression_opts
38
39
)
40
+ order = normalize_order (order )
39
41
40
42
# delete any pre-existing items in store
41
43
store .clear ()
42
44
43
45
# initialise metadata
44
46
meta = dict (shape = shape , chunks = chunks , dtype = dtype ,
45
47
compression = compression , compression_opts = compression_opts ,
46
- fill_value = fill_value )
48
+ fill_value = fill_value , order = order )
47
49
store ['meta' ] = encode_metadata (meta )
48
50
49
51
# initialise attributes
@@ -69,9 +71,9 @@ def __init__(self, store, readonly=False):
69
71
>>> zarr.init_store(store, shape=1000, chunks=100)
70
72
>>> z = zarr.Array(store)
71
73
>>> z
72
- zarr.core.Array((1000,), float64, chunks=(100,))
74
+ zarr.core.Array((1000,), float64, chunks=(100,), order=C )
73
75
compression: blosc; compression_opts: {'clevel': 5, 'cname': 'blosclz', 'shuffle': 1}
74
- nbytes: 7.8K; nbytes_stored: 271 ; ratio: 29.5 ; initialized: 0/10
76
+ nbytes: 7.8K; nbytes_stored: 289 ; ratio: 27.7 ; initialized: 0/10
75
77
store: builtins.dict
76
78
77
79
""" # flake8: noqa
@@ -96,6 +98,7 @@ def __init__(self, store, readonly=False):
96
98
self .compression = meta ['compression' ]
97
99
self .compression_opts = meta ['compression_opts' ]
98
100
self .fill_value = meta ['fill_value' ]
101
+ self .order = meta ['order' ]
99
102
compressor_cls = get_compressor_cls (self .compression )
100
103
self .compressor = compressor_cls (self .compression_opts )
101
104
@@ -106,7 +109,7 @@ def flush_metadata(self):
106
109
meta = dict (shape = self .shape , chunks = self .chunks , dtype = self .dtype ,
107
110
compression = self .compression ,
108
111
compression_opts = self .compression_opts ,
109
- fill_value = self .fill_value )
112
+ fill_value = self .fill_value , order = self . order )
110
113
self .store ['meta' ] = encode_metadata (meta )
111
114
112
115
@property
@@ -156,7 +159,7 @@ def __getitem__(self, item):
156
159
out_shape = tuple (stop - start for start , stop in selection )
157
160
158
161
# setup output array
159
- out = np .empty (out_shape , dtype = self .dtype )
162
+ out = np .empty (out_shape , dtype = self .dtype , order = self . order )
160
163
161
164
# determine indices of chunks overlapping the selection
162
165
chunk_range = get_chunk_range (selection , self .chunks )
@@ -263,17 +266,20 @@ def _chunk_getitem(self, cidx, item, dest):
263
266
264
267
else :
265
268
266
- if is_total_slice (item , self .chunks ) and dest .flags .c_contiguous :
269
+ if is_total_slice (item , self .chunks ) and \
270
+ ((self .order == 'C' and dest .flags .c_contiguous ) or
271
+ (self .order == 'F' and dest .flags .f_contiguous )):
267
272
268
273
# optimisation: we want the whole chunk, and the destination is
269
- # C contiguous, so we can decompress directly from the chunk
274
+ # contiguous, so we can decompress directly from the chunk
270
275
# into the destination array
271
276
self .compressor .decompress (cdata , dest )
272
277
273
278
else :
274
279
275
280
# decompress chunk
276
- chunk = np .empty (self .chunks , dtype = self .dtype )
281
+ chunk = np .empty (self .chunks , dtype = self .dtype ,
282
+ order = self .order )
277
283
self .compressor .decompress (cdata , chunk )
278
284
279
285
# set data in output array
@@ -305,13 +311,17 @@ def _chunk_setitem(self, cidx, key, value):
305
311
if np .isscalar (value ):
306
312
307
313
# setup array filled with value
308
- chunk = np .empty (self .chunks , dtype = self .dtype )
314
+ chunk = np .empty (self .chunks , dtype = self .dtype ,
315
+ order = self .order )
309
316
chunk .fill (value )
310
317
311
318
else :
312
319
313
- # ensure array is C contiguous
314
- chunk = np .ascontiguousarray (value , dtype = self .dtype )
320
+ # ensure array is contiguous
321
+ if self .order == 'F' :
322
+ chunk = np .asfortranarray (value , dtype = self .dtype )
323
+ else :
324
+ chunk = np .ascontiguousarray (value , dtype = self .dtype )
315
325
316
326
else :
317
327
# partially replace the contents of this chunk
@@ -325,14 +335,16 @@ def _chunk_setitem(self, cidx, key, value):
325
335
except KeyError :
326
336
327
337
# chunk not initialized
328
- chunk = np .empty (self .chunks , dtype = self .dtype )
338
+ chunk = np .empty (self .chunks , dtype = self .dtype ,
339
+ order = self .order )
329
340
if self .fill_value is not None :
330
341
chunk .fill (self .fill_value )
331
342
332
343
else :
333
344
334
345
# decompress chunk
335
- chunk = np .empty (self .chunks , dtype = self .dtype )
346
+ chunk = np .empty (self .chunks , dtype = self .dtype ,
347
+ order = self .order )
336
348
self .compressor .decompress (cdata , chunk )
337
349
338
350
# modify
@@ -350,6 +362,7 @@ def __repr__(self):
350
362
r += '%s' % str (self .shape )
351
363
r += ', %s' % str (self .dtype )
352
364
r += ', chunks=%s' % str (self .chunks )
365
+ r += ', order=%s' % self .order
353
366
r += ')'
354
367
r += '\n compression: %s' % self .compression
355
368
r += '; compression_opts: %s' % str (self .compression_opts )
@@ -469,9 +482,9 @@ def __init__(self, store, synchronizer, readonly=False):
469
482
>>> synchronizer = zarr.ThreadSynchronizer()
470
483
>>> z = zarr.SynchronizedArray(store, synchronizer)
471
484
>>> z
472
- zarr.core.SynchronizedArray((1000,), float64, chunks=(100,))
485
+ zarr.core.SynchronizedArray((1000,), float64, chunks=(100,), order=C )
473
486
compression: blosc; compression_opts: {'clevel': 5, 'cname': 'blosclz', 'shuffle': 1}
474
- nbytes: 7.8K; nbytes_stored: 271 ; ratio: 29.5 ; initialized: 0/10
487
+ nbytes: 7.8K; nbytes_stored: 289 ; ratio: 27.7 ; initialized: 0/10
475
488
store: builtins.dict
476
489
synchronizer: zarr.sync.ThreadSynchronizer
477
490
0 commit comments