Исходный код программы поиска теоретических ПЦР-фрагментов по найденным праймерам с распараллеленным циклом на Си

/*fragparr.c*/

#include <stdio.h>

#include <string.h>

#include <signal.h>

#include <malloc.h>

#include <stdlib.h>

#include <sys/stat.h>

#include <sys/types.h>

#include <fcntl.h>

#include <sys/time.h>

#include <omp.h>

#define FILENAME1 "sequence.raw"

#define FILENAME2 "primersort0.raw"

#define FILENAME3 "optprimer.raw"

#define MIN(a,b) ((a) < (b) ? (a) : (b))

#define MAX(a,b) ((a) > (b) ? (a) : (b))

#define XSIZE 4200

#define SIGMA 256

#define WORD 32

/*void prof(char * str, int i, struct timeval * B){

struct itimerval A;

struct timeval tmp;

if (getitimer(ITIMER_PROF, &A)){

perror("getitimer");

exit(1);

}

tmp.tv_usec=B->tv_usec-A.it_value.tv_usec;

tmp.tv_sec=B->tv_sec-A.it_value.tv_sec;

if (tmp.tv_usec<0){

tmp.tv_usec+=1000000;

tmp.tv_sec--;

}

fprintf(stderr, "%d %s: %d.%d - %d.%d\n", i, str, A.it_value.tv_sec,

A.it_value.tv_usec,

tmp.tv_sec, tmp.tv_usec);

*B=A.it_value;

}*/

/*Инвертирование строки*/

void reverse(char p1[], char p2[]){

char * tmp=p1;

while (*tmp++);

for (tmp--; --tmp>=p1; *p2++=*tmp);

*p2='\0';

}

/*Инвертирование символов*/

void inverse(char p1[], char p2[], int strl){

int i;

for (i=0; i<strl; i++)

switch (p1[i]){

case 'A':

p2[i]='T';

break;

case 'T':

p2[i]='A';

break;

case 'C':

p2[i]='G';

break;

case 'G':

p2[i]='C';

break;

}

p2[i]='\0';

}

/*[1]-----Примитивный алгоритм*/

/*

char* hospool( char *y , char *x, int m){

char* yy;

int i, j;

yy=y;

i=0;

while (y[i] != '\0'){

for ( j=0; j < m; ++j){

if (y[i+j]!= x[j])

break;

}

if (j==m){

yy=y+i;

return (yy);

}

i++;

}

return NULL;

}

*/

/*[2]-----Knuth Morris-Pratt-----/kmp/-----1977*/

/*

char* kmpstr( char *y , char *x, int m){

char* yy;

int i, j, n;

yy=y;

int *protr =(int*)malloc(m*sizeof(int));

protr[0]=0;

// Построение таблицы смещений

for(i=1, j=0; i<m; i++){

while(j>0 && x[j]!=x[i])

j = protr[j-1];

if(x[j]==x[i])

j++;

protr[i]=j;

}

// Поиск

i=0;

j=0;

while (y[i] != '\0'){

while(j>0 && x[j]!=y[i])

j=protr[j-1];

if(x[j]==y[i])

j++;

if (j==m){

free (protr);

yy=y+i-j+1;

return yy;

}

i++;

}

free (protr);

return NULL;

}

*/

/*[3]-----Boyer Moore-----/bm/-----1977*/

/*

//Построение таблицы для сдвига по функции плохого символа

void preBmBc(unsigned char *x, int m, int bmBc[]) {

int i;

for (i = 0; i < SIGMA; ++i)

bmBc[i] = m;

for (i = 0; i < m - 1; ++i)

bmBc[x[i]] = m - i - 1;

}

void suffixes(unsigned char *x, int m, int *suff) {

int f, g, i;

suff[m - 1] = m;

g = m - 1;

for (i = m - 2; i >= 0; --i) {

if (i > g && suff[i + m - 1 - f] < i - g)

suff[i] = suff[i + m - 1 - f];

else {

if (i < g)

g = i;

f = i;

while (g >= 0 && x[g] == x[g + m - 1 - f])

--g;

suff[i] = f - g;

}

}

}

//Построение таблицы для сдвига по функции хорошего суффикса

void preBmGs(unsigned char *x, int m, int bmGs[]) {

int i, j, suff[XSIZE];

suffixes(x, m, suff);

for (i = 0; i < m; ++i)

bmGs[i] = m;

j = 0;

for (i = m - 1; i >= 0; --i)

if (suff[i] == i + 1)

for (; j < m - 1 - i; ++j)

if (bmGs[j] == m)

bmGs[j] = m - 1 - i;

for (i = 0; i <= m - 2; ++i)

bmGs[m - 1 - suff[i]] = m - 1 - i;

}

char * search(unsigned char *y, unsigned char *x, int m) {

int i, j, bmGs[XSIZE], bmBc[SIGMA], n;

char * yy;

yy=y;

n=strlen(y);

// Подготовительные вычисления

preBmGs(x, m, bmGs);

preBmBc(x, m, bmBc);

// Поиск

j = 0;

while (j <= n - m) {

for (i = m - 1; i >= 0 && x[i] == y[i + j]; --i);

if (i < 0)

return yy+j;

else

j += MAX(bmGs[i], bmBc[y[i + j]] - m + 1 + i);

}

return NULL;

}

*/

