@staticmethod
def _data_by_tri(data_dict):
    """
        Nest the data by derived context and outgroup base.

        The resulting dictionary contains only SNPs which are appropriate for
        use of Hernandez's ancestral misidentification correction. It is
        organized as {(derived_tri, outgroup_base): {snp_id: data,...}}
        """
    result = {}
    genetic_bases = 'ACTG'
    for snp, snp_info in data_dict.items():
        if len(snp_info['segregating']) != 2:
            continue
        allele1, allele2 = snp_info['segregating']
        try:
            ingroup_tri = snp_info['context']
            outgroup_tri = snp_info['outgroup_context']
        except KeyError:
            continue
        if not outgroup_tri[1] == snp_info['outgroup_allele']:
            raise ValueError(
                'Outgroup context and allele are inconsistent for polymorphism: %s.'
                 % snp)
        outgroup_allele = outgroup_tri[1]
        if outgroup_tri[0] != ingroup_tri[0] or outgroup_tri[2] != ingroup_tri[
            2] or ingroup_tri[0] not in genetic_bases or ingroup_tri[2
            ] not in genetic_bases or outgroup_allele not in [allele1, allele2
            ] or allele1 not in genetic_bases or allele2 not in genetic_bases:
            continue
        if allele1 == outgroup_allele:
            derived_allele = allele2
        elif allele2 == outgroup_allele:
            derived_allele = allele1
        derived_tri = ingroup_tri[0] + derived_allele + ingroup_tri[2]
        result.setdefault((derived_tri, outgroup_allele), {})
        result[derived_tri, outgroup_allele][snp] = snp_info
    return result
