@_func_wrapper
    def get(self, path="/", cascade=True, lazy=False, lazy_loaded=False):
        """ Returns a requested NEO object as instance of NEO class.
        Set lazy_loaded to True to load a previously lazily loaded object
        (cache is ignored in this case)."""
        def fetch_attribute(attr_name, attr, node):
            """ fetch required attribute from the corresp. node in the file """
            try:
                if attr[1] == pq.Quantity:
                    arr = self._data.getNode(node, attr_name)
                    units = ""
                    for unit in arr._v_attrs._f_list(attrset='user'):
                        if unit.startswith("unit__"):
                            units += " * " + str(unit[6:]) + " ** " + str(arr._f_getAttr(unit))
                    units = units.replace(" * ", "", 1)
                    if not lazy or sum(arr.shape) <= 1:
                        nattr = pq.Quantity(arr.read(), units)
                    else:  # making an empty array
                        nattr = pq.Quantity(np.empty(tuple([0 for _ in range(attr[2])])), units)
                elif attr[1] == np.ndarray:
                    arr = self._data.getNode(node, attr_name)
                    if not lazy:
                        nattr = np.array(arr.read(), attr[3])
                        if nattr.shape == (0, 1):  # Fix: Empty arrays should have only one dimension
                            nattr = nattr.reshape(-1)
                    else:  # making an empty array
                        nattr = np.empty(0, attr[3])
                else:
                    nattr = node._f_getAttr(attr_name)
                    if attr[1] == str or attr[1] == int:
                        nattr = attr[1](nattr)  # compliance with NEO attr types
            except (AttributeError, tb.NoSuchNodeError):  # not assigned, continue
                nattr = None
            return nattr

        def get_lazy_shape(obj, node):
            attr = lazy_shape_arrays[type(obj).__name__]
            arr = self._data.getNode(node, attr)
            return arr.shape

        if path == "/":  # this is just for convenience. Try to return any object
            found = False
            for n in self._data.iterNodes(path):
                for obj_type in objectnames:
                    if obj_type.lower() in str(n._v_name).lower():
                        path = n._v_pathname
                        found = True
                if found:
                    break
        try:
            if path == "/":
                raise ValueError()  # root is not a NEO object
            node = self._data.getNode(path)
        except (tb.NoSuchNodeError, ValueError):  # create a new node?
            raise LookupError("There is no valid object with a given path " +
                              str(path) + ' . Please give correct path or just browse the file '
                              '(e.g. NeoHdf5IO()._data.root.<Block>._segments...) to find an '
                              'appropriate name.')
        classname = self._get_class_by_node(node)
        if not classname:
            raise LookupError("The requested object with the path " + str(path) +
                              " exists, but is not of a NEO type. Please check the '_type' attribute.")

        obj_type = classname.__name__
        try:
            object_ref = self._data.getNodeAttr(node, 'object_ref')
        except AttributeError:  # Object does not have reference, e.g. because this is an old file format
            object_ref = None
        if object_ref in self.objects_by_ref and not lazy_loaded:
            obj = self.objects_by_ref[object_ref]
            if cascade == 'lazy' or obj_type not in complex_relationships:
                return obj
        else:
            kwargs = {}
            # load attributes (inherited *-ed attrs are also here)
            attrs = classname._necessary_attrs + classname._recommended_attrs
            for i, attr in enumerate(attrs):
                attr_name = attr[0]
                nattr = fetch_attribute(attr_name, attr, node)
                if nattr is not None:
                    kwargs[attr_name] = nattr
            obj = class_by_name[obj_type](**kwargs)  # instantiate new object
            if lazy and obj_type in lazy_shape_arrays:
                obj.lazy_shape = get_lazy_shape(obj, node)
            self._update_path(obj, node)  # set up HDF attributes: name, path
            try:
                setattr(obj, "annotations", node._f_getAttr("annotations"))
            except AttributeError:
                pass  # not assigned, continue

        if object_ref and not lazy_loaded:
            self.objects_by_ref[object_ref] = obj
        # load relationships
        if cascade:
            # container is like segments, spiketrains, etc.
            for containername in getattr(obj, '_child_containers', []):
                if cascade == 'lazy':
                    relatives = LazyList(self, lazy)
                else:
                    relatives = []
                container = self._data.getNode(node, containername)
                for n in self._data.iterNodes(container):
                    if cascade == 'lazy':
                        relatives.append(n._v_pathname)
                    else:
                        try:
                            typename = n._f_getAttr("_type").lower()+'s'
                            if typename == containername:
                                relatives.append(self.get(n._v_pathname, lazy=lazy))
                        except AttributeError:  # alien node
                            pass  # not an error
                setattr(obj, containername, relatives)
                if not cascade == 'lazy':
                    # RC -> AnalogSignal relationship will not be created later, do it now
                    if obj_type == "RecordingChannel" and containername == "analogsignals":
                        for r in relatives:
                            r.recordingchannel = obj
                    # Cannot create Many-to-Many relationship with old format, create at least One-to-Many
                    if obj_type == "RecordingChannelGroup" and not object_ref:
                        for r in relatives:
                            r.recordingchannelgroups = [obj]
            # special processor for RC -> RCG
            if obj_type == "RecordingChannel":
                if hasattr(node, '_v_parent'):
                    parent = node._v_parent
                    if hasattr(parent, '_v_parent'):
                        parent = parent._v_parent
                        if 'object_ref' in parent._v_attrs:
                            obj.recordingchannelgroups.append(self.get(
                                parent._v_pathname, lazy=lazy))
        return obj
dataset/ETHPy150Open NeuralEnsemble/python-neo/neo/io/hdf5io.py/NeoHdf5IO.get/original