/*[4]-----Turbo Boyer Moore-----/tbm/-----1994*/

/*

//Построение таблицы для сдвига по функции плохого символа

void preBmBc(unsigned char *x, int m, int bmBc[]) {

int i;

for (i = 0; i < SIGMA; ++i)

bmBc[i] = m;

for (i = 0; i < m - 1; ++i)

bmBc[x[i]] = m - i - 1;

}

void suffixes(unsigned char *x, int m, int *suff) {

int f, g, i;

suff[m - 1] = m;

g = m - 1;

for (i = m - 2; i >= 0; --i) {

if (i > g && suff[i + m - 1 - f] < i - g)

suff[i] = suff[i + m - 1 - f];

else {

if (i < g)

g = i;

f = i;

while (g >= 0 && x[g] == x[g + m - 1 - f])

--g;

suff[i] = f - g;

}

}

}

//Построение таблицы для сдвига по функции хорошего суффикса

void preBmGs(unsigned char *x, int m, int bmGs[]) {

int i, j, suff[XSIZE];

suffixes(x, m, suff);

for (i = 0; i < m; ++i)

bmGs[i] = m;

j = 0;

for (i = m - 1; i >= 0; --i)

if (suff[i] == i + 1)

for (; j < m - 1 - i; ++j)

if (bmGs[j] == m)

bmGs[j] = m - 1 - i;

for (i = 0; i <= m - 2; ++i)

bmGs[m - 1 - suff[i]] = m - 1 - i;

}

char * search(unsigned char *y, unsigned char *x, int m) {

int bcShift, i, j, shift, u, v, turboShift, bmGs[XSIZE], bmBc[SIGMA], n;

char * yy;

yy=y;

n=strlen(y);

// Подготовительные вычисления

preBmGs(x, m, bmGs);

preBmBc(x, m, bmBc);

// Поиск

j = u = 0;

shift = m;

while (j <= n - m) {

i = m - 1;

while (i >= 0 && x[i] == y[i + j]) {

--i;

if (u != 0 && i == m - 1 - shift)

i -= u;

}

if (i < 0)

return yy+j;

else {

v = m - 1 - i;

turboShift = u - v;

bcShift = bmBc[y[i + j]] - m + 1 + i;

shift = MAX(turboShift, bcShift);

shift = MAX(shift, bmGs[i]);

if (shift == bmGs[i])

u = MIN(m - shift, v);

else {

if (turboShift < bcShift)

shift = MAX(shift, u + 1);

u = 0;

}

}

j += shift;

}

return NULL;

}

*/

/*[5]-----Zhu Takaoka-----/zt/-----1987*/

void suffixes(unsigned char *x, int m, int *suff) {

int f, g, i;

suff[m - 1] = m;

g = m - 1;

for (i = m - 2; i >= 0; --i) {

if (i > g && suff[i + m - 1 - f] < i - g)

suff[i] = suff[i + m - 1 - f];

else {

if (i < g)

g = i;

f = i;

while (g >= 0 && x[g] == x[g + m - 1 - f])

--g;

suff[i] = f - g;

}

}

}

//Построение таблицы для сдвига по функции хорошего суффикса

void preBmGs(unsigned char *x, int m, int bmGs[]) {

int i, j, suff[XSIZE];

suffixes(x, m, suff);

for (i = 0; i < m; ++i)

bmGs[i] = m;

j = 0;

for (i = m - 1; i >= 0; --i)

if (suff[i] == i + 1)

for (; j < m - 1 - i; ++j)

if (bmGs[j] == m)

bmGs[j] = m - 1 - i;

for (i = 0; i <= m - 2; ++i)

bmGs[m - 1 - suff[i]] = m - 1 - i;

}

//Построение таблицы для сдвига по функции плохого символа

void preZtBc(unsigned char *x, int m, int ztBc[SIGMA][SIGMA]) {

int i, j;

for (i = 0; i < SIGMA; ++i)

for (j = 0; j < SIGMA; ++j)

ztBc[i][j] = m;

for (i = 0; i < SIGMA; ++i)

ztBc[i][x[0]] = m - 1;

for (i = 1; i < m - 1; ++i)

ztBc[x[i - 1]][x[i]] = m - 1 - i;

}

