sumalibs first commit
This commit is contained in:
BIN
liblcs/.DS_Store
vendored
Normal file
BIN
liblcs/.DS_Store
vendored
Normal file
Binary file not shown.
25
liblcs/Makefile
Normal file
25
liblcs/Makefile
Normal file
@ -0,0 +1,25 @@
|
||||
|
||||
SOURCES = sse_banded_LCS_alignment.c \
|
||||
upperband.c
|
||||
|
||||
SRCS=$(SOURCES)
|
||||
|
||||
|
||||
OBJECTS= $(patsubst %.c,%.o,$(SOURCES))
|
||||
|
||||
LIBFILE= liblcs.a
|
||||
RANLIB=ranlib
|
||||
|
||||
|
||||
include ../global.mk
|
||||
|
||||
all: $(LIBFILE)
|
||||
|
||||
clean:
|
||||
rm -rf $(OBJECTS) $(LIBFILE)
|
||||
rm -f *.P
|
||||
rm -f *.a
|
||||
|
||||
$(LIBFILE): $(OBJECTS)
|
||||
ar -cr $@ $?
|
||||
$(RANLIB) $@
|
168
liblcs/_lcs.ext.1.c
Normal file
168
liblcs/_lcs.ext.1.c
Normal file
@ -0,0 +1,168 @@
|
||||
#include "_lcs.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
|
||||
// Allocate a band allowing to align sequences of length : 'length'
|
||||
|
||||
column_t* allocateColumn(int length,column_t *column, bool mode8bits)
|
||||
{
|
||||
int size;
|
||||
bool newc = false;
|
||||
|
||||
// The band length should be equal to the length
|
||||
// of the sequence + 7 for taking into account its
|
||||
// shape
|
||||
|
||||
size = (length+1) * ((mode8bits) ? sizeof(int8_t):sizeof(int16_t));
|
||||
|
||||
|
||||
// If the pointer to the old column is NULL we allocate
|
||||
// a new column
|
||||
|
||||
if (column==NULL)
|
||||
{
|
||||
|
||||
column = malloc(sizeof(column_t));
|
||||
if (!column)
|
||||
return NULL;
|
||||
|
||||
column->size = 0;
|
||||
column->data.shrt=NULL;
|
||||
column->score.shrt=NULL;
|
||||
newc = true;
|
||||
}
|
||||
|
||||
// Otherwise we check if its size is sufficient
|
||||
// or if it should be extended
|
||||
|
||||
if (size > column->size)
|
||||
{
|
||||
int16_t *old = column->data.shrt;
|
||||
int16_t *olds= column->score.shrt;
|
||||
|
||||
column->data.shrt = malloc(size);
|
||||
column->score.shrt= malloc(size);
|
||||
|
||||
if (column->data.shrt==NULL || column->score.shrt==NULL)
|
||||
{
|
||||
fprintf(stderr,"Allocation Error on column for a size of %d\n" , size);
|
||||
column->data.shrt = old;
|
||||
column->score.shrt= olds;
|
||||
|
||||
if (newc)
|
||||
{
|
||||
free(column);
|
||||
column=NULL;
|
||||
return NULL;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
column->size = size;
|
||||
}
|
||||
|
||||
return column;
|
||||
}
|
||||
|
||||
void freeColumn(column_p column)
|
||||
{
|
||||
if (column)
|
||||
{
|
||||
if (column->data.shrt)
|
||||
free(column->data.shrt);
|
||||
|
||||
if (column->score.shrt)
|
||||
free(column->score.shrt);
|
||||
|
||||
free(column);
|
||||
}
|
||||
}
|
||||
|
||||
int fastLCSScore(const char* seq1, const char* seq2,column_pp column,int32_t* lpath)
|
||||
{
|
||||
return fastLCSScore16(seq1,seq2,column,lpath);
|
||||
}
|
||||
|
||||
int simpleLCS(const char* seq1, const char* seq2,column_pp ppcolumn,int32_t* lpath)
|
||||
{
|
||||
int lseq1,lseq2; // length of the both sequences
|
||||
int lcs;
|
||||
int itmp; // tmp variables for swap
|
||||
const char* stmp; //
|
||||
int32_t *score;
|
||||
int32_t *path;
|
||||
column_t *column;
|
||||
int32_t i,j;
|
||||
int32_t sl,su,sd;
|
||||
int32_t pl,pu,pd;
|
||||
|
||||
// Made seq1 the longest sequences
|
||||
lseq1=strlen(seq1);
|
||||
lseq2=strlen(seq2);
|
||||
|
||||
if (lseq1 < lseq2)
|
||||
{
|
||||
itmp=lseq1;
|
||||
lseq1=lseq2;
|
||||
lseq2=itmp;
|
||||
|
||||
stmp=seq1;
|
||||
seq1=seq2;
|
||||
seq2=stmp;
|
||||
}
|
||||
|
||||
lseq1++;
|
||||
lseq2++;
|
||||
|
||||
// a band sized to the smallest sequence is allocated
|
||||
|
||||
if (ppcolumn)
|
||||
column = *ppcolumn;
|
||||
else
|
||||
column=NULL;
|
||||
|
||||
column = allocateColumn(lseq1*2,column,0);
|
||||
score = (int32_t*) column->score.shrt;
|
||||
path = (int32_t*) column->data.shrt;
|
||||
|
||||
memset(score,0,lseq1 * sizeof(int32_t));
|
||||
|
||||
for (j=0; j < lseq1; j++)
|
||||
path[j]=j;
|
||||
|
||||
for (i=1; i< lseq2; i++)
|
||||
{
|
||||
sl=0;
|
||||
pl=i;
|
||||
for (j=1; j < lseq1; j++)
|
||||
{
|
||||
sd=score[j-1] + (seq2[i-1]==seq1[j-1] ? 1:0);
|
||||
pd=path[j-1] + 1;
|
||||
|
||||
su=score[j];
|
||||
pu=path[j] + 1;
|
||||
|
||||
score[j-1]=sl;
|
||||
|
||||
if (su > sl) sl=su, pl=pu;
|
||||
if (sd > sl) sl=sd, pl=pd;
|
||||
}
|
||||
}
|
||||
|
||||
lcs = sl;
|
||||
if(lpath) *lpath=pl;
|
||||
|
||||
if (ppcolumn)
|
||||
*ppcolumn=column;
|
||||
else
|
||||
freeColumn(column);
|
||||
|
||||
return lcs;
|
||||
}
|
||||
|
34
liblcs/_lcs.ext.2.c
Normal file
34
liblcs/_lcs.ext.2.c
Normal file
@ -0,0 +1,34 @@
|
||||
#include "_lcs.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
|
||||
|
||||
#define VSIZE (8)
|
||||
#define VTYPE vInt16
|
||||
#define STYPE int16_t
|
||||
#define CMENB shrt
|
||||
#define VMODE false
|
||||
#define FASTLCSSCORE fastLCSScore16
|
||||
#define INSERT_REG _MM_INSERT_EPI16
|
||||
#define EXTRACT_REG _MM_EXTRACT_EPI16
|
||||
#define EQUAL_REG _MM_CMPEQ_EPI16
|
||||
#define GREATER_REG _MM_CMPGT_EPI16
|
||||
#define SMALLER_REG _MM_CMPLT_EPI16
|
||||
#define ADD_REG _MM_ADD_EPI16
|
||||
#define SUB_REG _MM_SUB_EPI16
|
||||
#define AND_REG _MM_AND_SI128
|
||||
#define ANDNOT_REG _MM_ANDNOT_SI128
|
||||
#define OR_REG _MM_OR_SI128
|
||||
#define SET_CONST _MM_SET1_EPI16
|
||||
#define GET_MAX _MM_MAX_EPI16
|
||||
#define GET_MIN _MM_MIN_EPI16
|
||||
#define MIN_SCORE INT16_MIN
|
||||
#define MAX_SCORE 32000
|
||||
|
||||
#include "_lcs_fast.h"
|
34
liblcs/_lcs.ext.3.c
Normal file
34
liblcs/_lcs.ext.3.c
Normal file
@ -0,0 +1,34 @@
|
||||
#include "_lcs.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
|
||||
|
||||
#define VSIZE (16)
|
||||
#define VTYPE vInt8
|
||||
#define STYPE int8_t
|
||||
#define CMENB byte
|
||||
#define VMODE true
|
||||
#define FASTLCSSCORE fastLCSScore8
|
||||
#define INSERT_REG _MM_INSERT_EPI8
|
||||
#define EXTRACT_REG _MM_EXTRACT_EPI8
|
||||
#define EQUAL_REG _MM_CMPEQ_EPI8
|
||||
#define GREATER_REG _MM_CMPGT_EPI8
|
||||
#define SMALLER_REG _MM_CMPLT_EPI8
|
||||
#define ADD_REG _MM_ADD_EPI8
|
||||
#define SUB_REG _MM_SUB_EPI8
|
||||
#define AND_REG _MM_AND_SI128
|
||||
#define ANDNOT_REG _MM_ANDNOT_SI128
|
||||
#define OR_REG _MM_OR_SI128
|
||||
#define SET_CONST _MM_SET1_EPI8
|
||||
#define GET_MAX _MM_MAX_EPI8
|
||||
#define GET_MIN _MM_MIN_EPI8
|
||||
#define MIN_SCORE INT8_MIN
|
||||
#define MAX_SCORE 127
|
||||
|
||||
#include "_lcs_fast.h"
|
29
liblcs/_lcs.h
Normal file
29
liblcs/_lcs.h
Normal file
@ -0,0 +1,29 @@
|
||||
#include "../libsse/_sse.h"
|
||||
|
||||
#define bool char
|
||||
#define false (1==0)
|
||||
#define true (1==1)
|
||||
|
||||
typedef struct {
|
||||
int16_t size;
|
||||
|
||||
union { int16_t *shrt;
|
||||
int8_t *byte;
|
||||
} data;
|
||||
|
||||
union { int16_t *shrt;
|
||||
int8_t *byte;
|
||||
} score;
|
||||
|
||||
|
||||
} column_t, **column_pp, *column_p;
|
||||
|
||||
column_p allocateColumn(int length,column_t *column, bool mode8bits);
|
||||
|
||||
void freeColumn(column_p column);
|
||||
|
||||
int fastLCSScore16(const char* seq1, const char* seq2,column_pp ppcolumn,int32_t* lpath);
|
||||
int fastLCSScore8(const char* seq1, const char* seq2,column_pp ppcolumn,int32_t* lpath);
|
||||
int simpleLCS(const char* seq1, const char* seq2,column_pp ppcolumn,int32_t* lpath);
|
||||
|
||||
int fastLCSScore(const char* seq1, const char* seq2,column_pp column,int32_t* lpath);
|
597
liblcs/_lcs_fast.h
Normal file
597
liblcs/_lcs_fast.h
Normal file
@ -0,0 +1,597 @@
|
||||
|
||||
/*
|
||||
* Print a SSE register for debug purpose
|
||||
*/
|
||||
|
||||
#ifdef __SSE2__
|
||||
|
||||
static void printreg(VTYPE r)
|
||||
{
|
||||
STYPE a0,a1,a2,a3,a4,a5,a6,a7;
|
||||
#if VMODE
|
||||
STYPE a8,a9,a10,a11,a12,a13,a14,a15;
|
||||
#endif
|
||||
|
||||
a0= EXTRACT_REG(r,0);
|
||||
a1= EXTRACT_REG(r,1);
|
||||
a2= EXTRACT_REG(r,2);
|
||||
a3= EXTRACT_REG(r,3);
|
||||
a4= EXTRACT_REG(r,4);
|
||||
a5= EXTRACT_REG(r,5);
|
||||
a6= EXTRACT_REG(r,6);
|
||||
a7= EXTRACT_REG(r,7);
|
||||
#if VMODE
|
||||
a8= EXTRACT_REG(r,8);
|
||||
a9= EXTRACT_REG(r,9);
|
||||
a10= EXTRACT_REG(r,10);
|
||||
a11= EXTRACT_REG(r,11);
|
||||
a12= EXTRACT_REG(r,12);
|
||||
a13= EXTRACT_REG(r,13);
|
||||
a14= EXTRACT_REG(r,14);
|
||||
a15= EXTRACT_REG(r,15);
|
||||
#endif
|
||||
|
||||
printf( "a00 :-> %7d %7d %7d %7d "
|
||||
" %7d %7d %7d %7d "
|
||||
#if VMODE
|
||||
"%7d %7d %7d %7d "
|
||||
" %7d %7d %7d %7d "
|
||||
#endif
|
||||
"\n"
|
||||
, a0,a1,a2,a3,a4,a5,a6,a7
|
||||
#if VMODE
|
||||
, a8,a9,a10,a11,a12,a13,a14,a15
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
* set position p of a SSE register with the value v
|
||||
*/
|
||||
|
||||
static inline VTYPE insert_reg(VTYPE r, STYPE v, int p)
|
||||
{
|
||||
switch (p) {
|
||||
case 0: return INSERT_REG(r,v,0);
|
||||
case 1: return INSERT_REG(r,v,1);
|
||||
case 2: return INSERT_REG(r,v,2);
|
||||
case 3: return INSERT_REG(r,v,3);
|
||||
case 4: return INSERT_REG(r,v,4);
|
||||
case 5: return INSERT_REG(r,v,5);
|
||||
case 6: return INSERT_REG(r,v,6);
|
||||
case 7: return INSERT_REG(r,v,7);
|
||||
#if VMODE
|
||||
case 8: return INSERT_REG(r,v,8);
|
||||
case 9: return INSERT_REG(r,v,9);
|
||||
case 10: return INSERT_REG(r,v,10);
|
||||
case 11: return INSERT_REG(r,v,11);
|
||||
case 12: return INSERT_REG(r,v,12);
|
||||
case 13: return INSERT_REG(r,v,13);
|
||||
case 14: return INSERT_REG(r,v,14);
|
||||
case 15: return INSERT_REG(r,v,15);
|
||||
#endif
|
||||
}
|
||||
return _MM_SETZERO_SI128();
|
||||
}
|
||||
|
||||
static inline STYPE extract_reg(VTYPE r, int p)
|
||||
{
|
||||
switch (p) {
|
||||
case 0: return EXTRACT_REG(r,0);
|
||||
case 1: return EXTRACT_REG(r,1);
|
||||
case 2: return EXTRACT_REG(r,2);
|
||||
case 3: return EXTRACT_REG(r,3);
|
||||
case 4: return EXTRACT_REG(r,4);
|
||||
case 5: return EXTRACT_REG(r,5);
|
||||
case 6: return EXTRACT_REG(r,6);
|
||||
case 7: return EXTRACT_REG(r,7);
|
||||
#if VMODE
|
||||
case 8: return EXTRACT_REG(r,8);
|
||||
case 9: return EXTRACT_REG(r,9);
|
||||
case 10: return EXTRACT_REG(r,10);
|
||||
case 11: return EXTRACT_REG(r,11);
|
||||
case 12: return EXTRACT_REG(r,12);
|
||||
case 13: return EXTRACT_REG(r,13);
|
||||
case 14: return EXTRACT_REG(r,14);
|
||||
case 15: return EXTRACT_REG(r,15);
|
||||
#endif
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define GET_H_SYMBOLE(s,p) ((p && p < lseq1) ? (s)[(p)-1]:255)
|
||||
#define GET_V_SYMBOLE(s,p) ((p && p < lseq2) ? (s)[(p)-1]:0)
|
||||
|
||||
#define LSHIFT_SCORE(r) { r = _MM_SLLI_SI128((r),sizeof(STYPE)); }
|
||||
#define SET_H_SYMBOLE(r,p,s) { r = insert_reg((r),(STYPE)GET_H_SYMBOLE(seq1,(s)),(p)); }
|
||||
#define PUSH_V_SYMBOLE(r,s) { r = insert_reg(_MM_SLLI_SI128((r),sizeof(STYPE)),(STYPE)GET_V_SYMBOLE(seq2,(s)),0); }
|
||||
#define EQUAL(f1,f2) _MM_AND_SI128(EQUAL_REG((f1),(f2)),SET_CONST(1))
|
||||
|
||||
int FASTLCSSCORE(const char* seq1, const char* seq2,column_pp ppcolumn,int32_t* lpath)
|
||||
{
|
||||
int lseq1,lseq2; // length of the both sequences
|
||||
|
||||
int itmp; // tmp variables for swap
|
||||
const char* stmp; //
|
||||
|
||||
int nbands; // Number of bands of width eight in the score matrix
|
||||
int lastband; // width of the last band
|
||||
|
||||
// Register for scanning the score matrix
|
||||
VTYPE minus1;
|
||||
VTYPE minus2;
|
||||
VTYPE current;
|
||||
|
||||
VTYPE left;
|
||||
VTYPE top;
|
||||
VTYPE diag;
|
||||
|
||||
|
||||
VTYPE sminus1;
|
||||
VTYPE sminus2;
|
||||
VTYPE scurrent;
|
||||
|
||||
VTYPE sleft;
|
||||
VTYPE stop;
|
||||
VTYPE sdiag;
|
||||
|
||||
VTYPE way;
|
||||
VTYPE onevect;
|
||||
VTYPE maxvect;
|
||||
|
||||
VTYPE fhseq; // The fragment of the horizontal sequence
|
||||
// to consider for aligment
|
||||
VTYPE fvseq; // The fragment of the horizontal sequence
|
||||
// to consider for aligment
|
||||
VTYPE match;
|
||||
|
||||
int band;
|
||||
int line;
|
||||
int limit;
|
||||
|
||||
int lcs;
|
||||
|
||||
int h;
|
||||
int i;
|
||||
|
||||
column_t *column;
|
||||
|
||||
|
||||
// Made seq1 the longest sequences
|
||||
lseq1=strlen(seq1);
|
||||
lseq2=strlen(seq2);
|
||||
|
||||
if (lseq1 < 10 || lseq2 < 10)
|
||||
return simpleLCS(seq1,seq2,ppcolumn,lpath);
|
||||
|
||||
if (lseq1 < lseq2)
|
||||
{
|
||||
itmp=lseq1;
|
||||
lseq1=lseq2;
|
||||
lseq2=itmp;
|
||||
|
||||
stmp=seq1;
|
||||
seq1=seq2;
|
||||
seq2=stmp;
|
||||
}
|
||||
|
||||
// we add one to both lengths for taking into
|
||||
// account the extra line and column in the score
|
||||
// matrix
|
||||
|
||||
lseq1++;
|
||||
lseq2++;
|
||||
|
||||
// a band sized to the smallest sequence is allocated
|
||||
|
||||
if (ppcolumn)
|
||||
column = *ppcolumn;
|
||||
else
|
||||
column=NULL;
|
||||
|
||||
column = allocateColumn(lseq2,column,VMODE);
|
||||
|
||||
// Check memory allocation
|
||||
if (column == NULL)
|
||||
return -1;
|
||||
|
||||
for (i=0; i<lseq2;i++)
|
||||
{
|
||||
column->data.CMENB[i]=MIN_SCORE;
|
||||
column->score.CMENB[i]=-1;
|
||||
}
|
||||
|
||||
nbands = lseq1 / VSIZE; // You have VSIZE element in one SSE register
|
||||
// Alignment will be realized in nbands
|
||||
|
||||
lastband = lseq1 - (nbands * VSIZE); // plus one of width lastband except if
|
||||
// lastband==0
|
||||
|
||||
if (lastband) nbands++;
|
||||
else lastband=VSIZE;
|
||||
|
||||
lastband--;
|
||||
|
||||
// printf("seq1 : %s seq2 : %s\n",seq1,seq2);
|
||||
|
||||
|
||||
minus2 = SET_CONST(MIN_SCORE);
|
||||
minus1 = _MM_SETZERO_SI128();
|
||||
|
||||
sminus1= _MM_SETZERO_SI128();
|
||||
sminus2= _MM_SETZERO_SI128();
|
||||
onevect= SET_CONST(1);
|
||||
maxvect= SET_CONST(MAX_SCORE);
|
||||
|
||||
h=0;
|
||||
|
||||
fhseq = _MM_SETZERO_SI128();
|
||||
fvseq = _MM_SETZERO_SI128();
|
||||
|
||||
//
|
||||
// Beginning of the first band
|
||||
//
|
||||
|
||||
for (line = 0; line < VSIZE; line++,h++) // avant VSIZE - 1
|
||||
{
|
||||
// printf("line= %4d h= %4d\n",line,h);
|
||||
SET_H_SYMBOLE(fhseq,line,h)
|
||||
PUSH_V_SYMBOLE(fvseq,line)
|
||||
minus2 = insert_reg(minus2,0,h);
|
||||
minus1 = insert_reg(minus1,MIN_SCORE,line); // 0 avant
|
||||
match = EQUAL(fhseq,fvseq);
|
||||
|
||||
if (lpath)
|
||||
{
|
||||
sminus2 = insert_reg(sminus2,line-1,line); // Je ne suis pas certain de l'initialisation
|
||||
sminus1 = insert_reg(sminus1,0,line);
|
||||
}
|
||||
|
||||
// printreg(fvseq);
|
||||
// printreg(fhseq);
|
||||
// printreg(match);
|
||||
// printf("================================\n");
|
||||
|
||||
current = minus1; // The best score is the upper one
|
||||
// It cannot be the best as set to MIN_SCORE
|
||||
|
||||
left = minus1;
|
||||
|
||||
// printf("Vert = "); printreg(current);
|
||||
|
||||
|
||||
LSHIFT_SCORE(minus1) // I shift minus1 so now I'll compare with the left position
|
||||
minus1=insert_reg(minus1,(column)->data.CMENB[line],0);
|
||||
|
||||
top=minus1;
|
||||
|
||||
if (lpath)
|
||||
{
|
||||
sleft=sminus1; // I store the path length corresponding to the upper path
|
||||
LSHIFT_SCORE(sminus1) // I shift to prepare the score coming from the left side
|
||||
sminus1=insert_reg(sminus1,(column)->score.CMENB[line],0);
|
||||
stop=sminus1;
|
||||
sdiag=sminus2;
|
||||
|
||||
}
|
||||
|
||||
// printf("Horz = "); printreg(minus1);
|
||||
|
||||
current = GET_MAX(current,minus1); // Look for the best between upper and left
|
||||
|
||||
// printf("BstHV= "); printreg(current);
|
||||
//
|
||||
// printf("Diag = "); printreg(ADD_REG(minus2,match));
|
||||
|
||||
diag=minus2;
|
||||
|
||||
// minus2 = ; // Minus2 contains the diagonal score, so I add the match reward
|
||||
// Diag score are setup to 0 so this one will win on the first iteration
|
||||
current = GET_MAX(current,ADD_REG(minus2,match));
|
||||
|
||||
if (lpath)
|
||||
{
|
||||
// printf("\n");
|
||||
// printf("current: ");
|
||||
// printreg(current);
|
||||
// printf("current: ");
|
||||
// printreg(SUB_REG(current,match));
|
||||
// printf("diag : ");
|
||||
// printreg(diag);
|
||||
// printf("left : ");
|
||||
// printreg(left);
|
||||
// printf("top : ");
|
||||
// printreg(top);
|
||||
|
||||
|
||||
way = EQUAL_REG(SUB_REG(current,match),diag);
|
||||
scurrent= OR_REG(AND_REG(way,sdiag),
|
||||
ANDNOT_REG(way,maxvect));
|
||||
// printf("sdiag : ");
|
||||
// printreg(scurrent);
|
||||
way = EQUAL_REG(current,left);
|
||||
scurrent= GET_MIN(scurrent,OR_REG(AND_REG(way,sleft),
|
||||
ANDNOT_REG(way,maxvect)));
|
||||
|
||||
// printf("sleft : ");
|
||||
// printreg(scurrent);
|
||||
way = EQUAL_REG(current,top);
|
||||
scurrent= GET_MIN(scurrent,OR_REG(AND_REG(way,stop),
|
||||
ANDNOT_REG(way,maxvect)));
|
||||
// printf("stop : ");
|
||||
// printreg(scurrent);
|
||||
|
||||
scurrent= ADD_REG(scurrent,onevect);
|
||||
|
||||
sminus2=sminus1;
|
||||
sminus1=scurrent;
|
||||
}
|
||||
// printf("line %d :Best = ",line); printreg(current);
|
||||
//
|
||||
// printf("================================\n");
|
||||
|
||||
minus2=minus1;
|
||||
minus1=current;
|
||||
|
||||
// printf("min2 = "); printreg(minus2);
|
||||
// printf("min1 = "); printreg(minus1);
|
||||
// printf("================================\n");
|
||||
|
||||
// printf("\n");
|
||||
// printf("sdiag : ");
|
||||
// printreg(sminus2);
|
||||
// printf("scur : ");
|
||||
// printreg(scurrent);
|
||||
// printf("current: ");
|
||||
// printreg(current);
|
||||
// printf("%8s\n",seq1);
|
||||
// printf("%8s\n",seq2);
|
||||
// printf("================================\n");
|
||||
|
||||
|
||||
} ///// <<<<<<<<------- Fin du debut de la premiere bande
|
||||
|
||||
|
||||
// printf("================================\n");
|
||||
|
||||
(column)->data.CMENB[lseq2-VSIZE+line]=EXTRACT_REG(current,VSIZE-1);
|
||||
|
||||
|
||||
if (lpath)
|
||||
(column)->score.CMENB[lseq2-VSIZE+line]=EXTRACT_REG(scurrent,VSIZE-1);
|
||||
|
||||
|
||||
|
||||
for (band=0; band < nbands; band++)
|
||||
{
|
||||
// SET_H_SYMBOLE(fhseq,line,h)
|
||||
// minus2 = insert_reg(minus2,0,line);
|
||||
// minus1 = insert_reg(minus1,MIN_SCORE,line); // 0 avant
|
||||
// h++;
|
||||
|
||||
for (; line < lseq2; line++)
|
||||
{
|
||||
// printf("Je tourne avec line= %d \n",line);
|
||||
PUSH_V_SYMBOLE(fvseq,line)
|
||||
|
||||
match = EQUAL(fhseq,fvseq);
|
||||
|
||||
// printreg(fvseq);
|
||||
// printreg(fhseq);
|
||||
// printreg(match);
|
||||
// printf("================================\n");
|
||||
|
||||
current = minus1;
|
||||
|
||||
left = minus1;
|
||||
|
||||
// Store the last current score in extra column
|
||||
(column)->data.CMENB[line-VSIZE]=EXTRACT_REG(current,VSIZE-1);
|
||||
LSHIFT_SCORE(minus1)
|
||||
minus1=insert_reg(minus1,(column)->data.CMENB[line],0);
|
||||
|
||||
top = minus1;
|
||||
|
||||
// printf("Vert = "); printreg(current);
|
||||
|
||||
if (lpath)
|
||||
{
|
||||
sleft= sminus1;
|
||||
(column)->score.CMENB[line-VSIZE]=EXTRACT_REG(scurrent,VSIZE-1);
|
||||
LSHIFT_SCORE(sminus1)
|
||||
sminus1=insert_reg(sminus1,(column)->score.CMENB[line],0);
|
||||
stop=sminus1;
|
||||
sdiag=sminus2;
|
||||
}
|
||||
|
||||
// printf("line = %d --> get = %d\n",line,(column)->data.CMENB[line]);
|
||||
|
||||
// printf("Horz = "); printreg(minus1);
|
||||
|
||||
current = GET_MAX(current,minus1);
|
||||
|
||||
diag=minus2;
|
||||
|
||||
current = GET_MAX(current,ADD_REG(minus2,match));
|
||||
|
||||
if (lpath)
|
||||
{
|
||||
// printf("\n");
|
||||
// printf("current: ");
|
||||
// printreg(current);
|
||||
// printf("current: ");
|
||||
// printreg(SUB_REG(current,match));
|
||||
// printf("diag : ");
|
||||
// printreg(diag);
|
||||
// printf("left : ");
|
||||
// printreg(left);
|
||||
// printf("top : ");
|
||||
// printreg(top);
|
||||
|
||||
way = EQUAL_REG(SUB_REG(current,match),diag);
|
||||
scurrent= OR_REG(AND_REG(way,sdiag),
|
||||
ANDNOT_REG(way,maxvect));
|
||||
|
||||
// printf("sdiag : ");
|
||||
// printreg(scurrent);
|
||||
|
||||
way = EQUAL_REG(current,left);
|
||||
scurrent= GET_MIN(scurrent,OR_REG(AND_REG(way,sleft),
|
||||
ANDNOT_REG(way,maxvect)));
|
||||
|
||||
// printf("sleft : ");
|
||||
// printreg(scurrent);
|
||||
|
||||
way = EQUAL_REG(current,top);
|
||||
scurrent= GET_MIN(scurrent,OR_REG(AND_REG(way,stop),
|
||||
ANDNOT_REG(way,maxvect)));
|
||||
|
||||
// printf("stop : ");
|
||||
// printreg(scurrent);
|
||||
|
||||
scurrent= ADD_REG(scurrent,onevect);
|
||||
|
||||
sminus2=sminus1;
|
||||
sminus1=scurrent;
|
||||
}
|
||||
|
||||
minus2=minus1;
|
||||
minus1=current;
|
||||
|
||||
// printf("\n");
|
||||
// printf("sdiag : ");
|
||||
// printreg(sminus2);
|
||||
// printf("scur : ");
|
||||
// printreg(scurrent);
|
||||
// printf("current: ");
|
||||
// printreg(current);
|
||||
// printf("%8s\n",seq1);
|
||||
// printf("%8s\n",seq2);
|
||||
}
|
||||
// printf("================================\n");
|
||||
|
||||
// end of the band and beginnig of the next one
|
||||
|
||||
limit=(band==(nbands-1)) ? lastband:VSIZE;
|
||||
|
||||
for (line = 0; line < limit; line++,h++)
|
||||
{
|
||||
// printf("Je fini avec line= %d \n",line);
|
||||
|
||||
SET_H_SYMBOLE(fhseq,line,h)
|
||||
PUSH_V_SYMBOLE(fvseq,line)
|
||||
|
||||
|
||||
minus2 = insert_reg(minus2,MIN_SCORE,line);
|
||||
minus1 = insert_reg(minus1,MIN_SCORE,line);
|
||||
current = minus1;
|
||||
left=minus1;
|
||||
|
||||
match = EQUAL(fhseq,fvseq);
|
||||
|
||||
if (lpath)
|
||||
{
|
||||
sminus2 = insert_reg(sminus2,lseq2-VSIZE+line,line);
|
||||
sminus1 = insert_reg(sminus1,h,line);
|
||||
sleft= sminus1;
|
||||
}
|
||||
|
||||
|
||||
// printf("\n");
|
||||
// printf("fhseq = "); printreg(fhseq);
|
||||
// printf("fvseq = "); printreg(fvseq);
|
||||
// printf("----------------------------------------------------------------\n");
|
||||
// printf("match = "); printreg(match);
|
||||
|
||||
|
||||
(column)->data.CMENB[lseq2-VSIZE+line]=EXTRACT_REG(current,VSIZE-1);
|
||||
LSHIFT_SCORE(minus1)
|
||||
minus1=insert_reg(minus1,(column)->data.CMENB[line],0);
|
||||
top=minus1;
|
||||
|
||||
current = GET_MAX(current,minus1);
|
||||
|
||||
if (lpath)
|
||||
{
|
||||
(column)->score.CMENB[lseq2-VSIZE+line]=EXTRACT_REG(scurrent,VSIZE-1);
|
||||
LSHIFT_SCORE(sminus1)
|
||||
sminus1=insert_reg(sminus1,(column)->score.CMENB[line],0);
|
||||
stop=sminus1;
|
||||
sdiag=sminus2;
|
||||
|
||||
way = EQUAL_REG(current,minus1);
|
||||
|
||||
scurrent= OR_REG(AND_REG(way,sminus1),
|
||||
ANDNOT_REG(way,scurrent));
|
||||
}
|
||||
|
||||
|
||||
diag=minus2;
|
||||
|
||||
current = GET_MAX(current,ADD_REG(minus2,match));
|
||||
|
||||
if (lpath)
|
||||
{
|
||||
way = EQUAL_REG(SUB_REG(current,match),diag);
|
||||
scurrent= OR_REG(AND_REG(way,sdiag),
|
||||
ANDNOT_REG(way,maxvect));
|
||||
|
||||
way = EQUAL_REG(current,left);
|
||||
scurrent= GET_MIN(scurrent,OR_REG(AND_REG(way,sleft),
|
||||
ANDNOT_REG(way,maxvect)));
|
||||
|
||||
way = EQUAL_REG(current,top);
|
||||
scurrent= GET_MIN(scurrent,OR_REG(AND_REG(way,stop),
|
||||
ANDNOT_REG(way,maxvect)));
|
||||
|
||||
scurrent= ADD_REG(scurrent,onevect);
|
||||
|
||||
sminus2=sminus1;
|
||||
sminus1=scurrent;
|
||||
}
|
||||
|
||||
// printf("currt = "); printreg(current);
|
||||
|
||||
minus2=minus1;
|
||||
minus1=current;
|
||||
|
||||
// printf("\n");
|
||||
// printf("sdiag : ");
|
||||
// printreg(sminus2);
|
||||
// printf("scur : ");
|
||||
// printreg(scurrent);
|
||||
// printf("current: ");
|
||||
// printreg(current);
|
||||
// printf("%8s\n",seq1);
|
||||
// printf("%8s\n",seq2);
|
||||
|
||||
// printf("Je stocke line= %d la valeur %d\n",lseq2-VSIZE+line,(column)->data.CMENB[lseq2-VSIZE+line]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// printf("\n");
|
||||
// printf("line = %d, h= %d, lastband = %d\n",line,h,lastband);
|
||||
// printf("currt = "); printreg(current);
|
||||
lcs = extract_reg(current,lastband);
|
||||
|
||||
if(lpath)
|
||||
*lpath= extract_reg(scurrent,lastband);
|
||||
// printf("lastband = %d (%d) lcs = %d\n",lastband,lseq2,lcs);
|
||||
|
||||
if (ppcolumn)
|
||||
*ppcolumn=column;
|
||||
else
|
||||
freeColumn(column);
|
||||
|
||||
return lcs;
|
||||
}
|
||||
|
||||
#else
|
||||
int FASTLCSSCORE(const char* seq1, const char* seq2,column_pp ppcolumn,int32_t* lpath)
|
||||
{
|
||||
return simpleLCS(seq1,seq2,ppcolumn,lpath);
|
||||
}
|
||||
|
||||
#endif /* __SSE2__ */
|
||||
|
211
liblcs/banded_LCS_alignment.c
Normal file
211
liblcs/banded_LCS_alignment.c
Normal file
@ -0,0 +1,211 @@
|
||||
/*
|
||||
* banded_LCS_alignment.c
|
||||
*
|
||||
* Created on: 7 nov. 2012
|
||||
* Author: merciece
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include "../libutils/utilities.h"
|
||||
|
||||
|
||||
typedef struct {
|
||||
int score;
|
||||
int l_path;
|
||||
}infos;
|
||||
|
||||
|
||||
int calculateScore(char nuc1, char nuc2)
|
||||
{
|
||||
return(nuc1 == nuc2);
|
||||
}
|
||||
|
||||
infos** banded_align(char *seq1, char *seq2, int l1, int l2, int bandLengthRight, int bandLengthLeft)
|
||||
{
|
||||
int i, j;
|
||||
//int c;
|
||||
//double id;
|
||||
int start, end;
|
||||
int diag_score, delete, insert, mismatch;
|
||||
int l_path, l_path_i, l_path_d;
|
||||
int bestScore;
|
||||
int mismatch_margin;
|
||||
int stop;
|
||||
int diag_index;
|
||||
infos **matrix;
|
||||
|
||||
l1++;
|
||||
l2++;
|
||||
mismatch_margin = bandLengthLeft; // the biggest one
|
||||
diag_index = l1-l2; // diagonal index
|
||||
stop=0;
|
||||
|
||||
//fprintf(stderr,"\nseq1 = %s, seq2=%s, bandLengthR = %d, bandLengthL = %d", seq1, seq2, bandLengthRight, bandLengthLeft);
|
||||
|
||||
// Matrix initialization~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
matrix = (infos**) malloc(l1 * sizeof(infos*));
|
||||
for (i = 0; i < l1; i++)
|
||||
matrix[i] = (infos*) malloc(l2 * sizeof(infos));
|
||||
|
||||
for (i = 0; i < l1; i++)
|
||||
for (j = 0; j < l2; j++)
|
||||
{
|
||||
matrix[i][j].score = 0;
|
||||
matrix[i][j].l_path = 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < l1; i++)
|
||||
matrix[i][0].l_path = i;
|
||||
|
||||
for (j = 0; j < l2; j++)
|
||||
matrix[0][j].l_path = j;
|
||||
|
||||
// Matrix initialized~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
for (i = 1; i < l1; i++)
|
||||
{
|
||||
start = i - bandLengthLeft;
|
||||
if (start < 1)
|
||||
start = 1;
|
||||
end = i+bandLengthRight+1;
|
||||
if (end > l2)
|
||||
end = l2;
|
||||
|
||||
for (j = start; j < end; j++)
|
||||
{
|
||||
delete = matrix[i-1][j].score;
|
||||
l_path_d = matrix[i-1][j].l_path + 1;
|
||||
insert = matrix[i][j-1].score;
|
||||
l_path_i = matrix[i][j-1].l_path + 1;
|
||||
mismatch = 0;
|
||||
|
||||
diag_score = calculateScore(seq1[i-1], seq2[j-1]);
|
||||
bestScore = matrix[i-1][j-1].score + diag_score;
|
||||
l_path = matrix[i-1][j-1].l_path + 1;
|
||||
if (diag_score == 0) // mismatch
|
||||
mismatch = 1;
|
||||
|
||||
if ((insert > bestScore) || ((insert == bestScore) && (l_path_i < l_path)))
|
||||
{
|
||||
bestScore = matrix[i][j-1].score;
|
||||
l_path = l_path_i;
|
||||
mismatch = 0;
|
||||
}
|
||||
|
||||
if ((delete > bestScore) || ((delete == bestScore) && (l_path_d < l_path)))
|
||||
{
|
||||
bestScore = delete;
|
||||
l_path = l_path_d;
|
||||
mismatch = 0;
|
||||
}
|
||||
|
||||
/*if (((i-j) - diag_index == 0) && (mismatch == 1))
|
||||
{
|
||||
//fprintf(stderr, "\nR = %d, L = %d\n", bandLengthRight, bandLengthLeft);
|
||||
if (bandLengthRight+bandLengthLeft == 0)
|
||||
{
|
||||
stop = 1;
|
||||
//fprintf(stderr, "\nBREAKING LOOPS\n");
|
||||
break;
|
||||
}
|
||||
if (bandLengthRight != 0)
|
||||
bandLengthRight = bandLengthRight - 1;
|
||||
if (bandLengthLeft != 0)
|
||||
bandLengthLeft = bandLengthLeft - 1;
|
||||
}*/
|
||||
|
||||
(matrix[i][j]).score = bestScore;
|
||||
(matrix[i][j]).l_path = l_path;
|
||||
}
|
||||
|
||||
//if ((bandLengthRight + bandLengthLeft == 0) && ((matrix[i][j].l_path - matrix[i][j].score) > mismatch_margin))
|
||||
if (stop==1)
|
||||
break;
|
||||
}
|
||||
return(matrix);
|
||||
}
|
||||
|
||||
|
||||
void calculateBandLength(int l1, int l2, double threshold, int* bandLengthRight, int* bandLengthLeft)
|
||||
{
|
||||
(*bandLengthLeft) = round(-l1 * threshold + l1);
|
||||
(*bandLengthRight) = round(-l1 * threshold + l2);
|
||||
|
||||
// fprintf(stderr,"\nR=%d, L=%d", (*bandLengthRight), (*bandLengthLeft));
|
||||
}
|
||||
|
||||
|
||||
double calculateId(infos** matrix, int len1, int len2)
|
||||
{
|
||||
double id;
|
||||
int l_ali;
|
||||
int l_lcs;
|
||||
|
||||
l_lcs = matrix[len1][len2].score;
|
||||
l_ali = matrix[len1][len2].l_path;
|
||||
|
||||
if (l_lcs == 0)
|
||||
id = 0.0;
|
||||
else
|
||||
id = (double) l_lcs / (double) l_ali;
|
||||
|
||||
//fprintf(stderr, "\n%d, %d\n", l_lcs, l_ali);
|
||||
return(id);
|
||||
}
|
||||
|
||||
|
||||
double banded_lcs_align(int16_t* seq1, int16_t* seq2, int l1, int l2, double threshold, BOOL n, int ref, BOOL lcsmode, int16_t* address)
|
||||
{
|
||||
double id;
|
||||
int bandLengthRight, bandLengthLeft;
|
||||
int i,j;
|
||||
|
||||
char* s1;
|
||||
char* s2;
|
||||
|
||||
s1 = (char*) malloc(l1*sizeof(char)+1);
|
||||
s2 = (char*) malloc(l2*sizeof(char)+1);
|
||||
|
||||
for (i=l1-1, j=0; i>=0, j<l1; i--, j++)
|
||||
*(s1+i) = (char) *(seq1+j);
|
||||
|
||||
for (i=0; i<l2; i++)
|
||||
*(s2+i) = (char) *(seq2+i);
|
||||
|
||||
*(s1+l1) = 0;
|
||||
*(s2+l2) = 0;
|
||||
|
||||
//fprintf(stderr, "\nl1=%d, %s\nl2=%d, %s\n", l1, s1, l2, s2);
|
||||
|
||||
infos** matrix;
|
||||
|
||||
calculateBandLength(l1, l2, threshold, &bandLengthRight, &bandLengthLeft);
|
||||
|
||||
matrix = banded_align(s1, s2, l1, l2, bandLengthRight, bandLengthLeft);
|
||||
|
||||
/*fprintf(stderr, "\n");
|
||||
for (i = 0; i <= l1; i++)
|
||||
{
|
||||
fprintf(stderr, "\n");
|
||||
for (j = 0; j <= l2; j++)
|
||||
fprintf(stderr, "%d/%d\t", matrix[i][j].score, matrix[i][j].l_path); //matrix[i][j].stop);
|
||||
}
|
||||
fprintf(stderr, "\n");*/
|
||||
|
||||
id = calculateId(matrix, l1, l2);
|
||||
|
||||
for (i = 0; i <= l1; i++)
|
||||
free(matrix[i]);
|
||||
|
||||
free(matrix);
|
||||
|
||||
free(s1);
|
||||
free(s2);
|
||||
|
||||
//fprintf(stderr, "\nscore = %lf\n", id);
|
||||
|
||||
return(id);
|
||||
}
|
9
liblcs/banded_LCS_alignment.h
Normal file
9
liblcs/banded_LCS_alignment.h
Normal file
@ -0,0 +1,9 @@
|
||||
/*
|
||||
* banded_LCS_alignment.h
|
||||
*
|
||||
* Created on: november 8, 2012
|
||||
* Author: mercier
|
||||
*/
|
||||
|
||||
|
||||
double banded_lcs_align(int16_t* seq1, int16_t* seq2, int l1, int l2, double threshold, BOOL n, int ref, BOOL lcsmode, int16_t* address);
|
724
liblcs/sse_banded_LCS_alignment.c
Normal file
724
liblcs/sse_banded_LCS_alignment.c
Normal file
@ -0,0 +1,724 @@
|
||||
/*
|
||||
* sse_banded_LCS_alignment.c
|
||||
*
|
||||
* Created on: 7 nov. 2012
|
||||
* Author: celine mercier
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <stdint.h>
|
||||
#include "../libutils/utilities.h"
|
||||
#include "../libsse/_sse.h"
|
||||
|
||||
|
||||
|
||||
/*static void printreg(__m128i r)
|
||||
{
|
||||
int16_t a0,a1,a2,a3,a4,a5,a6,a7;
|
||||
|
||||
a0= _MM_EXTRACT_EPI16(r,0);
|
||||
a1= _MM_EXTRACT_EPI16(r,1);
|
||||
a2= _MM_EXTRACT_EPI16(r,2);
|
||||
a3= _MM_EXTRACT_EPI16(r,3);
|
||||
a4= _MM_EXTRACT_EPI16(r,4);
|
||||
a5= _MM_EXTRACT_EPI16(r,5);
|
||||
a6= _MM_EXTRACT_EPI16(r,6);
|
||||
a7= _MM_EXTRACT_EPI16(r,7);
|
||||
|
||||
fprintf(stderr, "a00 :-> %7d %7d %7d %7d "
|
||||
" %7d %7d %7d %7d "
|
||||
"\n"
|
||||
, a0,a1,a2,a3,a4,a5,a6,a7
|
||||
);
|
||||
}
|
||||
*/
|
||||
|
||||
static inline int extract_reg(__m128i r, int p)
|
||||
{
|
||||
switch (p) {
|
||||
case 0: return(_MM_EXTRACT_EPI16(r,0));
|
||||
case 1: return(_MM_EXTRACT_EPI16(r,1));
|
||||
case 2: return(_MM_EXTRACT_EPI16(r,2));
|
||||
case 3: return(_MM_EXTRACT_EPI16(r,3));
|
||||
case 4: return(_MM_EXTRACT_EPI16(r,4));
|
||||
case 5: return(_MM_EXTRACT_EPI16(r,5));
|
||||
case 6: return(_MM_EXTRACT_EPI16(r,6));
|
||||
case 7: return(_MM_EXTRACT_EPI16(r,7));
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
void sse_banded_align_lcs_and_ali_len(int16_t* seq1, int16_t* seq2, int l1, int l2, int bandLengthLeft, int bandLengthTotal, int16_t* address, double* lcs_length, int* ali_length)
|
||||
{
|
||||
register int j;
|
||||
int k1, k2;
|
||||
int max, diff;
|
||||
int l_reg, l_loc;
|
||||
int line;
|
||||
int numberOfRegistersPerLine;
|
||||
int numberOfRegistersFor3Lines;
|
||||
|
||||
BOOL even_line;
|
||||
BOOL odd_line;
|
||||
BOOL even_BLL;
|
||||
BOOL odd_BLL;
|
||||
|
||||
um128* SSEregisters;
|
||||
um128* p_diag;
|
||||
um128* p_gap1;
|
||||
um128* p_gap2;
|
||||
um128* p_diag_j;
|
||||
um128* p_gap1_j;
|
||||
um128* p_gap2_j;
|
||||
um128 current;
|
||||
|
||||
um128* l_ali_SSEregisters;
|
||||
um128* p_l_ali_diag;
|
||||
um128* p_l_ali_gap1;
|
||||
um128* p_l_ali_gap2;
|
||||
um128* p_l_ali_diag_j;
|
||||
um128* p_l_ali_gap1_j;
|
||||
um128* p_l_ali_gap2_j;
|
||||
um128 l_ali_current;
|
||||
|
||||
um128 nucs1;
|
||||
um128 nucs2;
|
||||
um128 scores;
|
||||
|
||||
um128 boolean_reg;
|
||||
|
||||
// Initialisations
|
||||
|
||||
odd_BLL = bandLengthLeft & 1;
|
||||
even_BLL = !odd_BLL;
|
||||
|
||||
max = INT16_MAX - l1;
|
||||
|
||||
numberOfRegistersPerLine = bandLengthTotal / 8;
|
||||
numberOfRegistersFor3Lines = 3 * numberOfRegistersPerLine;
|
||||
|
||||
SSEregisters = (um128*) calloc(numberOfRegistersFor3Lines * 2, sizeof(um128));
|
||||
l_ali_SSEregisters = SSEregisters + numberOfRegistersFor3Lines;
|
||||
|
||||
// preparer registres SSE
|
||||
|
||||
for (j=0; j<numberOfRegistersFor3Lines; j++)
|
||||
l_ali_SSEregisters[j].i = _MM_LOAD_SI128(address+j*8);
|
||||
|
||||
p_diag = SSEregisters;
|
||||
p_gap1 = SSEregisters+numberOfRegistersPerLine;
|
||||
p_gap2 = SSEregisters+2*numberOfRegistersPerLine;
|
||||
|
||||
p_l_ali_diag = l_ali_SSEregisters;
|
||||
p_l_ali_gap1 = l_ali_SSEregisters+numberOfRegistersPerLine;
|
||||
p_l_ali_gap2 = l_ali_SSEregisters+2*numberOfRegistersPerLine;
|
||||
|
||||
// Loop on diagonals = 'lines' :
|
||||
for (line=2; line <= l1+l2; line++)
|
||||
{
|
||||
odd_line = line & 1;
|
||||
even_line = !odd_line;
|
||||
|
||||
// loop on the registers of a line :
|
||||
for (j=0; j < numberOfRegistersPerLine; j++)
|
||||
{
|
||||
p_diag_j = p_diag+j;
|
||||
p_gap1_j = p_gap1+j;
|
||||
p_gap2_j = p_gap2+j;
|
||||
p_l_ali_diag_j = p_l_ali_diag+j;
|
||||
p_l_ali_gap1_j = p_l_ali_gap1+j;
|
||||
p_l_ali_gap2_j = p_l_ali_gap2+j;
|
||||
|
||||
// comparing nucleotides for diagonal scores :
|
||||
|
||||
// k1 = position of the 1st nucleotide to align for seq1 and k2 = position of the 1st nucleotide to align for seq2
|
||||
if (odd_line && odd_BLL)
|
||||
k1 = (line / 2) + ((bandLengthLeft+1) / 2) - j*8;
|
||||
else
|
||||
k1 = (line / 2) + (bandLengthLeft/2) - j*8;
|
||||
|
||||
k2 = line - k1 - 1;
|
||||
|
||||
nucs1.i = _MM_LOADU_SI128(seq1+l1-k1);
|
||||
nucs2.i = _MM_LOADU_SI128(seq2+k2);
|
||||
|
||||
/* fprintf(stderr, "\nnucs, r %d, k1 = %d, k2 = %d\n", j, k1, k2);
|
||||
printreg(nucs1.i);
|
||||
printreg(nucs2.i);
|
||||
*/
|
||||
|
||||
// computing diagonal score :
|
||||
scores.i = _MM_AND_SI128(_MM_CMPEQ_EPI16(nucs1.i, nucs2.i), _MM_SET1_EPI16(1));
|
||||
current.i = _MM_ADDS_EPU16(p_diag_j->i, scores.i);
|
||||
|
||||
// Computing alignment length
|
||||
|
||||
l_ali_current.i = p_l_ali_diag_j->i;
|
||||
boolean_reg.i = _MM_CMPGT_EPI16(p_gap1_j->i, current.i);
|
||||
l_ali_current.i = _MM_OR_SI128(
|
||||
_MM_AND_SI128(p_l_ali_gap1_j->i, boolean_reg.i),
|
||||
_MM_ANDNOT_SI128(boolean_reg.i, l_ali_current.i));
|
||||
current.i = _MM_OR_SI128(
|
||||
_MM_AND_SI128(p_gap1_j->i, boolean_reg.i),
|
||||
_MM_ANDNOT_SI128(boolean_reg.i, current.i));
|
||||
boolean_reg.i = _MM_AND_SI128(
|
||||
_MM_CMPEQ_EPI16(p_gap1_j->i, current.i),
|
||||
_MM_CMPLT_EPI16(p_l_ali_gap1_j->i, l_ali_current.i));
|
||||
l_ali_current.i = _MM_OR_SI128(
|
||||
_MM_AND_SI128(p_l_ali_gap1_j->i, boolean_reg.i),
|
||||
_MM_ANDNOT_SI128(boolean_reg.i, l_ali_current.i));
|
||||
current.i = _MM_OR_SI128(
|
||||
_MM_AND_SI128(p_gap1_j->i, boolean_reg.i),
|
||||
_MM_ANDNOT_SI128(boolean_reg.i, current.i));
|
||||
boolean_reg.i = _MM_CMPGT_EPI16(p_gap2_j->i, current.i);
|
||||
l_ali_current.i = _MM_OR_SI128(
|
||||
_MM_AND_SI128(p_l_ali_gap2_j->i, boolean_reg.i),
|
||||
_MM_ANDNOT_SI128(boolean_reg.i, l_ali_current.i));
|
||||
current.i = _MM_OR_SI128(
|
||||
_MM_AND_SI128(p_gap2_j->i, boolean_reg.i),
|
||||
_MM_ANDNOT_SI128(boolean_reg.i, current.i));
|
||||
boolean_reg.i = _MM_AND_SI128(
|
||||
_MM_CMPEQ_EPI16(p_gap2_j->i, current.i),
|
||||
_MM_CMPLT_EPI16(p_l_ali_gap2_j->i, l_ali_current.i));
|
||||
l_ali_current.i = _MM_OR_SI128(
|
||||
_MM_AND_SI128(p_l_ali_gap2_j->i, boolean_reg.i),
|
||||
_MM_ANDNOT_SI128(boolean_reg.i, l_ali_current.i));
|
||||
current.i = _MM_OR_SI128(
|
||||
_MM_AND_SI128(p_gap2_j->i, boolean_reg.i),
|
||||
_MM_ANDNOT_SI128(boolean_reg.i, current.i));
|
||||
|
||||
|
||||
/* fprintf(stderr, "\nline = %d", line);
|
||||
fprintf(stderr, "\nDiag, r %d : ", j);
|
||||
printreg((*(p_diag_j)).i);
|
||||
fprintf(stderr, "Gap1 : ");
|
||||
printreg((*(p_gap1_j)).i);
|
||||
fprintf(stderr, "Gap2 : ");
|
||||
printreg((*(p_gap2_j)).i);
|
||||
fprintf(stderr, "current : ");
|
||||
printreg(current.i);
|
||||
fprintf(stderr, "L ALI\nDiag r %d : ", j);
|
||||
printreg((*(p_l_ali_diag_j)).i);
|
||||
fprintf(stderr, "Gap1 : ");
|
||||
printreg((*(p_l_ali_gap1_j)).i);
|
||||
fprintf(stderr, "Gap2 : ");
|
||||
printreg((*(p_l_ali_gap2_j)).i);
|
||||
fprintf(stderr, "current : ");
|
||||
printreg(l_ali_current.i);
|
||||
*/
|
||||
|
||||
// diag = gap1 and gap1 = current
|
||||
p_diag_j->i = p_gap1_j->i;
|
||||
p_gap1_j->i = current.i;
|
||||
|
||||
// l_ali_diag = l_ali_gap1 and l_ali_gap1 = l_ali_current+1
|
||||
p_l_ali_diag_j->i = p_l_ali_gap1_j->i;
|
||||
p_l_ali_gap1_j->i = _MM_ADD_EPI16(l_ali_current.i, _MM_SET1_EPI16(1));
|
||||
}
|
||||
|
||||
// shifts for gap2, to do only once all the registers of a line have been computed Copier gap2 puis le charger depuis la copie?
|
||||
|
||||
for (j=0; j < numberOfRegistersPerLine; j++)
|
||||
{
|
||||
if ((odd_line && even_BLL) || (even_line && odd_BLL))
|
||||
{
|
||||
p_gap2[j].i = _MM_LOADU_SI128((p_gap1[j].s16)-1);
|
||||
p_l_ali_gap2[j].i = _MM_LOADU_SI128((p_l_ali_gap1[j].s16)-1);
|
||||
if (j == 0)
|
||||
{
|
||||
p_gap2[j].i = _MM_INSERT_EPI16(p_gap2[j].i, 0, 0);
|
||||
p_l_ali_gap2[j].i = _MM_INSERT_EPI16(p_l_ali_gap2[j].i, max, 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
p_gap2[j].i = _MM_LOADU_SI128(p_gap1[j].s16+1);
|
||||
p_l_ali_gap2[j].i = _MM_LOADU_SI128(p_l_ali_gap1[j].s16+1);
|
||||
if (j == numberOfRegistersPerLine - 1)
|
||||
{
|
||||
p_gap2[j].i = _MM_INSERT_EPI16(p_gap2[j].i, 0, 7);
|
||||
p_l_ali_gap2[j].i = _MM_INSERT_EPI16(p_l_ali_gap2[j].i, max, 7);
|
||||
}
|
||||
}
|
||||
}
|
||||
// end shifts for gap2
|
||||
|
||||
}
|
||||
|
||||
/* /// Recovering LCS and alignment lengths \\\ */
|
||||
|
||||
// finding the location of the results in the registers :
|
||||
diff = l1-l2;
|
||||
if ((diff & 1) && odd_BLL)
|
||||
l_loc = (int) floor((double)(bandLengthLeft) / (double)2) - floor((double)(diff) / (double)2);
|
||||
else
|
||||
l_loc = (int) floor((double)(bandLengthLeft) / (double)2) - ceil((double)(diff) / (double)2);
|
||||
|
||||
l_reg = (int)floor((double)l_loc/(double)8.0);
|
||||
//fprintf(stderr, "\nl_reg = %d, l_loc = %d\n", l_reg, l_loc);
|
||||
l_loc = l_loc - l_reg*8;
|
||||
|
||||
// extracting the results from the registers :
|
||||
*lcs_length = extract_reg(p_gap1[l_reg].i, l_loc);
|
||||
*ali_length = extract_reg(p_l_ali_gap1[l_reg].i, l_loc) - 1;
|
||||
|
||||
// freeing the registers
|
||||
free(SSEregisters);
|
||||
}
|
||||
|
||||
|
||||
double sse_banded_align_just_lcs(int16_t* seq1, int16_t* seq2, int l1, int l2, int bandLengthLeft, int bandLengthTotal)
|
||||
{
|
||||
register int j;
|
||||
int k1, k2;
|
||||
int diff;
|
||||
int l_reg, l_loc;
|
||||
int16_t l_lcs;
|
||||
int line;
|
||||
int numberOfRegistersPerLine;
|
||||
int numberOfRegistersFor3Lines;
|
||||
|
||||
BOOL even_line;
|
||||
BOOL odd_line;
|
||||
BOOL even_BLL;
|
||||
BOOL odd_BLL;
|
||||
|
||||
um128* SSEregisters;
|
||||
um128* p_diag;
|
||||
um128* p_gap1;
|
||||
um128* p_gap2;
|
||||
um128* p_diag_j;
|
||||
um128* p_gap1_j;
|
||||
um128* p_gap2_j;
|
||||
um128 current;
|
||||
|
||||
um128 nucs1;
|
||||
um128 nucs2;
|
||||
um128 scores;
|
||||
|
||||
// Initialisations
|
||||
|
||||
odd_BLL = bandLengthLeft & 1;
|
||||
even_BLL = !odd_BLL;
|
||||
|
||||
numberOfRegistersPerLine = bandLengthTotal / 8;
|
||||
numberOfRegistersFor3Lines = 3 * numberOfRegistersPerLine;
|
||||
|
||||
SSEregisters = malloc(numberOfRegistersFor3Lines * sizeof(um128));
|
||||
|
||||
// preparer registres SSE
|
||||
|
||||
for (j=0; j<numberOfRegistersFor3Lines; j++)
|
||||
(*(SSEregisters+j)).i = _MM_SETZERO_SI128();
|
||||
|
||||
p_diag = SSEregisters;
|
||||
p_gap1 = SSEregisters+numberOfRegistersPerLine;
|
||||
p_gap2 = SSEregisters+2*numberOfRegistersPerLine;
|
||||
|
||||
// Loop on diagonals = 'lines' :
|
||||
for (line=2; line <= l1+l2; line++)
|
||||
{
|
||||
odd_line = line & 1;
|
||||
even_line = !odd_line;
|
||||
|
||||
// loop on the registers of a line :
|
||||
for (j=0; j < numberOfRegistersPerLine; j++)
|
||||
{
|
||||
p_diag_j = p_diag+j;
|
||||
p_gap1_j = p_gap1+j;
|
||||
p_gap2_j = p_gap2+j;
|
||||
|
||||
// comparing nucleotides for diagonal scores :
|
||||
|
||||
// k1 = position of the 1st nucleotide to align for seq1 and k2 = position of the 1st nucleotide to align for seq2
|
||||
if (odd_line && odd_BLL)
|
||||
k1 = (line / 2) + ((bandLengthLeft+1) / 2) - j*8;
|
||||
else
|
||||
k1 = (line / 2) + (bandLengthLeft/2) - j*8;
|
||||
|
||||
k2 = line - k1 - 1;
|
||||
|
||||
nucs1.i = _MM_LOADU_SI128(seq1+l1-k1);
|
||||
nucs2.i = _MM_LOADU_SI128(seq2+k2);
|
||||
|
||||
// computing diagonal score :
|
||||
scores.i = _MM_AND_SI128(_MM_CMPEQ_EPI16(nucs1.i, nucs2.i), _MM_SET1_EPI16(1));
|
||||
current.i = _MM_ADDS_EPU16((*(p_diag_j)).i, scores.i);
|
||||
|
||||
// current = max(gap1, current)
|
||||
current.i = _MM_MAX_EPI16((*(p_gap1_j)).i, current.i);
|
||||
|
||||
// current = max(gap2, current)
|
||||
current.i = _MM_MAX_EPI16((*(p_gap2_j)).i, current.i);
|
||||
|
||||
// diag = gap1 and gap1 = current
|
||||
(*(p_diag_j)).i = (*(p_gap1_j)).i;
|
||||
(*(p_gap1_j)).i = current.i;
|
||||
}
|
||||
|
||||
// shifts for gap2, to do only once all the registers of a line have been computed
|
||||
|
||||
for (j=0; j < numberOfRegistersPerLine; j++)
|
||||
{
|
||||
if ((odd_line && even_BLL) || (even_line && odd_BLL))
|
||||
{
|
||||
(*(p_gap2+j)).i = _MM_LOADU_SI128(((*(p_gap1+j)).s16)-1);
|
||||
if (j == 0)
|
||||
{
|
||||
(*(p_gap2+j)).i = _MM_INSERT_EPI16((*(p_gap2+j)).i, 0, 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
(*(p_gap2+j)).i = _MM_LOADU_SI128(((*(p_gap1+j)).s16)+1);
|
||||
if (j == numberOfRegistersPerLine - 1)
|
||||
{
|
||||
(*(p_gap2+j)).i = _MM_INSERT_EPI16((*(p_gap2+j)).i, 0, 7);
|
||||
}
|
||||
}
|
||||
}
|
||||
// end shifts for gap2
|
||||
|
||||
}
|
||||
|
||||
/* /// Recovering LCS and alignment lengths \\\ */
|
||||
|
||||
// finding the location of the results in the registers :
|
||||
diff = l1-l2;
|
||||
if ((diff & 1) && odd_BLL)
|
||||
l_loc = (int) floor((double)(bandLengthLeft) / (double)2) - floor((double)(diff) / (double)2);
|
||||
else
|
||||
l_loc = (int) floor((double)(bandLengthLeft) / (double)2) - ceil((double)(diff) / (double)2);
|
||||
|
||||
l_reg = (int)floor((double)l_loc/(double)8.0);
|
||||
//fprintf(stderr, "\nl_reg = %d, l_loc = %d\n", l_reg, l_loc);
|
||||
l_loc = l_loc - l_reg*8;
|
||||
|
||||
// extracting LCS from the registers :
|
||||
l_lcs = extract_reg((*(p_gap1+l_reg)).i, l_loc);
|
||||
|
||||
// freeing the registers
|
||||
free(SSEregisters);
|
||||
|
||||
return((double) l_lcs);
|
||||
}
|
||||
|
||||
|
||||
inline void calculateBandLengths(int l1, int l2, int* bandLengthRight, int* bandLengthLeft, int LCSmin)
|
||||
{
|
||||
(*bandLengthLeft) = l1 - LCSmin;
|
||||
(*bandLengthRight) = l2 - LCSmin;
|
||||
}
|
||||
|
||||
|
||||
int calculateLCSmin(int l1, int l2, double threshold, BOOL normalize, int reference, BOOL lcsmode)
|
||||
{
|
||||
int LCSmin;
|
||||
|
||||
if (threshold > 0)
|
||||
{
|
||||
if (normalize)
|
||||
{
|
||||
if (reference == MINLEN)
|
||||
LCSmin = threshold*l2;
|
||||
else // ref = maxlen or alilen
|
||||
LCSmin = threshold*l1;
|
||||
}
|
||||
else if (lcsmode)
|
||||
LCSmin = threshold;
|
||||
else if ((reference == MINLEN)) // not lcsmode
|
||||
LCSmin = l2 - threshold;
|
||||
else // not lcsmode and ref = maxlen or alilen
|
||||
LCSmin = l1 - threshold;
|
||||
}
|
||||
else
|
||||
LCSmin = 0;
|
||||
|
||||
return(LCSmin);
|
||||
}
|
||||
|
||||
|
||||
int calculateSSEBandLength(int bandLengthRight, int bandLengthLeft)
|
||||
{
|
||||
// *bandLengthTotal= (double) floor(bandLengthRight + bandLengthLeft) / 2.0 + 1;
|
||||
int bandLengthTotal= (double)(bandLengthRight + bandLengthLeft) / 2.0 + 1.0;
|
||||
|
||||
return (bandLengthTotal & (~ (int)7)) + (( bandLengthTotal & (int)7) ? 8:0); // Calcule le multiple de 8 superieur
|
||||
}
|
||||
|
||||
|
||||
int calculateSizeToAllocate(int maxLen, int minLen, int LCSmin)
|
||||
{
|
||||
int size;
|
||||
int notUsed;
|
||||
|
||||
calculateBandLengths(maxLen, minLen, ¬Used, &size, LCSmin); // max size = max left band length * 2
|
||||
|
||||
//fprintf(stderr, "\nsize for address before %8 = %d", size);
|
||||
|
||||
size*= 2;
|
||||
size = (size & (~ (int)7)) + (( size & (int)7) ? 8:0); // Calcule le multiple de 8 superieur
|
||||
size*= 3;
|
||||
size+= 16;
|
||||
|
||||
//fprintf(stderr, "\nsize for address = %d", size);
|
||||
|
||||
return(size*sizeof(int16_t));
|
||||
}
|
||||
|
||||
|
||||
void iniSeq(int16_t* seq, int size, int16_t iniValue)
|
||||
{
|
||||
int16_t *target=seq;
|
||||
int16_t *end = target + (size_t)size;
|
||||
|
||||
for (; target < end; target++)
|
||||
*target = iniValue;
|
||||
}
|
||||
|
||||
|
||||
void putSeqInSeq(int16_t* seq, char* s, int l, BOOL reverse)
|
||||
{
|
||||
int16_t *target=seq;
|
||||
int16_t *end = target + (size_t)l;
|
||||
char *source=s;
|
||||
|
||||
if (reverse)
|
||||
for (source=s + (size_t)l-1; target < end; target++, source--)
|
||||
*target=*source;
|
||||
else
|
||||
for (; target < end; source++,target++)
|
||||
*target=*source;
|
||||
}
|
||||
|
||||
|
||||
void initializeAddressWithGaps(int16_t* address, int bandLengthTotal, int bandLengthLeft, int l1)
|
||||
{
|
||||
int i;
|
||||
int address_00, x_address_10, address_01, address_01_shifted;
|
||||
int numberOfRegistersPerLine;
|
||||
int bm;
|
||||
int value=INT16_MAX-l1;
|
||||
|
||||
numberOfRegistersPerLine = bandLengthTotal / 8;
|
||||
bm = bandLengthLeft%2;
|
||||
|
||||
for (i=0; i < (3*numberOfRegistersPerLine*8); i++)
|
||||
address[i] = value;
|
||||
|
||||
// 0,0 set to 1 and 0,1 and 1,0 set to 2
|
||||
|
||||
address_00 = bandLengthLeft / 2;
|
||||
|
||||
x_address_10 = address_00 + bm - 1;
|
||||
address_01 = numberOfRegistersPerLine*8 + x_address_10;
|
||||
|
||||
address_01_shifted = numberOfRegistersPerLine*16 + address_00 - bm;
|
||||
|
||||
// fill address_00, address_01,+1, address_01_shifted,+1
|
||||
|
||||
address[address_00] = 1;
|
||||
address[address_01] = 2;
|
||||
address[address_01+1] = 2;
|
||||
address[address_01_shifted] = 2;
|
||||
address[address_01_shifted+1] = 2;
|
||||
}
|
||||
|
||||
|
||||
double sse_banded_lcs_align(int16_t* seq1, int16_t* seq2, int l1, int l2, BOOL normalize, int reference, BOOL lcsmode, int16_t* address, int LCSmin)
|
||||
{
|
||||
double id;
|
||||
int bandLengthRight, bandLengthLeft, bandLengthTotal;
|
||||
int ali_length;
|
||||
|
||||
//fprintf(stderr, "\nl1 = %d, l2 = %d\n", l1, l2);
|
||||
|
||||
calculateBandLengths(l1, l2, &bandLengthRight, &bandLengthLeft, LCSmin);
|
||||
|
||||
//fprintf(stderr, "\nBLL = %d, BLR = %d, LCSmin = %d\n", bandLengthLeft, bandLengthRight, LCSmin);
|
||||
|
||||
bandLengthTotal = calculateSSEBandLength(bandLengthRight, bandLengthLeft);
|
||||
|
||||
//fprintf(stderr, "\nBLT = %d\n", bandLengthTotal);
|
||||
|
||||
if ((reference == ALILEN) && (normalize || !lcsmode))
|
||||
{
|
||||
initializeAddressWithGaps(address, bandLengthTotal, bandLengthLeft, l1);
|
||||
sse_banded_align_lcs_and_ali_len(seq1, seq2, l1, l2, bandLengthLeft, bandLengthTotal, address, &id, &ali_length);
|
||||
}
|
||||
else
|
||||
id = sse_banded_align_just_lcs(seq1, seq2, l1, l2, bandLengthLeft, bandLengthTotal);
|
||||
|
||||
//fprintf(stderr, "\nid before normalizations = %f", id);
|
||||
|
||||
//fprintf(stderr, "\nlcs = %f, ali = %d\n", id, ali_length);
|
||||
|
||||
if (!lcsmode && !normalize)
|
||||
switch(reference) {
|
||||
case ALILEN: id = ali_length - id;
|
||||
break;
|
||||
case MAXLEN: id = l1 - id;
|
||||
break;
|
||||
case MINLEN: id = l2 - id;
|
||||
}
|
||||
|
||||
//fprintf(stderr, "\n2>>> %f, %d\n", id, ali_length);
|
||||
if (normalize)
|
||||
switch(reference) {
|
||||
case ALILEN: id = id / (double) ali_length;
|
||||
break;
|
||||
case MAXLEN: id = id / (double) l1;
|
||||
break;
|
||||
case MINLEN: id = id / (double) l2;
|
||||
}
|
||||
|
||||
//fprintf(stderr, "\nid = %f\n", id);
|
||||
return(id);
|
||||
}
|
||||
|
||||
|
||||
double generic_sse_banded_lcs_align(char* seq1, char* seq2, double threshold, BOOL normalize, int reference, BOOL lcsmode, int16_t** address, int* buffer_size, int16_t** iseq1,
|
||||
int16_t** iseq2, int* buffer_sizeS)
|
||||
{
|
||||
double id;
|
||||
int l1;
|
||||
int l2;
|
||||
int lmax, lmin;
|
||||
int sizeToAllocateForBand;
|
||||
int maxBLL, notUsed;
|
||||
int sizeToAllocateForSeqs;
|
||||
int LCSmin;
|
||||
|
||||
l1 = strlen(seq1);
|
||||
l2 = strlen(seq2);
|
||||
|
||||
if (l2 > l1)
|
||||
{
|
||||
lmax = l1;
|
||||
lmin = l2;
|
||||
}
|
||||
else
|
||||
{
|
||||
lmax = l2;
|
||||
lmin = l1;
|
||||
}
|
||||
|
||||
if (!lcsmode && (normalize==TRUE))
|
||||
{
|
||||
threshold = 1.0 - threshold;
|
||||
}
|
||||
|
||||
LCSmin = calculateLCSmin(lmax, lmin, threshold, normalize, reference, lcsmode);
|
||||
|
||||
// Allocating space for matrix band if the alignment must be computed
|
||||
|
||||
if ((reference == ALILEN) && ((lcsmode && normalize) || (!lcsmode))) // checking if alignment must be computed
|
||||
{
|
||||
sizeToAllocateForBand = calculateSizeToAllocate(lmax, lmin, LCSmin);
|
||||
|
||||
if (sizeToAllocateForBand > (*buffer_size))
|
||||
{
|
||||
// reallocating if needed
|
||||
address = reallocA16Address(*address, sizeToAllocateForBand);
|
||||
}
|
||||
}
|
||||
|
||||
// Allocating space for the int16_t arrays representing the sequences
|
||||
|
||||
calculateBandLengths(lmax, lmin, ¬Used, &maxBLL, LCSmin);
|
||||
|
||||
sizeToAllocateForSeqs = 2*maxBLL+lmax;
|
||||
|
||||
if (sizeToAllocateForSeqs > *buffer_sizeS)
|
||||
{
|
||||
(*(iseq1)) = realloc((*(iseq1)), sizeToAllocateForSeqs*sizeof(int16_t));
|
||||
(*(iseq2)) = realloc((*(iseq2)), sizeToAllocateForSeqs*sizeof(int16_t));
|
||||
}
|
||||
|
||||
iniSeq(*(iseq1), maxBLL, 0);
|
||||
iniSeq(*(iseq2), maxBLL, 255);
|
||||
*(iseq1) = *(iseq1)+maxBLL;
|
||||
*(iseq2) = *(iseq2)+maxBLL;
|
||||
|
||||
// longest seq must be first argument of sse_align function
|
||||
if (l2 > l1)
|
||||
{
|
||||
putSeqInSeq((*(iseq1)), seq2, l2, TRUE);
|
||||
putSeqInSeq((*(iseq2)), seq1, l1, FALSE);
|
||||
id = sse_banded_lcs_align(*(iseq1), *(iseq2), l2, l1, normalize, reference, lcsmode, *address, LCSmin);
|
||||
}
|
||||
else
|
||||
{
|
||||
putSeqInSeq((*(iseq1)), seq1, l1, TRUE);
|
||||
putSeqInSeq((*(iseq2)), seq2, l2, FALSE);
|
||||
id = sse_banded_lcs_align(*(iseq1), *(iseq2), l1, l2, normalize, reference, lcsmode, *address, LCSmin);
|
||||
}
|
||||
|
||||
return(id);
|
||||
}
|
||||
|
||||
|
||||
int prepareTablesForSumathings(int lmax, int lmin, double threshold, BOOL normalize, int reference, BOOL lcsmode,
|
||||
int16_t** address, int16_t** iseq1, int16_t** iseq2)
|
||||
{
|
||||
int sizeToAllocateForBand;
|
||||
int maxBLL;
|
||||
int notUsed;
|
||||
int sizeToAllocateForSeqs;
|
||||
int LCSmin;
|
||||
|
||||
LCSmin = calculateLCSmin(lmax, lmin, threshold, normalize, reference, lcsmode);
|
||||
|
||||
// Allocating space for matrix band if the alignment must be computed
|
||||
|
||||
if ((reference == ALILEN) && (normalize || !lcsmode)) // checking if alignment must be computed
|
||||
{
|
||||
sizeToAllocateForBand = calculateSizeToAllocate(lmax, lmin, LCSmin);
|
||||
(*(address)) = getA16Address(sizeToAllocateForBand);
|
||||
}
|
||||
|
||||
// Allocating space for the int16_t arrays representing the sequences
|
||||
|
||||
calculateBandLengths(lmax, lmin, ¬Used, &maxBLL, LCSmin);
|
||||
|
||||
sizeToAllocateForSeqs = 2*maxBLL+lmax;
|
||||
(*(iseq1)) = malloc(sizeToAllocateForSeqs*sizeof(int16_t));
|
||||
(*(iseq2)) = malloc(sizeToAllocateForSeqs*sizeof(int16_t));
|
||||
|
||||
iniSeq(*(iseq1), maxBLL, 0);
|
||||
iniSeq(*(iseq2), maxBLL, 255);
|
||||
*(iseq1) = *(iseq1)+maxBLL;
|
||||
*(iseq2) = *(iseq2)+maxBLL;
|
||||
|
||||
return(maxBLL+lmax);
|
||||
}
|
||||
|
||||
|
||||
double alignForSumathings(char* seq1, int16_t* iseq1, char* seq2, int16_t* iseq2, int l1, int l2,
|
||||
BOOL normalize, int reference, BOOL lcsmode, int16_t* address, int sizeForSeqs, int LCSmin)
|
||||
{
|
||||
double id;
|
||||
|
||||
iniSeq(iseq1, sizeForSeqs, 0);
|
||||
iniSeq(iseq2, sizeForSeqs, 255);
|
||||
|
||||
if (l2 > l1)
|
||||
{
|
||||
putSeqInSeq(iseq1, seq2, l2, TRUE);
|
||||
putSeqInSeq(iseq2, seq1, l1, FALSE);
|
||||
id = sse_banded_lcs_align(iseq1, iseq2, l2, l1, normalize, reference, lcsmode, address, LCSmin);
|
||||
}
|
||||
else
|
||||
{
|
||||
putSeqInSeq(iseq1, seq1, l1, TRUE);
|
||||
putSeqInSeq(iseq2, seq2, l2, FALSE);
|
||||
id = sse_banded_lcs_align(iseq1, iseq2, l1, l2, normalize, reference, lcsmode, address, LCSmin);
|
||||
}
|
||||
|
||||
return(id);
|
||||
}
|
||||
|
24
liblcs/sse_banded_LCS_alignment.h
Normal file
24
liblcs/sse_banded_LCS_alignment.h
Normal file
@ -0,0 +1,24 @@
|
||||
/*
|
||||
* sse_banded_LCS_alignment.h
|
||||
*
|
||||
* Created on: november 29, 2012
|
||||
* Author: mercier
|
||||
*/
|
||||
|
||||
#ifndef SSE_BANDED_LCS_ALIGNMENT_H_
|
||||
#define SSE_BANDED_LCS_ALIGNMENT_H_
|
||||
#include <stdint.h>
|
||||
|
||||
double sse_banded_lcs_align(int16_t* seq1, int16_t* seq2, int l1, int l2, BOOL normalize, int reference, BOOL lcsmode, int16_t* address, int LCSmin);
|
||||
int calculateSizeToAllocate(int maxLen, int minLen, int LCSmin);
|
||||
void calculateThresholdFromErrorNumber(int error, int length, double* threshold);
|
||||
void iniSeq(int16_t* seq, int size, int16_t iniValue);
|
||||
void putSeqInSeq(int16_t* seq, char* s, int l, BOOL reverse);
|
||||
double generic_sse_banded_lcs_align(char* seq1, char* seq2, double threshold, BOOL normalize, int reference, BOOL lcsmode, int16_t** address, int* buffer_size, int16_t** iseq1,
|
||||
int16_t** iseq2, int* buffer_sizeS);
|
||||
int prepareTablesForSumathings(int lmax, int lmin, double threshold, BOOL normalize, int reference, BOOL lcsmode,
|
||||
int16_t** address, int16_t** iseq1, int16_t** iseq2);
|
||||
double alignForSumathings(char* seq1, int16_t* iseq1, char* seq2, int16_t* iseq2, int l1, int l2, BOOL normalize,
|
||||
int reference, BOOL lcsmode, int16_t* address, int sizeForSeqs, int LCSmin);
|
||||
int calculateLCSmin(int l1, int l2, double threshold, BOOL normalize, int reference, BOOL lcsmode);
|
||||
#endif
|
382
liblcs/upperband.c
Normal file
382
liblcs/upperband.c
Normal file
@ -0,0 +1,382 @@
|
||||
#include "../libsse/_sse.h"
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include "../libutils/utilities.h"
|
||||
#include "../libfasta/sequence.h"
|
||||
#include "sse_banded_LCS_alignment.h"
|
||||
|
||||
|
||||
inline static uchar_v hash4m128(uchar_v frag)
|
||||
{
|
||||
uchar_v words;
|
||||
|
||||
vUInt8 mask_03= _MM_SET1_EPI8(0x03); // charge le registre avec 16x le meme octet
|
||||
vUInt8 mask_FC= _MM_SET1_EPI8(0xFC);
|
||||
|
||||
frag.m = _MM_SRLI_EPI64(frag.m,1); // shift logic a droite sur 2 x 64 bits
|
||||
frag.m = _MM_AND_SI128(frag.m,mask_03); // and sur les 128 bits
|
||||
|
||||
|
||||
words.m= _MM_SLLI_EPI64(frag.m,2);
|
||||
words.m= _MM_AND_SI128(words.m,mask_FC);
|
||||
frag.m = _MM_SRLI_SI128(frag.m,1);
|
||||
words.m= _MM_OR_SI128(words.m,frag.m);
|
||||
|
||||
words.m= _MM_SLLI_EPI64(words.m,2);
|
||||
words.m= _MM_AND_SI128(words.m,mask_FC);
|
||||
frag.m = _MM_SRLI_SI128(frag.m,1);
|
||||
words.m= _MM_OR_SI128(words.m,frag.m);
|
||||
|
||||
words.m= _MM_SLLI_EPI64(words.m,2);
|
||||
words.m= _MM_AND_SI128(words.m,mask_FC);
|
||||
frag.m = _MM_SRLI_SI128(frag.m,1);
|
||||
words.m= _MM_OR_SI128(words.m,frag.m);
|
||||
|
||||
return words;
|
||||
}
|
||||
|
||||
#ifdef __SSE2__
|
||||
|
||||
inline static int anyzerom128(vUInt8 data)
|
||||
{
|
||||
vUInt8 mask_00= _MM_SETZERO_SI128();
|
||||
uint64_v tmp;
|
||||
tmp.m = _MM_CMPEQ_EPI8(data,mask_00);
|
||||
return (int)(tmp.c[0]!=0 || tmp.c[1]!=0);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
inline static int anyzerom128(vUInt8 data)
|
||||
{
|
||||
int i;
|
||||
um128 tmp;
|
||||
tmp.i = data;
|
||||
for (i=0;i<8;i++)
|
||||
if (tmp.s8[i]==0)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
inline static void dumpm128(unsigned short *table,vUInt8 data)
|
||||
{
|
||||
memcpy(table,&data,16);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute 4mer occurrence table from a DNA sequence
|
||||
*
|
||||
* sequence : a pointer to the null terminated nuc sequence
|
||||
* table : a pointer to a 256 cells unisgned char table for
|
||||
* storing the occurrence table
|
||||
* count : pointer to an int value used as a return value
|
||||
* containing the global word counted
|
||||
*
|
||||
* returns the number of words observed in the sequence with a
|
||||
* count greater than 255.
|
||||
*/
|
||||
|
||||
int buildTable(const char* sequence, unsigned char *table, int *count)
|
||||
{
|
||||
int overflow = 0;
|
||||
int wc=0;
|
||||
int i;
|
||||
vUInt8 mask_00= _MM_SETZERO_SI128();
|
||||
|
||||
uchar_v frag;
|
||||
uchar_v words;
|
||||
uchar_v zero;
|
||||
|
||||
char* s;
|
||||
|
||||
s=(char*)sequence;
|
||||
|
||||
memset(table,0,256*sizeof(unsigned char));
|
||||
|
||||
// encode ascii sequence with A : 00 C : 01 T: 10 G : 11
|
||||
|
||||
for(frag.m=_MM_LOADU_SI128((vUInt8*)s);
|
||||
! anyzerom128(frag.m);
|
||||
s+=12,frag.m=_MM_LOADU_SI128((vUInt8*)s))
|
||||
{
|
||||
words= hash4m128(frag);
|
||||
|
||||
// printf("%d %d %d %d\n",words.c[0],words.c[1],words.c[2],words.c[3]);
|
||||
|
||||
if (table[words.c[0]]<255) table[words.c[0]]++; else overflow++;
|
||||
if (table[words.c[1]]<255) table[words.c[1]]++; else overflow++;
|
||||
if (table[words.c[2]]<255) table[words.c[2]]++; else overflow++;
|
||||
if (table[words.c[3]]<255) table[words.c[3]]++; else overflow++;
|
||||
if (table[words.c[4]]<255) table[words.c[4]]++; else overflow++;
|
||||
if (table[words.c[5]]<255) table[words.c[5]]++; else overflow++;
|
||||
if (table[words.c[6]]<255) table[words.c[6]]++; else overflow++;
|
||||
if (table[words.c[7]]<255) table[words.c[7]]++; else overflow++;
|
||||
if (table[words.c[8]]<255) table[words.c[8]]++; else overflow++;
|
||||
if (table[words.c[9]]<255) table[words.c[9]]++; else overflow++;
|
||||
if (table[words.c[10]]<255) table[words.c[10]]++; else overflow++;
|
||||
if (table[words.c[11]]<255) table[words.c[11]]++; else overflow++;
|
||||
|
||||
wc+=12;
|
||||
}
|
||||
|
||||
zero.m=_MM_CMPEQ_EPI8(frag.m,mask_00);
|
||||
//printf("frag=%d %d %d %d\n",frag.c[0],frag.c[1],frag.c[2],frag.c[3]);
|
||||
//printf("zero=%d %d %d %d\n",zero.c[0],zero.c[1],zero.c[2],zero.c[3]);
|
||||
words = hash4m128(frag);
|
||||
|
||||
if (zero.c[0]+zero.c[1]+zero.c[2]+zero.c[3]==0)
|
||||
for(i=0;zero.c[i+3]==0;i++,wc++)
|
||||
if (table[words.c[i]]<255) table[words.c[i]]++; else overflow++;
|
||||
|
||||
if (count) *count=wc;
|
||||
return overflow;
|
||||
}
|
||||
|
||||
static inline vUInt16 partialminsum(vUInt8 ft1,vUInt8 ft2)
|
||||
{
|
||||
vUInt8 mini;
|
||||
vUInt16 minilo;
|
||||
vUInt16 minihi;
|
||||
vUInt8 mask_00= _MM_SETZERO_SI128();
|
||||
|
||||
mini = _MM_MIN_EPU8(ft1,ft2);
|
||||
minilo = _MM_UNPACKLO_EPI8(mini,mask_00);
|
||||
minihi = _MM_UNPACKHI_EPI8(mini,mask_00);
|
||||
|
||||
return _MM_ADDS_EPU16(minilo,minihi);
|
||||
}
|
||||
|
||||
int compareTable(unsigned char *t1, int over1, unsigned char* t2, int over2)
|
||||
{
|
||||
vUInt8 ft1;
|
||||
vUInt8 ft2;
|
||||
vUInt8 *table1=(vUInt8*)t1;
|
||||
vUInt8 *table2=(vUInt8*)t2;
|
||||
ushort_v summini;
|
||||
int i;
|
||||
int total;
|
||||
|
||||
ft1 = _MM_LOADU_SI128(table1);
|
||||
ft2 = _MM_LOADU_SI128(table2);
|
||||
summini.m = partialminsum(ft1,ft2);
|
||||
table1++;
|
||||
table2++;
|
||||
|
||||
|
||||
for (i=1;i<16;i++,table1++,table2++)
|
||||
{
|
||||
ft1 = _MM_LOADU_SI128(table1);
|
||||
ft2 = _MM_LOADU_SI128(table2);
|
||||
summini.m = _MM_ADDS_EPU16(summini.m,partialminsum(ft1,ft2));
|
||||
|
||||
}
|
||||
|
||||
// Finishing the sum process
|
||||
|
||||
summini.m = _MM_ADDS_EPU16(summini.m,_MM_SRLI_SI128(summini.m,8)); // sum the 4 firsts with the 4 lasts
|
||||
summini.m = _MM_ADDS_EPU16(summini.m,_MM_SRLI_SI128(summini.m,4));
|
||||
|
||||
total = summini.c[0]+summini.c[1];
|
||||
total+= (over1 < over2) ? over1:over2;
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
int threshold4(int wordcount,double identity)
|
||||
{
|
||||
int error;
|
||||
int lmax;
|
||||
|
||||
wordcount+=3;
|
||||
error = (int)floor((double)wordcount * ((double)1.0-identity));
|
||||
lmax = (wordcount - error) / (error + 1);
|
||||
if (lmax < 4)
|
||||
return 0;
|
||||
return (lmax - 3) \
|
||||
* (error + 1) \
|
||||
+ ((wordcount - error) % (error + 1));
|
||||
}
|
||||
|
||||
|
||||
int thresholdLCS4(int32_t reflen,int32_t lcs)
|
||||
{
|
||||
int nbfrag;
|
||||
int smin;
|
||||
int R;
|
||||
int common;
|
||||
|
||||
nbfrag = (reflen - lcs)*2 + 1;
|
||||
smin = lcs/nbfrag;
|
||||
R = lcs - smin * nbfrag;
|
||||
common = MAX(smin - 2,0) * R + MAX(smin - 3,0) * (nbfrag - R);
|
||||
return common;
|
||||
}
|
||||
|
||||
|
||||
int hashDB(fastaSeqCount db)
|
||||
{
|
||||
int32_t i;
|
||||
int32_t count;
|
||||
|
||||
fprintf(stderr,"Indexing dataset...");
|
||||
|
||||
for (i=0; i < db.count;i++)
|
||||
{
|
||||
db.fastaSeqs[i].table = util_malloc((256)*sizeof(unsigned char), __FILE__, __LINE__);
|
||||
db.fastaSeqs[i].over = buildTable((const char*)(db.fastaSeqs[i].sequence),
|
||||
db.fastaSeqs[i].table,
|
||||
&count);
|
||||
}
|
||||
|
||||
fprintf(stderr," : Done\n");
|
||||
|
||||
return db.count;
|
||||
}
|
||||
|
||||
|
||||
BOOL isPossible(fastaSeqPtr seq1, fastaSeqPtr seq2, double threshold, BOOL normalize, int reference, BOOL lcsmode)
|
||||
{
|
||||
int32_t reflen;
|
||||
int32_t maxlen;
|
||||
int32_t lcs;
|
||||
int32_t mincount;
|
||||
|
||||
if (seq1->length < 12 || seq2->length < 12)
|
||||
return TRUE;
|
||||
|
||||
maxlen = MAX(seq1->length,seq2->length);
|
||||
|
||||
if (reference==ALILEN || reference==MAXLEN)
|
||||
reflen = maxlen;
|
||||
else
|
||||
reflen = MIN(seq1->length,seq2->length);
|
||||
|
||||
if (normalize)
|
||||
{
|
||||
if (! lcsmode)
|
||||
threshold = 1. - threshold;
|
||||
|
||||
lcs = (int32_t)ceil((double)reflen * threshold);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (! lcsmode)
|
||||
threshold = reflen - threshold;
|
||||
lcs = (int32_t) threshold;
|
||||
}
|
||||
|
||||
if (lcs > MIN(seq1->length,seq2->length))
|
||||
return FALSE;
|
||||
|
||||
mincount = thresholdLCS4(maxlen,lcs);
|
||||
|
||||
return compareTable(seq1->table,seq1->over,seq2->table,seq2->over) >=mincount;
|
||||
}
|
||||
|
||||
|
||||
BOOL isPossibleSumathings(fastaSeqPtr seq1, fastaSeqPtr seq2, int l1, int l2, double threshold, BOOL normalize, int reference, BOOL lcsmode)
|
||||
{ // optimized version of the filter for sumaclust and sumatra
|
||||
|
||||
int32_t reflen;
|
||||
int32_t lcs;
|
||||
int32_t mincount;
|
||||
|
||||
if (l1 < 12 || l2 < 12)
|
||||
return TRUE;
|
||||
|
||||
if (reference==ALILEN || reference==MAXLEN)
|
||||
reflen = l1;
|
||||
else
|
||||
reflen = l2;
|
||||
|
||||
if (normalize)
|
||||
lcs = (int32_t)ceil((double)reflen * threshold);
|
||||
else
|
||||
{
|
||||
if (! lcsmode)
|
||||
threshold = reflen - threshold;
|
||||
lcs = (int32_t) threshold;
|
||||
}
|
||||
|
||||
mincount = thresholdLCS4(l1,lcs);
|
||||
|
||||
return compareTable(seq1->table,seq1->over,seq2->table,seq2->over) >=mincount;
|
||||
}
|
||||
|
||||
|
||||
void filters(fastaSeqPtr seq1, fastaSeqPtr seq2, double threshold, BOOL normalize, int reference, BOOL lcsmode, double* score, int* LCSmin)
|
||||
{ // score takes value -1 if filters are passed. score must be initialized in calling function.
|
||||
int l1;
|
||||
int l2;
|
||||
|
||||
l1 = seq1->length;
|
||||
l2 = seq2->length;
|
||||
|
||||
if (l1 >= l2)
|
||||
{
|
||||
*LCSmin = calculateLCSmin(l1, l2, threshold, normalize, reference, lcsmode);
|
||||
if (l2 >= *LCSmin)
|
||||
{
|
||||
if (isPossibleSumathings(seq1, seq2, l1, l2, threshold, normalize, reference, lcsmode)) // 4-mers filter
|
||||
*score = -1.0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*LCSmin = calculateLCSmin(l2, l1, threshold, normalize, reference, lcsmode);
|
||||
if (l1 >= *LCSmin)
|
||||
{
|
||||
if (isPossibleSumathings(seq2, seq1, l2, l1, threshold, normalize, reference, lcsmode)) // 4-mers filter
|
||||
*score = -1.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void filtersSumatra(fastaSeqPtr seq1, fastaSeqPtr seq2, double threshold, BOOL normalize, int reference, BOOL lcsmode, double* score, int* LCSmin)
|
||||
{ // score takes value -2 if filters are not passed, -1 if filters are passed and >= 0 with max score if the 2 sequences are identical.
|
||||
|
||||
int l1;
|
||||
int l2;
|
||||
l1 = seq1->length;
|
||||
|
||||
*score = -2.0;
|
||||
|
||||
if (strcmp(seq1->sequence, seq2->sequence) == 0) // the 2 sequences are identical
|
||||
{
|
||||
if (lcsmode && normalize)
|
||||
*score = 1.0;
|
||||
else if (!lcsmode)
|
||||
*score = 0.0;
|
||||
else
|
||||
*score = l1;
|
||||
}
|
||||
|
||||
else if (threshold != 0)
|
||||
{
|
||||
l2 = seq2->length;
|
||||
|
||||
if (l1 >= l2)
|
||||
{
|
||||
*LCSmin = calculateLCSmin(l1, l2, threshold, normalize, reference, lcsmode);
|
||||
if (l2 >= *LCSmin)
|
||||
{
|
||||
if (isPossibleSumathings(seq1, seq2, l1, l2, threshold, normalize, reference, lcsmode)) // 4-mers filter
|
||||
*score = -1.0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*LCSmin = calculateLCSmin(l2, l1, threshold, normalize, reference, lcsmode);
|
||||
if (l1 >= *LCSmin)
|
||||
{
|
||||
if (isPossibleSumathings(seq2, seq1, l2, l1, threshold, normalize, reference, lcsmode)) // 4-mers filter
|
||||
*score = -1.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
*LCSmin = 0;
|
||||
}
|
18
liblcs/upperband.h
Normal file
18
liblcs/upperband.h
Normal file
@ -0,0 +1,18 @@
|
||||
|
||||
#ifndef UPPERBAND_H_
|
||||
#define UPPERBAND_H_
|
||||
|
||||
|
||||
int buildTable(const char *sequence, unsigned char *table, int *count);
|
||||
int compareTable(unsigned char *t1, int over1, unsigned char* t2, int over2);
|
||||
int threshold4(int wordcount,double identity);
|
||||
int thresholdLCS4(int32_t reflen,int32_t lcs);
|
||||
|
||||
|
||||
int hashDB(fastaSeqCount);
|
||||
BOOL isPossible(fastaSeqPtr, fastaSeqPtr, BOOL, int, double, BOOL);
|
||||
BOOL isPossibleSumathings(fastaSeqPtr seq1, fastaSeqPtr seq2, int l1, int l2, double threshold, BOOL normalize, int reference, BOOL lcsmode);
|
||||
void filters(fastaSeqPtr seq1, fastaSeqPtr seq2, double threshold, BOOL normalize, int reference, BOOL lcsmode, double* score, int* LCSmin);
|
||||
void filtersSumatra(fastaSeqPtr seq1, fastaSeqPtr seq2, double threshold, BOOL normalize, int reference, BOOL lcsmode, double* score, int* LCSmin);
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user