def METHOD_NAME(
    params: DataHandler,
    mask_ambiguous: np.ndarray,
    mask_has_ir: np.ndarray,
    mask_multichain: np.ndarray,
) -> np.ndarray:
    """Annotate chain pairing categories.
    Parameters
    ----------
    mask_ambiguous
        boolean array of the same length as `adata.obs`, marking
        which cells have an ambiguous receptor configuration.
    """
    string_length = len("two full chains")
    results = np.empty(dtype=f"<U{string_length}", shape=(params.adata.shape[0],))
    logging.debug("Done initalizing")
    mask_has_vj1 = ~_is_na(get.airr(params, "junction_aa", "VJ_1").values)
    mask_has_vdj1 = ~_is_na(get.airr(params, "junction_aa", "VDJ_1").values)
    mask_has_vj2 = ~_is_na(get.airr(params, "junction_aa", "VJ_2").values)
    mask_has_vdj2 = ~_is_na(get.airr(params, "junction_aa", "VDJ_2").values)
    logging.debug("Done with masks")
    for m in [mask_has_vj1, mask_has_vdj1, mask_has_vj2, mask_has_vdj2]:
        # no cell can have a junction_aa sequence but no TCR
        assert np.setdiff1d(np.where(m)[0], np.where(mask_has_ir)[0]).size == 0
    results[~mask_has_ir] = "no IR"
    results[mask_has_vj1] = "orphan VJ"
    results[mask_has_vdj1] = "orphan VDJ"
    results[mask_has_vj1 & mask_has_vdj1] = "single pair"
    results[mask_has_vj1 & mask_has_vdj1 & mask_has_vj2] = "extra VJ"
    results[mask_has_vj1 & mask_has_vdj1 & mask_has_vdj2] = "extra VDJ"
    results[mask_has_vj1 & mask_has_vdj1 & mask_has_vj2 & mask_has_vdj2] = "two full chains"
    results[mask_ambiguous] = "ambiguous"
    results[mask_multichain] = "multichain"
    assert "" not in results, "One or more chains are not characterized"
    return results