示例#1
0
 def test_bool_constants(self):
     rule = HCVR("TRUE OR 1G")
     self.assertEqual(rule(VariantCalls("1d")), True)
     rule = HCVR("FALSE AND 1G")
     self.assertEqual(rule(VariantCalls("1G")), False)
     rule = HCVR("TRUE OR (FALSE AND TRUE)")
     self.assertEqual(rule(VariantCalls("1G")), True)
示例#2
0
 def test_score_comment(self):
     rule = HCVR(
         'SCORE FROM (100G => 10, 200T => 3, 100S => "flag1 with_space")')
     self.assertEqual(rule(VariantCalls("100G 200d")), 10)
     result = rule.dtree(VariantCalls("100S 200T"))
     self.assertEqual(result.score, 3)
     self.assertIn("flag1 with_space", result.flags)
示例#3
0
 def test_bool_and(self):
     rule = HCVR("1G AND (2T AND 7Y)")
     self.assertEqual(rule(VariantCalls("2T 7Y 1G")), True)
     self.assertEqual(rule(VariantCalls("2T 7d 1G")), False)
     self.assertEqual(rule(VariantCalls("7Y 1G 2T")), True)
     with self.assertRaisesRegex(MissingPositionError,
                                 r"Missing position 1"):
         rule([])
示例#4
0
    def test_init_empty_sequence(self):
        reference = 'ACHE'
        sample = ['IN', 'C', '', 'E']
        expected_calls = VariantCalls('A1IN C2C E4E')

        calls = VariantCalls(reference=reference, sample=sample)

        self.assertEqual(expected_calls, calls)
示例#5
0
    def test_init_multiple_sequences(self):
        reference = 'ACHE'
        sample = ['IN', 'C', 'HR', 'E']
        expected_calls = VariantCalls('A1IN C2C H3HR E4E')

        calls = VariantCalls(reference=reference, sample=sample)

        self.assertEqual(expected_calls, calls)
示例#6
0
 def test_bool_or(self):
     rule = HCVR("1G OR (2T OR 7Y)")
     self.assertTrue(rule(VariantCalls("1d 2T 7d")))
     self.assertFalse(rule(VariantCalls("1d 2d 7d")))
     self.assertTrue(rule(VariantCalls("1G 2d 7d")))
     with self.assertRaisesRegex(MissingPositionError,
                                 r"Missing position 1"):
         rule([])
示例#7
0
    def test_hash(self):
        hash1 = hash(VariantCalls('A1IL H3R'))
        hash2 = hash(VariantCalls('H3R A1IL'))
        hash3 = hash(VariantCalls('A1IL H3Q'))
        hash4 = hash(VariantCalls('A1IL'))

        self.assertEqual(hash1, hash2)
        self.assertNotEqual(hash1, hash3)
        self.assertNotEqual(hash1, hash4)
示例#8
0
    def test_eq(self):
        calls1 = VariantCalls('A1IL H3R')
        calls2 = VariantCalls('H3R A1IL')
        calls3 = VariantCalls('A1IL H3Q')
        calls4 = VariantCalls('A1IL')

        self.assertEqual(calls1, calls2)
        self.assertNotEqual(calls1, calls3)
        self.assertNotEqual(calls1, calls4)
示例#9
0
 def test_score_from(self):
     rule = HCVR("SCORE FROM ( 100G => 5, 101DST => 20 )")
     self.assertEqual(rule(VariantCalls("100G 101G")), 5)
     self.assertEqual(rule(VariantCalls("100G 101d")), 5)
     self.assertEqual(rule(VariantCalls("100G 101D")), 25)
     self.assertEqual(rule(VariantCalls("100G 101DST")), 25)
     with self.assertRaisesRegex(MissingPositionError,
                                 r'Missing position 100.'):
         rule(VariantCalls("105G 106DST"))
示例#10
0
    def test_init_single_sequence(self):
        reference = 'ACHE'
        sample = 'ICRE'
        expected_calls = VariantCalls('A1I C2C H3R E4E')

        calls = VariantCalls(reference=reference, sample=sample)

        self.assertEqual(reference, calls.reference)
        self.assertEqual(expected_calls, calls)
示例#11
0
def add_mutations(text):
    """ Add a small set of mutations to an RT wild type. """

    # Start of RT reference.
    ref = ("PISPIETVPVKLKPGMDGPKVKQWPLTEEKIKALVEICTEMEKEGKISKIGPENPYNTPVFA"
           "IKKKDSTKWRKLVDFRELNKRTQDFWEVQLGIPHPAGLKKKKSVTVLDVGDAYFSVPLDEDF"
           "RKYTAFTIPSINNETPGIRYQYNVLPQGWKGSPAIFQSSMTKILEPFRKQNPDIVIYQYMDD"
           "LYVGSDLEIGQHRTKIEELRQHLLRWGLTTPDKKHQK")
    seq = list(ref)
    changes = VariantCalls(text)
    for mutation_set in changes:
        seq[mutation_set.pos - 1] = [m.variant for m in mutation_set]
    return VariantCalls(reference=ref, sample=seq)
