|
11 | 11 | from zarr.hierarchy import open_group, group as _create_group, Group
|
12 | 12 | from zarr.storage import contains_array, contains_group
|
13 | 13 | from zarr.errors import err_path_not_found
|
14 |
| -from zarr.util import normalize_storage_path |
| 14 | +from zarr.util import normalize_storage_path, TreeViewer |
15 | 15 |
|
16 | 16 |
|
17 | 17 | # noinspection PyShadowingBuiltins
|
@@ -507,16 +507,59 @@ def copy_store(source, dest, source_path='', dest_path='', excludes=None,
|
507 | 507 | dest[dest_key] = source[source_key]
|
508 | 508 |
|
509 | 509 |
|
510 |
| -def copy(source, dest, name=None, without_attrs=False, log=None, **create_kws): |
511 |
| - """TODO""" |
| 510 | +def copy(source, dest, name=None, shallow=False, without_attrs=False, log=None, |
| 511 | + **create_kws): |
| 512 | + """Copy the source object into the given destination. |
| 513 | +
|
| 514 | + Parameters |
| 515 | + ---------- |
| 516 | + source : group or array/dataset |
| 517 | + A zarr group or array, or an h5py group or dataset. |
| 518 | + dest : group |
| 519 | + A zarr or h5py group. |
| 520 | + name : str, optional |
| 521 | + Name to copy the object to. |
| 522 | + shallow : bool, optional |
| 523 | + If True, only copy immediate children of `source`. |
| 524 | + without_attrs : bool, optional |
| 525 | + Do not copy user attributes. |
| 526 | + log : callable, file path or file-like object, optional |
| 527 | + If provided, will be used to log progress information. |
| 528 | + **create_kws |
| 529 | + Passed through to the create_dataset method when copying an array/dataset. |
| 530 | +
|
| 531 | + Examples |
| 532 | + -------- |
| 533 | + >>> import h5py |
| 534 | + >>> import zarr |
| 535 | + >>> import numpy as np |
| 536 | + >>> source = h5py.File('data/example.h5', mode='w') |
| 537 | + >>> foo = source.create_group('foo') |
| 538 | + >>> baz = foo.create_dataset('bar/baz', data=np.arange(100), chunks=(50,)) |
| 539 | + >>> spam = source.create_dataset('spam', data=np.arange(100, 200), chunks=(30,)) |
| 540 | + >>> zarr.tree(source) |
| 541 | + / |
| 542 | + ├── foo |
| 543 | + │ └── bar |
| 544 | + │ └── baz (100,) int64 |
| 545 | + └── spam (100,) int64 |
| 546 | + >>> dest = zarr.group() |
| 547 | + >>> zarr.copy(source['foo'], dest) |
| 548 | + >>> dest.tree() # N.B., no spam |
| 549 | + / |
| 550 | + └── foo |
| 551 | + └── bar |
| 552 | + └── baz (100,) int64 |
| 553 | +
|
| 554 | + """ |
512 | 555 |
|
513 | 556 | # setup logging
|
514 | 557 | with _LogWriter(log) as log:
|
515 |
| - _copy(log, source, dest, name=name, without_attrs=without_attrs, **create_kws) |
| 558 | + _copy(log, source, dest, name=name, root=True, shallow=shallow, |
| 559 | + without_attrs=without_attrs, **create_kws) |
516 | 560 |
|
517 | 561 |
|
518 |
| -def _copy(log, source, dest, name=None, without_attrs=False, **create_kws): |
519 |
| - """TODO""" |
| 562 | +def _copy(log, source, dest, name, root, shallow, without_attrs, **create_kws): |
520 | 563 |
|
521 | 564 | # are we copying to/from h5py?
|
522 | 565 | source_h5py = source.__module__.startswith('h5py.')
|
@@ -569,4 +612,119 @@ def _copy(log, source, dest, name=None, without_attrs=False, **create_kws):
|
569 | 612 | if not without_attrs:
|
570 | 613 | ds.attrs.update(source.attrs)
|
571 | 614 |
|
572 |
| - else: |
| 615 | + elif root or not shallow: |
| 616 | + # copy a group |
| 617 | + |
| 618 | + # creat new group in destination |
| 619 | + grp = dest.create_group(name) |
| 620 | + |
| 621 | + # copy attributes |
| 622 | + if not without_attrs: |
| 623 | + grp.attrs.update(source.attrs) |
| 624 | + |
| 625 | + # recurse |
| 626 | + for k in source.keys(): |
| 627 | + _copy(log, source[k], grp, name=k, root=False, shallow=shallow, |
| 628 | + without_attrs=without_attrs, **create_kws) |
| 629 | + |
| 630 | + |
| 631 | +def tree(grp, expand=False, level=None): |
| 632 | + """Provide a ``print``-able display of the hierarchy. This function is provided |
| 633 | + mainly as a convenience for obtaining a tree view of an h5py group - zarr groups |
| 634 | + have a ``.tree()`` method. |
| 635 | +
|
| 636 | + Parameters |
| 637 | + ---------- |
| 638 | + grp : Group |
| 639 | + Zarr or h5py group. |
| 640 | + expand : bool, optional |
| 641 | + Only relevant for HTML representation. If True, tree will be fully expanded. |
| 642 | + level : int, optional |
| 643 | + Maximum depth to descend into hierarchy. |
| 644 | +
|
| 645 | + Examples |
| 646 | + -------- |
| 647 | + >>> import zarr |
| 648 | + >>> g1 = zarr.group() |
| 649 | + >>> g2 = g1.create_group('foo') |
| 650 | + >>> g3 = g1.create_group('bar') |
| 651 | + >>> g4 = g3.create_group('baz') |
| 652 | + >>> g5 = g3.create_group('qux') |
| 653 | + >>> d1 = g5.create_dataset('baz', shape=100, chunks=10) |
| 654 | + >>> g1.tree() |
| 655 | + / |
| 656 | + ├── bar |
| 657 | + │ ├── baz |
| 658 | + │ └── qux |
| 659 | + │ └── baz (100,) float64 |
| 660 | + └── foo |
| 661 | + >>> import h5py |
| 662 | + >>> h5f = h5py.File('data/example.h5', mode='w') |
| 663 | + >>> zarr.copy_all(g1, h5f) |
| 664 | + >>> zarr.tree(h5f) |
| 665 | + / |
| 666 | + ├── bar |
| 667 | + │ ├── baz |
| 668 | + │ └── qux |
| 669 | + │ └── baz (100,) float64 |
| 670 | + └── foo |
| 671 | +
|
| 672 | + See Also |
| 673 | + -------- |
| 674 | + zarr.hierarchy.Group.tree |
| 675 | +
|
| 676 | + """ |
| 677 | + |
| 678 | + return TreeViewer(grp, expand=expand, level=level) |
| 679 | + |
| 680 | + |
| 681 | +def copy_all(source, dest, shallow=False, without_attrs=False, log=None, **create_kws): |
| 682 | + """Copy all children of the source group into the destination group. |
| 683 | +
|
| 684 | + Parameters |
| 685 | + ---------- |
| 686 | + source : group or array/dataset |
| 687 | + A zarr group or array, or an h5py group or dataset. |
| 688 | + dest : group |
| 689 | + A zarr or h5py group. |
| 690 | + shallow : bool, optional |
| 691 | + If True, only copy immediate children of `source`. |
| 692 | + without_attrs : bool, optional |
| 693 | + Do not copy user attributes. |
| 694 | + log : callable, file path or file-like object, optional |
| 695 | + If provided, will be used to log progress information. |
| 696 | + **create_kws |
| 697 | + Passed through to the create_dataset method when copying an array/dataset. |
| 698 | +
|
| 699 | + Examples |
| 700 | + -------- |
| 701 | + >>> import h5py |
| 702 | + >>> import zarr |
| 703 | + >>> import numpy as np |
| 704 | + >>> source = h5py.File('data/example.h5', mode='w') |
| 705 | + >>> foo = source.create_group('foo') |
| 706 | + >>> baz = foo.create_dataset('bar/baz', data=np.arange(100), chunks=(50,)) |
| 707 | + >>> spam = source.create_dataset('spam', data=np.arange(100, 200), chunks=(30,)) |
| 708 | + >>> zarr.tree(source) |
| 709 | + / |
| 710 | + ├── foo |
| 711 | + │ └── bar |
| 712 | + │ └── baz (100,) int64 |
| 713 | + └── spam (100,) int64 |
| 714 | + >>> dest = zarr.group() |
| 715 | + >>> zarr.copy_all(source, dest) |
| 716 | + >>> dest.tree() |
| 717 | + / |
| 718 | + ├── foo |
| 719 | + │ └── bar |
| 720 | + │ └── baz (100,) int64 |
| 721 | + └── spam (100,) int64 |
| 722 | +
|
| 723 | + """ |
| 724 | + |
| 725 | + # setup logging |
| 726 | + with _LogWriter(log) as log: |
| 727 | + for k in source.keys(): |
| 728 | + _copy(log, source[k], dest, name=k, root=False, shallow=shallow, |
| 729 | + without_attrs=without_attrs, **create_kws) |
| 730 | + |
0 commit comments