import java.io.*; import java.util.*; import java.lang.Math.*; public class snpPrimer extends Thread { private Lock1 lock1_2; private Lock1 lock2_1; private Lock1 lock2_3; private String sequence = ""; //source sequence private String allele1 = ""; //first allele in sequence private String allele2 = ""; //second allele in sequence private int sloc = 0; //starting position of polymorphism in sequence private int optprimersize = 0; //optimum primer size private int maxprimersize = 0; //maximum primer size private int minprimersize = 0; //minimum primer size private int maxproductsize = 0; //maximum product size private int minproductsize = 0; //minimum product size private int maxprimerTm = 0; //maximum primer Tm private int optprimerTm = 0; //optimum primer Tm private int minprimerTm = 0; //minimum primer Tm private double maxprimergc = 0; //maximum primer GC% private double minprimergc = 0; //minimum primer GC% private double maxprimercom = 0; //maximum primer complementarity private double maxprimer3com = 0; //maximum primer 3' complementarity private double saltconc = 0; //salt (K+) concentration in mM private double primerconc = 0; //primer concentration in nM public snpPrimer (Lock1 l1, Lock1 l2, Lock1 l3, String s, String a1, String a2, int loc, int optprisize, int maxprisize, int minprisize, int maxprodsize, int minprodsize, int optpriTm, int maxpriTm, int minpriTm, double maxprigc, double minprigc, double maxpricom, double maxpri3com, double saltc, double primerc) { lock1_2 = l1; lock2_1 = l2; lock2_3 = l3; sequence = s; allele1 = a1; allele2 = a2; sloc = loc; optprimersize = optprisize; maxprimersize = maxprisize; minprimersize = minprisize; maxproductsize = maxprodsize; minproductsize = minprodsize; optprimerTm = optpriTm; maxprimerTm = maxpriTm; minprimerTm = minpriTm; maxprimergc = maxprigc; minprimergc = minprigc; maxprimercom = maxpricom; maxprimer3com = maxpri3com; saltconc = saltc; primerconc = primerc; } public void run() { int countout = 0; int misloc = 0; int allelep = 1; //1 indicates wild-type sequence, otherwise mutant DNA int tm = 0; double delta_H = 0; double delta_S = 0; double gc = 0; double valself = 0; double val3self = 0; char misch = ' '; String recogseq = ""; String inString = ""; boolean tmOK = false; boolean gcOK = false; boolean valselfOK = false; boolean val3selfOK = false; boolean recogseqOK = false; primer1List pl = new primer1List(); while (true) { inString = lock1_2.get(); if (inString.equalsIgnoreCase("finish")) break; else { StringTokenizer st = new StringTokenizer(inString); recogseq = st.nextToken(); //always recognition sequence misloc = Integer.valueOf(st.nextToken()).intValue(); //always mismatch position in wild-type DNA allelep = Integer.valueOf(st.nextToken()).intValue(); //always there if (st.hasMoreTokens()) //only when there is a mismatch misch = st.nextToken().charAt(0); recogseqOK = true; //check whether input primer size is OK for recognition sequence int seqlen = recogseq.length(); if (seqlen > maxprimersize) { System.out.println("Maximum allowable primer size too short"); break; } else if (seqlen > optprimersize) { optprimersize = seqlen; minprimersize = seqlen; } else if (seqlen > minprimersize) minprimersize = seqlen; } //There are two kinds of combinations: (1) inner primer neighbouring //the SNP; (2) reverse primer neighbouring the SNP //The mismatch should not locate on the end of the primer. //The priority assumption is: Tm > 3'complementarity > complementarity > //GC% > primer size > product size. //Therefore, the strategy is to find the primer(s) //with Tm closest to optimum Tm as specified in input. //There are (maxprimersize-minprimersize+1) options in total int options = maxprimersize - minprimersize + 1; int count = options; int primersize = 0; int prevsize = 0; boolean OK = false; while (count != 0) { if (count == options) { //first choose optimum primer size to test primersize = optprimersize; } else if ((options - count) % 2 == 0) { //primer shorter than optimum length primersize = optprimersize - (options - count) / 2; } else { //primer longer than optimum length primersize = optprimersize + (options - count) / 2 + 1; } //check whether primersize out of range if (primersize < minprimersize) primersize = prevsize + 1; else if (primersize > maxprimersize) primersize = prevsize - 1; if ((primersize < minprimersize) || (primersize > maxprimersize)) break; prevsize = primersize; int number = 0; //the number of options for current primer if (misloc == sloc) { //no mismatch is introduced, normal primer design required //i.e. one forward primer on left of the SNP and one reverse //primer on the right of the SNP. Here needed is the forward. //start from one position left of the SNP and move left one //by one until reach the (maxproductsize-minprimersize-1) //position left of the SNP. number = maxproductsize - primersize - minprimersize - 1; if (sloc < maxproductsize - minprimersize - 1) number = sloc - primersize; } else if (misloc < sloc) { //mismatch is on the left of the SNP //start from two positions left of the SNP (one position //left of the 3' end of the primer) and move left one //by one until one step short of making the mismatch at the //end of primer. number = sloc - 1 - misloc; if (primersize > misloc + 1) number = sloc - primersize; } else { //mismatch is on the right of the SNP //start from two positons right of the SNP (one position right //of the 3' end of the would-be primer) and move right one //by one along the lower strand until one step short of making //the mismatch at the end of the primer number = misloc - sloc - allele1.length(); if (primersize + misloc - 1 > sequence.length()) number = sequence.length() - sloc - allele1.length() - primersize; } int p1 = 0; int p2 = 0; String inner = ""; //get all possible inner primers of specified size while (number > 0) { if (misloc == sloc) { p1 = sloc - number; p2 = p1 - primersize; inner = sequence.substring(p2, p1); } else if (misloc < sloc) { p1 = misloc + number; p2 = p1 - primersize; int p3 = primersize - number - 1; //position of mismatch in primer String s1 = sequence.substring(p2, p1); designPrimer design = new designPrimer(); inner = design.getForward(s1, p3, misch); } else if (misloc > sloc) { p1 = misloc - number - 1; p2 = p1 + primersize; int p3 = number; String s1 = sequence.substring(p1, p2); designPrimer design = new designPrimer(); inner = design.getReverse(s1, p3, misch); } if (inner.length() !=0) { baseList seq = new baseList(); for (int i=0; i= minprimergc) && (gc <= maxprimergc)) { gcOK = true; //check melting temperature delta_H = seq.delta_H * -1000.0; delta_S = seq.delta_S * -1.0; tm = (int)(delta_H / (delta_S + 1.987 * Math.log(primerconc/4000000000.0)) - 273.15 + 16.6 * Math.log(saltconc/1000.0) / Math.log(10)); if ((tm >= minprimerTm) && (tm <= maxprimerTm)) { OK = true; tmOK = true; } else OK = false; } else OK = false; //check complementarity if (OK == true) { checkPrimer check = new checkPrimer(); valself = check.evalself(inner); if (valself <= maxprimercom) { valselfOK = true; val3self = check.eval3self(inner); if (val3self <= maxprimer3com) { val3selfOK = true; OK = true; } else OK = false; } else OK = false; } if (OK == true) { //save the primer into primer list primer1Entry p1n; if (misloc <= sloc) p1n = new primer1Entry(inner, tm, (p2+1), p1, sloc, misloc, optprimerTm); else p1n = new primer1Entry(inner, tm, p2, (p1+1), sloc, misloc, optprimerTm); pl.insert(p1n); countout++; } } //end of "if inner ..." number--; } //end of while (number) count--; } //end of while (count) if ((countout == 0) && (recogseqOK == true)) { System.out.println("No appropriate inner primers found"); if (gcOK == false) System.out.println("Please reset GC content range"); else if (tmOK == false) System.out.println("Please reset Tm or GC content inputs"); else if ((valselfOK == false) && (val3selfOK == false)) { System.out.println("Please reset complementarity inputs and/or"); System.out.println("reset the Tm or GC content inputs"); } else if (valselfOK == false) { System.out.println("Please reset the Maximum complementarity inputs"); System.out.println("and/or reset the Tm or GC content inputs"); } else if (val3selfOK == false) { System.out.println("Please reset the 3' Maximum complementarity inputs"); System.out.println("and/or reset other inputs like Tm inputs"); } } else if (recogseqOK == false) System.out.println("No suitable enzyme found"); else if (countout != 0) { while (pl.empty() != true) { //pass on primer sequence, positions and Tm and for which allele primer1Entry pn = pl.get(); lock2_3.put(java.lang.String.valueOf(pn.end5) + " " + pn.entry + " " + java.lang.String.valueOf(pn.end3) + " " + java.lang.String.valueOf(pn.tm) + " " + java.lang.String.valueOf(allelep)); } } //reinitialize all relevant variables countout = 0; recogseqOK = false; gcOK = false; tmOK = false; valselfOK = false; val3selfOK = false; //inform the outerPrimer thread that current parsing completed lock2_3.put("break"); } //end of while (true) lock2_3.put("finish"); //terminate all threads return; } //end of run() }