# Path: denovoFilter/check_independence.py
# def check_independence(de_novos, family_ids):
#     """ identify de novos that would otherwise lead to double counting.
#     
#     This is so we can remove de novos that are shared between multiple probands
#     of a family or that are recurrent in a single gene in a single person.
#     
#     Args:
#         de_novos: dataframe of de novo variants
#         family_ids: dictionary of family IDs, indexed by individual IDs.
#     
#     Returns:
#         pandas Series indicating whether each site is independent
#     """
#     
#     family_dups = family_recurrence(de_novos, family_ids)
#     person_dups = person_recurrence(de_novos)
#     
#     return ~family_dups & ~person_dups
# 
# def person_recurrence(de_novos):
#     """ identify de novos recurrent in a gene within individuals.
#     
#     Find the de novos that are recurrent within a single individual in a
#     single gene. We shall treat these as a single de novo event. Prioritise
#     including the most severe event within a gene, then take the first variant
#     left after that.
#     
#     Args:
#         de_novos: dataframe of de novo variants
#     
#     Returns:
#         pandas Series for whether each candidate is a duplicate or not
#     """
#     
#     # find the variants which are recurrent within a person in a single gene
#     from_start = de_novos.duplicated(["person_stable_id", "symbol"])
#     from_end = de_novos.duplicated(["person_stable_id", "symbol"], keep='last')
#     
#     person_dups = from_start | from_end
#     in_person_dups = de_novos[person_dups]
#     
#     # split the dataset, so we can process gene by gene
#     genes = in_person_dups.groupby(["person_stable_id", "symbol"])
#     
#     # pick a variant for each person, the first of the most severe consequence
#     retain = pandas.Series([], dtype=numpy.bool_)
#     for key, gene in genes:
#         consequence = get_most_severe(gene["consequence"])
#         first = gene[gene["consequence"] == consequence].index[0]
#         
#         gene_retain = pandas.Series([True] * len(gene), index=gene.index)
#         gene_retain[first] = False
#         retain = retain.append(gene_retain)
#     
#     # set the selected de novos
#     person_dups.loc[retain.index] = retain
#     
#     return person_dups
# 
# def family_recurrence(de_novos, family_ids):
#     ''' identify de novos recurrent within a family.
#     
#     Args:
#         de_novos: dataframe of de novo variants
#         family_ids: dictionary of family IDs, indexed by individual IDs.
#     
#     Returns:
#         pandas Series for whether each candidate is a duplicate or not
#     '''
#     
#     # restrict ourselves to the the first de novo for each family. This is
#     # randomly ordered, it might be better to select the older probands.
#     families = de_novos[["chrom", "pos", "ref", "alt"]].copy()
#     families['family_id'] = de_novos['person_stable_id'].map(family_ids)
#     
#     return families.duplicated()


import unittest
from pandas import DataFrame, Series
from denovoFilter.check_independence import check_independence, \
    person_recurrence, family_recurrence
    def test_family_recurrence(self):
        ''' test that family_recurrence() works correctly
        '''
        
        family_ids = {'a': 'fam1', 'b': 'fam1'}
        status = family_recurrence(self.variants, family_ids)
        self.assertTrue(all(status == Series([False, False])))
        
        # set up some variants that are at the same position
        self.variants['symbol'] = ['TEST1', 'TEST1']
        self.variants['chrom'] = ['1', '1']
        self.variants['pos'] = [100, 100]
        self.variants['ref'] = ['C', 'C']
        self.variants['alt'] = ['T', 'T']
        
        # if the sites are at the same position, and in the ssame family, then
        # we'll fail all but the first occurrence
        status = family_recurrence(self.variants, family_ids)
        self.assertTrue(all(status == Series([False, True])))
        
        # if the sites are not in the same family, then they can't be recurrent
        family_ids = {'a': 'fam1', 'b': 'fam2'}
        status = family_recurrence(self.variants, family_ids)
        self.assertTrue(all(status == Series([False, False])))
    
    def test_check_independence(self):
        ''' check that check_independence works correctly
        '''
        
        family_ids = {'a': 'fam1', 'b': 'fam2'}

