def test_free_energy_optmization(self): """Tests that the oligo search optimizes the free energy and scans both left and right of the mutation midpoint. """ self.config.should_calc_replichore = False OLIGO_SIZE = 20 self.config.oligo_size = OLIGO_SIZE OLIGO_END_BUFFER_DISTANCE = 2 self.config.oligo_end_buffer_distance = OLIGO_END_BUFFER_DISTANCE OLIGO_GENERATOR = OligoGenerator(self.config) ### Test that the window slides downstream. RAW_SEQ_1 = 'GGGGGGGGGGCCCCCCCCCCCCCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' SEQ_OBJ_1 = Seq(RAW_SEQ_1, generic_dna) GENOME_RECORD_1 = SeqRecord(SEQ_OBJ_1) self.config.genome_record = GENOME_RECORD_1 OLIGO_TARGET = OligoTarget( self.config, { 'target_id': '1', 'replichore': 2, 'strand': -1, 'start': 35, 'end': 36, 'mutation_type': 'R' }) oligo_result = OLIGO_GENERATOR.generate_oligo(OLIGO_TARGET) self.assertTrue(oligo_result.ss_dG > DEFAULT_MIN_SS_DG) EXPECTED_SEQ = 'A*A*AAAAAAAAAAAAAAAAAA' self.assertEqual(EXPECTED_SEQ, str(oligo_result.oligo_seq).upper()) ### Test that the window slides upstream. RAW_SEQ_2 = 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGGGGGGGGGGCCCCCCCCCCCCC' SEQ_OBJ_2 = Seq(RAW_SEQ_2, generic_dna) GENOME_RECORD_2 = SeqRecord(SEQ_OBJ_2) self.config.genome_record = GENOME_RECORD_2 OLIGO_TARGET = OligoTarget( self.config, { 'target_id': '1', 'replichore': 2, 'strand': -1, 'start': 22, 'end': 23, 'mutation_type': 'R' }) oligo_result = OLIGO_GENERATOR.generate_oligo(OLIGO_TARGET) self.assertTrue(oligo_result.ss_dG > DEFAULT_MIN_SS_DG) EXPECTED_SEQ = 'A*A*AAAAAAAAAAAAAAAAAA' self.assertEqual(EXPECTED_SEQ, str(oligo_result.oligo_seq).upper())
def print_mage_oligos(variant_set, output_filehandle, target_id_prefix, replication_origin_params, experiment_dir=OPT_MAGE_EXPERIMENT_DIR__FORWARD): """Prints MAGE oligos for Variants in variant_set. Args: variant_set: A VariantSet. output_filehandle: Target for writing the designed oligos. target_id_prefix: String prefix used for target id string in output. replication_origin_params: ReplicationOriginParams object. experiment_dir: Direction to print oligos. Choose from VALID_PRINT_OLIGOS_DIR. Raises: ValidationException """ assert experiment_dir in OPT_MAGE_VALID_EXPERIMENT_DIRS # First validate that we support printing oligos for this type. passing_variants = _validate_variant_set_for_printing_mage_oligos( variant_set) config = OptMAGEConfig() config.replication_origin = replication_origin_params.get_origin_interval() config.replication_terminus = ( replication_origin_params.get_terminus_interval()) oligo_target_list = [] for variant in passing_variants: alt_value = variant.variantalternate_set.all()[0].alt_value # Configure the oligo for this variant. target_params = { 'target_id': variant.position, 'strand': 1, 'start': variant.position, 'end': variant.position + 1, } if experiment_dir == OPT_MAGE_EXPERIMENT_DIR__REVERSE: target_params.update({ 'mutation_type': OPT_MAGE_MUTATION_TYPE__REFERENCE, }) else: target_params.update({ 'mutation_type': OPT_MAGE_MUTATION_TYPE__SUBSTITUTION, 'mutation_seq': alt_value, }) oligo_target_list.append(OligoTarget(config, target_params)) oligo_generator = OligoGenerator(config) oligo_result_list = [ oligo_generator.generate_oligo(oligo_target) for oligo_target in oligo_target_list ] OligoWriter.write_default(oligo_result_list, output_filehandle)
def test_mutation__positive_strand(self): """Test making a mutation relative to the positive strand. """ self.config.should_calc_replichore = False OLIGO_SIZE = 7 self.config.oligo_size = OLIGO_SIZE OLIGO_END_BUFFER_DISTANCE = 0 self.config.oligo_end_buffer_distance = OLIGO_END_BUFFER_DISTANCE self.config.num_phosphorothioate_bonds = 0 self.config.min_ss_dG = -200 # just want the centered window OLIGO_GENERATOR = OligoGenerator(self.config) RAW_SEQ_1 = 'CGCTAGCCC' SEQ_OBJ_1 = Seq(RAW_SEQ_1, generic_dna) GENOME_RECORD_1 = SeqRecord(SEQ_OBJ_1) self.config.genome_record = GENOME_RECORD_1 OLIGO_TARGET = OligoTarget( self.config, { 'target_id': '1', 'replichore': 2, # so we get an oligo in the positive sense. 'strand': 1, 'start': 4, 'end': 7, 'mutation_type': 'M', 'mutation_seq': 'TAA' }) oligo_result = OLIGO_GENERATOR.generate_oligo(OLIGO_TARGET) self.assertEqual(OLIGO_SIZE, len(oligo_result.oligo_seq)) self.assertEqual('TAG', str(oligo_result.original_seq)) self.assertEqual('TAA', str(oligo_result.mutation_seq)) EXPECTED_OLIGO_SEQ = 'GCTAACC' self.assertEqual(EXPECTED_OLIGO_SEQ, str(oligo_result.oligo_seq).upper()) # Try similar with oligo size 8. OLIGO_SIZE = 8 self.config.oligo_size = OLIGO_SIZE oligo_result = OLIGO_GENERATOR.generate_oligo(OLIGO_TARGET) self.assertEqual(OLIGO_SIZE, len(oligo_result.oligo_seq)) EXPECTED_OLIGO_SEQ = 'CGCTAACC' self.assertEqual(EXPECTED_OLIGO_SEQ, str(oligo_result.oligo_seq).upper())
def test_input_accepts_strings_or_numbers(self): """Input might be parsed from file so should handle numbers as strings. """ self.config.num_phosphorothioate_bonds = 0 OLIGO_GENERATOR = OligoGenerator(self.config) OLIGO_TARGET = OligoTarget( self.config, { 'target_id': '1', 'replichore': 2, # so we get an oligo in the positive sense. 'strand': 1, 'start': '2216229', # Testing this. 'end': 2216230, 'mutation_type': 'M', 'mutation_seq': 'T' }) OLIGO_GENERATOR.generate_oligo(OLIGO_TARGET)
def print_mage_oligos(variant_set, output_filehandle, target_id_prefix, replication_origin_params, experiment_dir=OPT_MAGE_EXPERIMENT_DIR__FORWARD): """Prints MAGE oligos for Variants in variant_set. Args: variant_set: A VariantSet. output_filehandle: Target for writing the designed oligos. target_id_prefix: String prefix used for target id string in output. replication_origin_params: ReplicationOriginParams object. experiment_dir: Direction to print oligos. Choose from VALID_PRINT_OLIGOS_DIR. Raises: ValidationException """ assert experiment_dir in OPT_MAGE_VALID_EXPERIMENT_DIRS # First validate that we support printing oligos for this type. passing_variants = _validate_variant_set_for_printing_mage_oligos( variant_set) config = OptMAGEConfig() config.replication_origin = replication_origin_params.get_origin_interval() config.replication_terminus = ( replication_origin_params.get_terminus_interval()) oligo_target_list = [] for variant in passing_variants: alt_value = variant.variantalternate_set.all()[0].alt_value # Configure the oligo for this variant. target_params = { 'target_id': variant.position, 'strand': 1, 'start': variant.position, 'end': variant.position + 1, } if experiment_dir == OPT_MAGE_EXPERIMENT_DIR__REVERSE: target_params.update({ 'mutation_type': OPT_MAGE_MUTATION_TYPE__REFERENCE, }) else: target_params.update({ 'mutation_type': OPT_MAGE_MUTATION_TYPE__SUBSTITUTION, 'mutation_seq': alt_value, }) oligo_target_list.append(OligoTarget(config, target_params)) oligo_generator = OligoGenerator(config) oligo_result_list = [ oligo_generator.generate_oligo(oligo_target) for oligo_target in oligo_target_list] OligoWriter.write_default(oligo_result_list, output_filehandle)
def test_oligo_generator__from_reference__target_reverse_strand(self): """Test for synthesizing an oligo that targets the reverse strand, meaning a forward-sense oligo. """ OLIGO_SIZE = 90 self.config.oligo_size = OLIGO_SIZE OLIGO_END_BUFFER_DISTANCE = 20 self.config.oligo_end_buffer_distance = OLIGO_END_BUFFER_DISTANCE # Set this arbitrarily low so we pretty much guarantee we get the # oligo sequence centered around the mutation. self.config.min_ss_dG = -200 # Ignore phosphorothioates for now. self.config.num_phosphorothioate_bonds = 0 oligo_generator = OligoGenerator(self.config) # Replichore 1 and positive strand means the anti-sense strand will # be targeted, so the oligo will have a positive sense. params = { 'target_id': 'r_1_set1_ftsA_104352', 'replichore': 'NA', 'strand': '+1', 'start': 104352, 'end': 104353, 'mutation_type': 'R' } oligo_target = OligoTarget(self.config, params) # Test getting the candidate block sequence. formatted_block_seq = str( oligo_generator.get_candidate_block_seq(oligo_target)).upper() EXPECTED_BLOCK_SEQ = 'CCGGATTCTTGATCCCTTCCTGATAGTCAATCGCATACTCTTGCGGGATCACATGCAGCACACGATGCTCATCGCGCACACGCACCGATTTCGCGGTATGGACGACGTTTTCCACATCTTCTTGCGTCACTTCTTCTT' self.assertEqual(EXPECTED_BLOCK_SEQ, formatted_block_seq) # Test getting the actual oligo seq. formatted_oligo_seq = str( oligo_generator.generate_oligo(oligo_target).oligo_seq).upper() EXPECTED_OLIGO_SEQ = 'AGTCAATCGCATACTCTTGCGGGATCACATGCAGCACACGATGCTCATCGCGCACACGCACCGATTTCGCGGTATGGACGACGTTTTCCA' self.assertEqual(OLIGO_SIZE, len(formatted_oligo_seq)) self.assertEqual(EXPECTED_OLIGO_SEQ, formatted_oligo_seq)
def test_mutation__full_genome__positive_strand(self): self.config.num_phosphorothioate_bonds = 0 OLIGO_GENERATOR = OligoGenerator(self.config) OLIGO_TARGET = OligoTarget( self.config, { 'target_id': '1', 'replichore': 2, # so we get an oligo in the positive sense. 'strand': 1, 'start': 2216229, 'end': 2216230, 'mutation_type': 'M', 'mutation_seq': 'T' }) oligo_result = OLIGO_GENERATOR.generate_oligo(OLIGO_TARGET) self.assertEqual(DEFAULT_OLIGO_SIZE, len(oligo_result.oligo_seq)) self.assertEqual('C', str(oligo_result.original_seq).upper()) self.assertEqual('T', str(oligo_result.mutation_seq).upper()) self.assertEqual(2216229, oligo_result.start) self.assertEqual(2216230, oligo_result.end)
def test_deletion(self): """Test making a deletion. """ self.config.should_calc_replichore = False OLIGO_SIZE = 7 self.config.oligo_size = OLIGO_SIZE OLIGO_END_BUFFER_DISTANCE = 2 self.config.oligo_end_buffer_distance = OLIGO_END_BUFFER_DISTANCE self.config.num_phosphorothioate_bonds = 0 self.config.min_ss_dG = -200 # just want the centered window OLIGO_GENERATOR = OligoGenerator(self.config) # TCGC AGC RAW_SEQ_1 = 'TTTTTTTCGCTAGCCCTTTTTTTTTTTTTTTT' SEQ_OBJ_1 = Seq(RAW_SEQ_1, generic_dna) GENOME_RECORD_1 = SeqRecord(SEQ_OBJ_1) self.config.genome_record = GENOME_RECORD_1 OLIGO_TARGET = OligoTarget( self.config, { 'target_id': '1', 'replichore': 2, # so we get an oligo in the positive sense. 'strand': 1, 'start': 11, 'end': 12, 'mutation_type': 'D', }) oligo_result = OLIGO_GENERATOR.generate_oligo(OLIGO_TARGET) self.assertEqual(OLIGO_SIZE, len(oligo_result.oligo_seq)) EXPECTED_OLIGO_SEQ = 'TCGCAGC' EXPECTED_OLIGO_SEQ_ALTERNATE = 'CGCAGCC' self.assertTrue( str(oligo_result.oligo_seq).upper() in [EXPECTED_OLIGO_SEQ, EXPECTED_OLIGO_SEQ_ALTERNATE], 'Got: ' + str(oligo_result.oligo_seq).upper()) # Try similar with oligo size 8. OLIGO_SIZE = 8 self.config.oligo_size = OLIGO_SIZE oligo_result = OLIGO_GENERATOR.generate_oligo(OLIGO_TARGET) self.assertEqual(OLIGO_SIZE, len(oligo_result.oligo_seq)) EXPECTED_OLIGO_SEQ = 'TCGCAGCC' EXPECTED_OLIGO_SEQ_ALTERNATE = 'TTCGCAGC' self.assertTrue( str(oligo_result.oligo_seq).upper() in [EXPECTED_OLIGO_SEQ, EXPECTED_OLIGO_SEQ_ALTERNATE]) ### Test bigger deletion. OLIGO_SIZE = 7 self.config.oligo_size = OLIGO_SIZE OLIGO_TARGET = OligoTarget( self.config, { 'target_id': '1', 'replichore': 2, # so we get an oligo in the positive sense. 'strand': 1, 'start': 11, 'end': 14, 'mutation_type': 'D', }) oligo_result = OLIGO_GENERATOR.generate_oligo(OLIGO_TARGET) self.assertEqual(OLIGO_SIZE, len(oligo_result.oligo_seq)) EXPECTED_OLIGO_SEQ = 'TCGCCCC' EXPECTED_OLIGO_SEQ_ALTERNATE = 'TTCGCCC' self.assertTrue( str(oligo_result.oligo_seq).upper() in [EXPECTED_OLIGO_SEQ, EXPECTED_OLIGO_SEQ_ALTERNATE]) # Try similar with oligo size 8. OLIGO_SIZE = 8 self.config.oligo_size = OLIGO_SIZE oligo_result = OLIGO_GENERATOR.generate_oligo(OLIGO_TARGET) self.assertEqual(OLIGO_SIZE, len(oligo_result.oligo_seq)) EXPECTED_OLIGO_SEQ = 'TTCGCCCC' EXPECTED_OLIGO_SEQ_ALTERNATE = 'TCGCCCCT' self.assertTrue( str(oligo_result.oligo_seq).upper() in [EXPECTED_OLIGO_SEQ, EXPECTED_OLIGO_SEQ_ALTERNATE])