示例#12
0
    def test_init_text(self):
        expected_mutation_sets = {MutationSet('A1IL'), MutationSet('H3R')}

        calls = VariantCalls('A1IL H3R')

        self.assertIsNone(calls.reference)
        self.assertEqual(expected_mutation_sets, calls.mutation_sets)
示例#13
0
    def test_in(self):
        calls = VariantCalls('A1IL H3R')
        mutation_set1 = MutationSet('H3R')
        mutation_set2 = MutationSet('H4R')

        self.assertIn(mutation_set1, calls)
        self.assertNotIn(mutation_set2, calls)
示例#14
0
    def test_iter(self):
        calls = VariantCalls('A1IL H3R')
        expected_mutation_sets = {MutationSet('A1IL'), MutationSet('H3R')}

        mutation_sets = set(calls)

        self.assertEqual(expected_mutation_sets, mutation_sets)
示例#15
0
    def test_str(self):
        expected_str = 'A1IL H3R'
        calls = VariantCalls(expected_str)

        s = str(calls)

        self.assertEqual(expected_str, s)
示例#16
0
    def test_repr(self):
        expected_repr = "VariantCalls('A1IL H3R')"
        calls = VariantCalls('A1IL H3R')

        r = repr(calls)

        self.assertEqual(expected_repr, r)
示例#17
0
def calculate_component_score(combination, positions):
    variants = {}  # {pos: mutation_text}
    for mutation_text in combination.split('+'):
        mutation_text = mutation_text.strip()
        mutation_set = MutationSet(mutation_text)
        old_mutation_text = variants.get(mutation_set.pos)
        if old_mutation_text is not None:
            mutation_text = old_mutation_text + ''.join(
                m.variant for m in mutation_set.mutations)
        variants[mutation_set.pos] = mutation_text
    variant_calls = VariantCalls(' '.join(variants.values()))
    combination_positions = {}
    for mutation_set in variant_calls:
        position_scores = positions[mutation_set.pos]
        if position_scores:
            combination_positions[mutation_set.pos] = position_scores
    if not combination_positions:
        return 0
    score_formula = build_score_formula(combination_positions)
    try:
        rule = HCVR(score_formula)
    except Exception as ex:
        raise ValueError('Bad formula for {}.'.format(combination)) from ex
    component_score = rule(variant_calls)
    return component_score
示例#18
0
    def test_score_residues(self):
        rule = ASI2("SCORE FROM ( 100G => 10, 101D => 20 )")
        expected_residue = repr({Mutation('S100G')})

        result = rule.dtree(VariantCalls("S100G R101d"))

        self.assertEqual(expected_residue, repr(result.residues))
示例#19
0
    def test_true_positive(self):
        m = VariantCalls('Q54H 444H')
        rule = HCVR("SCORE FROM ( 54H => 0, 444H => 8 )")
        dtree = rule.dtree(m)

        expected_repr = "[Mutation('Q54H'), Mutation('444H')]"
        self.assertEqual(expected_repr, repr(sorted(dtree.residues)))
示例#20
0
    def test_init_bad_length(self):
        reference = 'ACHE'
        sample = 'ICREL'

        with self.assertRaisesRegex(
                ValueError,
                r'Reference length was 4 and sample length was 5\.'):
            VariantCalls(reference=reference, sample=sample)
示例#21
0
    def test_init_with_reference(self):
        expected_reference = 'ASH'
        expected_repr = "VariantCalls('A1IL H3R')"

        calls = VariantCalls('1IL 3R', reference=expected_reference)
        r = repr(calls)

        self.assertEqual(expected_reference, calls.reference)
        self.assertEqual(expected_repr, r)
