#!/usr/bin/perl ####### # oligo.pl # Author: Lance Harden, Davidson College # August 2006 # # Description: Oligo tells the user where to make cuts in order to # optimize the melting temperatures of each individual oligo. Optimization # is defined as the maximin of the oligo melting temperatures. This # program allows the user to synthesize shorter oligos and then anneal them # together. ## CGCGGCCGCTTCTAGATTCGGGTGTCAACAATTGACCAAAATATCGATTTACAGCGTAATGCGCTTTCTAGTGCAAATTGTGACCGCATTTTACTAGTTGCGGCCGCC use strict; my \$nowtime = localtime; print \$nowtime,"\n\n"; print "Enter your top strand sequence: \n\n"; my \$seq = ; chomp(\$seq); \$seq = uc(\$seq); my \$total = length(\$seq); print "Enter your minimum oligo length: \n\n"; my \$lowerbound = ; chomp(\$lowerbound); print "Enter your maximum oligo length: \n\n"; my \$upperbound = ; chomp(\$upperbound); if (\$upperbound < \$lowerbound) { print "Your upperbound is less than your lowerbound. Rerun the program using reasonable values.\n\n"; exit; } # 4 Oligos my \$currentmax4 = 0; my @besttemps4; my @bestcuts4; if (\$total/3 <= \$upperbound) { for (my \$iA4 = \$lowerbound; \$iA4 <= \$upperbound; \$iA4++) { my \$BC4 = \$total - \$iA4; if (\$BC4 < 2*\$lowerbound) { last; } my \$effmin4 = (\$BC4 - \$lowerbound < \$upperbound ? \$BC4 - \$lowerbound : \$upperbound); for (my \$iB4 = \$lowerbound; \$iB4 <= \$effmin4; \$iB4++) { my \$C4 = \$total - \$iA4 - \$iB4; if (\$C4 < \$lowerbound) { last; } if (\$C4 > \$upperbound) { next; } my \$oligoA4 = substr(\$seq, 0, \$iA4); my \$oligoB4 = substr(\$seq, \$iA4, \$iB4); my \$oligoC4 = substr(\$seq, \$iA4 + \$iB4, \$C4); my @A4_gc = \$oligoA4 =~ m/[CG]/g; my \$A4_gc_content = scalar(@A4_gc) / length(\$oligoA4); my @B4_gc = \$oligoB4 =~ m/[CG]/g; my \$B4_gc_content = scalar(@B4_gc) / length(\$oligoB4); my @C4_gc = \$oligoC4 =~ m/[CG]/g; my \$C4_gc_content = scalar(@C4_gc) / length(\$oligoC4); my \$meltA4 = 81.5 + (16.6*log10(.1)) + (41*\$A4_gc_content) - (675/length(\$oligoA4)); my \$meltB4 = 81.5 + (16.6*log10(.1)) + (41*\$B4_gc_content) - (675/length(\$oligoB4)); my \$meltC4 = 81.5 + (16.6*log10(.1)) + (41*\$C4_gc_content) - (675/length(\$oligoC4)); my \$temp4 = (\$meltA4 < \$meltB4 ? \$meltA4 : \$meltB4); my \$min4 = (\$temp4 < \$meltC4 ? \$temp4 : \$meltC4); if (\$min4 > \$currentmax4) { \$currentmax4 = \$min4; @besttemps4 = (\$meltA4, \$meltB4, \$meltC4); @bestcuts4 = (length(\$oligoA4), length(\$oligoB4), length(\$oligoC4)); } } } print "@bestcuts4\n@besttemps4\n\n"; } # 5 Oligos my \$currentmax5 = 0; my @besttemps5; my @bestcuts5; if (\$total/4 <= \$upperbound) { for (my \$iA5 = \$lowerbound; \$iA5 <= \$upperbound; \$iA5++) { my \$BCD5 = \$total - \$iA5; if (\$BCD5 < 3*\$lowerbound) { last; } my \$effmin51 = (\$BCD5 - 2*\$lowerbound < \$upperbound ? \$BCD5 - 2*\$lowerbound : \$upperbound); for (my \$iB5 = \$lowerbound; \$iB5 <= \$effmin51; \$iB5++) { my \$CD5 = \$total - \$iA5 - \$iB5; if (\$CD5 < 2*\$lowerbound) { last; } my \$effmin52 = (\$CD5 - \$lowerbound < \$upperbound ? \$CD5 - \$lowerbound : \$upperbound); for (my \$iC5 = \$lowerbound; \$iC5 <= \$effmin52; \$iC5++) { my \$D5 = \$total - \$iA5 - \$iB5 - \$iC5; if (\$D5 < \$lowerbound) { last; } if (\$D5 > \$upperbound) { next; } my \$oligoA5 = substr(\$seq, 0, \$iA5); my \$oligoB5 = substr(\$seq, \$iA5, \$iB5); my \$oligoC5 = substr(\$seq, \$iA5 + \$iB5, \$iC5); my \$oligoD5 = substr(\$seq, \$iA5 + \$iB5 + \$iC5, \$D5); my @A5_gc = \$oligoA5 =~ m/[CG]/g; my \$A5_gc_content = scalar(@A5_gc) / length(\$oligoA5); my @B5_gc = \$oligoB5 =~ m/[CG]/g; my \$B5_gc_content = scalar(@B5_gc) / length(\$oligoB5); my @C5_gc = \$oligoC5 =~ m/[CG]/g; my \$C5_gc_content = scalar(@C5_gc) / length(\$oligoC5); my @D5_gc = \$oligoD5 =~ m/[CG]/g; my \$D5_gc_content = scalar(@D5_gc) / length(\$oligoD5); my \$meltA5 = 81.5 + (16.6*log10(.1)) + (41*\$A5_gc_content) - (675/length(\$oligoA5)); my \$meltB5 = 81.5 + (16.6*log10(.1)) + (41*\$B5_gc_content) - (675/length(\$oligoB5)); my \$meltC5 = 81.5 + (16.6*log10(.1)) + (41*\$C5_gc_content) - (675/length(\$oligoC5)); my \$meltD5 = 81.5 + (16.6*log10(.1)) + (41*\$D5_gc_content) - (675/length(\$oligoD5)); my \$temp5 = (\$meltA5 < \$meltB5 ? \$meltA5 : \$meltB5); \$temp5 = (\$temp5 < \$meltC5 ? \$temp5 : \$meltC5); my \$min5 = (\$temp5 < \$meltD5 ? \$temp5 : \$meltD5); if (\$min5 > \$currentmax5) { \$currentmax5 = \$min5; @besttemps5 = (\$meltA5, \$meltB5, \$meltC5, \$meltD5); @bestcuts5 = (length(\$oligoA5), length(\$oligoB5), length(\$oligoC5), length(\$oligoD5)); } } } } print "@bestcuts5\n@besttemps5\n\n"; } # 6 Oligos my \$currentmax6 = 0; my @besttemps6; my @bestcuts6; if (\$total/5 <= \$upperbound) { for (my \$iA6 = \$lowerbound; \$iA6 <= \$upperbound; \$iA6++) { my \$BCDE6 = \$total - \$iA6; if (\$BCDE6 < 4*\$lowerbound) { last; } my \$effmin61 = (\$BCDE6 - 3*\$lowerbound < \$upperbound ? \$BCDE6 - 3*\$lowerbound : \$upperbound); for (my \$iB6 = \$lowerbound; \$iB6 <= \$effmin61; \$iB6++) { my \$CDE6 = \$total - \$iA6 - \$iB6; if (\$CDE6 < 3*\$lowerbound) { last; } my \$effmin62 = (\$CDE6 - 2*\$lowerbound < \$upperbound ? \$CDE6 - 2*\$lowerbound : \$upperbound); for (my \$iC6 = \$lowerbound; \$iC6 <= \$effmin62; \$iC6++) { my \$DE6 = \$total - \$iA6 - \$iB6 - \$iC6; if (\$DE6 < 2*\$lowerbound) { last; } my \$effmin63 = (\$DE6 - \$lowerbound < \$upperbound ? \$DE6 - \$lowerbound : \$upperbound); for (my \$iD6 = \$lowerbound; \$iD6 <= \$effmin63; \$iD6++) { my \$E6 = \$total - \$iA6 - \$iB6 - \$iC6 - \$iD6; if (\$E6 < \$lowerbound) { last; } if (\$E6 > \$upperbound) { next; } my \$oligoA6 = substr(\$seq, 0, \$iA6); my \$oligoB6 = substr(\$seq, \$iA6, \$iB6); my \$oligoC6 = substr(\$seq, \$iA6 + \$iB6, \$iC6); my \$oligoD6 = substr(\$seq, \$iA6 + \$iB6 + \$iC6, \$iD6); my \$oligoE6 = substr(\$seq, \$iA6 + \$iB6 + \$iC6 + \$iD6, \$E6); my @A6_gc = \$oligoA6 =~ m/[CG]/g; my \$A6_gc_content = scalar(@A6_gc) / length(\$oligoA6); my @B6_gc = \$oligoB6 =~ m/[CG]/g; my \$B6_gc_content = scalar(@B6_gc) / length(\$oligoB6); my @C6_gc = \$oligoC6 =~ m/[CG]/g; my \$C6_gc_content = scalar(@C6_gc) / length(\$oligoC6); my @D6_gc = \$oligoD6 =~ m/[CG]/g; my \$D6_gc_content = scalar(@D6_gc) / length(\$oligoD6); my @E6_gc = \$oligoE6 =~ m/[CG]/g; my \$E6_gc_content = scalar(@E6_gc) / length(\$oligoE6); my \$meltA6 = 81.5 + (16.6*log10(.1)) + (41*\$A6_gc_content) - (675/length(\$oligoA6)); my \$meltB6 = 81.5 + (16.6*log10(.1)) + (41*\$B6_gc_content) - (675/length(\$oligoB6)); my \$meltC6 = 81.5 + (16.6*log10(.1)) + (41*\$C6_gc_content) - (675/length(\$oligoC6)); my \$meltD6 = 81.5 + (16.6*log10(.1)) + (41*\$D6_gc_content) - (675/length(\$oligoD6)); my \$meltE6 = 81.5 + (16.6*log10(.1)) + (41*\$E6_gc_content) - (675/length(\$oligoE6)); my \$temp6 = (\$meltA6 < \$meltB6 ? \$meltA6 : \$meltB6); \$temp6 = (\$temp6 < \$meltC6 ? \$temp6 : \$meltC6); \$temp6 = (\$temp6 < \$meltD6 ? \$temp6 : \$meltD6); my \$min6 = (\$temp6 < \$meltE6 ? \$temp6 : \$meltE6); if (\$min6 > \$currentmax6) { \$currentmax6 = \$min6; @besttemps6 = (\$meltA6, \$meltB6, \$meltC6, \$meltD6, \$meltE6); @bestcuts6 = (length(\$oligoA6), length(\$oligoB6), length(\$oligoC6), length(\$oligoD6), length(\$oligoE6)); } } } } } print "@bestcuts6\n@besttemps6\n\n"; } # 7 Oligos my \$currentmax7 = 0; my @besttemps7; my @bestcuts7; my \$count7 = 0; if (\$total/6 <= \$upperbound) { for (my \$iA7 = \$lowerbound; \$iA7 <= \$upperbound; \$iA7++) { my \$BCDEF7 = \$total - \$iA7; if (\$BCDEF7 < 5*\$lowerbound) { last; } my \$effmin71 = (\$BCDEF7 - 4*\$lowerbound < \$upperbound ? \$BCDEF7 - 4*\$lowerbound : \$upperbound); for (my \$iB7 = \$lowerbound; \$iB7 <= \$effmin71; \$iB7++) { my \$CDEF7 = \$total - \$iA7 - \$iB7; if (\$CDEF7 < 4*\$lowerbound) { last; } my \$effmin72 = (\$CDEF7 - 3*\$lowerbound < \$upperbound ? \$CDEF7 - 3*\$lowerbound : \$upperbound); for (my \$iC7 = \$lowerbound; \$iC7 <= \$effmin72; \$iC7++) { my \$DEF7 = \$total - \$iA7 - \$iB7 - \$iC7; if (\$DEF7 < 3*\$lowerbound) { last; } my \$effmin73 = (\$DEF7 - 2*\$lowerbound < \$upperbound ? \$DEF7 - 2*\$lowerbound : \$upperbound); for (my \$iD7 = \$lowerbound; \$iD7 <= \$effmin73; \$iD7++) { my \$EF7 = \$total - \$iA7 - \$iB7 - \$iC7 - \$iD7; if (\$EF7 < 2*\$lowerbound) { last; } my \$effmin74 = (\$EF7 - \$lowerbound < \$upperbound ? \$EF7 - \$lowerbound : \$upperbound); for (my \$iE7 = \$lowerbound; \$iE7 <= \$EF7 - \$lowerbound; \$iE7++) { my \$F7 = \$total - \$iA7 - \$iB7 - \$iC7 - \$iD7 - \$iE7; if (\$F7 < \$lowerbound) { last; } if (\$F7 > \$upperbound) { next; } \$count7++; my \$oligoA7 = substr(\$seq, 0, \$iA7); my \$oligoB7 = substr(\$seq, \$iA7, \$iB7); my \$oligoC7 = substr(\$seq, \$iA7 + \$iB7, \$iC7); my \$oligoD7 = substr(\$seq, \$iA7 + \$iB7 + \$iC7, \$iD7); my \$oligoE7 = substr(\$seq, \$iA7 + \$iB7 + \$iC7 + \$iD7, \$iE7); my \$oligoF7 = substr(\$seq, \$iA7 + \$iB7 + \$iC7 + \$iD7 + \$iE7, \$F7); my @A7_gc = \$oligoA7 =~ m/[CG]/g; my \$A7_gc_content = scalar(@A7_gc) / length(\$oligoA7); my @B7_gc = \$oligoB7 =~ m/[CG]/g; my \$B7_gc_content = scalar(@B7_gc) / length(\$oligoB7); my @C7_gc = \$oligoC7 =~ m/[CG]/g; my \$C7_gc_content = scalar(@C7_gc) / length(\$oligoC7); my @D7_gc = \$oligoD7 =~ m/[CG]/g; my \$D7_gc_content = scalar(@D7_gc) / length(\$oligoD7); my @E7_gc = \$oligoE7 =~ m/[CG]/g; my \$E7_gc_content = scalar(@E7_gc) / length(\$oligoE7); my @F7_gc = \$oligoF7 =~ m/[CG]/g; my \$F7_gc_content = scalar(@F7_gc) / length(\$oligoF7); my \$meltA7 = 81.5 + (16.6*log10(.1)) + (41*\$A7_gc_content) - (675/length(\$oligoA7)); my \$meltB7 = 81.5 + (16.6*log10(.1)) + (41*\$B7_gc_content) - (675/length(\$oligoB7)); my \$meltC7 = 81.5 + (16.6*log10(.1)) + (41*\$C7_gc_content) - (675/length(\$oligoC7)); my \$meltD7 = 81.5 + (16.6*log10(.1)) + (41*\$D7_gc_content) - (675/length(\$oligoD7)); my \$meltE7 = 81.5 + (16.6*log10(.1)) + (41*\$E7_gc_content) - (675/length(\$oligoE7)); my \$meltF7 = 81.5 + (16.6*log10(.1)) + (41*\$F7_gc_content) - (675/length(\$oligoF7)); my \$temp7 = (\$meltA7 < \$meltB7 ? \$meltA7 : \$meltB7); \$temp7 = (\$temp7 < \$meltC7 ? \$temp7 : \$meltC7); \$temp7 = (\$temp7 < \$meltD7 ? \$temp7 : \$meltD7); \$temp7 = (\$temp7 < \$meltE7 ? \$temp7 : \$meltE7); my \$min7 = (\$temp7 < \$meltF7 ? \$temp7 : \$meltF7); if (\$min7 > \$currentmax7) { \$currentmax7 = \$min7; @besttemps7 = (\$meltA7, \$meltB7, \$meltC7, \$meltD7, \$meltE7, \$meltF7); @bestcuts7 = (length(\$oligoA7), length(\$oligoB7), length(\$oligoC7), length(\$oligoD7), length(\$oligoE7), length(\$oligoF7)); } } } } } } print "@bestcuts7\n@besttemps7\n\n"; } print "\$count7\n\n"; \$nowtime = localtime; print \$nowtime,"\n\n"; # 8 Oligos - BEWARE, this case may take over a day to compute! my \$currentmax8 = 0; my @besttemps8; my @bestcuts8; if (\$total/7 <= \$upperbound) { for (my \$iA8 = \$lowerbound; \$iA8 <= \$upperbound; \$iA8++) { my \$BCDEFG8 = \$total - \$iA8; if (\$BCDEFG8 < 6*\$lowerbound) { last; } my \$effmin81 = (\$BCDEFG8 - 5*\$lowerbound < \$upperbound ? \$BCDEFG8 - 5*\$lowerbound : \$upperbound); for (my \$iB8 = \$lowerbound; \$iB8 <= \$effmin81; \$iB8++) { my \$CDEFG8 = \$total - \$iA8 - \$iB8; if (\$CDEFG8 < 5*\$lowerbound) { last; } my \$effmin82 = (\$CDEFG8 - 4*\$lowerbound < \$upperbound ? \$CDEFG8 - 4*\$lowerbound : \$upperbound); for (my \$iC8 = \$lowerbound; \$iC8 <= \$effmin82; \$iC8++) { my \$DEFG8 = \$total - \$iA8 - \$iB8 - \$iC8; if (\$DEFG8 < 4*\$lowerbound) { last; } my \$effmin83 = (\$DEFG8 - 3*\$lowerbound < \$upperbound ? \$DEFG8 - 3*\$lowerbound : \$upperbound); for (my \$iD8 = \$lowerbound; \$iD8 <= \$effmin83; \$iD8++) { my \$EFG8 = \$total - \$iA8 - \$iB8 - \$iC8 - \$iD8; if (\$EFG8 < 3*\$lowerbound) { last; } my \$effmin84 = (\$EFG8 - 2*\$lowerbound < \$upperbound ? \$EFG8 - 2*\$lowerbound : \$upperbound); for (my \$iE8 = \$lowerbound; \$iE8 <= \$effmin84; \$iE8++) { my \$FG8 = \$total - \$iA8 - \$iB8 - \$iC8 - \$iD8 - \$iE8; if (\$FG8 < 2*\$lowerbound) { last; } my \$effmin85 = (\$FG8 - \$lowerbound < \$upperbound ? \$FG8 - \$lowerbound : \$upperbound); for (my \$iF8 = \$lowerbound; \$iF8 <= \$effmin85; \$iF8++) { my \$G8 = \$total - \$iA8 - \$iB8 - \$iC8 - \$iD8 - \$iE8 - \$iF8; if (\$G8 < \$lowerbound) { last; } if (\$G8 > \$upperbound) { next; } my \$oligoA8 = substr(\$seq, 0, \$iA8); my \$oligoB8 = substr(\$seq, \$iA8, \$iB8); my \$oligoC8 = substr(\$seq, \$iA8 + \$iB8, \$iC8); my \$oligoD8 = substr(\$seq, \$iA8 + \$iB8 + \$iC8, \$iD8); my \$oligoE8 = substr(\$seq, \$iA8 + \$iB8 + \$iC8 + \$iD8, \$iE8); my \$oligoF8 = substr(\$seq, \$iA8 + \$iB8 + \$iC8 + \$iD8 + \$iE8, \$iF8); my \$oligoG8 = substr(\$seq, \$iA8 + \$iB8 + \$iC8 + \$iD8 + \$iE8 + \$iF8, \$G8); my @A8_gc = \$oligoA8 =~ m/[CG]/g; my \$A8_gc_content = scalar(@A8_gc) / length(\$oligoA8); my @B8_gc = \$oligoB8 =~ m/[CG]/g; my \$B8_gc_content = scalar(@B8_gc) / length(\$oligoB8); my @C8_gc = \$oligoC8 =~ m/[CG]/g; my \$C8_gc_content = scalar(@C8_gc) / length(\$oligoC8); my @D8_gc = \$oligoD8 =~ m/[CG]/g; my \$D8_gc_content = scalar(@D8_gc) / length(\$oligoD8); my @E8_gc = \$oligoE8 =~ m/[CG]/g; my \$E8_gc_content = scalar(@E8_gc) / length(\$oligoE8); my @F8_gc = \$oligoF8 =~ m/[CG]/g; my \$F8_gc_content = scalar(@F8_gc) / length(\$oligoF8); my @G8_gc = \$oligoG8 =~ m/[CG]/g; my \$G8_gc_content = scalar(@G8_gc) / length(\$oligoG8); my \$meltA8 = 81.5 + (16.6*log10(.1)) + (41*\$A8_gc_content) - (675/length(\$oligoA8)); my \$meltB8 = 81.5 + (16.6*log10(.1)) + (41*\$B8_gc_content) - (675/length(\$oligoB8)); my \$meltC8 = 81.5 + (16.6*log10(.1)) + (41*\$C8_gc_content) - (675/length(\$oligoC8)); my \$meltD8 = 81.5 + (16.6*log10(.1)) + (41*\$D8_gc_content) - (675/length(\$oligoD8)); my \$meltE8 = 81.5 + (16.6*log10(.1)) + (41*\$E8_gc_content) - (675/length(\$oligoE8)); my \$meltF8 = 81.5 + (16.6*log10(.1)) + (41*\$F8_gc_content) - (675/length(\$oligoF8)); my \$meltG8 = 81.5 + (16.6*log10(.1)) + (41*\$G8_gc_content) - (675/length(\$oligoG8)); my \$temp8 = (\$meltA8 < \$meltB8 ? \$meltA8 : \$meltB8); \$temp8 = (\$temp8 < \$meltC8 ? \$temp8 : \$meltC8); \$temp8 = (\$temp8 < \$meltD8 ? \$temp8 : \$meltD8); \$temp8 = (\$temp8 < \$meltE8 ? \$temp8 : \$meltE8); \$temp8 = (\$temp8 < \$meltF8 ? \$temp8 : \$meltF8); my \$min8 = (\$temp8 < \$meltG8 ? \$temp8 : \$meltG8); if (\$min8 > \$currentmax8) { \$currentmax8 = \$min8; @besttemps8 = (\$meltA8, \$meltB8, \$meltC8, \$meltD8, \$meltE8, \$meltF8, \$meltG8); @bestcuts8 = (length(\$oligoA8), length(\$oligoB8), length(\$oligoC8), length(\$oligoD8), length(\$oligoE8), length(\$oligoF8), length(\$oligoG8)); } } } } } } } print "@bestcuts8\n@besttemps8\n\n"; } \$nowtime = localtime; print \$nowtime,"\n\n"; sub log10 { my \$n = shift; return log(\$n)/log(10); }