char * search(unsigned char *y, unsigned char *x, int m) {

int i, j, ztBc[SIGMA][SIGMA], bmGs[XSIZE], n;

char * yy;

yy=y;

n=strlen(y);

// Подготовительные вычисления

preZtBc(x, m, ztBc);

preBmGs(x, m, bmGs);

// Поиск

j = 0;

while (j <= n - m) {

i = m - 1;

while (i >=0 && x[i] == y[i + j])

--i;

if (i < 0)

return yy+j;

else

j += MAX(bmGs[i],ztBc[y[j + m - 2]][y[j + m - 1]]);

}

return NULL;

}

/*[6]-----Genomic Rapid Algofor String Pattern Matching-----/graspm/-----2009*/

/*

typedef struct GRASPmList {

int k;

struct GRASPmList *next;

} GList;

void ADD_LIST(GList **l, int e) {

GList *t = (GList *)malloc(sizeof(GList));

t->k = e;

t->next = *l;

*l = t;

}

char * search(unsigned char *t, unsigned char *p, int m) {

GList *pos, *z[SIGMA];

int i, j, k, first, hbc[SIGMA], n;

char * yy;

yy=t;

n=strlen(t);

// Подготовительные вычисления

for(i=0; i<SIGMA; i++)

z[i]=NULL;

if (p[0] == p[m-1])

for(i=0; i<SIGMA; i++)

ADD_LIST(&z[i], 0);

for(i=0; i<m-1;i++)

if (p[i+1] == p[m-1])

ADD_LIST(&z[p[i]],(i+1));

for(i=0;i<SIGMA;i++)

hbc[i]=m;

for(i=0;i<m;i++)

hbc[p[i]]=m-i-1;

// Поиск

j = m-1;

while (j<n) {

while (k=hbc[t[j]]) j += k; {

pos = z[t[j-1]];

while(pos!=NULL) {

k = pos->k;

i = 0;

first = j-k;

while(i<m && p[i]==t[first+i])

i++;

if(i==m && first<=n-m)

return yy+first;

pos = pos->next;

}

}

j+=m;

}

return NULL;

}

*/

/*[7]-----Quick Search-----/qs/-----1990*/

/*

//Построение таблицы смещений

void preQsBc(unsigned char *P, int m, int qbc[]) {

int i;

for(i=0;i<SIGMA;i++)

qbc[i]=m+1;

for(i=0;i<m;i++)

qbc[P[i]]=m-i;

}

char * search(unsigned char *T, unsigned char *P, int m) {

int i, s, qsbc[SIGMA], n;

char * yy;

yy=T;

n=strlen(T);

// Подготовительные вычисления

preQsBc(P, m, qsbc);

// Поиск

s = 0;

while(s<=n-m) {

i=0;

while(i<m && P[i]==T[s+i])

i++;

if(i==m)

return yy+s;

s+=qsbc[T[s+m]];

}

return NULL;

}

*/

/*[8]-----Shift Or-----/so/-----1992*/

/*

int preSo(unsigned char *x, int m, unsigned int S[]) {

unsigned int j, lim;

int i;

for (i = 0; i < SIGMA; ++i)

S[i] = ~0;

for (lim = i = 0, j = 1; i < m; ++i, j <<= 1) {

S[x[i]] &= ~j;

lim |= j;

}

lim = ~(lim>>1);

return(lim);

}

char * search_large(unsigned char *y, unsigned char *x, int m) {

unsigned int lim, D, k, h, p_len;

unsigned int S[SIGMA];

int j, n;

char *yy;

yy=y;

n=strlen(y);

p_len = m;

m=32;

// Подготовительные вычисления

lim = preSo(x, m, S);

// Поиск

for (D = ~0, j = 0; j < n; ++j) {

D = (D<<1) | S[y[j]];

if (D < lim) {

k = 0;

h = j-m+1;

while(k<p_len && x[k]==y[h+k])

k++;

if(k==p_len)

return yy+j-m+1;

}

}

return NULL;

}

char * search(unsigned char *y, unsigned char *x, int m) {

unsigned int lim, D;

unsigned int S[SIGMA];

int j, n;

if (m > WORD) return search_large(y, x, m);

char *yy;

yy=y;

n=strlen(y);

// Подготовительные вычисления

lim = preSo(x, m, S);

// Поиск

for (D = ~0, j = 0; j < n; ++j) {

D = (D<<1) | S[y[j]];

if (D < lim)

return yy+j-m+1;

}

return NULL;

}

*/

/*[9]-----Karp Rabin-----/kr/-----1987*/