示例#22
0
    def interpret(self, aaseq, region):
        result = AsiResult()
        raw_mutations = defaultdict(set)
        result.alg_name = self.alg_name
        result.alg_version = self.alg_version
        drug_classes = self.gene_def.get(region, {})
        default_level = ResistanceLevels.FAIL.level
        default_level_name = self.level_def[str(default_level)]

        mutations = VariantCalls(reference=self.stds[region], sample=aaseq)

        for drug_class in drug_classes:
            for drug_code in self.drug_class[drug_class]:
                drug_name, drug_rules = self.drugs[drug_code]
                drug_result = AsiDrugResult()
                drug_result.code = drug_code
                drug_result.name = drug_name
                drug_result.level = default_level
                drug_result.level_name = default_level_name
                drug_result.drug_class = drug_class

                for condition, actions in drug_rules:

                    rule = HCVR(condition)
                    try:
                        rule_result = rule.dtree(mutations)

                        score = float(rule_result.score)
                        flags = rule_result.flags
                        # rule_result.residues doesn't always have wild types.
                        m = {
                            mutation
                            for mutation_set in mutations
                            for mutation in mutation_set
                            if mutation in rule_result.residues
                        }
                        raw_mutations[drug_class] |= m

                        for action, comment in actions:
                            if action == 'level':
                                if int(comment) > drug_result.level:
                                    drug_result.level = int(comment)
                                    drug_result.level_name = self.level_def[
                                        comment]
                            elif action == 'comment':
                                comment, _ = self.comment_def[comment]
                                while (re.search('\$numberOfMutsIn{', comment)
                                       or re.search('\$listMutsIn{', comment)):
                                    comment = self.comment_filter(
                                        comment, aaseq, region)
                                drug_result.comments.append(comment)
                            elif action == 'scorerange':
                                drug_result.score = score
                                scorerange = comment
                                if scorerange == 'useglobalrange':
                                    scorerange = self.global_range
                                if score == 0 and flags:
                                    if 'Not available' in flags:
                                        drug_result.level = ResistanceLevels.NA.level
                                    elif 'Not indicated' in flags:
                                        drug_result.level = ResistanceLevels.NOT_INDICATED.level
                                    elif 'Effect unknown' in flags:
                                        drug_result.level = ResistanceLevels.UNKNOWN_MUTATIONS.level
                                else:
                                    # use score range to determine level
                                    for low_score, high_score, level in scorerange:
                                        if low_score == '-INF':
                                            low_score = -99999  # that is close enough to negative infinity.
                                        else:
                                            low_score = float(low_score)

                                        if high_score == 'INF':
                                            high_score = 99999  # that is close enough to infinity.
                                        else:
                                            high_score = float(high_score)

                                        if low_score <= drug_result.score <= high_score:
                                            if int(level) > drug_result.level:
                                                drug_result.level = int(level)
                                            break
                    except MissingPositionError:
                        drug_result.level = ResistanceLevels.FAIL.level

                    drug_result.level_name = self.level_def[str(
                        drug_result.level)]
                result.drugs.append(drug_result)

        for cls, cls_mutations in raw_mutations.items():
            result.mutations[cls] = [str(m) for m in cls_mutations]

        result.drugs.sort(key=lambda e: e.code)
        result.drugs.sort(key=lambda e: e.drug_class, reverse=True)
        # comments
        for target_region, results in self.mutation_comments:
            if target_region != region:
                continue
            for cond, actions in results:

                # This evaluates comment rules.
                # Previous evaluation was scoring rules.
                rule = HCVR(cond)
                try:
                    scoring = rule(mutations)

                    if scoring:
                        for _, act in actions:
                            comment_template, _ = self.comment_def[act]
                            comment = self.comment_filter(
                                comment_template, aaseq, region)
                            result.mutation_comments.append(comment)
                except MissingPositionError:
                    pass

        return result
示例#23
0
 def test_bool_or(self):
     rule = ASI2("1G OR (2T OR 7Y)")
     self.assertTrue(rule(VariantCalls("1d 2T 7d")))
     self.assertFalse(rule(VariantCalls("1d 2d 7d")))
     self.assertTrue(rule(VariantCalls("1G 2d 7d")))
示例#24
0
 def test_bool_and(self):
     rule = ASI2("1G AND (2T AND 7Y)")
     self.assertEqual(rule(VariantCalls("2T 7Y 1G")), True)
     self.assertEqual(rule(VariantCalls("2T 7d 1G")), False)
     self.assertEqual(rule(VariantCalls("7Y 1G 2T")), True)
示例#25
0
 def test_score_from_max_neg(self):
     rule = ASI2("SCORE FROM (MAX (100G => -10, 101D => -20, 102D => 30))")
     self.assertEqual(rule(VariantCalls("100G 101D 102d")), -10)
示例#26
0
 def test_score_from_max(self):
     rule = ASI2("SCORE FROM (MAX (100G => 10, 101D => 20, 102D => 30))")
     self.assertEqual(rule(VariantCalls("100G 101D 102d")), 20)
     self.assertEqual(rule(VariantCalls("100d 101d 102d")), False)
示例#27
0
 def test_score_negate(self):
     rule = ASI2("SCORE FROM ( NOT 100G => 10, NOT 101SD => 20 )")
     self.assertEqual(rule(VariantCalls("100G 101d")), 20)
     self.assertEqual(rule(VariantCalls("100S 101S")), 10)
示例#28
0
 def test_score_from(self):
     rule = ASI2("SCORE FROM ( 100G => 10, 101D => 20 )")
     self.assertEqual(rule(VariantCalls("100G 101d")), 10)
示例#29
0
 def test_atleast_missing(self):
     rule = ASI2("SELECT ATLEAST 2 FROM (41L, 67N, 70R, 210W, 215F, 219Q)")
     with self.assertRaisesRegex(MissingPositionError,
                                 r'Missing position 70.'):
         rule(VariantCalls('41L 67N'))
示例#30
0
 def test_atleast_false(self):
     rule = ASI2("SELECT ATLEAST 2 FROM (41L, 67N, 70R, 210W, 215F, 219Q)")
     self.assertFalse(rule(VariantCalls('41L 67d 70d 210d 215d 219d')))