Example #1
0
class ClonoFilterModelTest(TestCase):
    def setUp(self):
        make_fake_patient_with_3_clonotypes()
        self.s = Sample.objects.get()
        self.f = ClonoFilter(sample=self.s)
        self.f.save()

    def test_top_clones_returns_top_clones(self):
        self.assertEqual(2, self.f.top_clones(1)[0].count)
        self.assertEqual(1, self.f.top_clones(2)[1].count)

    def test_entropy_returns_entropy(self):
        self.assertEqual(1.0397207708399179, self.f.entropy())

    def test_min_copy_defaults_to_min_copy_for_that_sample(self):
        from django.db.models import Min
        aggregate = Clonotype.objects.aggregate(Min('count'))
        min_count = aggregate['count__min']
        self.assertEqual(self.f.min_count, min_count)

    def test_css_class_returns_clonofilter_class_string(self):
        self.assertEqual(self.f.css_class(), "cf-1")

    def test_update_generates_a_new_clonofilter_and_merges_filters_with_existing(self):
        from django.forms.models import model_to_dict
        self.f.min_copy = 1
        self.f.save()
        new_cf, new_created = self.f.update({'max_length': 50})
        test_cf, test_created = ClonoFilter.objects.get_or_create(**{
            'sample': self.s,
            'min_count': 1,
            'max_length': 50
        })

        self.assertEqual(new_created, True)
        self.assertEqual(test_created, False)
        self.assertEqual(
            model_to_dict(new_cf),
            model_to_dict(test_cf)
        )
        self.assertEqual(new_cf.id, test_cf.id)
        self.assertEqual(new_cf.id, 2)
        self.assertEqual(self.f.id, 1)

    def test_functionality_dict_contains_all_functional_groups_as_ratios(self):
        self.assertEqual({u'Out of frame': 0.5, u'Productive': 0.5},
                         self.f.functionality_dict())

    def test_functionality_dict_returns_dict(self):
        self.assertIsInstance(self.f.functionality_dict(), dict)

    def test_j_usage_considers_norm_factor(self):
        cf = ClonoFilter(sample=self.s, norm_factor=2)
        j_usage_dict = cf.j_usage_dict()
        self.assertEqual({u'TRBJ2-4': 0.5, u'TRBJ1-1': 1.5}, j_usage_dict)

    def test_j_usage_dict_returns_dict_indexed_by_j_gene(self):
        j_usage_dict = self.f.j_usage_dict()
        self.assertIsInstance(j_usage_dict, dict)

        self.assertEqual({u'TRBJ2-4': 0.25, u'TRBJ1-1': 0.75}, j_usage_dict)

    def test_v_usage_considers_norm_factor(self):
        cf = ClonoFilter(sample=self.s, norm_factor=2)
        v_usage_dict = cf.v_usage_dict()
        self.assertEqual({u'TRBV1-1': 0.5, u'TRBV25-1': 1.5}, v_usage_dict)

    def test_v_usage_dict_returns_dict_indexed_by_v_family(self):
        v_usage_dict = self.f.v_usage_dict()
        self.assertIsInstance(v_usage_dict, dict)

        self.assertEqual({u'TRBV1-1': 0.25, u'TRBV25-1': 0.75}, v_usage_dict)

    def test_normalization_factor_initializes_to_sum_of_raw_counts(self):
        self.f.save()
        self.assertEqual(self.f.size(), self.f.norm_factor)

    def test_get_recombinations_filters_properly(self):
        self.f.min_length = 40
        self.f.save()
        recombinations = Recombination.objects.filter(cdr3_length__gte=40)
        self.assertEqual(map(repr, recombinations),
                         map(repr, self.f.get_recombinations()))

    def test_given_a_clonofilter_return_a_recombination_queryset(self):
        recombination_qs = self.f.get_recombinations()
        self.assertEqual(map(repr, Recombination.objects.all()),
                         map(repr, recombination_qs))

    def test_count_method_returns_number_of_recombinations(self):
        self.assertEqual(3, self.f.count())

    def test_norm_size_method_returns_normalized_sum_of_copy(self):
        from django.db.models import Sum
        self.f.norm_factor = 10.0
        self.f.save()
        self.assertEqual(.4, self.f.norm_size())

    def test_size_method_returns_sum_of_copy(self):
        from django.db.models import Sum
        self.assertEqual(4, self.f.size())

    def test_default_from_sample_does_not_create_a_default_if_one_exists(self):
        ClonoFilter.objects.all().delete()
        ClonoFilter.default_from_sample(self.s)
        ClonoFilter.default_from_sample(self.s)
        self.assertEqual(1, ClonoFilter.objects.all().count())

    def test_default_from_sample_creates_a_default_clonofilter_if_one_does_not_exist(self):
        ClonoFilter.objects.all().delete()
        cf = ClonoFilter.default_from_sample(self.s)
        self.assertEqual(cf, ClonoFilter.objects.get())

    def test_cdr3_length_sum_utilizes_norm_factor_if_it_exists(self):
        self.f.norm_factor = 10
        norm_cdr3_length_sum = self.f.cdr3_length_sum()
        self.assertEqual([[36, .1], [39, .1], [42, .2]], norm_cdr3_length_sum)

    def test_clonofilter_has_min_and_max_length_as_int(self):
        self.f.min_length = 1
        self.f.max_length = 10
        self.f.save()
        f = ClonoFilter.objects.get()
        self.assertEqual(f.min_length, self.f.min_length)
        self.assertEqual(f.max_length, self.f.max_length)
        self.assertIsInstance(f.min_length, int)
        self.assertIsInstance(f.max_length, int)

    def test_clonofilter_filters_on_min_and_max_length(self):
        filtered_clonotypes = Clonotype.objects.filter(
            recombination__cdr3_length__gte=37,
            recombination__cdr3_length__lte=40)
        self.f.min_length = 37
        self.f.max_length = 40
        self.assertQuerysetEqual(filtered_clonotypes,
                                 map(repr, self.f.get_clonotypes()))

    def test_clonofilter_filters_on_v_family(self):
        filtered_clonotypes = Clonotype.objects.filter(
            recombination__v_gene_name=9)
        self.f.v_family_name = 9
        self.f.save()

        self.assertQuerysetEqual(filtered_clonotypes,
                                 map(repr, self.f.get_clonotypes()))

    def test_clonofilter_filters_on_j_gene_name(self):
        filtered_clonotypes = Clonotype.objects.filter(
            recombination__j_gene_name='TRBJ2-4')
        self.f.j_gene_name = 'TRBJ2-4'
        self.f.save()

        self.assertQuerysetEqual(filtered_clonotypes,
                                 map(repr, self.f.get_clonotypes()))

    def test_clonofilter_has_normalization_factor_as_a_float(self):
        self.f.norm_factor = 1
        self.f.save()
        f = ClonoFilter.objects.get()
        self.assertEqual(f.norm_factor, self.f.norm_factor)
        self.assertIsInstance(f.norm_factor, float)

    def test_clonofilter_get_clonotypes_should_not_filter_on_a_parameter_if_it_is_not_included(self):
        try:
            self.f.get_clonotypes()
        except ValueError:
            self.fail('clonofilter.get_clonotypes should not fail if sample exists but no other filtering attributes are given')

    def test_clonofilter_filters_on_min_copy(self):
        min_clonotypes = Clonotype.objects.filter(count__gte=2)
        self.f.min_count = 2
        self.assertQuerysetEqual(min_clonotypes,
                                 map(repr, self.f.get_clonotypes()))

    def test_clonofilter_has_min_copy(self):
        self.f.min_copy = 0
        self.assertEqual(0, self.f.min_copy)

    def test_clonofilter_has_sample(self):
        f = ClonoFilter.objects.get()
        self.assertEqual(self.s, self.f.sample)

    def test_vj_counts_dict_returns_a_nested_dict(self):
        '''
        dict should be indexed by:
            dict['v_family']['j_gene'] = count
        '''
        vj_counts = self.f.vj_counts_dict()
        self.assertIsInstance(vj_counts, dict)

        assert(vj_counts)

        for v_family in vj_counts.values():
            self.assertIsInstance(v_family, dict)

        self.assertEqual(vj_counts['TRBV1-1']['TRBJ1-1'], 0.25)

    def test_vj_counts_utilizes_norm_factor_if_it_exists(self):
        self.f.norm_factor = 10
        norm_vj_counts = self.f.vj_counts()
        self.assertEqual(.2, norm_vj_counts[0][0])

    def test_vj_counts_returns_an_empty_2d_list_with_dimensions_len_vfam_by_jgene(self):
        v_family_names = Recombination.v_gene_names()
        j_gene_names = Recombination.j_gene_names()
        vj_counts = self.f.vj_counts()
        self.assertEqual(len(v_family_names), len(vj_counts))
        self.assertEqual(len(j_gene_names), len(vj_counts[0]))

    def test_vj_counts_returns_a_2d_list_of_v_j_and_sum_of_copies(self):
        #        from collections import defaultdict
        vj_counts = self.f.vj_counts()
        self.assertIsInstance(vj_counts[0], list)
        self.assertEqual(
            ['[0.5, 0.25]', '[0.25, 0]'], map(repr, vj_counts))

    def test_cdr3_length_sum_returns_a_list(self):
        sums = self.f.cdr3_length_sum()
        self.assertIsInstance(sums, list)

    def test_cdr3_length_sum_returns_a_nested_list_of_cdr3_lengths_and_their_counts(self):
        hist = self.f.cdr3_length_sum()
        self.assertEqual([[36, 0.25], [39, .25], [42, 0.5]], hist)

    def test_cdr3_length_sum_should_sort_output_by_cdr3_length(self):
        r = RecombinationFactory(
            cdr3_length=10
        )

        ClonotypeFactory(
            sample=self.s,
            recombination=r,
            frequency=9.336458E-6,
            count=1,
        )

        self.assertEqual(
            [[36, 0.25], [39, 0.25], [42, .5]], self.f.cdr3_length_sum())