/*

#define REHASH(a, b, h) ((((h) - (a)*d) << 1) + (b))

char * search(char *y, char *x, int m) {

int d, hx, hy, i, j, n;

char *yy;

yy=y;

n=strlen(y);

// Подготовительные вычисления

for (d = i = 1; i < m; ++i)

d = (d<<1);

for (hy = hx = i = 0; i < m; ++i) {

hx = ((hx<<1) + x[i]);

hy = ((hy<<1) + y[i]);

}

// Поиск

j = 0;

while (j <= n-m) {

if (hx == hy && memcmp(x, y + j, m) == 0)

return yy+j;

hy = REHASH(y[j], y[j + m], hy);

++j;

}

return NULL;

}

*/

struct write_rec{

int offset;

short len;

char lenp;

char num;

char prim[24];

};

/*Для ассемблерной реализации*/

/*char* mystrstr(char *x, char *y);*/

int main(int args, char ** argv){

int f, k, flag, i, lenf, j, kolvo, cpu;

char * bufdata, * primer, * p, * penter, * pend, * pp, *p2enter, *ptester;

struct stat st;

struct itimerval A;

struct timeval B;

struct write_rec W;

A.it_interval.tv_sec=0x7fffffff;

A.it_interval.tv_usec=0;

A.it_value=A.it_interval;

B=A.it_value;

signal(SIGPROF, SIG_IGN);

if (setitimer(ITIMER_PROF, &A, NULL)){

perror("setittime");

exit(1);

}

if ((f=open(FILENAME1, O_RDONLY))==-1){

perror("open");

exit(1);

}

if (fstat(f, &st)==-1){

perror("stat");

exit(1);

}

if ((bufdata=malloc(st.st_size+1))==NULL){

perror("malloc");

exit(1);

}

memset(bufdata, '\0', st.st_size+1);

if (read(f, bufdata, st.st_size)!=st.st_size){

perror("read");

exit(1);

}

close(f);

if ((f=open(FILENAME2, O_RDONLY))==-1){

perror("open");

exit(1);

}

if (fstat(f, &st)==-1){

perror("stat");

exit(1);

}

if ((primer=malloc(st.st_size+1))==NULL){

perror("malloc");

exit(1);

}

memset(primer, '\0', st.st_size+1);

if (read(f, primer, st.st_size)!=st.st_size){

perror("read");

exit(1);

}

lenf=st.st_size;

close(f);

if ((f=open(FILENAME3, O_WRONLY | O_APPEND | O_CREAT, 0600))==-1){

perror("openwrite");

exit(1);

}

// prof("Before out for", 0, &B);

printf("Длина %d\n", lenf);

W.num=1;

cpu=atoi(argv[1]);

printf("Количество потоков %d\n", cpu);

omp_set_num_threads(cpu);

#pragma omp parallel for private(penter), private(pend), private(pp), private(p)

for (j=0; j<lenf; j=j+32){

char str[26]="ATG", rev[26], inv[26];

p=primer+j;

flag=0;

strcpy(str+3, p);

// prof("Before strlen", i, &B);

int l=strlen(str);

W.lenp=l;

memset(W.prim, 0, 24);

strncpy(W.prim, str+3, l);

// prof("Before strlen", i, &B);

reverse(str, rev);

inverse(rev, inv, l);

/*Первое вхождение праймера в строку*/

// prof("Before strstr 1", i, &B);

for (p=bufdata; penter=search(p, str, l); p=pend+l){

/*for (p=bufdata; penter=strstr(p, str); p=pend+l){*/

/*for (p=bufdata; penter=mystrstr(p, str); p=pend+l){*/

// prof("Before strstr 2", i, &B);

/*Первое вхождение инвертированного праймера в строку*/

pend=search(penter+l, inv, l);

/*pend=strstr(penter+l, inv);*/

/*pend=mystrstr(penter+l, inv);*/

// prof("After strstr 2", i, &B);

if (pend){

char ctmp;

ctmp=*pend;

*pend='\0';

/*Поиск дополнительных вхождений праймера в строку*/

// prof("Before strstr 3", i, &B);

for (pp=penter; pp; pp=search(pp+1, str, l))

/*for (pp=penter; pp; pp=strstr(pp+1, str))*/

/*for (pp=penter; pp; pp=mystrstr(pp+1, str))*/

penter=pp;

// prof("After strstr 3", i, &B);

*pend=ctmp;

k=pend-penter+l;

// prof("In", i, &B);

if (k>60 && k<3500){

if (flag==0){

printf("Прямой праймер %s\n", str);

printf("Обратный праймер %s\n", rev);

printf("Обратный инвертированный праймер %s\n", inv);

flag=1;

}

W.offset=penter-bufdata+1;

W.len=k;

if (write(f, &W, 32)!=32){

perror("write");

exit(1);

}

printf("%d %d %d\n", penter-bufdata+1, k, l);

}

}

else

break;

}

}

free(bufdata);

free(primer);

close(f);

printf("Поиск завершен!\n");

exit(0);

}

Наши рекомендации