# Buggy code
def _read_fluid_selection(self, chunks, selector, fields, size):
    """Reads given fields masked by a given selection.

    Parameters
    ----------
    chunks
        A list of chunks
        A chunk is a list of grids
    selector
        A region (inside your domain) specifying which parts of the field you want to read
        See [1] and [2]
    fields : array_like
        Tuples (fname, ftype) representing a field
    size : int
        Size of the data to read

    Returns
    -------
    dict
        keys are tuples (ftype, fname) representing a field
        values are flat (``size``,) ndarrays with data from that field
    """
    f = self._handle
    bp = self.base_path
    mp = self.meshes_path
    ds = f[bp + mp]
    chunks = list(chunks)

    rv = {}
    ind = {}

    if isinstance(selector, GridSelector):
        if not (len(chunks) == len(chunks[0].objs) == 1):
            raise RuntimeError

    if size is None:
        size = sum((g.count(selector) for chunk in chunks for g in chunk.objs))
    for field in fields:
        rv[field] = np.empty(size, dtype=np.float64)
        ind[field] = 0

    for ftype, fname in fields:
        field = (ftype, fname)
        for chunk in chunks:
            for grid in chunk.objs:
                component = fname.replace("_", "/").replace("-", "_")
                if component.split("/")[0] not in grid.ftypes:
                    continue
                mask = grid._get_selector_mask(selector)
                if mask is None:
                    continue
                data = get_component(ds, component, grid.findex, grid.foffset)
                # The following is a modified AMRGridPatch.select(...)
                data.shape = (
                    mask.shape
                )  # Workaround - casts a 2D (x,y) array to 3D (x,y,1)
                count = grid.count(selector)
                rv[field][ind[field] : ind[field] + count] = data[mask]
                ind[field] += count

    for field in fields:
        rv[field] = rv[field][: ind[field]]
        rv[field].flatten()

    return rv


# Traceback (KeyError)
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-6-606762cc9ee1> in <module>()
----> 1 yt.load('./example-ptcl/hdf5/data00000400.h5')

~/miniconda3/lib/python3.6/site-packages/yt/convenience.py in load(*args, **kwargs)
84     candidates = find_lowest_subclasses(candidates)
85     if len(candidates) == 1:
---> 86         return candidates[0](*args, **kwargs)
87     if len(candidates) == 0:
88         if ytcfg.get("yt", "enzo_db") != '' \

~/miniconda3/lib/python3.6/site-packages/yt/frontends/open_pmd/data_structures.py in __init__(self, filename, dataset_type, storage_filename, units_override, unit_system, **kwargs)
385         self.storage_filename = storage_filename
386         self.fluid_types += ("openPMD",)
--> 387         particles = tuple(str(c) for c in self._handle[self.base_path + self.particles_path].keys())
388         if len(particles) > 1:
389             # Only use on-disk particle names if there is more than one species

~/miniconda3/lib/python3.6/site-packages/yt/utilities/file_handler.py in __getitem__(self, key)
43
44     def __getitem__(self, key):
---> 45         return self.handle[key]
46
47     def __contains__(self, item):

h5py/_objects.pyx in h5py._objects.with_phil.wrapper (/Users/ilan/minonda/conda-bld/h5py_1496887972496/work/h5py/_objects.c:2846)()

h5py/_objects.pyx in h5py._objects.with_phil.wrapper (/Users/ilan/minonda/conda-bld/h5py_1496887972496/work/h5py/_objects.c:2804)()

~/miniconda3/lib/python3.6/site-packages/h5py/_hl/group.py in __getitem__(self, name)
167                 raise ValueError("Invalid HDF5 object reference")
168         else:
--> 169             oid = h5o.open(self.id, self._e(name), lapl=self._lapl)
170
171         otype = h5i.get_type(oid)

h5py/_objects.pyx in h5py._objects.with_phil.wrapper (/Users/ilan/minonda/conda-bld/h5py_1496887972496/work/h5py/_objects.c:2846)()

h5py/_objects.pyx in h5py._objects.with_phil.wrapper (/Users/ilan/minonda/conda-bld/h5py_1496887972496/work/h5py/_objects.c:2804)()

h5py/h5o.pyx in h5py.h5o.open (/Users/ilan/minonda/conda-bld/h5py_1496887972496/work/h5py/h5o.c:3740)()

KeyError: "Unable to open object (Object 'particles' doesn't exist)"

# Fixed code
def _read_fluid_selection(self, chunks, selector, fields, size):
    """Reads given fields masked by a given selection.

    Parameters
    ----------
    chunks
        A list of chunks
        A chunk is a list of grids
    selector
        A region (inside your domain) specifying which parts of the field you want to read
        See [1] and [2]
    fields : array_like
        Tuples (fname, ftype) representing a field
    size : int
        Size of the data to read

    Returns
    -------
    dict
        keys are tuples (ftype, fname) representing a field
        values are flat (``size``,) ndarrays with data from that field
    """
    f = self._handle
    bp = self.base_path
    mp = self.meshes_path
    ds = f[bp + mp]
    chunks = list(chunks)

    rv = {}
    ind = {}

    if isinstance(selector, GridSelector):
        if not (len(chunks) == len(chunks[0].objs) == 1):
            raise RuntimeError

    if size is None:
        size = sum((g.count(selector) for chunk in chunks for g in chunk.objs))
    for field in fields:
        rv[field] = np.empty(size, dtype=np.float64)
        ind[field] = 0

    for ftype, fname in fields:
        field = (ftype, fname)
        for chunk in chunks:
            for grid in chunk.objs:
                mask = grid._get_selector_mask(selector)
                if mask is None:
                    continue
                component = fname.replace("_", "/").replace("-", "_")
                if component.split("/")[0] not in grid.ftypes:
                    data = np.full(grid.ActiveDimensions, 0, dtype=np.float64)
                else:
                    data = get_component(ds, component, grid.findex, grid.foffset)
                # The following is a modified AMRGridPatch.select(...)
                data.shape = (
                    mask.shape
                )  # Workaround - casts a 2D (x,y) array to 3D (x,y,1)
                count = grid.count(selector)
                rv[field][ind[field] : ind[field] + count] = data[mask]
                ind[field] += count

    for field in fields:
        rv[field] = rv[field][: ind[field]]
        rv[field].flatten()

    return rv