def build_and_filter(base_folder, size_pyramid, factor, thresh_factor=1):
    """Build a filtered pyramid of contact maps
 
    Build a fragment pyramid for multi-scale analysis and remove high sparsity
    (i.e. low-coverage) and short fragments.

    Parameters
    ----------
    base_folder : str or pathlib.Path
        Where to create the hdf5 files containing the matrices.
    size_pyramid : int
        How many levels (contact maps of decreasing resolution) to generate.
    factor : int
        Subsampling factor (binning) from one level to the next.
    thresh_factor : float, optional
        Number of standard deviations below the mean coverage beyond which
        lesser covered fragments will be discarded. Default is 1.

    Returns
    -------
    obj_pyramid : Pyramid
        The pyramid object containing all the levels.
    """

    min_bin_per_contig = 1
    fact_sub_sampling = factor

    all_pyramid_folder = os.path.join(base_folder, "pyramids")
    if not (os.path.exists(all_pyramid_folder)):
        os.mkdir(all_pyramid_folder)
    init_pyramid_folder = os.path.join(
        all_pyramid_folder, "pyramid_" + str(1) + "_no_thresh"
    )
    if not (os.path.exists(init_pyramid_folder)):
        init_size_pyramid = 1
        build(base_folder, init_size_pyramid, factor, min_bin_per_contig)
    init_pyramid_folder_level_0 = os.path.join(init_pyramid_folder, "level_0")
    contig_info = os.path.join(
        init_pyramid_folder_level_0, "0_contig_info.txt"
    )
    fragments_list = os.path.join(
        init_pyramid_folder_level_0, "0_fragments_list.txt"
    )
    init_abs_fragments_contacts = os.path.join(
        init_pyramid_folder_level_0, "0_abs_frag_contacts.txt"
    )

    init_pyramid_file = os.path.join(init_pyramid_folder, "pyramid.hdf5")

    pyramid_folder = os.path.join(
        all_pyramid_folder, "pyramid_" + str(size_pyramid) + "_thresh_auto"
    )
    if not (os.path.exists(pyramid_folder)):
        os.mkdir(pyramid_folder)
    level = 0
    pyramid_level_folder = os.path.join(pyramid_folder, "level_" + str(level))
    if not (os.path.exists(pyramid_level_folder)):
        os.mkdir(pyramid_level_folder)

    current_contig_info = os.path.join(
        pyramid_level_folder, str(level) + "_contig_info.txt"
    )
    current_frag_list = os.path.join(
        pyramid_level_folder, str(level) + "_fragments_list.txt"
    )
    current_abs_fragments_contacts = os.path.join(
        pyramid_level_folder, str(level) + "_abs_frag_contacts.txt"
    )
    if not (
        os.path.exists(current_contig_info)
        and os.path.exists(current_frag_list)
        and os.path.exists(current_abs_fragments_contacts)
    ):
        logger.info("start filtering")
        pyramid_0 = h5py.File(init_pyramid_file)

        remove_problematic_fragments(
            contig_info,
            fragments_list,
            init_abs_fragments_contacts,
            current_contig_info,
            current_frag_list,
            current_abs_fragments_contacts,
            pyramid_0,
            thresh_factor=thresh_factor,
        )
        pyramid_0.close()
        #
    else:
        logger.info("filtering already done...")

    hdf5_pyramid_file = os.path.join(pyramid_folder, "pyramid.hdf5")

    pyramid_handle = h5py.File(hdf5_pyramid_file)

    pyramid_level_folder = os.path.join(pyramid_folder, "level_" + str(level))
    level_pyramid = str(level) + "_"
    sub_2_super_frag_index_file = os.path.join(
        pyramid_level_folder, level_pyramid + "sub_2_super_index_frag.txt"
    )
    for level in range(0, size_pyramid):
        pyramid_level_folder = os.path.join(
            pyramid_folder, "level_" + str(level)
        )
        if not (os.path.exists(pyramid_level_folder)):
            os.mkdir(pyramid_level_folder)
        level_pyramid = str(level) + "_"
        new_contig_list_file = os.path.join(
            pyramid_level_folder, level_pyramid + "contig_info.txt"
        )
        new_fragments_list_file = os.path.join(
            pyramid_level_folder, level_pyramid + "fragments_list.txt"
        )
        new_abs_fragments_contacts_file = os.path.join(
            pyramid_level_folder, level_pyramid + "abs_frag_contacts.txt"
        )

        if level > 0:
            if (
                os.path.exists(new_contig_list_file)
                and os.path.exists(new_fragments_list_file)
                and os.path.exists(new_abs_fragments_contacts_file)
                and os.path.exists((sub_2_super_frag_index_file))
            ):
                logger.info("level already built")
                nfrags = file_len(new_fragments_list_file) - 1
            else:  # this should never append !!!
                logger.info("writing new_files..")
                nfrags = subsample_data_set(
                    current_contig_info,
                    current_frag_list,
                    fact_sub_sampling,
                    current_abs_fragments_contacts,
                    new_abs_fragments_contacts_file,
                    min_bin_per_contig,
                    new_contig_list_file,
                    new_fragments_list_file,
                    sub_2_super_frag_index_file,
                )
        else:
            if (
                os.path.exists(new_contig_list_file)
                and os.path.exists(new_fragments_list_file)
                and os.path.exists(new_abs_fragments_contacts_file)
            ):
                logger.info("level already built...")
                nfrags = file_len(new_fragments_list_file) - 1

        try:
            status = pyramid_handle.attrs[str(level)] == "done"
        except KeyError:
            pyramid_handle.attrs[str(level)] = "pending"
            status = False
        if not (status):
            logger.info("Start filling the pyramid")
            # level_to_fill = pyramid_handle.create_dataset(str(level),
            # (nfrags,nfrags), 'i')
            # fill_pyramid_level(level_to_fill,new_abs_fragments_contacts_file,
            # size_chunk,nfrags)
            fill_sparse_pyramid_level(
                pyramid_handle, level, new_abs_fragments_contacts_file, nfrags
            )
            pyramid_handle.attrs[str(level)] = "done"

        current_frag_list = new_fragments_list_file
        current_contig_info = new_contig_list_file
        current_abs_fragments_contacts = new_abs_fragments_contacts_file
        sub_2_super_frag_index_file = os.path.join(
            pyramid_level_folder, level_pyramid + "sub_2_super_index_frag.txt"
        )
    logger.info("pyramid built.")

    obj_pyramid = pyramid(pyramid_folder, size_pyramid)
    pyramid_handle.close()
    return obj_pyramid
Build a filtered pyramid of contact maps
 
    Build a fragment pyramid for multi-scale analysis and remove high sparsity
    (i.e. low-coverage) and short fragments.

    Parameters
    ----------
    base_folder : str or pathlib.Path
        Where to create the hdf5 files containing the matrices.
    size_pyramid : int
        How many levels (contact maps of decreasing resolution) to generate.
    factor : int
        Subsampling factor (binning) from one level to the next.
    thresh_factor : float, optional
        Number of standard deviations below the mean coverage beyond which
        lesser covered fragments will be discarded. Default is 1.

    Returns
    -------
    obj_pyramid : Pyramid
        The pyramid object containing all the levels.