#include #include "common.h" #include "cheapcgi.h" #include "htmshell.h" #include "dnautil.h" char *skipFirstWord(char *s) { s += strspn(s, whiteSpaceChopper); s += strcspn(s, whiteSpaceChopper); s += strspn(s, whiteSpaceChopper); return s; } int calcTm(char *dna, int size) { int res = 0; int i; char c; for (i=0; i= startIx + 2*pinSize; endIx -= 1) { gotPin = TRUE; for (i=0; i bSize ? bSize : aSize); int i; long score = 0; long contigScore = 0; long bestContigScore = 0; int contigCount = 0; int baseScore; boolean inMatch = FALSE; char a,b; for (i=0; i bestContigScore) bestContigScore = contigScore; contigScore = 0; inMatch = FALSE; } } } return (score > bestContigScore ? score : bestContigScore); } long bestScore(char *a, int aSize, char *b, int bSize) { long bestScore = -0x7000000; long score; int i; for (i=0;i bestScore) bestScore = score; } for (i=0; i bestScore) bestScore = score; } return bestScore; } /* Find a primer in source that meets the following specifications: 1. It is within 3 degrees of tm. 2. It has no hairpins. 3. It doesn't complement with compo. 4. It ends in a C or a G. Return TRUE if found one, and put it in the return variables pPrimer and pPrimerSize. If the compo var is null, it won't be checked. */ boolean findPrimer(char *source, int sourceSize, char *compo, int compoSize, char *compoRcBuf, int desiredTm, int tmRange, char **pPrimer, int *pPrimerSize) { int startIx; int endIx; int tm; int hairpinCutoff = 4; int compoCutoff = 16; char firstBase; if (compo != NULL) { memcpy(compoRcBuf, compo, compoSize); reverseComplement(compoRcBuf, compoSize); } for (startIx=0; startIx max) max = size; } return max; } struct primerPair { char *forward; int forwardSize; char *reverse; int reverseSize; }; boolean findTmPrimerPair(char *leftRcBuf, int tm, int tmRange, char *left, char *right, struct primerPair *pp) { char *fPrimer; int fPrimerSize; int leftSize = strlen(left); int leftStart; char *rPrimer; int rPrimerSize; for (leftStart=0; leftStartforward = fPrimer; pp->forwardSize = fPrimerSize; pp->reverse = rPrimer; pp->reverseSize = rPrimerSize; return TRUE; } } } return FALSE; } boolean findTmPrimerList(int tm, int tmRange, int count, char *lefts[], char *rights[], struct primerPair *primers) { int i; int longestLeftSize = longestStrlen(lefts, count); char *leftRcBuf = needMem(longestLeftSize); boolean gotAll = TRUE; for (i=0; i= oparen) errAbort("Expecting gene name at start of line."); /* Squirrel away name portion. */ if (firstDna > line) firstDna[-1] = 0; if ((geneNames[i] = strdup(skipLeadingSpaces(line))) == NULL) errAbort("Out of memory."); /* Get rid of any remaining white space in input. */ eraseWhiteSpace(firstDna); /* Grab stuff to left and right of parenthesis. */ if ((origDna[i] = strdup(firstDna)) == NULL) errAbort("Out of memory."); oparen = strchr(firstDna, '('); cparen = strchr(oparen, ')'); *oparen = 0; lefts[i] = firstDna; rights[i] = cparen; /* Reverse complement the left side to make things * easier later. */ reverseComplement(lefts[i], strlen(lefts[i])); } if (findPrimerList(lineCount, lefts, rights, primers)) { for (i=0; iforward, pp->forwardSize); fbuf[pp->forwardSize] = 0; memcpy(rbuf, pp->reverse, pp->reverseSize); rbuf[pp->reverseSize] = 0; /* Uppercase input corresponding to reverse primer */ s = strstr(oDna, rbuf); if (s == NULL) errAbort("How strange, primer is not in the input!"); toUpperN(s, pp->reverseSize); /* Reverse complement both primers, so forward one comes first. */ reverseComplement(rbuf, pp->reverseSize); reverseComplement(fbuf, pp->forwardSize); /* Uppercase input corresponding to forward primer */ s = strstr(oDna, fbuf); if (s == NULL) errAbort("Weird, primer is not in the input!"); toUpperN(s, pp->forwardSize); printf("

