<jupyter_start><jupyter_text>5 Groups and Links Objectives: * Create groups and subgroups * List contents of a group * Iterate though all objects in a file<jupyter_code>USE_H5PY=0  # set to 0 to use HDF Server instead
if USE_H5PY:
    import h5py
else:
    import h5pyd as h5py
import os
#
# Get folder/directory for HDF files we create  
#
def getMyFolder():
    DIR_NAME = "HDFLabTutorial/"
    if USE_H5PY:
        myfolder = os.getenv("HOME") + "/" + DIR_NAME
        if not os.path.isdir(myfolder):
            # create a directory on the local disk if needed
            print("created folder:", myfolder)
            os.mkdir(myfolder)
    else:
        dir = h5py.Folder('/home/')  # get folder object for root
        username = os.getenv("JUPYTERHUB_USER")
        myfolder = None
        for name in dir:
            # we should come across the given domain
            if username.startswith(name):
                # check any folders where the name matches at least part of the username
                # e.g. folder: "/home/bob/" for username "<EMAIL>"
                path = '/home/' + name + '/'
                f = h5py.Folder(path)
                if f.owner == username:
                    myfolder = path
                f.close()
                if myfolder:
                    break

        dir.close()
    
        # create a workshop subfolder if not already present
        myfolder += DIR_NAME
        try:
            h5py.Folder(myfolder)
        except IOError as ioe:
            if ioe.errno != 404:
                return None  # unexpected error
            # not present - create it now
            h5py.Folder(myfolder, mode='x')
            print("created folder:", myfolder)
       
    return myfolder
# Get your home folder
# will be a posix directory is H5PY is 1, or a server folder if 0
home = getMyFolder()
home  # this is the folder where you have permission to write to
# create a file on the disk, or a domain on the server (based on USE_H5PY)
filename = home + "05.h5"
f = h5py.File(filename, 'w')
# the file handle is also the root group
if isinstance(f,h5py.Group):
    print("f is a Group instance")
else:
    print("this is unexpected!")
# For h5py, the id is an integer.
# For h5pyd, the id is a UUID.  The "g-" prefix of the id indicates that this is a group

f.id.id
list(f)  # no groups in root (yet)!
# create two groups
if "g1" not in f:
    f.create_group("g1")
if "g2" not in f:
    f.create_group("g2") 
g1 = f["g1"]
g2 = f["g2"]
print("g1 id:", g1.id.id)
print("g2 id:", g2.id.id)   
list(f)<jupyter_output><empty_output><jupyter_text>Problem:  Use the hsls or h5ls to list contents of file<jupyter_code># each object has a name property that gives the h5path of the object 
g1.name
# create a scalar (just one element) dataset
f.create_dataset("dset1", data=42)
# now the root group has two sub-groups and one dataset
# we can do a typical Python iteration
for x in f:
    print(x, f[x].id.id)
# You can treat groups like Python dictionaries.
# Look up an item by providing the name
f["dset1"].dtype
# every object has a file property that will lead you back to the file
# it belongs to (in case you got lost)
g1.file
# groups can have sub-groups
g1.create_group("g1.1")
# you can address it by name from the parent group
g1["g1.1"].id.id
# of by an h5path from root
f["/g1/g1.1"].id.id
g2 = f["g2"]
g1_1 = g1["g1.1"]
# You can create links to existing objects
g2["g1.1"] = g1_1<jupyter_output><empty_output><jupyter_text>Problem: Run hsls or h5ls on this file with the -r option<jupyter_code># soft links create a link by name that may or may not refer to an actual object
f["softlink"] = h5py.SoftLink("/g2/dset")
# the links show up in a list
list(f)
# but in this case it doesn't refer to anything
try:
    print("softlink:", f["softlink"])
except KeyError as ke:
    print("error:", ke)
# external links can point to an object in another file
# (This link won't be valid for h5py, but works with h5pyd)
f["external_link"] = h5py.ExternalLink("/shared/tall.h5", "/g1/g1.1/dset1.1.1")
# now you can reference it as if it was a part of the file
if not USE_H5PY:
    print("external shape:", f["external_link"].shape)
# To iterate through all the members of a group recursively use the visit method
def printname(name):
    print(name)
f.visit(printname)<jupyter_output>g2
g2/g1.1
g1
dset1
{'fraction_non_alphanumeric': 0.09942594718714122, 'fraction_numerical': 0.020436280137772676, 'mean_word_length': 2.7358490566037736, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '3', 'dir': 'jupyter-structured-clean-dedup', 'id': '418044', 'license': 'MIT', 'n_tokens_mistral': 1459, 'n_tokens_neox': 1421, 'n_words': 550, 'path': 'Tutorial/05-GroupsAndLinks.ipynb', 'repo_name': 'HDFGroup/hdflab_examples', 'size': '4360'}