# Path: denovoFilter/check_independence.py
# def check_independence(de_novos, family_ids):
#     """ identify de novos that would otherwise lead to double counting.
#     
#     This is so we can remove de novos that are shared between multiple probands
#     of a family or that are recurrent in a single gene in a single person.
#     
#     Args:
#         de_novos: dataframe of de novo variants
#         family_ids: dictionary of family IDs, indexed by individual IDs.
#     
#     Returns:
#         pandas Series indicating whether each site is independent
#     """
#     
#     family_dups = family_recurrence(de_novos, family_ids)
#     person_dups = person_recurrence(de_novos)
#     
#     return ~family_dups & ~person_dups
# 
# def person_recurrence(de_novos):
#     """ identify de novos recurrent in a gene within individuals.
#     
#     Find the de novos that are recurrent within a single individual in a
#     single gene. We shall treat these as a single de novo event. Prioritise
#     including the most severe event within a gene, then take the first variant
#     left after that.
#     
#     Args:
#         de_novos: dataframe of de novo variants
#     
#     Returns:
#         pandas Series for whether each candidate is a duplicate or not
#     """
#     
#     # find the variants which are recurrent within a person in a single gene
#     from_start = de_novos.duplicated(["person_stable_id", "symbol"])
#     from_end = de_novos.duplicated(["person_stable_id", "symbol"], keep='last')
#     
#     person_dups = from_start | from_end
#     in_person_dups = de_novos[person_dups]
#     
#     # split the dataset, so we can process gene by gene
#     genes = in_person_dups.groupby(["person_stable_id", "symbol"])
#     
#     # pick a variant for each person, the first of the most severe consequence
#     retain = pandas.Series([], dtype=numpy.bool_)
#     for key, gene in genes:
#         consequence = get_most_severe(gene["consequence"])
#         first = gene[gene["consequence"] == consequence].index[0]
#         
#         gene_retain = pandas.Series([True] * len(gene), index=gene.index)
#         gene_retain[first] = False
#         retain = retain.append(gene_retain)
#     
#     # set the selected de novos
#     person_dups.loc[retain.index] = retain
#     
#     return person_dups
# 
# def family_recurrence(de_novos, family_ids):
#     ''' identify de novos recurrent within a family.
#     
#     Args:
#         de_novos: dataframe of de novo variants
#         family_ids: dictionary of family IDs, indexed by individual IDs.
#     
#     Returns:
#         pandas Series for whether each candidate is a duplicate or not
#     '''
#     
#     # restrict ourselves to the the first de novo for each family. This is
#     # randomly ordered, it might be better to select the older probands.
#     families = de_novos[["chrom", "pos", "ref", "alt"]].copy()
#     families['family_id'] = de_novos['person_stable_id'].map(family_ids)
#     
#     return families.duplicated()


# Path: tests/test_check_independence.py
import unittest
from pandas import DataFrame, Series
from denovoFilter.check_independence import check_independence, \
    person_recurrence, family_recurrence

    def test_family_recurrence(self):
        ''' test that family_recurrence() works correctly
        '''
        
        family_ids = {'a': 'fam1', 'b': 'fam1'}
        status = family_recurrence(self.variants, family_ids)
        self.assertTrue(all(status == Series([False, False])))
        
        # set up some variants that are at the same position
        self.variants['symbol'] = ['TEST1', 'TEST1']
        self.variants['chrom'] = ['1', '1']
        self.variants['pos'] = [100, 100]
        self.variants['ref'] = ['C', 'C']
        self.variants['alt'] = ['T', 'T']
        
        # if the sites are at the same position, and in the ssame family, then
        # we'll fail all but the first occurrence
        status = family_recurrence(self.variants, family_ids)
        self.assertTrue(all(status == Series([False, True])))
        
        # if the sites are not in the same family, then they can't be recurrent
        family_ids = {'a': 'fam1', 'b': 'fam2'}
        status = family_recurrence(self.variants, family_ids)
        self.assertTrue(all(status == Series([False, False])))
    
    def test_check_independence(self):
        ''' check that check_independence works correctly
        '''
        
        family_ids = {'a': 'fam1', 'b': 'fam2'}

        status = check_independence(self.variants, family_ids)