%s %s
\n", geneNames[i], oDna); printf("forward %s %d bases Tm = %d
\n", fbuf, pp->forwardSize, calcTm(pp->forward, pp->forwardSize)); printf("reverse %s %d bases Tm = %d

\n", rbuf, pp->reverseSize, calcTm(pp->reverse, pp->reverseSize)); } } else { printf("

Sorry, couldn't find suitable primers. Try again with\n"); printf("more flanking DNA to search.

\n"); if (lineCount > 1) { printf("

Also try submitting less primers in a batch.

\n"); } } } #endif /* OLD */ void filterBadChars(char *in, char *out) /* Remove everything but nucleotides and parenthesis as you * copy from in to out. (In and out may point to same place. */ { char filter[256]; char c; zeroBytes(filter, sizeof(filter)); filter['a'] = 'a'; filter['A'] = 'A'; filter['c'] = 'c'; filter['C'] = 'C'; filter['g'] = 'g'; filter['G'] = 'G'; filter['t'] = 't'; filter['T'] = 'T'; filter['('] = '('; filter[')'] = ')'; while ((c = *in++) != 0) { if ((c = filter[c]) != 0) *out++ = c; } *out++ = 0; } void doMiddle() { char *dnaLines; char *origDna; /* Not chopped up and inverse complemented */ char *left, *right; struct primerPair primer; int idealTm; /* Grab the input. */ dnaLines = cgiString("dnaLines"); idealTm = cgiInt("idealTm"); if (idealTm < 25 || idealTm > 90) errAbort("Ideal Tm should be between about 45 and 70, not %d", idealTm); /* Massage it into a form we can work with. */ tolowers(dnaLines); { char *oparen, *cparen; /* Get input line, make sure it has two parenthesis */ oparen = strchr(dnaLines, '('); if (oparen == NULL) errAbort("Missing parenthesis in input."); cparen = strchr(oparen, ')'); if (cparen == NULL) errAbort("Missing parenthesis in input."); /* Get rid of junk in input. */ filterBadChars(dnaLines,dnaLines); /* Grab stuff to left and right of parenthesis. */ if ((origDna = strdup(dnaLines)) == NULL) errAbort("Out of memory."); oparen = strchr(dnaLines, '('); cparen = strchr(oparen, ')'); *oparen = 0; left = dnaLines; right = cparen; /* Reverse complement the left side to make things * easier later. */ reverseComplement(left, strlen(left)); } if (findPrimerList(1, &left, &right, &primer, idealTm)) { struct primerPair *pp = &primer; char fbuf[128],rbuf[128]; char *s; /* convert primerse to null terminated strings. */ memcpy(fbuf, pp->forward, pp->forwardSize); fbuf[pp->forwardSize] = 0; memcpy(rbuf, pp->reverse, pp->reverseSize); rbuf[pp->reverseSize] = 0; /* Uppercase input corresponding to reverse primer */ s = strstr(origDna, rbuf); if (s == NULL) errAbort("How strange, primer is not in the input!"); toUpperN(s, pp->reverseSize); /* Reverse complement both primers, so forward one comes first. */ reverseComplement(rbuf, pp->reverseSize); reverseComplement(fbuf, pp->forwardSize); /* Uppercase input corresponding to forward primer */ s = strstr(origDna, fbuf); if (s == NULL) errAbort("Weird, primer is not in the input!"); toUpperN(s, pp->forwardSize); printf("

%s
\n", origDna); printf("forward %s %d bases Tm = %d
\n", fbuf, pp->forwardSize, calcTm(pp->forward, pp->forwardSize)); printf("reverse %s %d bases Tm = %d

\n", rbuf, pp->reverseSize, calcTm(pp->reverse, pp->reverseSize)); } else { printf("

Sorry, couldn't find suitable primers. Try again with\n"); printf("more flanking DNA to search.

\n"); } } int main(int argc, char *argv[]) { dnaUtilOpen(); htmShell("PrimeMate Results", doMiddle, "POST"); return 0; }