<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def read_10x_h5(filename, genome=None, gex_only=True) -> AnnData: """Read 10x-Genomics-formatted hdf5 file. Parameters filename : `str` | :class:`~pathlib.Path` Filename. genome : `str`, optional (default: ``None``) Filter expression to this genes within this genome. For legacy 10x h5 files, this must be provided if the data contains more than one genome. gex_only : `bool`, optional (default: `True`) Only keep 'Gene Expression' data and ignore other feature types, e.g. 'Antibody Capture', 'CRISPR Guide Capture', or 'Custom' Returns ------- Annotated data matrix, where obsevations/cells are named by their barcode and variables/genes by gene name. The data matrix is stored in `adata.X`, cell names in `adata.obs_names` and gene names in `adata.var_names`. The gene IDs are stored in `adata.var['gene_ids']`. The feature types are stored in `adata.var['feature_types']` """

    logg.info('reading', filename, r=True, end=' ')
    with tables.open_file(str(filename), 'r') as f:
        v3 = '/matrix' in f
    if v3:
        adata = _read_v3_10x_h5(filename)
        if genome:
            if genome not in adata.var['genome'].values:
                raise ValueError(
                    "Could not find data corresponding to genome '{genome}' in '{filename}'. "
                    "Available genomes are: {avail}."
                    .format(
                        genome=genome, filename=filename,
                        avail=list(adata.var["genome"].unique()),
                    )
                )
            adata = adata[:, list(map(lambda x: x == str(genome), adata.var['genome']))]
        if gex_only:
            adata = adata[:, list(map(lambda x: x == 'Gene Expression', adata.var['feature_types']))]
        return adata
    else:
        return _read_legacy_10x_h5(filename, genome=genome)