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)
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)
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)
def test_equal_with_wildtype_mismatch(self): set1 = MutationSet('Q1AC') set2 = MutationSet('R1AC') expected_message = 'Wild type mismatch between Q1AC and R1AC' with self.assertRaisesRegex(ValueError, expected_message): if set1 == set2: pass
def test_init_negative_text(self): expected_wildtype = 'Q' expected_position = 1 expected_mutations = MutationSet('Q1DEFGHIKLMNPQRSTVWY').mutations ms = MutationSet('Q1!AC') self.assertEqual(expected_wildtype, ms.wildtype) self.assertEqual(expected_position, ms.pos) self.assertEqual(expected_mutations, ms.mutations)
def test_equal(self): set1 = MutationSet('Q1AC') set2 = MutationSet('Q1CA') set3 = MutationSet('Q2AC') set4 = MutationSet('R2AC') set5 = MutationSet('Q1A') self.assertEqual(set1, set2) self.assertNotEqual(set1, set3) self.assertNotEqual(set1, set4) self.assertNotEqual(set1, set5)
def test_hash(self): hash1 = hash(MutationSet('Q1AC')) hash2 = hash(MutationSet('Q1CA')) hash3 = hash(MutationSet('Q2AC')) hash4 = hash(MutationSet('Q1A')) hash5 = hash(MutationSet('R1AC')) self.assertEqual(hash1, hash2) self.assertNotEqual(hash1, hash3) self.assertNotEqual(hash1, hash4) self.assertEqual(hash1, hash5)
def replace_wild_types(combination, reference): mutations = combination.split('+') for i, mutation_text in enumerate(mutations): mutation_set = MutationSet(mutation_text) expected_wild_type = reference[mutation_set.pos - 1] if mutation_set.wildtype != expected_wild_type: mutation_set = MutationSet( wildtype=expected_wild_type, pos=mutation_set.pos, variants=''.join(m.variant for m in mutation_set.mutations)) mutations[i] = str(mutation_set) pass return '+'.join(mutations)
def test_repr_negative(self): expected_repr = "MutationSet('Q1!AC')" ms = MutationSet('Q1!AC') r = repr(ms) self.assertEqual(expected_repr, r)
def test_init_no_mutations_without_position(self): wildtype = 'Q' mutations = set() with self.assertRaisesRegex(ValueError, r'No position and no variants\.'): MutationSet(wildtype=wildtype, mutations=mutations)
def test_init_no_mutations_without_wildtype(self): position = 1 mutations = set() with self.assertRaisesRegex(ValueError, r'No wildtype and no variants\.'): MutationSet(pos=position, mutations=mutations)
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
def test_repr_converted_to_negative(self): expected_repr = "MutationSet('Q1!AC')" ms = MutationSet('Q1DEFGHIKLMNPQRSTVWY') r = repr(ms) self.assertEqual(expected_repr, r)
def test_str(self): expected_str = 'Q1AC' ms = MutationSet(expected_str) s = str(ms) self.assertEqual(expected_str, s)
def _expand_score_map(score_map, main_genotype): # {genotype_override: {pos: {score: MutationSet}}} override_map = defaultdict(lambda: defaultdict(dict)) base_positions = defaultdict(dict) # {pos: {score: MutationSet}} for key, scores in score_map.items(): if key is None: pos = genotype_override = None else: pos, genotype_override = key if genotype_override is None: base_positions[pos] = scores else: override_map[genotype_override][pos] = scores if not override_map: return [(base_positions, main_genotype)] subtypes = SPLIT_GENOTYPES[main_genotype] for genotype_override in subtypes: positions = override_map[genotype_override] for pos, base_scores in base_positions.items(): for score, base_mutation_set in base_scores.items(): subtype_mutation_set = positions[pos].get(score) if subtype_mutation_set is None: combined_mutation_set = base_mutation_set else: combined_mutation_set = MutationSet( mutations=base_mutation_set.mutations | subtype_mutation_set.mutations) positions[pos][score] = combined_mutation_set first_positions = override_map[subtypes[0]] if all(override_map[other_subtype] == first_positions for other_subtype in subtypes[1:]): return [(first_positions, main_genotype)] return [(positions, subtype.upper()) for subtype, positions in override_map.items()]
def test_in(self): ms = MutationSet('A10IL') self.assertIn(Mutation('A10I'), ms) self.assertIn(Mutation('A10L'), ms) self.assertIn(Mutation('10L'), ms) self.assertNotIn(Mutation('A10S'), ms)
def test_init_position_mismatch(self): wildtype = 'Q' position = 2 mutations = {Mutation('Q1A'), Mutation('Q1C')} with self.assertRaisesRegex(ValueError, r'Multiple positions found: 1, 2\.'): MutationSet(wildtype=wildtype, pos=position, mutations=mutations)
def test_init_wildtype_mismatch(self): wildtype = 'R' position = 1 mutations = {Mutation('Q1A'), Mutation('Q1C')} with self.assertRaisesRegex(ValueError, r'Multiple wildtypes found: Q, R\.'): MutationSet(wildtype=wildtype, pos=position, mutations=mutations)
def test_init_bad_text(self): expected_message = \ r'MutationSet text expects wild type \(optional\), position, and ' \ r'one or more variants\.' for bad_text in ('!20A', '20Ac', 'r20Q', 'R20', 'R20!'): with self.subTest(bad_text): with self.assertRaisesRegex(ValueError, expected_message): MutationSet(bad_text)
def test_no_wildtypes(self): expected_position = 10 expected_mutations = {Mutation('10C')} ms = MutationSet(pos=expected_position, mutations=expected_mutations) self.assertIsNone(ms.wildtype) self.assertEqual(expected_position, ms.pos) self.assertEqual(expected_mutations, ms.mutations)
def test_init_text(self): expected_wildtype = 'Q' expected_position = 1 expected_mutations = {Mutation('Q1A'), Mutation('Q1C')} ms = MutationSet('Q1AC') self.assertEqual(expected_wildtype, ms.wildtype) self.assertEqual(expected_position, ms.pos) self.assertEqual(expected_mutations, ms.mutations)
def test_init_mutations_some_without_wildtype(self): expected_wildtype = 'Q' expected_position = 1 expected_mutations = {Mutation('Q1A'), Mutation('1C')} ms = MutationSet(mutations=expected_mutations) self.assertEqual(expected_wildtype, ms.wildtype) self.assertEqual(expected_position, ms.pos) self.assertEqual(expected_mutations, ms.mutations)
def test_init_variants(self): expected_wildtype = 'Q' expected_position = 1 expected_mutations = {Mutation('Q1A'), Mutation('Q1C')} ms = MutationSet(wildtype=expected_wildtype, pos=expected_position, variants='AC') self.assertEqual(expected_wildtype, ms.wildtype) self.assertEqual(expected_position, ms.pos) self.assertEqual(expected_mutations, ms.mutations)
def test_init_no_mutations(self): expected_wildtype = 'Q' expected_position = 1 expected_mutations = set() ms = MutationSet(wildtype=expected_wildtype, pos=expected_position, mutations=expected_mutations) self.assertEqual(expected_wildtype, ms.wildtype) self.assertEqual(expected_position, ms.pos) self.assertEqual(expected_mutations, ms.mutations)
def _monitor_positions(self, section, position_scores, reference): monitored_positions = getattr(section, 'monitored_positions', []) max_pos = len(reference.sequence) for pos in monitored_positions: scores = position_scores[pos] seen_variants = { mutation.variant for mutation_set in scores.values() for mutation in mutation_set } try: wild_type = reference.sequence[pos - 1] except IndexError: self.invalid_positions.append( f'{section.sheet_name}: {section.drug_name} {pos} ' f'(max {max_pos})') continue mutation_set = MutationSet('{}{}!{}{}'.format( wild_type, pos, ''.join(seen_variants), wild_type)) position_scores[pos]['Effect unknown'] = mutation_set
def __init__(self, _label=None, _pos=None, args=None): """Initialize set of mutations from a potentially ambiguous residue """ self.mutations = MutationSet(''.join(args))
def test_init_args(self): expected_mutation_set = MutationSet('Q80KR') m = AsiMutations(args='Q80KR') self.assertEqual(expected_mutation_set, m.mutations) self.assertEqual(expected_mutation_set.wildtype, m.mutations.wildtype)
def test_length(self): self.assertEqual(1, len(MutationSet('A10I'))) self.assertEqual(2, len(MutationSet('A10IL')))
def test_immutable(self): ms = MutationSet('Q80KR') with self.assertRaises(AttributeError): ms.wildtype = 'D'
def test_no_wildtype(self): for text in "20N 10NNN 1ASDF 0X".split(): mutations = MutationSet(text) self.assertIsNone(mutations.wildtype)