Mercurial > repos > calkan > mrfast
changeset 0:7b3dc85dc7fd
Uploaded mrfast source tarball
author | calkan |
---|---|
date | Tue, 21 Feb 2012 10:29:47 -0500 |
parents | |
children | d4054b05b015 |
files | mrfast-2.1.0.4/CommandLineParser.c mrfast-2.1.0.4/CommandLineParser.h mrfast-2.1.0.4/Common.c mrfast-2.1.0.4/Common.h mrfast-2.1.0.4/HashTable.c mrfast-2.1.0.4/HashTable.h mrfast-2.1.0.4/Makefile mrfast-2.1.0.4/MrFAST.c mrfast-2.1.0.4/MrFAST.h mrfast-2.1.0.4/Output.c mrfast-2.1.0.4/Output.h mrfast-2.1.0.4/Reads.c mrfast-2.1.0.4/Reads.h mrfast-2.1.0.4/RefGenome.c mrfast-2.1.0.4/RefGenome.h mrfast-2.1.0.4/baseFAST.c mrfast-2.1.0.4/header |
diffstat | 17 files changed, 11429 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mrfast-2.1.0.4/CommandLineParser.c Tue Feb 21 10:29:47 2012 -0500 @@ -0,0 +1,388 @@ +/* + * Copyright (c) <2008 - 2012>, University of Washington, Simon Fraser University + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * - Neither the names of the University of Washington, Simon Fraser University, + * nor the names of its contributors may be + * used to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + Authors: + Farhad Hormozdiari + Faraz Hach + Can Alkan + Emails: + farhadh AT uw DOT edu + fhach AT cs DOT sfu DOT ca + calkan AT uw DOT edu +*/ + + +#include <stdio.h> +#include <stdlib.h> +#include <getopt.h> +#include <string.h> +#include <ctype.h> +#include "Common.h" +#include "CommandLineParser.h" + +int uniqueMode=1; +int indexingMode; +int searchingMode; +int pairedEndMode; +int pairedEndDiscordantMode; +int transChromosal=0; +int pairedEndProfilingMode; +int seqCompressed; +int outCompressed; +int cropSize = 0; +int progressRep = 0; +int minPairEndedDistance=-1; +int maxPairEndedDistance=-1; +int minPairEndedDiscordantDistance=-1; +int maxPairEndedDiscordantDistance=-1; +int bestMode; +int nosamMode; +char *seqFile1; +char *seqFile2; +char *mappingOutput = "output"; +char *mappingOutputPath = ""; +char *unmappedOutput = "unmapped"; +char fileName[1000][2][FILE_NAME_LENGTH]; +int fileCnt; +int maxOEAOutput=1000; +int maxDiscordantOutput=10000; +unsigned char errThreshold=2; +unsigned char maxHits=0; +unsigned char WINDOW_SIZE = 12; +unsigned int CONTIG_SIZE; +unsigned int CONTIG_MAX_SIZE; + +void printHelp(); + +int parseCommandLine (int argc, char *argv[]) +{ + + int o; + int index; + char *fastaFile = NULL; + char *batchFile = NULL ; + int batchMode = 0; + + static struct option longOptions[] = + { + {"pe", no_argument, &pairedEndMode, 1}, + {"discordant-vh", no_argument, &pairedEndDiscordantMode, 1}, + {"trans", no_argument, &transChromosal , 1}, + {"profile", no_argument, &pairedEndProfilingMode, 1}, + {"seqcomp", no_argument, &seqCompressed, 1}, + {"outcomp", no_argument, &outCompressed, 1}, + {"progress", no_argument, &progressRep, 1}, + {"best", no_argument, &bestMode, 1}, + {"index", required_argument, 0, 'i'}, + {"search", required_argument, 0, 's'}, + {"help", no_argument, 0, 'h'}, + {"version", no_argument, 0, 'v'}, + {"seq", required_argument, 0, 'x'}, + {"seq1", required_argument, 0, 'x'}, + {"seq2", required_argument, 0, 'y'}, + {"ws", required_argument, 0, 'w'}, + {"min", required_argument, 0, 'l'}, + {"max", required_argument, 0, 'm'}, + {"crop", required_argument, 0, 'c'}, + {"maxoea", required_argument, 0, 'a'}, + {"maxdis", required_argument, 0, 'd'}, + {"nosam", no_argument, &nosamMode, 1}, + {0, 0, 0, 0}, + }; + + while ( (o = getopt_long ( argc, argv, "bhvn:e:o:u:i:s:x:y:w:l:m:c:a:d:", longOptions, &index)) != -1 ) + { + switch (o) + { + case 'a': + maxOEAOutput = atoi(optarg); + break; + case 'd': + maxDiscordantOutput = atoi(optarg); + break; + case 'i': + indexingMode = 1; + fastaFile = optarg; + break; + case 's': + searchingMode = 1; + fastaFile = optarg; + break; + case 'b': + batchMode = 1; + break; + case 'c': + cropSize = atoi(optarg); + break; + case 'w': + WINDOW_SIZE = atoi(optarg); + break; + case 'x': + seqFile1 = optarg; + break; + case 'y': + seqFile2 = optarg; + break; + case 'u': + unmappedOutput = optarg; + break; + case 'o': + mappingOutput = getMem(FILE_NAME_LENGTH); + mappingOutputPath = getMem(FILE_NAME_LENGTH); + stripPath (optarg, &mappingOutputPath, &mappingOutput); + break; + case 'n': + maxHits = atoi(optarg); + break; + case 'e': + errThreshold = atoi(optarg); + break; + case 'l': + minPairEndedDistance = atoi(optarg); + break; + case 'm': + maxPairEndedDistance = atoi(optarg); + break; + case 'h': + printHelp(); + return 0; + break; + case 'v': + fprintf(stdout, "%s.%s\n", versionNumber, versionNumberF); + return 0; + break; + /* case '?': + fprintf(stderr, "Unknown parameter: %s\n", longOptions[index].name); + abort(); + break;*/ + } + + } + if (indexingMode + searchingMode != 1) + { + fprintf(stdout, "ERROR: Indexing / Searching mode should be selected\n"); + return 0; + } + + if (WINDOW_SIZE > 15 || WINDOW_SIZE < 11) + { + fprintf(stdout, "ERROR: Window size should be in [12..15]\n"); + return 0; + } + + + if ( indexingMode ) + { + CONTIG_SIZE = 15000000; + CONTIG_MAX_SIZE = 40000000; + + if (batchMode) + { + batchFile = fastaFile; + fastaFile = NULL; + } + + if (batchFile == NULL && fastaFile == NULL) + { + fprintf(stdout, "ERROR: Reference(s) should be indicated for indexing\n"); + return 0; + } + + if (pairedEndDiscordantMode) + { + fprintf(stdout, "ERROR: --discordant cannot be used in indexing mode. \n"); + return 0; + } + + } + + + if ( searchingMode ) + { + CONTIG_SIZE = 300000000; + CONTIG_MAX_SIZE = 300000000; + + + if (batchMode) + { + batchFile = fastaFile; + fastaFile = NULL; + } + + if (batchFile == NULL && fastaFile == NULL) + { + fprintf(stdout, "ERROR: Index File(s) should be indiciated for searching\n"); + return 0; + } + + if (seqFile1 == NULL && seqFile2 == NULL) + { + fprintf(stdout, "ERROR: Please indicate a sequence file for searching.\n"); + return 0; + } + + + if (!pairedEndMode && seqFile2 != NULL) + { + fprintf(stdout, "ERROR: Second File can be indicated in pairedend mode\n"); + return 0; + } + + if (pairedEndMode && (minPairEndedDistance <0 || maxPairEndedDistance < 0 || minPairEndedDistance > maxPairEndedDistance)) + { + fprintf(stdout, "ERROR: Please enter a valid range for pairedend sequences.\n"); + return 0; + } + + if (pairedEndMode && seqFile1 == NULL) + { + fprintf(stdout, "ERROR: Please indicate the first file for pairedend search.\n"); + return 0; + } + + if (!pairedEndMode && pairedEndDiscordantMode) + { + fprintf(stdout, "ERROR: --discordant should be used with --pe"); + return 0; + } + + if (!pairedEndMode && pairedEndProfilingMode) + { + fprintf(stdout, "ERROR: --profile should be used with --pe"); + return 0; + } + } + + int i = 0; + + + if (batchMode) + { + FILE *fp = fileOpen(batchFile, "r"); + + if (fp == NULL) + return 0; + + fileCnt = 0; + + while ( fgets(fileName[fileCnt][0], FILE_NAME_LENGTH, fp)) + { + for (i = strlen(fileName[fileCnt][0])-1; i>=0; i--) + if ( !isspace(fileName[fileCnt][0][i])) + break; + fileName[fileCnt][0][i+1] = '\0'; + + if (strcmp(fileName[fileCnt][0], "") != 0) + { + sprintf(fileName[fileCnt][1], "%s.index", fileName[fileCnt][0]); + fileCnt++; + } + } + } + else + { + sprintf(fileName[fileCnt][0], "%s", fastaFile); + sprintf(fileName[fileCnt][1], "%s.index", fileName[fileCnt][0]); + fileCnt++; + } + + + if (pairedEndProfilingMode) + { + + minPairEndedDistance = 0; + maxPairEndedDistance = 300000000; + + } + + if (pairedEndDiscordantMode) + { + minPairEndedDiscordantDistance = minPairEndedDistance; + maxPairEndedDiscordantDistance = maxPairEndedDistance; + + minPairEndedDistance = 0; + maxPairEndedDistance = 300000000; + } + + return 1; +} + + +void printHelp() +{ + char *errorType; + if (mrFAST) + { + fprintf(stdout,"mrFAST : Micro-Read Fast Alignment Search Tool.\n\n"); + fprintf(stdout,"Usage: mrfast [options]\n\n"); + errorType="edit distance"; + } + else + { + fprintf(stdout,"mrsFAST : Micro-Read Substitutions (only) Fast Alignment Search Tool.\n\n"); + fprintf(stdout,"mrsFAST is a cache oblivious read mapping tool. mrsFAST capable of mapping\n"); + fprintf(stdout,"single and paired end reads to the reference genome. Bisulfite treated \n"); + fprintf(stdout,"sequences are not supported in this version. By default mrsFAST reports \n"); + fprintf(stdout,"the output in SAM format.\n\n"); + fprintf(stdout,"Usage: mrsFAST [options]\n\n"); + errorType="hamming distance"; + } + + fprintf(stdout,"General Options:\n"); + fprintf(stdout," -v|--version\t\tCurrent Version.\n"); + fprintf(stdout," -h\t\t\tShows the help file.\n"); + fprintf(stdout,"\n\n"); + + fprintf(stdout,"Indexing Options:\n"); + fprintf(stdout," --index [file]\t\tGenerate an index from the specified fasta file. \n"); + fprintf(stdout," -b\t\t\tIndicates the indexing will be done in batch mode.\n\t\t\tThe file specified in --index should contain the \n\t\t\tlist of fasta files.\n"); + fprintf(stdout," --ws [int]\t\tSet window size for indexing (default:12 max:14).\n"); + fprintf(stdout,"\n\n"); + + fprintf(stdout,"Searching Options:\n"); + fprintf(stdout," --search [file]\tSearch in the specified genome. Provide the path to the fasta file. \n\t\t\tIndex file should be in the same directory.\n"); + fprintf(stdout," -b\t\t\tIndicates the mapping will be done in batch mode. \n\t\t\tThe file specified in --search should contain the \n\t\t\tlist of fasta files.\n"); + fprintf(stdout," --pe \t\t\tSearch will be done in Paired-End mode.\n"); + fprintf(stdout," --seq [file]\t\tInput sequences in fasta/fastq format [file]. If \n\t\t\tpaired end reads are interleaved, use this option.\n"); + fprintf(stdout," --seq1 [file]\t\tInput sequences in fasta/fastq format [file] (First \n\t\t\tfile). Use this option to indicate the first file of \n\t\t\tpaired end reads. \n"); + fprintf(stdout," --seq2 [file]\t\tInput sequences in fasta/fastq format [file] (Second \n\t\t\tfile). Use this option to indicate the second file of \n\t\t\tpaired end reads. \n"); + fprintf(stdout," -o [file]\t\tOutput of the mapped sequences. The default is \"output\".\n"); + fprintf(stdout," -u [file]\t\tSave unmapped sequences in fasta/fastq format.\n"); + fprintf(stdout," --best \t\tOnly the best mapping from all the possible mapping is returned.\n"); + fprintf(stdout," --seqcomp \t\tIndicates that the input sequences are compressed (gz).\n"); + fprintf(stdout," --outcomp \t\tIndicates that output file should be compressed (gz).\n"); + fprintf(stdout," -e [int]\t\tMaximum allowed %s (default 2).\n", errorType); + fprintf(stdout," --min [int]\t\tMin distance allowed between a pair of end sequences.\n"); + fprintf(stdout," --max [int]\t\tMax distance allowed between a pair of end sequences.\n"); + + fprintf(stdout," --maxoea [int]\t\tMax number of One End Anchored (OEA) returned for each read pair. We recommend 100 or above for NovelSeq use.\n"); + fprintf(stdout," --maxdis [int]\t\tMax number of discordant map locations returned for each read pair. We recommend 300 or above for VariationHunter use.\n"); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mrfast-2.1.0.4/CommandLineParser.h Tue Feb 21 10:29:47 2012 -0500 @@ -0,0 +1,49 @@ +/* + * Copyright (c) <2008 - 2012>, University of Washington, Simon Fraser University + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * - Neither the names of the University of Washington, Simon Fraser University, + * nor the names of its contributors may be + * used to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + Authors: + Farhad Hormozdiari + Faraz Hach + Can Alkan + Emails: + farhadh AT uw DOT edu + fhach AT cs DOT sfu DOT ca + calkan AT uw DOT edu +*/ + + + +#ifndef __COMMAND_LINE_PARSER__ +#define __COMMAND_LINE_PARSER__ + +int parseCommandLine (int argc, char *argv[]); + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mrfast-2.1.0.4/Common.c Tue Feb 21 10:29:47 2012 -0500 @@ -0,0 +1,184 @@ +/* + * Copyright (c) <2008 - 2012>, University of Washington, Simon Fraser University + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * - Neither the names of the University of Washington, Simon Fraser University, + * nor the names of its contributors may be + * used to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + Authors: + Farhad Hormozdiari + Faraz Hach + Can Alkan + Emails: + farhadh AT uw DOT edu + fhach AT cs DOT sfu DOT ca + calkan AT uw DOT edu + */ + + + +#include <stdio.h> +#include <stdlib.h> +#include <sys/time.h> +#include <zlib.h> +#include <string.h> +#include "Common.h" + + +unsigned short SEQ_LENGTH = 0; +long long memUsage = 0; +/**********************************************/ +FILE *fileOpen(char *fileName, char *mode) +{ + FILE *fp; + fp = fopen (fileName, mode); + if (fp == NULL) + { + fprintf(stdout, "Error: Cannot Open the file %s\n", fileName); + fflush(stdout); + exit(0); + } + return fp; +} +/**********************************************/ +gzFile fileOpenGZ(char *fileName, char *mode) +{ + gzFile gzfp; + gzfp = gzopen (fileName, mode); + if (gzfp == Z_NULL) + { + fprintf(stdout, "Error: Cannot Open the file %s\n", fileName); + fflush(stdout); + exit(0); + } + return gzfp; +} +/**********************************************/ +double getTime(void) +{ + struct timeval t; + gettimeofday(&t, NULL); + return t.tv_sec+t.tv_usec/1000000.0; +} + +/**********************************************/ +char reverseCompleteChar(char c) +{ + char ret; + switch (c) + { + case 'A': + ret = 'T'; + break; + case 'T': + ret = 'A'; + break; + case 'C': + ret = 'G'; + break; + case 'G': + ret = 'C'; + break; + default: + ret = 'N'; + break; + } + return ret; +} +/**********************************************/ +void reverseComplete (char *seq, char *rcSeq , int length) +{ + int i; + for (i=0; i<length; i++) + { + rcSeq[i]=reverseCompleteChar (seq[length-1-i]) ; + } +} +/**********************************************/ +void * getMem(size_t size) +{ + void *ret; + ret = malloc(size); + if (ret == NULL){ + fprintf(stderr, "Cannot allocate memory. Currently addressed memory = %0.2f MB, requested memory = %0.2f MB.\nCheck the available main memory, and if you have user limits (ulimit -v).\n", getMemUsage(), (double)size); + exit(0); + } + memUsage+=size; + return ret; +} +/**********************************************/ +void freeMem(void *ptr, size_t size) +{ + memUsage-=size; + free(ptr); +} +/**********************************************/ +double getMemUsage() +{ + return memUsage/1048576.0; +} +/**********************************************/ +void reverse (char *seq, char *rcSeq , int length) +{ + int i; + int l = length; + if(l != strlen(seq)) + l = strlen(seq); + for (i=0; i<l; i++) + { + rcSeq[i]=seq[l-1-i] ; + } + rcSeq[l] = '\0'; +} +/**********************************************/ +void stripPath(char *full, char **path, char **fileName) +{ + int i; + int pos = -1; + + for (i=strlen(full)-1; i>=0; i--) + { + if (full[i]=='/') + { + pos = i; + break; + } + + } + + if (pos != -1) + { + sprintf(*fileName, "%s%c", (full+pos+1), '\0'); + full[pos+1]='\0'; + sprintf(*path,"%s%c", full, '\0'); + } + else + { + sprintf(*fileName, "%s%c", full, '\0'); + sprintf(*path,"%c", '\0'); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mrfast-2.1.0.4/Common.h Tue Feb 21 10:29:47 2012 -0500 @@ -0,0 +1,111 @@ +/* + * Copyright (c) <2008 - 2012>, University of Washington, Simon Fraser University + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * - Neither the names of the University of Washington, Simon Fraser University, + * nor the names of its contributors may be + * used to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + Authors: + Farhad Hormozdiari + Faraz Hach + Can Alkan + Emails: + farhadh AT uw DOT edu + fhach AT cs DOT sfu DOT ca + calkan AT uw DOT edu + */ + + + +#ifndef __COMMON__ +#define __COMMON__ + +#include <zlib.h> + +#define SEQ_MAX_LENGTH 300 // Seq Max Length +#define CONTIG_OVERLAP 200 // No. of characters overlapped between contings +#define CONTIG_NAME_SIZE 200 // Contig name max size +#define FILE_NAME_LENGTH 400 // Filename Max Length +#define DISCORDANT_CUT_OFF 800 +#define MAX_OPEN_FILE 600 +#define MAX_TRANS_CHROMOSAL_OUTPUT 50 +#define MAX_OEA_OUT 500 + +extern unsigned int CONTIG_SIZE; +extern unsigned int CONTIG_MAX_SIZE; + + +extern unsigned char WINDOW_SIZE ; // WINDOW SIZE for indexing/searching +extern unsigned short SEQ_LENGTH; // Sequence(read) length + +extern char *versionNumber; +extern char *versionNumberF; +extern unsigned char mrFAST; + + +extern int maxOEAOutput; +extern int maxDiscordantOutput; +extern int uniqueMode; +extern int indexingMode; +extern int searchingMode; +extern int pairedEndMode; +extern int pairedEndDiscordantMode; +extern int transChromosal; +extern int pairedEndProfilingMode; +extern int bestMode; +extern int nosamMode; +extern int seqCompressed; +extern int outCompressed; +extern int cropSize; +extern int progressRep; +extern char *seqFile1; +extern char *seqFile2; +extern char *seqUnmapped; +extern char *mappingOutput; +extern char *mappingOutputPath; +extern char *unmappedOutput; +extern unsigned char seqFastq; +extern unsigned char errThreshold; +extern unsigned char maxHits; +extern int minPairEndedDiscordantDistance; +extern int maxPairEndedDiscordantDistance; +extern int minPairEndedDistance; +extern int maxPairEndedDistance; +extern char fileName[1000][2][FILE_NAME_LENGTH]; +extern int fileCnt; +extern long long memUsage; + +FILE * fileOpen(char *fileName, char *mode); +gzFile fileOpenGZ(char *fileName, char *mode); +double getTime(void); +void reverseComplete (char *seq, char *rcSeq , int length); +void * getMem(size_t size); +void freeMem(void * ptr, size_t size); +double getMemUsage(); +void reverse (char *seq, char *rcSeq , int length); +void stripPath(char *full, char **path, char **fileName); +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mrfast-2.1.0.4/HashTable.c Tue Feb 21 10:29:47 2012 -0500 @@ -0,0 +1,472 @@ +/* + * Copyright (c) <2008 - 2012>, University of Washington, Simon Fraser University + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * - Neither the names of the University of Washington, Simon Fraser University, + * nor the names of its contributors may be + * used to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + Authors: + Farhad Hormozdiari + Faraz Hach + Can Alkan + Emails: + farhadh AT uw DOT edu + fhach AT cs DOT sfu DOT ca + calkan AT uw DOT edu +*/ + + + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <math.h> +#include "Common.h" +#include "RefGenome.h" +#include "HashTable.h" +/**********************************************/ +FILE *_ih_fp = NULL; +IHashTable *_ih_hashTable = NULL; +int _ih_maxHashTableSize = 0; +char *_ih_refGen = NULL; +char *_ih_refGenName = NULL; +long long _ih_memUsage = 0; +int _ih_refGenOff = 0; +/**********************************************/ + +int hashVal(char *seq) +{ + int i=0; + int val=0, numericVal=0; + + while(i<WINDOW_SIZE) + { + switch (seq[i]) + { + case 'A': + numericVal = 0; + break; + case 'C': + numericVal = 1; + break; + case 'G' : + numericVal = 2; + break; + case 'T': + numericVal = 3; + break; + default: + return -1; + break; + } + val = (val << 2)|numericVal; + i++; + } + return val; +} +/**********************************************/ +void freeIHashTableContent(IHashTable *hashTable, unsigned int maxSize) +{ + int i=0; + for (i=0; i<maxSize; i++) + { + if (hashTable[i].locs != NULL) + { + freeMem(hashTable[i].locs, (hashTable[i].locs[0]+1)*(sizeof(unsigned int))); + hashTable[i].locs = NULL; + } + } +} +/**********************************************/ +void initSavingIHashTable(char *fileName) +{ + int tmp; + _ih_fp = fileOpen(fileName, "w"); + unsigned char bIndex = 0; // Bisulfite Index + + // First Two bytes are indicating the type of the index & window size + tmp = fwrite(&bIndex, sizeof(bIndex), 1, _ih_fp); + tmp = fwrite(&WINDOW_SIZE, sizeof(WINDOW_SIZE), 1, _ih_fp); + + if (tmp == 0) + fprintf(stderr, "Write error while initializing hash table.\n"); + +} +/**********************************************/ +void finalizeSavingIHashTable() +{ + fclose(_ih_fp); +} +/**********************************************/ +void saveIHashTable(IHashTable *hashTable, unsigned int size, unsigned int maxSize, char *refGen, char *refGenName, int refGenOffset) +{ + int tmp; + + // Every Chunk starts with a byte indicating whether it has extra info; + unsigned char extraInfo = 0; + tmp = fwrite (&extraInfo, sizeof(extraInfo), 1, _ih_fp); + + short len = strlen(refGenName); + tmp = fwrite(&len, sizeof(len), 1, _ih_fp); + tmp = fwrite(refGenName, sizeof(char), len, _ih_fp); + + tmp = fwrite(&refGenOffset, sizeof(refGenOffset), 1, _ih_fp); + + unsigned int refGenLength = strlen(refGen); + tmp = fwrite(&refGenLength, sizeof(refGenLength), 1, _ih_fp); + + tmp = fwrite(refGen, sizeof(char), refGenLength, _ih_fp); + tmp = fwrite(&size, sizeof(size), 1, _ih_fp); + + int i=0,j=0; + unsigned char cnt=0; + for (i=0; i<maxSize; i++) + { + if (hashTable[i].locs != NULL) + { + tmp = fwrite(&i, sizeof(i), 1, _ih_fp); + + if (hashTable[i].locs[0] < 250) + { + cnt = hashTable[i].locs[0]; + tmp = fwrite(&cnt, sizeof(cnt), 1, _ih_fp); + } + else + { + cnt =0; + tmp = fwrite (&cnt, sizeof(cnt), 1, _ih_fp); + tmp = fwrite (&(hashTable[i].locs[0]), sizeof(hashTable[i].locs[0]), 1, _ih_fp); + } + + for (j=1; j<=hashTable[i].locs[0]; j++) + tmp = fwrite(&(hashTable[i].locs[j]), sizeof(hashTable[i].locs[j]), 1, _ih_fp); + } + } + + if (tmp == 0) + fprintf(stderr, "Write error while saving hash table.\n"); +} +/**********************************************/ +unsigned int addIHashTableLocation(IHashTable *hashTable, int hv, int location) +{ + unsigned int sizeInc = 0; + + if (hashTable[hv].locs == NULL) + { + sizeInc = 1; + hashTable[hv].locs = getMem (sizeof(unsigned int)*2); + hashTable[hv].locs[0]=1; + hashTable[hv].locs[1]=location; + } + else + { + int size = hashTable[hv].locs[0]; + int i; + unsigned int *tmp = getMem( (size + 2) * sizeof(unsigned int) ); + + for (i = 0; i <= size; i++) + { + tmp[i] = hashTable[hv].locs[i]; + } + size++; + tmp[0] = size; + tmp[size] = location; + + freeMem(hashTable[hv].locs, (hashTable[hv].locs[0]*(sizeof(unsigned int)))); + hashTable[hv].locs = tmp; + } + return sizeInc; +} +/**********************************************/ +void generateIHashTable(char *fileName, char *indexName) +{ + double startTime = getTime(); + unsigned int hashTableSize = 0; + unsigned int hashTableMaxSize = pow(4, WINDOW_SIZE); + IHashTable *hashTable = getMem(sizeof(IHashTable)*hashTableMaxSize); + char *refGenName; + char *refGen; + int refGenOff = 0; + int i, hv, l, flag; + + + for ( i = 0; i < hashTableMaxSize; i++) + { + hashTable[i].locs = NULL; + } + + //Loading Fasta File + if (!initLoadingRefGenome(fileName)) + return; + initSavingIHashTable(indexName); + + fprintf(stdout, "Generating Index from %s", fileName); + fflush(stdout); + + char *prev = getMem (CONTIG_NAME_SIZE); + prev[0]='\0'; + + do + { + flag = loadRefGenome (&refGen, &refGenName, &refGenOff); + + if ( strcmp(prev, refGenName) != 0) + { + fprintf(stdout, "\n - %s ", refGenName); + fflush(stdout); + sprintf(prev, "%s", refGenName); + } + else + { + fprintf(stdout, "."); + fflush(stdout); + } + + l = strlen(refGen) - WINDOW_SIZE; + + for (i=0; i < l; i++) + { + hv = hashVal(refGen + i); + if (hv != -1) + { + hashTableSize += addIHashTableLocation (hashTable, hv, i+1); + } + } + + saveIHashTable(hashTable, hashTableSize, hashTableMaxSize, refGen, refGenName, refGenOff); + freeIHashTableContent(hashTable, hashTableMaxSize); + hashTableSize = 0; + } while (flag); + + freeMem(prev, CONTIG_NAME_SIZE); + freeMem(hashTable, sizeof(IHashTable)*hashTableMaxSize); + + finalizeLoadingRefGenome(); + finalizeSavingIHashTable(); + + fprintf(stdout, "\nDONE in %0.2fs!\n", (getTime()-startTime)); +} + +/**********************************************/ +void finalizeLoadingIHashTable() +{ + freeIHashTableContent(_ih_hashTable, _ih_maxHashTableSize); + freeMem(_ih_hashTable, sizeof(IHashTable)* _ih_maxHashTableSize); + freeMem(_ih_refGen, strlen(_ih_refGen)+1) ; + freeMem(_ih_refGenName, strlen(_ih_refGenName)+1); + fclose(_ih_fp); +} + +/**********************************************/ +int loadIHashTable(double *loadTime, int errThreshould) +{ + double startTime = getTime(); + unsigned char extraInfo = 0; + short len; + unsigned int refGenLength; + unsigned int hashTableSize; + unsigned int tmpSize; + int tmp; + int i=0,j=0; + + if ( fread(&extraInfo, sizeof(extraInfo), 1, _ih_fp) != sizeof(extraInfo) ) + return 0; + + freeIHashTableContent(_ih_hashTable, _ih_maxHashTableSize); + freeMem(_ih_refGen, strlen(_ih_refGen)+1) ; + freeMem(_ih_refGenName, strlen(_ih_refGenName)+1); + + // Reading Chr Name + tmp = fread(&len, sizeof(len), 1, _ih_fp); + if (tmp == 0){ + fprintf(stderr, "Read error while loading hash table.\n"); + exit(0); + } + + _ih_refGenName = getMem(sizeof(char)* (len+1)); + tmp = fread(_ih_refGenName, sizeof(char), len, _ih_fp); + _ih_refGenName [len] ='\0'; + + tmp = fread(&_ih_refGenOff, sizeof (_ih_refGenOff), 1, _ih_fp); + + // Reading Size and Content of Ref Genome + tmp = fread(&refGenLength, sizeof(refGenLength), 1, _ih_fp); + _ih_refGen = getMem(sizeof(char)*(refGenLength+1)); + tmp = fread(_ih_refGen, sizeof(char), refGenLength, _ih_fp); + _ih_refGen[refGenLength]='\0'; + + //Reading Hashtable Size and Content + tmp = fread(&hashTableSize, sizeof(hashTableSize), 1, _ih_fp); + + unsigned int hv; + unsigned char cnt=0; + unsigned int index = 1; + unsigned int tmpValue = 0; + for (i=0; i<hashTableSize; i++) + { + index = 1; + tmp = fread(&hv, sizeof(hv), 1, _ih_fp); + tmp = fread(&cnt, sizeof(cnt), 1, _ih_fp); + + if (cnt>0) + { + tmpSize = cnt; + } + else + { + tmp = fread(&tmpSize, sizeof(tmpSize), 1, _ih_fp); + } + + _ih_hashTable[hv].locs = getMem( sizeof(unsigned int)* (tmpSize+1) ); + _ih_hashTable[hv].locs[0] = tmpSize; + +/* for (j=1; j<=tmpSize; j++) + tmp = fread(&(_ih_hashTable[hv].locs[j]), sizeof(_ih_hashTable[hv].locs[j]), 1, _ih_fp); +*/ + + if(tmpSize != 0) + { + tmp = fread(&(_ih_hashTable[hv].locs[index]), sizeof(_ih_hashTable[hv].locs[index]), 1, _ih_fp); + index++; + } + + for (j=2; j<=tmpSize; j++) + { + tmp = fread(&tmpValue, sizeof(_ih_hashTable[hv].locs[index-1]), 1, _ih_fp); + if(abs(tmpValue-_ih_hashTable[hv].locs[index-1]) > errThreshould) + { + _ih_hashTable[hv].locs[index] = tmpValue; + index++; + } + } + _ih_hashTable[hv].locs[0] = index-1; + } + *loadTime = getTime()-startTime; + return 1; +} +/**********************************************/ +unsigned int *getIHashTableCandidates(int hv) +{ + if ( hv != -1 ) + return _ih_hashTable[hv].locs; + else + return NULL; +} +/**********************************************/ +/**********************************************/ +/**********************************************/ +void configHashTable() +{ + if (WINDOW_SIZE <= 15) + { + generateHashTable = &generateIHashTable; + loadHashTable = &loadIHashTable; + finalizeLoadingHashTable = &finalizeLoadingIHashTable; + getCandidates = &getIHashTableCandidates; + } + else + { + + + } +} +/**********************************************/ +int initLoadingHashTable(char *fileName) +{ + int i; + unsigned char bsIndex; + int tmp; + + _ih_fp = fileOpen(fileName, "r"); + + if (_ih_fp == NULL) + return 0; + + tmp = fread(&bsIndex, sizeof(bsIndex), 1, _ih_fp); + + if (tmp == 0){ + fprintf(stderr, "Read error while inilializing hash table loading.\n"); + exit(0); + } + + if (bsIndex) + { + fprintf(stdout, "Error: Wrong Type of Index indicated"); + return 0; + } + + tmp = fread(&WINDOW_SIZE, sizeof(WINDOW_SIZE), 1, _ih_fp); + + configHashTable(); + + if (_ih_maxHashTableSize != pow(4, WINDOW_SIZE)) + { + + if (_ih_hashTable != NULL) + { + freeIHashTableContent(_ih_hashTable, _ih_maxHashTableSize); + freeMem(_ih_hashTable, sizeof(IHashTable)* _ih_maxHashTableSize); + freeMem(_ih_refGen, strlen(_ih_refGen)+1) ; + freeMem(_ih_refGenName, strlen(_ih_refGenName)+1); + } + + _ih_maxHashTableSize = pow(4, WINDOW_SIZE); + + _ih_hashTable = getMem (sizeof(IHashTable) * _ih_maxHashTableSize); + for (i=0; i<_ih_maxHashTableSize; i++) + _ih_hashTable[i].locs = NULL; + _ih_refGen = getMem(1); + _ih_refGen[0]='\0'; + _ih_refGenName = getMem(1); + _ih_refGenName[0] = '\0'; + } + + return 1; +} +/**********************************************/ +char *getRefGenome() +{ + return _ih_refGen; + +} +/**********************************************/ +char *getRefGenomeName() +{ + return _ih_refGenName; + +} +/**********************************************/ +int getRefGenomeOffset() +{ + return _ih_refGenOff; + +} +/**********************************************/ +HashTable *getHashTable() +{ + return NULL; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mrfast-2.1.0.4/HashTable.h Tue Feb 21 10:29:47 2012 -0500 @@ -0,0 +1,71 @@ +/* + * Copyright (c) <2008 - 2012>, University of Washington, Simon Fraser University + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * - Neither the names of the University of Washington, Simon Fraser University, + * nor the names of its contributors may be + * used to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + Authors: + Farhad Hormozdiari + Faraz Hach + Can Alkan + Emails: + farhadh AT uw DOT edu + fhach AT cs DOT sfu DOT ca + calkan AT uw DOT edu + */ + + + +#ifndef __HASH_TABLE__ +#define __HASH_TABLE__ + +typedef struct HashTable +{ + long long hv; + int *locs; +} HashTable; + +typedef struct +{ + unsigned int *locs; +} IHashTable; + +int hashVal(char *seq); +void configHashTable(); +char *getRefGenome(); +char *getRefGenomeName(); +int getRefGenomeOffset(); +int initLoadingHashTable(char *fileName); +HashTable *getHashTable(); + +void (*generateHashTable)(char *fileName, char *indexName); +int (*loadHashTable)(double *loadTime, int errThreshould); +void (*finalizeLoadingHashTable)(); +unsigned int *(*getCandidates)(int hv); + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mrfast-2.1.0.4/Makefile Tue Feb 21 10:29:47 2012 -0500 @@ -0,0 +1,18 @@ +CC=gcc +CFLAGS = -c -O3 -Wall +LDFLAGS = -lz -lm +SOURCES = baseFAST.c CommandLineParser.c Common.c HashTable.c MrFAST.c Output.c Reads.c RefGenome.c +OBJECTS = $(SOURCES:.c=.o) +EXECUTABLE = mrfast + + +all: $(SOURCES) $(EXECUTABLE) + rm -rf *.o + +$(EXECUTABLE): $(OBJECTS) + $(CC) $(OBJECTS) -o $@ $(LDFLAGS) + +.c.o: + $(CC) $(CFLAGS) $< -o $@ +clean: + rm -f *.o *~ #*
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mrfast-2.1.0.4/MrFAST.c Tue Feb 21 10:29:47 2012 -0500 @@ -0,0 +1,8148 @@ +/* + * Copyright (c) <2008 - 2012>, University of Washington, Simon Fraser University + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * - Neither the names of the University of Washington, Simon Fraser University, + * nor the names of its contributors may be + * used to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* +Authors: + Farhad Hormozdiari + Faraz Hach + Can Alkan +Emails: + farhadh AT uw DOT edu + fhach AT cs DOT sfu DOT ca + calkan AT uw DOT edu +*/ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <math.h> +#include <dirent.h> +#include <xmmintrin.h> +#include <emmintrin.h> +#include <mmintrin.h> + + +#include "Common.h" +#include "Reads.h" +#include "HashTable.h" +#include "Output.h" +#include "MrFAST.h" +#include "RefGenome.h" + + +#define min(a,b) ((a)>(b)?(b):(a)) +#define min3(a,b,c) ((a)>(b)?(b>c?c:b):(a>c?c:a)) +#define CHARCODE(a) (a=='A' ? 0 : (a=='C' ? 1 : (a=='G' ? 2 : (a=='T' ? 3 : 4)))) + +#define MAX_REF_SIZE 18 + + +float calculateScore(int index, char *seq, char *qual, char *md); +unsigned char mrFAST = 1; +char *versionNumberF="0.4"; + +long long verificationCnt = 0; +long long mappingCnt = 0; +long long mappedSeqCnt = 0; +long long completedSeqCnt = 0; +char *mappingOutput; +/**********************************************/ +char *_msf_refGen = NULL; +int _msf_refGenLength = 0; +int _msf_refGenOffset = 0; +char *_msf_refGenName = NULL; + +int _msf_refGenBeg; +int _msf_refGenEnd; + +IHashTable *_msf_hashTable = NULL; + +int *_msf_samplingLocs; +int *_msf_samplingLocsEnds; +int _msf_samplingLocsSize; + +Read *_msf_seqList; +int _msf_seqListSize; + +Pair *_msf_sort_seqList = NULL; +int *_msf_map_sort_seqList; + +ReadIndexTable *_msf_rIndex = NULL; +int _msf_rIndexSize; +int _msf_rIndexMax; + +SAM _msf_output; + +OPT_FIELDS *_msf_optionalFields; + +char *_msf_op; + +int *_msf_verifiedLocs = NULL; + +char _msf_numbers[200][3]; +char _msf_cigar[5]; + +MappingInfo *_msf_mappingInfo; + +int *_msf_seqHits; +int _msf_openFiles = 0; +int _msf_maxLSize=0; +int _msf_maxRSize=0; + +BestFullMappingInfo *bestHitMappingInfo; + +/*************************/ +int _msf_maxFile=0; +char _msf_fileName[4000][200][2][FILE_NAME_LENGTH]; +int _msf_fileCount[4000]; + +char *_msf_readHasConcordantMapping; //boolean if a read has concordant mapping :D + +int *_msf_oeaMapping; +int *_msf_discordantMapping; + +FILE *bestConcordantFILE; +FILE *bestDiscordantFILE; + +int counter = 0; + +int scoreF[200][200]; +int scoreB[200][200]; + +int score[200][200]; +int direction1[200][200]; +int direction2[200][200]; + +__m128i MASK; + +int lookUpTable[15625][15625]; + +/**************************************************Methods***************************************************/ +int smallEditDistanceF(char *a, int lena, char *b, int lenb) +{ + int matrix[20][20]; + int i = 0; + int j = 0; + + for(i = 0; i <= lena; i++) + { + matrix[0][i] = i; + } + + for(i = 0; i <= lenb; i++) + { + matrix[i][0] = i; + } + + + for(i = 1; i <= lenb; i++) + { + for(j = 1; j <= lena; j++) + { + matrix[i][j] = min3(matrix[i-1][j-1]+ (a[j-1] != b[i-1]),matrix[i][j-1]+1 ,matrix[i-1][j]+1); + } + } + return (matrix[lenb][lena]>errThreshold?-1:matrix[lenb][lena]); +} + +int smallEditDistanceB(char *a, int lena, char *b, int lenb) +{ + int matrix[20][20]; + int i = 0; + int j = 0; + + for(i = 0; i <= lena; i++) + { + matrix[0][i] = i; + } + + for(i = 0; i <= lenb; i++) + { + matrix[i][0] = i; + } + + + for(i = 1; i <= lenb; i++) + { + for(j = 1; j <= lena; j++) + { + matrix[i][j] = min3(matrix[i-1][j-1]+ (*(a-j+1) != *(b-i+1)),matrix[i][j-1]+1 ,matrix[i-1][j]+1); + } + } + + return (matrix[lenb][lena]>errThreshold?-1:matrix[lenb][lena]); +} + +char fastEditDistance(int per1, int per2) +{ + + int i = 0; + int j = 0; + + char str1[7]; + char str2[7]; + + int val1 = per1; + int val2 = per2; + + int index = 0; + int mod = 0; + + int matrix[7][7]; + + int min = 20; + + while(index < 6) + { + mod = val1%5; + str1[5-index] = (mod==0 ? 'A':(mod==1?'C':mod==2?'G':(mod==3)?'T':'N')); + val1 = val1 /5; + index++; + } + + str1[6] = '\0'; + + index = 0; + while(index < 6) + { + mod=val2%5; + str2[5-index] = (mod==0 ? 'A':(mod==1?'C':mod==2?'G':(mod==3)?'T':'N')); + val2 = val2 / 5; + index++; + } + str2[6] = '\0'; + + for(i = 0; i < 7; i++) + { + matrix[0][i] = i; + matrix[i][0] = i; + } + + for(i = 1; i < 7; i++) + { + for(j = 1; j < 7; j++) + { + matrix[i][j] = min3(matrix[i-1][j-1]+ (str1[i-1] != str2[j-1]),matrix[i][j-1]+1 ,matrix[i-1][j]+1); + } + } + + for(i = 0; i < 7; i++) + { + if(matrix[i][6] < min) + min = matrix[i][6]; + } + + for(i = 0; i < 7; i++) + { + if(matrix[6][i] < min) + min = matrix[6][i]; + } + return min; +} + +void initLookUpTable() +{ + int i = 0; + + MASK = _mm_insert_epi16(MASK,1,0); + MASK = _mm_insert_epi16(MASK,1,1); + MASK = _mm_insert_epi16(MASK,1,2); + MASK = _mm_insert_epi16(MASK,1,3); + MASK = _mm_insert_epi16(MASK,1,4); + MASK = _mm_insert_epi16(MASK,0,5); + MASK = _mm_insert_epi16(MASK,0,6); + MASK = _mm_insert_epi16(MASK,0,7); + + for(i = 0 ; i < errThreshold + 1; i++) + { + scoreF[0][i] = i; + scoreF[i][0] = i; + } + + for(i = 0 ; i < errThreshold + 1; i++) + { + scoreB[0][i] = i; + scoreB[i][0] = i; + } + + +} + +int backwardEditDistanceSSE2Odd(char *a, int lena, char *b,int lenb) +{ + if(lenb == 0 || lena == 0) + return 0; + + int i = 0; + int j = 0; + int k = 0; + + + int e = errThreshold; + + char flag = 0; + + int minError = 2*e; + + __m128i R0, R1; + __m128i Diag; + __m128i Side1, Side2; + __m128i Down1, Down2; + __m128i Error; + __m128i tmp; + + /* initialize */ + R0 = _mm_setzero_si128 (); + R1 = _mm_setzero_si128 (); + Diag = _mm_setzero_si128 (); + Side1 = _mm_setzero_si128 (); + Side2 = _mm_setzero_si128 (); + Down1 = _mm_setzero_si128 (); + Down2 = _mm_setzero_si128 (); + Error = _mm_setzero_si128 (); + tmp = _mm_setzero_si128 (); + /* end initialize */ + + if(lenb <= e) + { + return smallEditDistanceB(a,lena,b,lenb); + } + + + R1 = _mm_xor_si128(R1, R1); + R0 = _mm_xor_si128(R0, R0); + + Diag = _mm_xor_si128(Diag, Diag); + Side1 = _mm_xor_si128(Side1, Side1); + Down1 = _mm_xor_si128(Down1, Down1); + + Diag = _mm_insert_epi16(Diag,2*e,0); + + Side1 = _mm_insert_epi16(Side1,1,0); + Side1 = _mm_insert_epi16(Side1,2*e,1); + + Down1 = _mm_insert_epi16(Down1,2*e,0); + Down1 = _mm_insert_epi16(Down1,1,1); + Down1 = _mm_insert_epi16(Down1,2*e,2); + + R0 = _mm_insert_epi16(R0,0,0); + + R1 = _mm_insert_epi16(R1,1,0); + R1 = _mm_insert_epi16(R1,1,1); + + for(i=2; i <= e; i++) + { + //set side + Side1 = _mm_slli_si128(Side1,2); + Side1 = _mm_insert_epi16(Side1,1,0); + + Down1 = _mm_insert_epi16(Down1,1,0); + Down1 = _mm_slli_si128(Down1,2); + Down1 = _mm_insert_epi16(Down1,2*e,0); + + Diag = _mm_xor_si128(Diag, Diag); + if( i%2 == 0) + { + Diag = _mm_insert_epi16(Diag,2*e,0); + + for(j=1;j<=i-1;j++) + { + Diag = _mm_slli_si128(Diag, 2); + Diag = _mm_insert_epi16(Diag, *(b-(i/2-1+(i/2-j))) != *(a-(i/2-1-(i/2-j))),0); + } + Diag = _mm_slli_si128(Diag, 2); + Diag = _mm_insert_epi16(Diag, 2*e,0); + + R0 = _mm_min_epi16(R1+Side1, _mm_slli_si128(R0,2)+Diag); + R0 = _mm_min_epi16(R0, _mm_slli_si128(R1,2)+Down1); + } + + else + { + Diag = _mm_insert_epi16(Diag,2*e,0); + for(j=i/2-1;j>=-i/2;j--) + { + Diag = _mm_slli_si128(Diag, 2); + Diag = _mm_insert_epi16(Diag, *(b-((i+1)/2+j-1)) != *(a-((i-1)/2-j-1)),0); + } + Diag = _mm_slli_si128(Diag, 2); + Diag = _mm_insert_epi16(Diag, 2*e,0); + + R1 = _mm_min_epi16(R0+Side1, _mm_slli_si128(R1,2)+Diag); + R1 = _mm_min_epi16(R1, _mm_slli_si128(R0,2)+Down1); + } + } + Error = _mm_xor_si128(Error, Error); + Side2 = _mm_xor_si128(Side2, Side2); + Down2 = _mm_xor_si128(Down2, Down2); + Down1 = _mm_xor_si128(Down1, Down1); + + Error = _mm_insert_epi16(Error,e,0); + Side1 = _mm_insert_epi16(Side2,2*e,0); + Side2 = _mm_insert_epi16(Side2,2*e,0); + Down1 = _mm_insert_epi16(Down1,2*e,0); + + + for(j=0; j < e; j++) + { + Side2 = _mm_slli_si128(Side2, 2); + Side2 = _mm_insert_epi16(Side2,1,0); + + Side1 = _mm_slli_si128(Side1, 2); + Side1 = _mm_insert_epi16(Side1,1,0); + + Down1 = _mm_slli_si128(Down1, 2); + Down1 = _mm_insert_epi16(Down1,1,0); + + Down2 = _mm_slli_si128(Down2, 2); + Down2 = _mm_insert_epi16(Down2,1,0); + + Error = _mm_slli_si128(Error, 2); + Error = _mm_insert_epi16(Error, e, 0); + } + + Down2= _mm_slli_si128(Down2, 2); + Down2 = _mm_insert_epi16(Down2,2*e,0); + + for(; i <= 2*lenb-(e-1);i++) + { + flag = 0; + Diag = _mm_xor_si128(Diag, Diag); + if( i%2 == 0) + { + for(j=e/2;j>=-e/2;j--) + { + Diag = _mm_slli_si128(Diag, 2); + Diag = _mm_insert_epi16(Diag, *(b-(i/2-1+j)) != *(a-(i/2-1-j)),0); + } + + R0 = _mm_min_epi16(_mm_srli_si128(R1,2)+Side1, R0+Diag); + R0 = _mm_min_epi16(R0, R1+Down1); + + + if(_mm_extract_epi16(R0,0) <= e) + flag = 1; + tmp = _mm_srli_si128(R0,2); + for(j=0; j <= e;j++) + { + if(_mm_extract_epi16(tmp,0) <= e) + flag = 1; + tmp = _mm_srli_si128(tmp,2); + } + + if(flag == 0) + return -1; + + if(i == 2*lenb-e) + { + tmp = _mm_srli_si128(R0,2); + for(k=0; k < e-2;k++) + tmp = _mm_srli_si128(tmp,2); + minError = _mm_extract_epi16(tmp,0); + } + + } + + else + { + for(j=e/2;j>=-e/2-1;j--) + { + Diag = _mm_slli_si128(Diag, 2); + Diag = _mm_insert_epi16(Diag, *(b-((i+1)/2+j-1)) != *(a-((i)/2-j-1)),0); + } + + // printf("@%d %d %d %d\n", _mm_extract_epi16(Diag,0), _mm_extract_epi16(Diag,1), _mm_extract_epi16(Diag,2), + // _mm_extract_epi16(Diag,3)); + + R1 = _mm_min_epi16(R0+Side2, R1+Diag); + + // printf("#~%d %d %d %d\n", _mm_extract_epi16(R1,0), _mm_extract_epi16(R1,1), _mm_extract_epi16(R1,2), + // _mm_extract_epi16(R1,3)); + + R1 = _mm_min_epi16(R1, _mm_slli_si128(R0,2)+Down2); + + // printf("$%d %d %d %d\n", _mm_extract_epi16(Side2,0), _mm_extract_epi16(Side2,1), _mm_extract_epi16(Side2,2), + // _mm_extract_epi16(Side2,3)); + + // printf("#%d %d %d %d\n", _mm_extract_epi16(R1,0), _mm_extract_epi16(R1,1), _mm_extract_epi16(R1,2), + // _mm_extract_epi16(R1,3)); + + + + if(i >= 2*lenb-e) + { + tmp = _mm_srli_si128(R1,2); + for(k=0; k < e-1;k++) + tmp = _mm_srli_si128(tmp,2); + minError = min(minError, _mm_extract_epi16(tmp,0)); + } + } + } + + //first cell + Diag = _mm_xor_si128(Diag,Diag); + Diag = _mm_insert_epi16(Diag, *(b-(lenb-3)) != *(a-lena), 0); + Diag = _mm_insert_epi16(Diag, *(b-(lenb-2)) != *(a-(lena-1)), 1); + Diag = _mm_insert_epi16(Diag, *(b-(lenb-1)) != *(a-(lena-2)), 2); + Diag = _mm_insert_epi16(Diag, 2*e, 3); + R1 = _mm_min_epi16(R0+Side2, R1+Diag); + R1 = _mm_min_epi16(R1, _mm_slli_si128(R0,2)+Down2); + + minError = min(minError, _mm_extract_epi16(R1,2)); + + //second cell + Diag = _mm_xor_si128(Diag,Diag); + Diag = _mm_insert_epi16(Diag, *(b-(lenb-2)) != *(a-(lena)), 0); + Diag = _mm_insert_epi16(Diag, *(b-(lenb-1)) != *(a-(lena-1)), 1); + Diag = _mm_insert_epi16(Diag, 2*e, 2); + + R0 = _mm_min_epi16(_mm_srli_si128(R1,2)+Side1, R0+Diag); + R0 = _mm_min_epi16(R0, R1+Down1); + + minError = min(minError, _mm_extract_epi16(R0,1)); + + //third cell + Diag = _mm_xor_si128(Diag,Diag); + Diag = _mm_insert_epi16(Diag, *(b-(lenb-2)) != *(a-(lena+1)), 0); + Diag = _mm_insert_epi16(Diag, *(b-(lenb-1)) != *(a-(lena)), 1); + Diag = _mm_insert_epi16(Diag, 2*e, 2); + + R1 = _mm_min_epi16(R0+Side2, R1+Diag); + R1 = _mm_min_epi16(R1, _mm_slli_si128(R0,2)+Down2); + + minError = min(minError, _mm_extract_epi16(R1,1)); + + //forth + Diag = _mm_xor_si128(Diag,Diag); + Diag = _mm_insert_epi16(Diag, *(b-(lenb-1)) != *(a-(lena+1)), 0); + Diag = _mm_insert_epi16(Diag, 2*e, 1); + + R0 = _mm_min_epi16(_mm_srli_si128(R1,2)+Side1, R0+Diag); + R0 = _mm_min_epi16(R0, R1+Down1); + + minError = min(minError, _mm_extract_epi16(R0,0)); + + //fifth + Diag = _mm_xor_si128(Diag,Diag); + Diag = _mm_insert_epi16(Diag, *(b-(lenb-1)) != *(a-(lena+2)), 0); + Diag = _mm_insert_epi16(Diag, 2*e, 1); + + R1 = _mm_min_epi16(R0+Side2, R1+Diag); + R1 = _mm_min_epi16(R1, _mm_slli_si128(R0,2)+Down2); + + minError = min(minError, _mm_extract_epi16(R0,0)); + + if(minError > e) + return -1; + return minError; +} + +int backwardEditDistanceSSE2G(char *a, int lena, char *b,int lenb) +{ + if(lenb == 0 || lena == 0) + return 0; + + int i = 0; + int j = 0; + int k = 0; + + + int e = errThreshold; + + char flag = 0; + + int minError = 2*e; + + __m128i R0, R1; + __m128i Diag; + __m128i Side1, Side2; + __m128i Down1, Down2; + __m128i Error; + __m128i tmp; + + /* initialize */ + R0 = _mm_setzero_si128 (); + R1 = _mm_setzero_si128 (); + Diag = _mm_setzero_si128 (); + Side1 = _mm_setzero_si128 (); + Side2 = _mm_setzero_si128 (); + Down1 = _mm_setzero_si128 (); + Down2 = _mm_setzero_si128 (); + Error = _mm_setzero_si128 (); + tmp = _mm_setzero_si128 (); + /* end initialize */ + + if(lenb <= e) + { + return smallEditDistanceB(a,lena,b,lenb); + } + + + R1 = _mm_xor_si128(R1, R1); + R0 = _mm_xor_si128(R0, R0); + + Diag = _mm_xor_si128(Diag, Diag); + Side1 = _mm_xor_si128(Side1, Side1); + Down1 = _mm_xor_si128(Down1, Down1); + + Diag = _mm_insert_epi16(Diag,2*e,0); + + Side1 = _mm_insert_epi16(Side1,1,0); + Side1 = _mm_insert_epi16(Side1,2*e,1); + + Down1 = _mm_insert_epi16(Down1,2*e,0); + Down1 = _mm_insert_epi16(Down1,1,1); + Down1 = _mm_insert_epi16(Down1,2*e,2); + + R0 = _mm_insert_epi16(R0,0,0); + + R1 = _mm_insert_epi16(R1,1,0); + R1 = _mm_insert_epi16(R1,1,1); + + for(i=2; i <= e; i++) + { + //set side + Side1 = _mm_slli_si128(Side1,2); + Side1 = _mm_insert_epi16(Side1,1,0); + + Down1 = _mm_insert_epi16(Down1,1,0); + Down1 = _mm_slli_si128(Down1,2); + Down1 = _mm_insert_epi16(Down1,2*e,0); + + Diag = _mm_xor_si128(Diag, Diag); + if( i%2 == 0) + { + Diag = _mm_insert_epi16(Diag,2*e,0); + + for(j=1;j<=i-1;j++) + { + Diag = _mm_slli_si128(Diag, 2); + Diag = _mm_insert_epi16(Diag, *(b-(i/2-1+(i/2-j))) != *(a-(i/2-1-(i/2-j))),0); + } + Diag = _mm_slli_si128(Diag, 2); + Diag = _mm_insert_epi16(Diag, 2*e,0); + + R0 = _mm_min_epi16(R1+Side1, _mm_slli_si128(R0,2)+Diag); + R0 = _mm_min_epi16(R0, _mm_slli_si128(R1,2)+Down1); + } + + else + { + Diag = _mm_insert_epi16(Diag,2*e,0); + for(j=i/2-1;j>=-i/2;j--) + { + Diag = _mm_slli_si128(Diag, 2); + Diag = _mm_insert_epi16(Diag, *(b-((i+1)/2+j-1)) != *(a-((i-1)/2-j-1)),0); + } + Diag = _mm_slli_si128(Diag, 2); + Diag = _mm_insert_epi16(Diag, 2*e,0); + + R1 = _mm_min_epi16(R0+Side1, _mm_slli_si128(R1,2)+Diag); + R1 = _mm_min_epi16(R1, _mm_slli_si128(R0,2)+Down1); + } + } + Error = _mm_xor_si128(Error, Error); + Side2 = _mm_xor_si128(Side2, Side2); + Down2 = _mm_xor_si128(Down2, Down2); + Down1 = _mm_xor_si128(Down1, Down1); + + Error = _mm_insert_epi16(Error,e,0); + Side2 = _mm_insert_epi16(Side2,2*e,0); + Down1 = _mm_insert_epi16(Down1,2*e,0); + + + for(j=0; j < e; j++) + { + Side2 = _mm_slli_si128(Side2, 2); + Side2 = _mm_insert_epi16(Side2,1,0); + + Down1 = _mm_slli_si128(Down1, 2); + Down1 = _mm_insert_epi16(Down1,1,0); + + Down2 = _mm_slli_si128(Down2, 2); + Down2 = _mm_insert_epi16(Down2,1,0); + + Error = _mm_slli_si128(Error, 2); + Error = _mm_insert_epi16(Error, e, 0); + } + + Down2= _mm_slli_si128(Down2, 2); + Down2 = _mm_insert_epi16(Down2,2*e,0); + + for(; i <= 2*lenb-(e-1);i++) + { + flag = 0; + Diag = _mm_xor_si128(Diag, Diag); + if( i%2 == 0) + { + for(j=e/2;j>=-e/2;j--) + { + Diag = _mm_slli_si128(Diag, 2); + Diag = _mm_insert_epi16(Diag, *(b-(i/2-1+j)) != *(a-(i/2-1-j)),0); + } + + R0 = _mm_min_epi16(R1+Side2, R0+Diag); + R0 = _mm_min_epi16(R0, _mm_slli_si128(R1,2)+Down2); + + if(_mm_extract_epi16(R0,0) <= e) + flag = 1; + tmp = _mm_srli_si128(R0,2); + for(j=0; j <= e;j++) + { + if(_mm_extract_epi16(tmp,0) <= e) + flag = 1; + tmp = _mm_srli_si128(tmp,2); + } + + if(flag == 0) + return -1; + + if(i == 2*lenb-e) + { + tmp = _mm_srli_si128(R0,2); + for(k=0; k < e-1;k++) + tmp = _mm_srli_si128(tmp,2); + minError = _mm_extract_epi16(tmp,0); + } + + } + + else + { + for(j=-e/2+1;j<=e/2;j++) + { + Diag = _mm_slli_si128(Diag, 2); + Diag = _mm_insert_epi16(Diag, *(b-((i+1)/2-j-1)) != *(a-((i-1)/2+j-1)),0); + } + + R1 = _mm_min_epi16(_mm_srli_si128(R0,2)+Side1, R1+Diag); + R1 = _mm_min_epi16(R1, R0+Down1); + + + if(i >= 2*lenb-e) + { + tmp = _mm_srli_si128(R1,2); + for(k=0; k < e-2;k++) + tmp = _mm_srli_si128(tmp,2); + minError = min(minError, _mm_extract_epi16(tmp,0)); + } + } + } + + j=0; + int tmpE = e; + for(;j<2*(e-2)+1;j++) + { + + Diag = _mm_xor_si128(Diag, Diag); + //set the first element + if(j==0) + { + for( k=0;k<=e-1;k++ ) + { + Diag = _mm_slli_si128(Diag, 2); + Diag = _mm_insert_epi16(Diag, *(b-(lenb-1-k)) != *(a-((i-lenb)-1+k)),0); + } + + R0 = _mm_min_epi16(R1+Side2, R0+Diag); + R0 = _mm_min_epi16(R0, _mm_slli_si128(R1,2)+Down2); + + + tmpE--; + tmp = _mm_srli_si128(R0,2); + for(k=0; k < e-2;k++) + tmp = _mm_srli_si128(tmp,2); + minError = min(minError, _mm_extract_epi16(tmp,0)); + } + else if(j%2 == 0) + { + for(k=0;k<tmpE;k++) + { + Diag = _mm_slli_si128(Diag, 2); + Diag = _mm_insert_epi16(Diag, *(b-(lenb-1-k)) != *(a-((i-lenb)-1+k)),0); + } + + R0 = _mm_min_epi16(R1+Side2, R0+Diag); + R0 = _mm_min_epi16(R0, _mm_slli_si128(R1,2)+Down2); + + tmpE--; + + tmp = _mm_srli_si128(R0,2); + for(k=0; k < tmpE-1;k++) + tmp = _mm_srli_si128(tmp,2); + minError = min(minError, _mm_extract_epi16(tmp,0)); + } + + + else + { + for(k=0;k<tmpE;k++) + { + Diag = _mm_slli_si128(Diag, 2); + Diag = _mm_insert_epi16(Diag, *(b-(lenb-1-k)) != *(a-((i-lenb)-1+k)),0); + } + + R1 = _mm_min_epi16(_mm_srli_si128(R0,2)+Side1, R1+Diag); + R1 = _mm_min_epi16(R1, R0+Down1); + + tmp = _mm_srli_si128(R1,2); + for(k=0; k < tmpE-2;k++) + tmp = _mm_srli_si128(tmp,2); + minError = min(minError, _mm_extract_epi16(tmp,0)); + } + i++; + } + //Diag + + Diag = _mm_xor_si128(Diag,Diag); + Diag = _mm_insert_epi16(Diag, 2*e, 0); + Diag = _mm_insert_epi16(Diag, *(a-(lenb+e-2)) != *(b-(lenb-1)), 1); + + Side1 = _mm_insert_epi16(Side1,1,0); + Side1 = _mm_insert_epi16(Side1,1,1); + + Down1 = _mm_insert_epi16(Down1, 2*e, 0); + Down1 = _mm_insert_epi16(Down1, 1, 1); + + R1 = _mm_min_epi16(R0+Side1, _mm_slli_si128(R1,2)+Diag); + R1 = _mm_min_epi16(R1, _mm_slli_si128(R0,2)+Down1); + + minError = min(minError, _mm_extract_epi16(R1,1)); + + Diag = _mm_insert_epi16(Diag, *(a-(lenb+e-1)) != *(b-(lenb-1)), 0); + Down1 = _mm_insert_epi16(Down1, 1, 0); + + R0 = _mm_min_epi16(R1+Down1,R0+Diag); + R0 = _mm_min_epi16(R0,_mm_srli_si128(R1,2)+Side1); + + minError = min(minError, _mm_extract_epi16(R0,0)); + + if(minError > e) + return -1; + return minError; +} + +inline int backwardEditDistanceSSE2Extention(char *a, int lena, char *b,int lenb) +{ + if(lenb == 0 || lena == 0) + return 0; + + int i = 0; + int j = 0; + int k = 0; + + int i0; + int i1; + int i2; + int i4; + int i5; + + int e = 4; + int mismatch = errThreshold; + + int minError = 2*errThreshold; + int index = 0; + int tmpValue = 0; + + if(lenb <= e) + { + return smallEditDistanceB(a,lena,b,lenb); + } + + + __m128i R0, R1; + __m128i Diag; + __m128i Side1, Side2; + __m128i Down1, Down2; + __m128i tmp; + __m128i SeqA, SeqB; + __m128i Result; + + /* initialize */ + R0 = _mm_setzero_si128 (); + R1 = _mm_setzero_si128 (); + Diag = _mm_setzero_si128 (); + Side1 = _mm_setzero_si128 (); + Side2 = _mm_setzero_si128 (); + Down1 = _mm_setzero_si128 (); + Down2 = _mm_setzero_si128 (); + SeqA = _mm_setzero_si128 (); + SeqB = _mm_setzero_si128 (); + Result = _mm_setzero_si128 (); + /* end initialize */ + + R1 = _mm_xor_si128(R1, R1); + R0 = _mm_xor_si128(R0, R0); + + Diag = _mm_xor_si128(Diag, Diag); + Diag = _mm_insert_epi16(Diag,minError,0); + + i0 = (a[0] != b[0]); + i1 = min(i0, ( *(a-1)!=*b) )+1; + i2 = min(i0,( a[0] != *(b-1) ) )+1; + + i0 = min3( i0+ ( *(a-1)!=*(b-1) ),i1+1,i2+1); + i4 = min(i1, ( *(a-2)!=b[0] )+1)+1; + i5 = min(i2, (a[0] != *(b-2))+1)+1; + + R1 = _mm_insert_epi16(R1, 3, 0); + R1 = _mm_insert_epi16(R1, i1, 1); + R1 = _mm_insert_epi16(R1, i2, 2); + R1 = _mm_insert_epi16(R1, 3, 3); + + + R0 = _mm_insert_epi16(R0, 4, 0); + R0 = _mm_insert_epi16(R0, i4, 1); + R0 = _mm_insert_epi16(R0, i0, 2); + R0 = _mm_insert_epi16(R0, i5, 3); + R0 = _mm_insert_epi16(R0, 4, 4); + + + Side2 = _mm_xor_si128(Side2, Side2); + Down2 = _mm_xor_si128(Down2, Down2); + Down1 = _mm_xor_si128(Down1, Down1); + Side1 = _mm_xor_si128(Side1, Side1); + + Side2 = _mm_insert_epi16(Side2,minError,0); + Down1 = _mm_insert_epi16(Down1,minError,0); + + Side1 = _mm_insert_epi16(Side1,1,0); + + index = 0; + for(j=0; j < e; j++) + { + Side2 = _mm_slli_si128(Side2, 2); + Side2 = _mm_insert_epi16(Side2,1,0); + + Down1 = _mm_slli_si128(Down1, 2); + Down1 = _mm_insert_epi16(Down1,1,0); + + Down2 = _mm_slli_si128(Down2, 2); + Down2 = _mm_insert_epi16(Down2,1,0); + + Side1 = _mm_slli_si128(Side1, 2); + Side1 = _mm_insert_epi16(Side1,1,0); + + SeqA = _mm_slli_si128(SeqA, 2); + SeqB = _mm_slli_si128(SeqB, 2); + SeqA = _mm_insert_epi16(SeqA,*(a-index),0); + SeqB = _mm_insert_epi16(SeqB,*(b-index),0); + index++; + } + + Down2= _mm_slli_si128(Down2, 2); + Down2 = _mm_insert_epi16(Down2,minError,0); + + index = 4; + i = 5; + + int loopEnd = 2*lenb-(e-1); + for(; i <= loopEnd ;i++) + { + + Diag = _mm_xor_si128(Diag, Diag); + if( i%2 == 0) + { + SeqA = _mm_slli_si128(SeqA, 2); + SeqB = _mm_slli_si128(SeqB, 2); + SeqA = _mm_insert_epi16(SeqA,*(a-(index)),0); + SeqB = _mm_insert_epi16(SeqB,*(b-(index)),0); + + index++; + + tmp = _mm_shufflelo_epi16(SeqB,27); + tmp = _mm_slli_si128(tmp, 2); + tmpValue = _mm_extract_epi16(tmp, 5); + tmp = _mm_insert_epi16(tmp, tmpValue, 0); + + Result = _mm_cmpeq_epi16(SeqA, tmp); + Diag = _mm_andnot_si128(Result, MASK); + + R0 = _mm_min_epi16(R1+Side2, R0+Diag); + R0 = _mm_min_epi16(R0, _mm_slli_si128(R1,2)+Down2); + + if(_mm_extract_epi16(R0, 0) > errThreshold && _mm_extract_epi16(R0, 1) > errThreshold && _mm_extract_epi16(R0, 2) > errThreshold + && _mm_extract_epi16(R0, 3) > errThreshold && _mm_extract_epi16(R0, 4) > errThreshold && _mm_extract_epi16(R1, 0) > errThreshold + && _mm_extract_epi16(R1, 1) > errThreshold && _mm_extract_epi16(R1, 2) > errThreshold && _mm_extract_epi16(R1, 3) > errThreshold) + return -1; + + if(i == 2*lenb-e) + { + tmp = _mm_srli_si128(R0,2); + for(k=0; k < e-1;k++) + tmp = _mm_srli_si128(tmp,2); + minError = _mm_extract_epi16(tmp,0); + } + + } + + else + { + Result = _mm_cmpeq_epi16(SeqA, _mm_shufflelo_epi16(SeqB,27)); + Diag = _mm_andnot_si128(Result, MASK); + + R1 = _mm_min_epi16(_mm_srli_si128(R0,2)+Side1, R1+Diag); + R1 = _mm_min_epi16(R1, R0+Down1); + + + if(i >= 2*lenb-e) + { + tmp = _mm_srli_si128(R1,2); + for(k=0; k < e-2;k++) + tmp = _mm_srli_si128(tmp,2); + minError = min(minError, _mm_extract_epi16(tmp,0)); + } + } + + + } + + j=0; + int tmpE = e; + for(;j<2*(e-2)+1;j++) + { + + Diag = _mm_xor_si128(Diag, Diag); + //set the first element + if(j==0) + { + for( k=0;k<=e-1;k++ ) + { + Diag = _mm_slli_si128(Diag, 2); + Diag = _mm_insert_epi16(Diag, *(b-(lenb-1-k)) != *(a-((i-lenb)-1+k)),0); + } + + R0 = _mm_min_epi16(R1+Side2, R0+Diag); + R0 = _mm_min_epi16(R0, _mm_slli_si128(R1,2)+Down2); + + tmpE--; + + tmp = _mm_srli_si128(R0,2); + for(k=0; k < e-2;k++) + tmp = _mm_srli_si128(tmp,2); + minError = min(minError, _mm_extract_epi16(tmp,0)); + } + else if(j%2 == 0) + { + for(k=0;k<tmpE;k++) + { + Diag = _mm_slli_si128(Diag, 2); + Diag = _mm_insert_epi16(Diag, *(b-(lenb-1-k)) != *(a-((i-lenb)-1+k)),0); + } + + R0 = _mm_min_epi16(R1+Side2, R0+Diag); + R0 = _mm_min_epi16(R0, _mm_slli_si128(R1,2)+Down2); + + tmpE--; + + tmp = _mm_srli_si128(R0,2); + for(k=0; k < tmpE-1;k++) + tmp = _mm_srli_si128(tmp,2); + minError = min(minError, _mm_extract_epi16(tmp,0)); + } + + + else + { + for(k=0;k<tmpE;k++) + { + Diag = _mm_slli_si128(Diag, 2); + Diag = _mm_insert_epi16(Diag, *(b-(lenb-1-k)) != *(a-((i-lenb)-1+k)),0); + } + + R1 = _mm_min_epi16(_mm_srli_si128(R0,2)+Side1, R1+Diag); + R1 = _mm_min_epi16(R1, R0+Down1); + + tmp = _mm_srli_si128(R1,2); + for(k=0; k < tmpE-2;k++) + tmp = _mm_srli_si128(tmp,2); + minError = min(minError, _mm_extract_epi16(tmp,0)); + } + i++; + } + //Diag + + Diag = _mm_xor_si128(Diag,Diag); + Diag = _mm_insert_epi16(Diag, 2*errThreshold, 0); + Diag = _mm_insert_epi16(Diag, *(a-(lenb+e-2)) != *(b-(lenb-1)), 1); + + Side1 = _mm_insert_epi16(Side1,1,0); + Side1 = _mm_insert_epi16(Side1,1,1); + + Down1 = _mm_insert_epi16(Down1, 2*errThreshold, 0); + Down1 = _mm_insert_epi16(Down1, 1, 1); + + R1 = _mm_min_epi16(R0+Side1, _mm_slli_si128(R1,2)+Diag); + R1 = _mm_min_epi16(R1, _mm_slli_si128(R0,2)+Down1); + + minError = min(minError, _mm_extract_epi16(R1,1)); + + Diag = _mm_insert_epi16(Diag, *(a-(lenb+e-1)) != *(b-(lenb-1)), 0); + Down1 = _mm_insert_epi16(Down1, 1, 0); + + R0 = _mm_min_epi16(R1+Down1,R0+Diag); + R0 = _mm_min_epi16(R0,_mm_srli_si128(R1,2)+Side1); + + minError = min(minError, _mm_extract_epi16(R0,0)); + + if(minError > mismatch) + return -1; + return minError; +} + +int backwardEditDistance4SSE2(char *a, int lena, char *b,int lenb) +{ + if(lenb == 0 || lena == 0) + return 0; + + int i = 0; + int j = 0; + int k = 0; + + int i0; + int i1; + int i2; + int i4; + int i5; + + int e = errThreshold; + + int minError = 2*e; + int index = 0; + int tmpValue = 0; + + if(lenb <= e) + { + return smallEditDistanceB(a,lena,b,lenb); + } + + __m128i R0, R1; + __m128i Diag; + __m128i Side1, Side2; + __m128i Down1, Down2; + __m128i tmp; + __m128i SeqA, SeqB; + __m128i Result; + + /* initialize */ + R0 = _mm_setzero_si128 (); + R1 = _mm_setzero_si128 (); + Diag = _mm_setzero_si128 (); + Side1 = _mm_setzero_si128 (); + Side2 = _mm_setzero_si128 (); + Down1 = _mm_setzero_si128 (); + Down2 = _mm_setzero_si128 (); + SeqA = _mm_setzero_si128 (); + SeqB = _mm_setzero_si128 (); + Result = _mm_setzero_si128 (); + /* end initialize */ + + R1 = _mm_xor_si128(R1, R1); + R0 = _mm_xor_si128(R0, R0); + + Diag = _mm_xor_si128(Diag, Diag); + Diag = _mm_insert_epi16(Diag,2*e,0); + + i0 = (a[0] != b[0]); + i1 = min(i0, ( *(a-1)!=*b) )+1; + i2 = min(i0,( a[0] != *(b-1) ) )+1; + + i0 = min3( i0+ ( *(a-1)!=*(b-1) ),i1+1,i2+1); + i4 = min(i1, ( *(a-2)!=b[0] )+1)+1; + i5 = min(i2, (a[0] != *(b-2))+1)+1; + + R1 = _mm_insert_epi16(R1, 3, 0); + R1 = _mm_insert_epi16(R1, i1, 1); + R1 = _mm_insert_epi16(R1, i2, 2); + R1 = _mm_insert_epi16(R1, 3, 3); + + + R0 = _mm_insert_epi16(R0, 4, 0); + R0 = _mm_insert_epi16(R0, i4, 1); + R0 = _mm_insert_epi16(R0, i0, 2); + R0 = _mm_insert_epi16(R0, i5, 3); + R0 = _mm_insert_epi16(R0, 4, 4); + + Side2 = _mm_xor_si128(Side2, Side2); + Down2 = _mm_xor_si128(Down2, Down2); + Down1 = _mm_xor_si128(Down1, Down1); + Side1 = _mm_xor_si128(Side1, Side1); + + Side2 = _mm_insert_epi16(Side2,2*e,0); + Down1 = _mm_insert_epi16(Down1,2*e,0); + + Side1 = _mm_insert_epi16(Side1,1,0); + + index = 0; + for(j=0; j < e; j++) + { + Side2 = _mm_slli_si128(Side2, 2); + Side2 = _mm_insert_epi16(Side2,1,0); + + Down1 = _mm_slli_si128(Down1, 2); + Down1 = _mm_insert_epi16(Down1,1,0); + + Down2 = _mm_slli_si128(Down2, 2); + Down2 = _mm_insert_epi16(Down2,1,0); + + Side1 = _mm_slli_si128(Side1, 2); + Side1 = _mm_insert_epi16(Side1,1,0); + + SeqA = _mm_slli_si128(SeqA, 2); + SeqB = _mm_slli_si128(SeqB, 2); + SeqA = _mm_insert_epi16(SeqA,*(a-index),0); + SeqB = _mm_insert_epi16(SeqB,*(b-index),0); + index++; + } + + Down2= _mm_slli_si128(Down2, 2); + Down2 = _mm_insert_epi16(Down2,2*e,0); + + index = 4; + i = 5; + int loopEnd = 2*lenb-(e-1); + for(; i <= loopEnd ;i++) + { + + Diag = _mm_xor_si128(Diag, Diag); + if( i%2 == 0) + { + SeqA = _mm_slli_si128(SeqA, 2); + SeqB = _mm_slli_si128(SeqB, 2); + SeqA = _mm_insert_epi16(SeqA,*(a-(index)),0); + SeqB = _mm_insert_epi16(SeqB,*(b-(index)),0); + + index++; + + tmp = _mm_shufflelo_epi16(SeqB,27); + tmp = _mm_slli_si128(tmp, 2); + tmpValue = _mm_extract_epi16(tmp, 5); + tmp = _mm_insert_epi16(tmp, tmpValue, 0); + + Result = _mm_cmpeq_epi16(SeqA, tmp); + Diag = _mm_andnot_si128(Result, MASK); + + R0 = _mm_min_epi16(R1+Side2, R0+Diag); + R0 = _mm_min_epi16(R0, _mm_slli_si128(R1,2)+Down2); + + //tmp = _mm_sub_epi16(Error, R0); + //i0 = _mm_movemask_epi8(tmp); + + if( _mm_extract_epi16(R0, 0) > e && _mm_extract_epi16(R0, 1) > e && _mm_extract_epi16(R0, 2) > e + && _mm_extract_epi16(R0, 3) > e && _mm_extract_epi16(R0, 4) > e && _mm_extract_epi16(R1, 0) > e && + _mm_extract_epi16(R1, 1) > e && _mm_extract_epi16(R1, 2) > e && _mm_extract_epi16(R1, 3) > e ) + return -1; + + if(i == 2*lenb-e) + { + tmp = _mm_srli_si128(R0,2); + for(k=0; k < e-1;k++) + tmp = _mm_srli_si128(tmp,2); + minError = _mm_extract_epi16(tmp,0); + } + + } + + else + { + Result = _mm_cmpeq_epi16(SeqA, _mm_shufflelo_epi16(SeqB,27)); + Diag = _mm_andnot_si128(Result, MASK); + + R1 = _mm_min_epi16(_mm_srli_si128(R0,2)+Side1, R1+Diag); + R1 = _mm_min_epi16(R1, R0+Down1); + + if(i >= 2*lenb-e) + { + tmp = _mm_srli_si128(R1,2); + for(k=0; k < e-2;k++) + tmp = _mm_srli_si128(tmp,2); + minError = min(minError, _mm_extract_epi16(tmp,0)); + } + } + + + } + + j=0; + + int tmpE = e; + + for(;j<2*(e-2)+1;j++) + { + + Diag = _mm_xor_si128(Diag, Diag); + //set the first element + if(j==0) + { + for( k=0;k<=e-1;k++ ) + { + Diag = _mm_slli_si128(Diag, 2); + Diag = _mm_insert_epi16(Diag, *(b-(lenb-1-k)) != *(a-((i-lenb)-1+k)),0); + } + + R0 = _mm_min_epi16(R1+Side2, R0+Diag); + R0 = _mm_min_epi16(R0, _mm_slli_si128(R1,2)+Down2); + + tmpE--; + + tmp = _mm_srli_si128(R0,2); + for(k=0; k < e-2;k++) + tmp = _mm_srli_si128(tmp,2); + minError = min(minError, _mm_extract_epi16(tmp,0)); + } + else if(j%2 == 0) + { + for(k=0;k<tmpE;k++) + { + Diag = _mm_slli_si128(Diag, 2); + Diag = _mm_insert_epi16(Diag, *(b-(lenb-1-k)) != *(a-((i-lenb)-1+k)),0); + } + + R0 = _mm_min_epi16(R1+Side2, R0+Diag); + R0 = _mm_min_epi16(R0, _mm_slli_si128(R1,2)+Down2); + + tmpE--; + + tmp = _mm_srli_si128(R0,2); + for(k=0; k < tmpE-1;k++) + tmp = _mm_srli_si128(tmp,2); + minError = min(minError, _mm_extract_epi16(tmp,0)); + } + + + else + { + for(k=0;k<tmpE;k++) + { + Diag = _mm_slli_si128(Diag, 2); + Diag = _mm_insert_epi16(Diag, *(b-(lenb-1-k)) != *(a-((i-lenb)-1+k)),0); + } + + R1 = _mm_min_epi16(_mm_srli_si128(R0,2)+Side1, R1+Diag); + R1 = _mm_min_epi16(R1, R0+Down1); + + tmp = _mm_srli_si128(R1,2); + for(k=0; k < tmpE-2;k++) + tmp = _mm_srli_si128(tmp,2); + minError = min(minError, _mm_extract_epi16(tmp,0)); + } + i++; + } + //Diag + + Diag = _mm_xor_si128(Diag,Diag); + Diag = _mm_insert_epi16(Diag, 2*e, 0); + Diag = _mm_insert_epi16(Diag, *(a-(lenb+e-2)) != *(b-(lenb-1)), 1); + + Side1 = _mm_insert_epi16(Side1,1,0); + Side1 = _mm_insert_epi16(Side1,1,1); + + Down1 = _mm_insert_epi16(Down1, 2*e, 0); + Down1 = _mm_insert_epi16(Down1, 1, 1); + + R1 = _mm_min_epi16(R0+Side1, _mm_slli_si128(R1,2)+Diag); + R1 = _mm_min_epi16(R1, _mm_slli_si128(R0,2)+Down1); + + minError = min(minError, _mm_extract_epi16(R1,1)); + + Diag = _mm_insert_epi16(Diag, *(a-(lenb+e-1)) != *(b-(lenb-1)), 0); + Down1 = _mm_insert_epi16(Down1, 1, 0); + + R0 = _mm_min_epi16(R1+Down1,R0+Diag); + R0 = _mm_min_epi16(R0,_mm_srli_si128(R1,2)+Side1); + + minError = min(minError, _mm_extract_epi16(R0,0)); + + if(minError > e) + return -1; + return minError; +} + +inline int forwardEditDistanceSSE2Extention(char *a, int lena, char *b,int lenb) +{ + if(lenb == 0 || lena == 0) + return 0; + + int i = 0; + int j = 0; + int k = 0; + + int i0=0; + int i1=0; + int i2=0; + int i4=0; + int i5=0; + + int mismatch = errThreshold; + int e = 4; + + int minError = 4*mismatch+1; + int index = 0; + int tmpValue = 0; + + if(lenb <= e) + { + return smallEditDistanceF(a,lena,b,lenb); + } + + + register __m128i R0, R1; + __m128i Diag; + __m128i Side1, Side2; + __m128i Down1, Down2; + __m128i tmp; + register __m128i SeqA, SeqB; + __m128i Result; + + __m128i tmpSeqA; + __m128i tmpSeqB; + + /* initialize */ + R0 = _mm_setzero_si128 (); + R1 = _mm_setzero_si128 (); + Diag = _mm_setzero_si128 (); + Side1 = _mm_setzero_si128 (); + Side2 = _mm_setzero_si128 (); + Down1 = _mm_setzero_si128 (); + Down2 = _mm_setzero_si128 (); + SeqA = _mm_setzero_si128 (); + SeqB = _mm_setzero_si128 (); + Result = _mm_setzero_si128 (); + /* end initialize */ + + + R1 = _mm_xor_si128(R1, R1); + R0 = _mm_xor_si128(R0, R0); + + Diag = _mm_xor_si128(Diag, Diag); + Diag = _mm_insert_epi16(Diag,minError,0); + + i0 = (a[0] != b[0]); + i1 = min(i0, (a[1]!=b[0]))+1; + i2 = min(i0,(a[0]!=b[1]))+1; + + i0 = min3(i0+(a[1]!=b[1]),i1+1,i2+1); + i4 = min(i1, (a[2]!=b[0])+1)+1; + i5 = min(i2, (a[0]!=b[2])+1)+1; + + R1 = _mm_insert_epi16(R1, 3, 0); + R1 = _mm_insert_epi16(R1, i1, 1); + R1 = _mm_insert_epi16(R1, i2, 2); + R1 = _mm_insert_epi16(R1, 3, 3); + + R0 = _mm_insert_epi16(R0, 4, 0); + R0 = _mm_insert_epi16(R0, i4, 1); + R0 = _mm_insert_epi16(R0, i0, 2); + R0 = _mm_insert_epi16(R0, i5, 3); + R0 = _mm_insert_epi16(R0, 4, 4); + + Side2 = _mm_xor_si128(Side2, Side2); + Down2 = _mm_xor_si128(Down2, Down2); + Down1 = _mm_xor_si128(Down1, Down1); + Side1 = _mm_xor_si128(Side1, Side1); + + Side2 = _mm_insert_epi16(Side2,minError,0); + Down1 = _mm_insert_epi16(Down1,minError,0); + + Side1 = _mm_insert_epi16(Side1,1,0); + + index = 0; + for(j=0; j < e; j++) + { + Side2 = _mm_slli_si128(Side2, 2); + Side2 = _mm_insert_epi16(Side2,1,0); + + Down1 = _mm_slli_si128(Down1, 2); + Down1 = _mm_insert_epi16(Down1,1,0); + + Down2 = _mm_slli_si128(Down2, 2); + Down2 = _mm_insert_epi16(Down2,1,0); + + Side1 = _mm_slli_si128(Side1, 2); + Side1 = _mm_insert_epi16(Side1,1,0); + + SeqA = _mm_slli_si128(SeqA, 2); + SeqB = _mm_slli_si128(SeqB, 2); + SeqA = _mm_insert_epi16(SeqA,a[index],0); + SeqB = _mm_insert_epi16(SeqB,b[index],0); + index++; + } + + Down2= _mm_slli_si128(Down2, 2); + Down2 = _mm_insert_epi16(Down2,minError,0); + + index = 4; + i = 5; + + int loopEnd = 2*lenb-(e-1); + for(; i <= loopEnd ;i++) + { + if( i%2 == 0) + { + tmpSeqA = _mm_slli_si128(SeqA, 2); + tmpSeqB = _mm_slli_si128(SeqB, 2); + SeqA = _mm_insert_epi16(tmpSeqA,a[index],0); + SeqB = _mm_insert_epi16(tmpSeqB,b[index],0); + + index++; + + tmp = _mm_shufflelo_epi16(SeqB,27); + tmp = _mm_slli_si128(tmp, 2); + tmpValue = _mm_extract_epi16(tmp, 5); + tmp = _mm_insert_epi16(tmp, tmpValue, 0); + + Result = _mm_cmpeq_epi16(SeqA, tmp); + Diag = _mm_andnot_si128(Result, MASK); + + R0 = _mm_min_epi16(R1+Side2, R0+Diag); + R0 = _mm_min_epi16(R0, _mm_slli_si128(R1,2)+Down2); + + if(_mm_extract_epi16(R0, 0) > errThreshold && _mm_extract_epi16(R0, 1) > errThreshold && _mm_extract_epi16(R0, 2) > errThreshold + && _mm_extract_epi16(R0, 3) > errThreshold && _mm_extract_epi16(R0, 4) > errThreshold && + _mm_extract_epi16(R1, 0) > errThreshold && _mm_extract_epi16(R1, 1) > errThreshold && + _mm_extract_epi16(R1, 2) > errThreshold && _mm_extract_epi16(R1, 3) > errThreshold) + return -1; + + if(i == 2*lenb-e) + { + tmp = _mm_srli_si128(R0,2); + for(k=0; k < e-1;k++) + tmp = _mm_srli_si128(tmp,2); + minError = _mm_extract_epi16(tmp,0); + } + + } + + else + { + Result = _mm_cmpeq_epi16(SeqA, _mm_shufflelo_epi16(SeqB,27)); + Diag = _mm_andnot_si128(Result, MASK); + + R1 = _mm_min_epi16(_mm_srli_si128(R0,2)+Side1, R1+Diag); + R1 = _mm_min_epi16(R1, R0+Down1); + + if(i >= 2*lenb-e) + { + tmp = _mm_srli_si128(R1,2); + for(k=0; k < e-2;k++) + tmp = _mm_srli_si128(tmp,2); + minError = min(minError, _mm_extract_epi16(tmp,0)); + } + } + } + + j=0; + int tmpE = e; + for(;j<2*(e-2)+1;j++) + { + + Diag = _mm_xor_si128(Diag, Diag); + //set the first element + if(j==0) + { + for( k=0;k<=e-1;k++ ) + { + Diag = _mm_slli_si128(Diag, 2); + Diag = _mm_insert_epi16(Diag, b[lenb-1-k] != a[(i-lenb)-1+k],0); + } + + R0 = _mm_min_epi16(R1+Side2, R0+Diag); + R0 = _mm_min_epi16(R0, _mm_slli_si128(R1,2)+Down2); + + tmpE--; + + tmp = _mm_srli_si128(R0,2); + for(k=0; k < e-2;k++) + tmp = _mm_srli_si128(tmp,2); + minError = min(minError, _mm_extract_epi16(tmp,0)); + } + else if(j%2 == 0) + { + for(k=0;k<tmpE;k++) + { + Diag = _mm_slli_si128(Diag, 2); + Diag = _mm_insert_epi16(Diag, b[lenb-1-k] != a[(i-lenb)-1+k],0); + } + + R0 = _mm_min_epi16(R1+Side2, R0+Diag); + R0 = _mm_min_epi16(R0, _mm_slli_si128(R1,2)+Down2); + + tmpE--; + + tmp = _mm_srli_si128(R0,2); + for(k=0; k < tmpE-1;k++) + tmp = _mm_srli_si128(tmp,2); + minError = min(minError, _mm_extract_epi16(tmp,0)); + } + + + else + { + for(k=0;k<tmpE;k++) + { + Diag = _mm_slli_si128(Diag, 2); + Diag = _mm_insert_epi16(Diag, b[lenb-1-k] != a[(i-lenb)-1+k],0); + } + + R1 = _mm_min_epi16(_mm_srli_si128(R0,2)+Side1, R1+Diag); + R1 = _mm_min_epi16(R1, R0+Down1); + + tmp = _mm_srli_si128(R1,2); + for(k=0; k < tmpE-2;k++) + tmp = _mm_srli_si128(tmp,2); + minError = min(minError, _mm_extract_epi16(tmp,0)); + } + i++; + } + //Diag + + Diag = _mm_xor_si128(Diag,Diag); + Diag = _mm_insert_epi16(Diag, minError, 0); + Diag = _mm_insert_epi16(Diag, a[lenb+e-2] != b[lenb-1], 1); + + Side1 = _mm_insert_epi16(Side1,1,0); + Side1 = _mm_insert_epi16(Side1,1,1); + + Down1 = _mm_insert_epi16(Down1, minError, 0); + Down1 = _mm_insert_epi16(Down1, 1, 1); + + R1 = _mm_min_epi16(R0+Side1, _mm_slli_si128(R1,2)+Diag); + R1 = _mm_min_epi16(R1, _mm_slli_si128(R0,2)+Down1); + + minError = min(minError, _mm_extract_epi16(R1,1)); + + Diag = _mm_insert_epi16(Diag, a[lenb+e-1] != b[lenb-1], 0); + Down1 = _mm_insert_epi16(Down1, 1, 0); + + R0 = _mm_min_epi16(R1+Down1,R0+Diag); + R0 = _mm_min_epi16(R0,_mm_srli_si128(R1,2)+Side1); + + + minError = min(minError, _mm_extract_epi16(R0,0)); + + + if(minError > mismatch) + return -1; + return minError; +} + + + +int forwardEditDistance4SSE2(char *a, int lena, char *b,int lenb) +{ + if(lenb == 0 || lena == 0) + return 0; + + int i = 0; + int j = 0; + int k = 0; + + int i0=0; + int i1=0; + int i2=0; + int i4=0; + int i5=0; + + int e = errThreshold; + + int minError = 2*e; + int index = 0; + int tmpValue = 0; + + if(lenb <= e) + { + return smallEditDistanceF(a,lena,b,lenb); + } + + + register __m128i R0, R1; + __m128i Diag; + __m128i Side1, Side2; + __m128i Down1, Down2; + __m128i tmp; + register __m128i SeqA, SeqB; + __m128i Result; + + __m128i tmpSeqA; + __m128i tmpSeqB; + + /* initialize */ + R0 = _mm_setzero_si128 (); + R1 = _mm_setzero_si128 (); + Diag = _mm_setzero_si128 (); + Side1 = _mm_setzero_si128 (); + Side2 = _mm_setzero_si128 (); + Down1 = _mm_setzero_si128 (); + Down2 = _mm_setzero_si128 (); + SeqA = _mm_setzero_si128 (); + SeqB = _mm_setzero_si128 (); + Result = _mm_setzero_si128 (); + /* end initialize */ + + R1 = _mm_xor_si128(R1, R1); + R0 = _mm_xor_si128(R0, R0); + + Diag = _mm_xor_si128(Diag, Diag); + Diag = _mm_insert_epi16(Diag,2*e,0); + + i0 = (a[0] != b[0]); + i1 = min(i0, (a[1]!=b[0]))+1; + i2 = min(i0,(a[0]!=b[1]))+1; + + i0 = min3(i0+(a[1]!=b[1]),i1+1,i2+1); + i4 = min(i1, (a[2]!=b[0])+1)+1; + i5 = min(i2, (a[0]!=b[2])+1)+1; + + R1 = _mm_insert_epi16(R1, 3, 0); + R1 = _mm_insert_epi16(R1, i1, 1); + R1 = _mm_insert_epi16(R1, i2, 2); + R1 = _mm_insert_epi16(R1, 3, 3); + + R0 = _mm_insert_epi16(R0, 4, 0); + R0 = _mm_insert_epi16(R0, i4, 1); + R0 = _mm_insert_epi16(R0, i0, 2); + R0 = _mm_insert_epi16(R0, i5, 3); + R0 = _mm_insert_epi16(R0, 4, 4); + + Side2 = _mm_xor_si128(Side2, Side2); + Down2 = _mm_xor_si128(Down2, Down2); + Down1 = _mm_xor_si128(Down1, Down1); + Side1 = _mm_xor_si128(Side1, Side1); + + Side2 = _mm_insert_epi16(Side2,2*e,0); + Down1 = _mm_insert_epi16(Down1,2*e,0); + + Side1 = _mm_insert_epi16(Side1,1,0); + + index = 0; + for(j=0; j < e; j++) + { + Side2 = _mm_slli_si128(Side2, 2); + Side2 = _mm_insert_epi16(Side2,1,0); + + Down1 = _mm_slli_si128(Down1, 2); + Down1 = _mm_insert_epi16(Down1,1,0); + + Down2 = _mm_slli_si128(Down2, 2); + Down2 = _mm_insert_epi16(Down2,1,0); + + Side1 = _mm_slli_si128(Side1, 2); + Side1 = _mm_insert_epi16(Side1,1,0); + + SeqA = _mm_slli_si128(SeqA, 2); + SeqB = _mm_slli_si128(SeqB, 2); + SeqA = _mm_insert_epi16(SeqA,a[index],0); + SeqB = _mm_insert_epi16(SeqB,b[index],0); + index++; + } + + Down2= _mm_slli_si128(Down2, 2); + Down2 = _mm_insert_epi16(Down2,2*e,0); + + index = 4; + i = 5; + + int loopEnd = 2*lenb-(e-1); + for(; i <= loopEnd ;i++) + { + //Diag = _mm_xor_si128(Diag, Diag); + if( i%2 == 0) + { + tmpSeqA = _mm_slli_si128(SeqA, 2); + tmpSeqB = _mm_slli_si128(SeqB, 2); + SeqA = _mm_insert_epi16(tmpSeqA,a[index],0); + SeqB = _mm_insert_epi16(tmpSeqB,b[index],0); + + index++; + + tmp = _mm_shufflelo_epi16(SeqB,27); + tmp = _mm_slli_si128(tmp, 2); + tmpValue = _mm_extract_epi16(tmp, 5); + tmp = _mm_insert_epi16(tmp, tmpValue, 0); + + Result = _mm_cmpeq_epi16(SeqA, tmp); + Diag = _mm_andnot_si128(Result, MASK); + + R0 = _mm_min_epi16(R1+Side2, R0+Diag); + R0 = _mm_min_epi16(R0, _mm_slli_si128(R1,2)+Down2); + + if(_mm_extract_epi16(R0, 0) > e && _mm_extract_epi16(R0, 1) > e && _mm_extract_epi16(R0, 2) > e + && _mm_extract_epi16(R0, 3) > e && _mm_extract_epi16(R0, 4) > e && _mm_extract_epi16(R1, 0) > e && + _mm_extract_epi16(R1, 1) > e && _mm_extract_epi16(R1, 2) > e && _mm_extract_epi16(R1, 3) > e) + return -1; + + if(i == 2*lenb-e) + { + tmp = _mm_srli_si128(R0,2); + for(k=0; k < e-1;k++) + tmp = _mm_srli_si128(tmp,2); + minError = _mm_extract_epi16(tmp,0); + } + + } + + else + { + Result = _mm_cmpeq_epi16(SeqA, _mm_shufflelo_epi16(SeqB,27)); + Diag = _mm_andnot_si128(Result, MASK); + + R1 = _mm_min_epi16(_mm_srli_si128(R0,2)+Side1, R1+Diag); + R1 = _mm_min_epi16(R1, R0+Down1); + + if(i >= 2*lenb-e) + { + tmp = _mm_srli_si128(R1,2); + for(k=0; k < e-2;k++) + tmp = _mm_srli_si128(tmp,2); + minError = min(minError, _mm_extract_epi16(tmp,0)); + } + } + + + } + j=0; + int tmpE = e; + for(;j<2*(e-2)+1;j++) + { + + Diag = _mm_xor_si128(Diag, Diag); + //set the first element + if(j==0) + { + for( k=0;k<=e-1;k++ ) + { + Diag = _mm_slli_si128(Diag, 2); + Diag = _mm_insert_epi16(Diag, b[lenb-1-k] != a[(i-lenb)-1+k],0); + } + + R0 = _mm_min_epi16(R1+Side2, R0+Diag); + R0 = _mm_min_epi16(R0, _mm_slli_si128(R1,2)+Down2); + + tmpE--; + + tmp = _mm_srli_si128(R0,2); + for(k=0; k < e-2;k++) + tmp = _mm_srli_si128(tmp,2); + minError = min(minError, _mm_extract_epi16(tmp,0)); + } + else if(j%2 == 0) + { + for(k=0;k<tmpE;k++) + { + Diag = _mm_slli_si128(Diag, 2); + Diag = _mm_insert_epi16(Diag, b[lenb-1-k] != a[(i-lenb)-1+k],0); + } + + R0 = _mm_min_epi16(R1+Side2, R0+Diag); + R0 = _mm_min_epi16(R0, _mm_slli_si128(R1,2)+Down2); + + tmpE--; + + tmp = _mm_srli_si128(R0,2); + for(k=0; k < tmpE-1;k++) + tmp = _mm_srli_si128(tmp,2); + minError = min(minError, _mm_extract_epi16(tmp,0)); + } + + + else + { + for(k=0;k<tmpE;k++) + { + Diag = _mm_slli_si128(Diag, 2); + Diag = _mm_insert_epi16(Diag, b[lenb-1-k] != a[(i-lenb)-1+k],0); + } + + R1 = _mm_min_epi16(_mm_srli_si128(R0,2)+Side1, R1+Diag); + R1 = _mm_min_epi16(R1, R0+Down1); + + tmp = _mm_srli_si128(R1,2); + for(k=0; k < tmpE-2;k++) + tmp = _mm_srli_si128(tmp,2); + minError = min(minError, _mm_extract_epi16(tmp,0)); + } + i++; + } + //Diag + + Diag = _mm_xor_si128(Diag,Diag); + Diag = _mm_insert_epi16(Diag, 2*e, 0); + Diag = _mm_insert_epi16(Diag, a[lenb+e-2] != b[lenb-1], 1); + + Side1 = _mm_insert_epi16(Side1,1,0); + Side1 = _mm_insert_epi16(Side1,1,1); + + Down1 = _mm_insert_epi16(Down1, 2*e, 0); + Down1 = _mm_insert_epi16(Down1, 1, 1); + + R1 = _mm_min_epi16(R0+Side1, _mm_slli_si128(R1,2)+Diag); + R1 = _mm_min_epi16(R1, _mm_slli_si128(R0,2)+Down1); + + minError = min(minError, _mm_extract_epi16(R1,1)); + + Diag = _mm_insert_epi16(Diag, a[lenb+e-1] != b[lenb-1], 0); + Down1 = _mm_insert_epi16(Down1, 1, 0); + + R0 = _mm_min_epi16(R1+Down1,R0+Diag); + R0 = _mm_min_epi16(R0,_mm_srli_si128(R1,2)+Side1); + + minError = min(minError, _mm_extract_epi16(R0,0)); + + if(minError > e) + return -1; + return minError; +} + +int forwardEditDistanceSSE2Odd(char *a, int lena, char *b,int lenb) +{ + if(lenb == 0 || lena == 0) + return 0; + + int i = 0; + int j = 0; + int k = 0; + + int e = errThreshold; + + int minError = 2*e; + + char flag = 0; + + if(lenb <= e) + { + return smallEditDistanceF(a,lena,b,lenb); + } + + + __m128i R0, R1; + __m128i Diag; + __m128i Side1, Side2; + __m128i Down1, Down2; + __m128i Error; + __m128i tmp; + + /* initialize */ + R0 = _mm_setzero_si128 (); + R1 = _mm_setzero_si128 (); + Diag = _mm_setzero_si128 (); + Side1 = _mm_setzero_si128 (); + Side2 = _mm_setzero_si128 (); + Down1 = _mm_setzero_si128 (); + Down2 = _mm_setzero_si128 (); + Error = _mm_setzero_si128 (); + tmp = _mm_setzero_si128 (); + /* end initialize */ + + R1 = _mm_xor_si128(R1, R1); + R0 = _mm_xor_si128(R0, R0); + + Diag = _mm_xor_si128(Diag, Diag); + Side1 = _mm_xor_si128(Side1, Side1); + Down1 = _mm_xor_si128(Down1, Down1); + + Diag = _mm_insert_epi16(Diag,2*e,0); + + Side1 = _mm_insert_epi16(Side1,1,0); + Side1 = _mm_insert_epi16(Side1,2*e,1); + + Down1 = _mm_insert_epi16(Down1,2*e,0); + Down1 = _mm_insert_epi16(Down1,1,1); + Down1 = _mm_insert_epi16(Down1,2*e,2); + + R0 = _mm_insert_epi16(R0,0,0); + + R1 = _mm_insert_epi16(R1,1,0); + R1 = _mm_insert_epi16(R1,1,1); + + for(i=2; i <= e; i++) + { + //set side + Side1 = _mm_slli_si128(Side1,2); + Side1 = _mm_insert_epi16(Side1,1,0); + + Down1 = _mm_insert_epi16(Down1,1,0); + Down1 = _mm_slli_si128(Down1,2); + Down1 = _mm_insert_epi16(Down1,2*e,0); + + Diag = _mm_xor_si128(Diag, Diag); + if( i%2 == 0) + { + Diag = _mm_insert_epi16(Diag,2*e,0); + + for(j=1;j<=i-1;j++) + { + Diag = _mm_slli_si128(Diag, 2); + Diag = _mm_insert_epi16(Diag, b[i/2-1+(i/2-j)] != a[i/2-1-(i/2-j)],0); + } + Diag = _mm_slli_si128(Diag, 2); + Diag = _mm_insert_epi16(Diag, 2*e,0); + + R0 = _mm_min_epi16(R1+Side1, _mm_slli_si128(R0,2)+Diag); + R0 = _mm_min_epi16(R0, _mm_slli_si128(R1,2)+Down1); + + } + + else + { + Diag = _mm_insert_epi16(Diag,2*e,0); + for(j=i/2-1;j>=-i/2;j--) + { + Diag = _mm_slli_si128(Diag, 2); + Diag = _mm_insert_epi16(Diag, b[(i+1)/2+j-1] != a[(i-1)/2-j-1],0); + } + Diag = _mm_slli_si128(Diag, 2); + Diag = _mm_insert_epi16(Diag, 2*e,0); + + R1 = _mm_min_epi16(R0+Side1, _mm_slli_si128(R1,2)+Diag); + R1 = _mm_min_epi16(R1, _mm_slli_si128(R0,2)+Down1); + + } + } + Error = _mm_xor_si128(Error, Error); + Side2 = _mm_xor_si128(Side2, Side2); + Side1 = _mm_xor_si128(Side1, Side1); + Down2 = _mm_xor_si128(Down2, Down2); + Down1 = _mm_xor_si128(Down1, Down1); + + + Error = _mm_insert_epi16(Error,e,0); + Side2 = _mm_insert_epi16(Side2,2*e,0); + Side1 = _mm_insert_epi16(Side2,2*e,0); + Down1 = _mm_insert_epi16(Down1,2*e,0); + + + for(j=0; j < e; j++) + { + Side2 = _mm_slli_si128(Side2, 2); + Side2 = _mm_insert_epi16(Side2,1,0); + + Side1 = _mm_slli_si128(Side1, 2); + Side1 = _mm_insert_epi16(Side1,1,0); + + Down1 = _mm_slli_si128(Down1, 2); + Down1 = _mm_insert_epi16(Down1,1,0); + + Down2 = _mm_slli_si128(Down2, 2); + Down2 = _mm_insert_epi16(Down2,1,0); + + Error = _mm_slli_si128(Error, 2); + Error = _mm_insert_epi16(Error, e, 0); + } + + Down2= _mm_slli_si128(Down2, 2); + Down2 = _mm_insert_epi16(Down2,2*e,0); + + for(; i <= 2*lenb-(e-1);i++) + { + flag = 0; + Diag = _mm_xor_si128(Diag, Diag); + if( i%2 == 0) + { + for(j=e/2;j>=-e/2;j--) + { + Diag = _mm_slli_si128(Diag, 2); + Diag = _mm_insert_epi16(Diag, b[i/2-1+j] != a[i/2-1-j],0); + } + + + R0 = _mm_min_epi16(_mm_srli_si128(R1,2)+Side1, R0+Diag); + R0 = _mm_min_epi16(R0, R1+Down1); + + if(_mm_extract_epi16(R0,0) <= e) + flag = 1; + + tmp = _mm_srli_si128(R0,2); + for(j=0; j < e-1;j++) + { + if(_mm_extract_epi16(tmp,0) <= e) + flag = 1; + tmp = _mm_srli_si128(tmp,2); + } + // printf("#%d %d %d\n", _mm_extract_epi16(R0,0), _mm_extract_epi16(R0,1), _mm_extract_epi16(R0,2)); + if(flag == 0) + return -1; + + if(i == 2*lenb-(e-1)) + { + tmp = _mm_srli_si128(R0,2); + for(k=0; k < e-2;k++) + tmp = _mm_srli_si128(tmp,2); + minError = _mm_extract_epi16(tmp,0); + } + + } + + else + { + for(j=e/2;j>=-e/2-1;j--) + { + Diag = _mm_slli_si128(Diag, 2); + Diag = _mm_insert_epi16(Diag, b[(i+1)/2+j-1] != a[(i)/2-j-1],0); + } + + R1 = _mm_min_epi16(R0+Side2, R1+Diag); + R1 = _mm_min_epi16(R1, _mm_slli_si128(R0,2)+Down2); + + //printf("#%d %d %d %d\n", _mm_extract_epi16(R1,0), _mm_extract_epi16(R1,1), _mm_extract_epi16(R1,2), + // _mm_extract_epi16(R1,3)); + + if(i >= 2*lenb-e) + { + tmp = _mm_srli_si128(R1,2); + for(k=0; k < e-1;k++) + tmp = _mm_srli_si128(tmp,2); + minError = min(minError, _mm_extract_epi16(tmp,0)); + } + } + } + + //first cell + Diag = _mm_xor_si128(Diag,Diag); + Diag = _mm_insert_epi16(Diag, b[lenb-3] != a[lena], 0); + Diag = _mm_insert_epi16(Diag, b[lenb-2] != a[lena-1], 1); + Diag = _mm_insert_epi16(Diag, b[lenb-1] != a[lena-2], 2); + Diag = _mm_insert_epi16(Diag, 2*e, 3); + R1 = _mm_min_epi16(R0+Side2, R1+Diag); + R1 = _mm_min_epi16(R1, _mm_slli_si128(R0,2)+Down2); + + + minError = min(minError, _mm_extract_epi16(R1,2)); + + //second cell + Diag = _mm_xor_si128(Diag,Diag); + Diag = _mm_insert_epi16(Diag, b[lenb-2] != a[lena], 0); + Diag = _mm_insert_epi16(Diag, b[lenb-1] != a[lena-1], 1); + Diag = _mm_insert_epi16(Diag, 2*e, 2); + + R0 = _mm_min_epi16(_mm_srli_si128(R1,2)+Side1, R0+Diag); + R0 = _mm_min_epi16(R0, R1+Down1); + + + minError = min(minError, _mm_extract_epi16(R0,1)); + + //third cell + Diag = _mm_xor_si128(Diag,Diag); + Diag = _mm_insert_epi16(Diag, b[lenb-2] != a[lena+1], 0); + Diag = _mm_insert_epi16(Diag, b[lenb-1] != a[lena], 1); + Diag = _mm_insert_epi16(Diag, 2*e, 2); + + R1 = _mm_min_epi16(R0+Side2, R1+Diag); + R1 = _mm_min_epi16(R1, _mm_slli_si128(R0,2)+Down2); + + + minError = min(minError, _mm_extract_epi16(R1,1)); + + //forth + Diag = _mm_xor_si128(Diag,Diag); + Diag = _mm_insert_epi16(Diag, b[lenb-1] != a[lena+1], 0); + Diag = _mm_insert_epi16(Diag, 2*e, 1); + + R0 = _mm_min_epi16(_mm_srli_si128(R1,2)+Side1, R0+Diag); + R0 = _mm_min_epi16(R0, R1+Down1); + + minError = min(minError, _mm_extract_epi16(R0,0)); + + //fifth + Diag = _mm_xor_si128(Diag,Diag); + Diag = _mm_insert_epi16(Diag, b[lenb-1] != a[lena+2], 0); + Diag = _mm_insert_epi16(Diag, 2*e, 1); + + R1 = _mm_min_epi16(R0+Side2, R1+Diag); + R1 = _mm_min_epi16(R1, _mm_slli_si128(R0,2)+Down2); + + + minError = min(minError, _mm_extract_epi16(R1,0)); + + if(minError > e) + return -1; + return minError; + +} + +int forwardEditDistanceSSE2G(char *a, int lena, char *b,int lenb) +{ + if(lenb == 0 || lena == 0) + return 0; + + int i = 0; + int j = 0; + int k = 0; + + int e = errThreshold; + + int minError = 2*e; + + char flag = 0; + + if(lenb <= e) + { + return smallEditDistanceF(a,lena,b,lenb); + } + + + __m128i R0, R1; + __m128i Diag; + __m128i Side1, Side2; + __m128i Down1, Down2; + __m128i Error; + __m128i tmp; + + /* initialize */ + R0 = _mm_setzero_si128 (); + R1 = _mm_setzero_si128 (); + Diag = _mm_setzero_si128 (); + Side1 = _mm_setzero_si128 (); + Side2 = _mm_setzero_si128 (); + Down1 = _mm_setzero_si128 (); + Down2 = _mm_setzero_si128 (); + Error = _mm_setzero_si128 (); + tmp = _mm_setzero_si128 (); + /* end initialize */ + + R1 = _mm_xor_si128(R1, R1); + R0 = _mm_xor_si128(R0, R0); + + Diag = _mm_xor_si128(Diag, Diag); + Side1 = _mm_xor_si128(Side1, Side1); + Down1 = _mm_xor_si128(Down1, Down1); + + Diag = _mm_insert_epi16(Diag,2*e,0); + + Side1 = _mm_insert_epi16(Side1,1,0); + Side1 = _mm_insert_epi16(Side1,2*e,1); + + Down1 = _mm_insert_epi16(Down1,2*e,0); + Down1 = _mm_insert_epi16(Down1,1,1); + Down1 = _mm_insert_epi16(Down1,2*e,2); + + R0 = _mm_insert_epi16(R0,0,0); + + R1 = _mm_insert_epi16(R1,1,0); + R1 = _mm_insert_epi16(R1,1,1); + + for(i=2; i <= e; i++) + { + //set side + Side1 = _mm_slli_si128(Side1,2); + Side1 = _mm_insert_epi16(Side1,1,0); + + Down1 = _mm_insert_epi16(Down1,1,0); + Down1 = _mm_slli_si128(Down1,2); + Down1 = _mm_insert_epi16(Down1,2*e,0); + + Diag = _mm_xor_si128(Diag, Diag); + if( i%2 == 0) + { + Diag = _mm_insert_epi16(Diag,2*e,0); + + for(j=1;j<=i-1;j++) + { + Diag = _mm_slli_si128(Diag, 2); + Diag = _mm_insert_epi16(Diag, b[i/2-1+(i/2-j)] != a[i/2-1-(i/2-j)],0); + } + Diag = _mm_slli_si128(Diag, 2); + Diag = _mm_insert_epi16(Diag, 2*e,0); + + R0 = _mm_min_epi16(R1+Side1, _mm_slli_si128(R0,2)+Diag); + R0 = _mm_min_epi16(R0, _mm_slli_si128(R1,2)+Down1); + } + + else + { + Diag = _mm_insert_epi16(Diag,2*e,0); + for(j=i/2-1;j>=-i/2;j--) + { + Diag = _mm_slli_si128(Diag, 2); + Diag = _mm_insert_epi16(Diag, b[(i+1)/2+j-1] != a[(i-1)/2-j-1],0); + } + Diag = _mm_slli_si128(Diag, 2); + Diag = _mm_insert_epi16(Diag, 2*e,0); + + R1 = _mm_min_epi16(R0+Side1, _mm_slli_si128(R1,2)+Diag); + R1 = _mm_min_epi16(R1, _mm_slli_si128(R0,2)+Down1); + } + } + Error = _mm_xor_si128(Error, Error); + Side2 = _mm_xor_si128(Side2, Side2); + Down2 = _mm_xor_si128(Down2, Down2); + Down1 = _mm_xor_si128(Down1, Down1); + + Error = _mm_insert_epi16(Error,e,0); + Side2 = _mm_insert_epi16(Side2,2*e,0); + Down1 = _mm_insert_epi16(Down1,2*e,0); + + + for(j=0; j < e; j++) + { + Side2 = _mm_slli_si128(Side2, 2); + Side2 = _mm_insert_epi16(Side2,1,0); + + Down1 = _mm_slli_si128(Down1, 2); + Down1 = _mm_insert_epi16(Down1,1,0); + + Down2 = _mm_slli_si128(Down2, 2); + Down2 = _mm_insert_epi16(Down2,1,0); + + Error = _mm_slli_si128(Error, 2); + Error = _mm_insert_epi16(Error, e, 0); + } + + Down2= _mm_slli_si128(Down2, 2); + Down2 = _mm_insert_epi16(Down2,2*e,0); + + for(; i <= 2*lenb-(e-1);i++) + { + flag = 0; + Diag = _mm_xor_si128(Diag, Diag); + if( i%2 == 0) + { + for(j=e/2;j>=-e/2;j--) + { + Diag = _mm_slli_si128(Diag, 2); + Diag = _mm_insert_epi16(Diag, b[i/2-1+j] != a[i/2-1-j],0); + } + + R0 = _mm_min_epi16(R1+Side2, R0+Diag); + R0 = _mm_min_epi16(R0, _mm_slli_si128(R1,2)+Down2); + + + if(_mm_extract_epi16(R0,0) <= e) + flag = 1; + + tmp = _mm_srli_si128(R0,2); + for(j=0; j < e-1;j++) + { + if(_mm_extract_epi16(tmp,0) <= e) + flag = 1; + tmp = _mm_srli_si128(tmp,2); + } + + + if(flag == 0) + return -1; + + if(i == 2*lenb-e) + { + tmp = _mm_srli_si128(R0,2); + for(k=0; k < e-1;k++) + tmp = _mm_srli_si128(tmp,2); + minError = _mm_extract_epi16(tmp,0); + } + + } + + else + { + for(j=-e/2+1;j<=e/2;j++) + { + Diag = _mm_slli_si128(Diag, 2); + Diag = _mm_insert_epi16(Diag, b[(i+1)/2-j-1] != a[(i-1)/2+j-1],0); + } + + R1 = _mm_min_epi16(_mm_srli_si128(R0,2)+Side1, R1+Diag); + R1 = _mm_min_epi16(R1, R0+Down1); + + if(i >= 2*lenb-e) + { + tmp = _mm_srli_si128(R1,2); + for(k=0; k < e-2;k++) + tmp = _mm_srli_si128(tmp,2); + minError = min(minError, _mm_extract_epi16(tmp,0)); + } + } + } + + j=0; + int tmpE = e; + for(;j<2*(e-2)+1;j++) + { + + Diag = _mm_xor_si128(Diag, Diag); + //set the first element + if(j==0) + { + for( k=0;k<=e-1;k++ ) + { + Diag = _mm_slli_si128(Diag, 2); + Diag = _mm_insert_epi16(Diag, b[lenb-1-k] != a[(i-lenb)-1+k],0); + } + + R0 = _mm_min_epi16(R1+Side2, R0+Diag); + R0 = _mm_min_epi16(R0, _mm_slli_si128(R1,2)+Down2); + + tmpE--; + + tmp = _mm_srli_si128(R0,2); + for(k=0; k < e-2;k++) + tmp = _mm_srli_si128(tmp,2); + minError = min(minError, _mm_extract_epi16(tmp,0)); + } + else if(j%2 == 0) + { + for(k=0;k<tmpE;k++) + { + Diag = _mm_slli_si128(Diag, 2); + Diag = _mm_insert_epi16(Diag, b[lenb-1-k] != a[(i-lenb)-1+k],0); + } + + R0 = _mm_min_epi16(R1+Side2, R0+Diag); + R0 = _mm_min_epi16(R0, _mm_slli_si128(R1,2)+Down2); + + tmpE--; + + tmp = _mm_srli_si128(R0,2); + for(k=0; k < tmpE-1;k++) + tmp = _mm_srli_si128(tmp,2); + minError = min(minError, _mm_extract_epi16(tmp,0)); + } + + + else + { + for(k=0;k<tmpE;k++) + { + Diag = _mm_slli_si128(Diag, 2); + Diag = _mm_insert_epi16(Diag, b[lenb-1-k] != a[(i-lenb)-1+k],0); + } + + R1 = _mm_min_epi16(_mm_srli_si128(R0,2)+Side1, R1+Diag); + R1 = _mm_min_epi16(R1, R0+Down1); + + tmp = _mm_srli_si128(R1,2); + for(k=0; k < tmpE-1;k++) + tmp = _mm_srli_si128(tmp,2); + minError = min(minError, _mm_extract_epi16(tmp,0)); + } + i++; + } + //Diag + + Diag = _mm_xor_si128(Diag,Diag); + Diag = _mm_insert_epi16(Diag, 2*e, 0); + Diag = _mm_insert_epi16(Diag, a[lenb+e-2] != b[lenb-1], 1); + + Side1 = _mm_insert_epi16(Side1,1,0); + Side1 = _mm_insert_epi16(Side1,1,1); + + Down1 = _mm_insert_epi16(Down1, 2*e, 0); + Down1 = _mm_insert_epi16(Down1, 1, 1); + + R1 = _mm_min_epi16(R0+Side1, _mm_slli_si128(R1,2)+Diag); + R1 = _mm_min_epi16(R1, _mm_slli_si128(R0,2)+Down1); + + minError = min(minError, _mm_extract_epi16(R1,1)); + + Diag = _mm_insert_epi16(Diag, a[lenb+e-1] != b[lenb-1], 1); + Down1 = _mm_insert_epi16(Down1, 1, 0); + + R0 = _mm_min_epi16(R1+Down1,R0+Diag); + R0 = _mm_min_epi16(R0,_mm_srli_si128(R1,2)+Side1); + + minError = min(minError, _mm_extract_epi16(R0,0)); + + if(minError > e) + return -1; + return minError; +} + + +int forwardEditDistance2SSE2(char *a, int lena, char *b,int lenb) +{ + if(lenb == 0 || lena == 0) + return 0; + + + + int i0 = 0; + int i1 = 0; + + + int error; //0: if the two character are equal 1: if not + + int i = 0; //loop index + + int e = 2; //error bound + + int totalError = 0; + + __m128i R0; + __m128i R1; + + __m128i Side1, Side2,Side; //side matrix + __m128i Down1, Down2,Down; //down matrix + __m128i Diag; + + __m128i tmp; + __m128i ERROR_REACH; + + /* initialize */ + R0 = _mm_setzero_si128 (); + R1 = _mm_setzero_si128 (); + Diag = _mm_setzero_si128 (); + Side1 = _mm_setzero_si128 (); + Side2 = _mm_setzero_si128 (); + Down1 = _mm_setzero_si128 (); + Down2 = _mm_setzero_si128 (); + Side = _mm_setzero_si128 (); + Down = _mm_setzero_si128 (); + tmp = _mm_setzero_si128 (); + ERROR_REACH = _mm_setzero_si128 (); + /* end initialize */ + + + if(lenb <= e) + { + return smallEditDistanceF(a,lena,b,lenb); + } + + ERROR_REACH = _mm_set_epi16(0,0,0,0,0,e,e,e); + + R0 = _mm_insert_epi16(R0,0,0); + + R1 = _mm_insert_epi16(R1,1,0); + R1 = _mm_insert_epi16(R1,1,1); + +// error = ((a[0]) != (b[0])); + + Diag = _mm_set_epi16(0,0,0,0,0,2*e,((a[0]) != (b[0])),2*e); + Side1 = _mm_set_epi16(0,0,0,0,0,2*e,1,1); + Side2 = _mm_set_epi16(0,0,0,0,0,1,1,2*e); + Down1 = _mm_set_epi16(0,0,0,0,0,2*e,1,1); + Down2 = _mm_set_epi16(0,0,0,0,0,1,1,2*e); + + tmp = _mm_slli_si128(R1,2); + + R0 = _mm_min_epi16(R1+Side1, R0+Diag); + R0 = _mm_min_epi16(R0,tmp+Down2); + + for (i = 3; i < 2*lena; i++) + { + if(i % 2 ==1) + { + + Diag = _mm_xor_si128(Diag, Diag); + error = ((a[(i+1)/2-1]) != (b[(i-1)/2-1])); + Diag = _mm_insert_epi16(Diag,error,0); + error = ((a[(i-1)/2-1]) != (b[(i+1)/2-1])); + Diag = _mm_insert_epi16(Diag,error,1); +// Diag = _mm_set_epi16(0, 0, 0, 0, 0, 0, ((a[(i-1)/2-1]) != (b[(i+1)/2-1])) ,((a[(i+1)/2-1]) != (b[(i-1)/2-1]))); + + + tmp = _mm_srli_si128(R0,2); + + R1 = _mm_min_epi16(tmp+Side1, R1+Diag); + R1 = _mm_min_epi16(R1,R0+Down1); + + if(i > 2 * lenb - 2) + { + i1 = _mm_extract_epi16(R1, 1); + totalError = min(totalError, i1); + } + } + + else if(i % 2 == 0) + { + error = ((a[i/2]) != (b[i/2-2])); + Diag = _mm_insert_epi16(Diag,error,0); + error = ((a[i/2-1]) != (b[i/2-1])); + Diag = _mm_insert_epi16(Diag,error,1); + error = ((a[i/2-2]) != (b[i/2])); + Diag = _mm_insert_epi16(Diag,error,2); + + // Diag = _mm_set_epi16(0, 0, 0, 0, 0, ((a[i/2-2]) != (b[i/2])) , ((a[i/2-1]) != (b[i/2-1])) , ((a[i/2]) != (b[i/2-2])) ); + + tmp = _mm_slli_si128(R1,2); + + R0 = _mm_min_epi16(R1+Side1, R0+Diag); + R0 = _mm_min_epi16(R0,tmp+Down2); + + tmp = _mm_sub_epi16(ERROR_REACH, R0); + i0 = _mm_movemask_epi8(tmp); + + if(i0 == 63 && _mm_extract_epi16(R1,0) > errThreshold && _mm_extract_epi16(R1,1) > errThreshold && i < 2 * lenb - 2) + return -1; + if(i == 2 * lenb - 2) { + totalError = _mm_extract_epi16(R0, 2); + } + } + } + + Down1 = _mm_insert_epi16(Down1,2*e,0); + + //fill the first part of the error + error = ((a[i/2]) != (b[i/2-2])); + Diag = _mm_insert_epi16(Diag,error,0); + error = ((a[i/2-1]) != (b[i/2-1])); + Diag = _mm_insert_epi16(Diag,error,1); + Diag = _mm_insert_epi16(Diag,2*e,2); +// Diag = _mm_set_epi16(0, 0, 0, 0, 0, 2*e , ((a[i/2-1]) != (b[i/2-1])) , ((a[i/2]) != (b[i/2-2])) ); + + R0 = _mm_min_epi16(R1+Side1, R0+Diag); + R0 = _mm_min_epi16(R0,_mm_slli_si128(R1,2)+Down1); + +// i0 = _mm_extract_epi16(R0, 0); + i1 = _mm_extract_epi16(R0, 1); + + totalError = min(totalError, i1); + + //fill the second part of the error + i++; + + Diag = _mm_xor_si128(Diag, Diag); + Diag = _mm_insert_epi16(Diag,2*e,0); + error = ((a[i/2]) != (b[lenb-1])); + Diag = _mm_insert_epi16(Diag,error,1); + Diag = _mm_insert_epi16(Diag,2*e,2); +// Diag = _mm_set_epi16(0, 0, 0, 0, 0, 2*e , ((a[i/2]) != (b[lenb-1])) , 2*e ); + + + R1 = _mm_min_epi16(R0+Side1, _mm_slli_si128(R1,2)+Diag); + R1 = _mm_min_epi16(R1,_mm_slli_si128(R0,2)+Down1); + +// i0 = _mm_extract_epi16(R1, 0); + i1 = _mm_extract_epi16(R1, 1); + + totalError = min(totalError, i1); + //fill the last the last element of the matrix + i++; + + Diag = _mm_xor_si128(Diag, Diag); + error = ((a[i/2]) != (b[lenb-1])); + Diag = _mm_insert_epi16(Diag,error,0); + +// Diag = _mm_set_epi16(0, 0, 0, 0, 0, 0 , 0 , ((a[i/2]) != (b[lenb-1])) ); + + + Down = _mm_insert_epi16(Down,1,0); + + Side = _mm_insert_epi16(Side,1,0); + + tmp = _mm_srli_si128(R1,2); + + R0 = _mm_min_epi16(R1+Down, _mm_srli_si128(R0,2)+Diag); + R0 = _mm_min_epi16(R0,tmp+Side); + + i0 = _mm_extract_epi16(R0, 0); + + totalError = min(totalError, i0); + + if(totalError > e) + return -1; + + return totalError; + +} + +int backwardEditDistance2SSE2(char *a, int lena, char *b,int lenb) +{ + if(lenb == 0 || lena == 0) + return 0; + + int i0 = 0; + int i1 = 0; + + int error; //0: if the two character are equal 1: if not + + int i = 0; //loop index + + int e = 2; //error bound + + int totalError = 0; + + __m128i R0; + __m128i R1; + + __m128i Side1, Side2,Side; //side matrix + __m128i Down1, Down2,Down; //down matrix + __m128i Diag; //diag matrix + + __m128i tmp; + __m128i ERROR_REACH; + + /* initialize */ + R0 = _mm_setzero_si128 (); + R1 = _mm_setzero_si128 (); + Diag = _mm_setzero_si128 (); + Side1 = _mm_setzero_si128 (); + Side2 = _mm_setzero_si128 (); + Side = _mm_setzero_si128 (); + Down1 = _mm_setzero_si128 (); + Down2 = _mm_setzero_si128 (); + Down = _mm_setzero_si128 (); + ERROR_REACH = _mm_setzero_si128 (); + tmp = _mm_setzero_si128 (); + /* end initialize */ + + if(lenb <= e) + { + return smallEditDistanceB(a,lena,b,lenb); + } + + + ERROR_REACH = _mm_set_epi16(0,0,0,0,0,e,e,e); + + R0 = _mm_insert_epi16(R0,0,0); + + R1 = _mm_insert_epi16(R1,1,0); + R1 = _mm_insert_epi16(R1,1,1); + + error = ((a[0]) != (b[0])); + + Diag = _mm_insert_epi16(Diag,2*e,0); + Diag = _mm_insert_epi16(Diag,error,1); + Diag = _mm_insert_epi16(Diag,2*e,2); + + Side1 = _mm_insert_epi16(Side1,1,0); + Side1 = _mm_insert_epi16(Side1,1,1); + Side1 = _mm_insert_epi16(Side1,2*e,2); + + Side2 = _mm_insert_epi16(Side2,2*e,0); + Side2 = _mm_insert_epi16(Side2,1,1); + Side2 = _mm_insert_epi16(Side2,1,2); + + Down1 = _mm_insert_epi16(Down1,1,0); + Down1 = _mm_insert_epi16(Down1,1,1); + Down1 = _mm_insert_epi16(Down1,2*e,2); + + Down2 = _mm_insert_epi16(Down2,2*e,0); + Down2 = _mm_insert_epi16(Down2,1,1); + Down2 = _mm_insert_epi16(Down2,1,2); + + tmp = _mm_slli_si128(R1,2); + + R0 = _mm_min_epi16(R1+Side1, R0+Diag); + R0 = _mm_min_epi16(R0,tmp+Down2); + +// printf("%d %d %d\n", _mm_extract_epi16(R0,0), _mm_extract_epi16(R0,1), _mm_extract_epi16(R0,2)); + for (i = 3; i < 2*lena; i++) + { + if(i % 2 ==1) + { + Diag = _mm_sub_epi8(Diag, Diag); + error = ( *(a-((i+1)/2-1)) != *(b-((i-1)/2-1)) ); + Diag = _mm_insert_epi16(Diag,error,0); + error = ( *(a-((i-1)/2-1)) != *(b-((i+1)/2-1)) ); + Diag = _mm_insert_epi16(Diag,error,1); + //printf("#%d #%d\n", _mm_extract_epi16(Diag,0), _mm_extract_epi16(Diag,1)); + tmp = _mm_srli_si128(R0,2); + + R1 = _mm_min_epi16(tmp+Side1, R1+Diag); + R1 = _mm_min_epi16(R1,R0+Down1); + + if(i > 2 * lenb - 2) { + i1 = _mm_extract_epi16(R1, 1); + totalError = min(totalError, i1); + } +// printf("%d %d\n", _mm_extract_epi16(R1,0), _mm_extract_epi16(R1,1)); + } + + else if(i % 2 == 0) + { + error = ( *(a-(i/2)) != *(b-(i/2-2)) ); + Diag = _mm_insert_epi16(Diag,error,0); + error = ( *(a-(i/2-1)) != *(b-(i/2-1)) ); + Diag = _mm_insert_epi16(Diag,error,1); + error = ( *(a-(i/2-2)) != *(b-(i/2))); + Diag = _mm_insert_epi16(Diag,error,2); + + tmp = _mm_slli_si128(R1,2); + + R0 = _mm_min_epi16(R1+Side1, R0+Diag); + R0 = _mm_min_epi16(R0,tmp+Down2); + + tmp = _mm_sub_epi16(ERROR_REACH, R0); + i0 = _mm_movemask_epi8(tmp); + + if(i0 == 63 && _mm_extract_epi16(R1,0) > errThreshold && _mm_extract_epi16(R1,1) > errThreshold && i < 2 * lenb - 2) + return -1; + + if(i == 2 * lenb - 2) { + totalError = _mm_extract_epi16(R0, 2); + } + } + } + Down1 = _mm_insert_epi16(Down1,2*e,0); + + //fill the first part of the error + error = ( *(a-(i/2)) != *(b-(i/2-2)) ); + Diag = _mm_insert_epi16(Diag,error,0); + error = ( *(a-(i/2-1)) != *(b-(i/2-1)) ); + Diag = _mm_insert_epi16(Diag,error,1); + Diag = _mm_insert_epi16(Diag,2*e,2); + + R0 = _mm_min_epi16(R1+Side1, R0+Diag); + R0 = _mm_min_epi16(R0,_mm_slli_si128(R1,2)+Down1); + + i0 = _mm_extract_epi16(R0, 0); + i1 = _mm_extract_epi16(R0, 1); + + totalError = min(totalError, i1); + + //fill the second part of the error + i++; + Diag = _mm_sub_epi8(Diag, Diag); + Diag = _mm_insert_epi16(Diag,2*e,0); + error = ( *(a-(i/2)) != *(b-(lenb-1)) ); + Diag = _mm_insert_epi16(Diag,error,1); + Diag = _mm_insert_epi16(Diag,2*e,2); + + R1 = _mm_min_epi16(R0+Side1, _mm_slli_si128(R1,2)+Diag); + R1 = _mm_min_epi16(R1,_mm_slli_si128(R0,2)+Down1); + + i0 = _mm_extract_epi16(R1, 0); + i1 = _mm_extract_epi16(R1, 1); + + totalError = min(totalError, i1); + + //fill the last the last element of the matrix + i++; + Diag = _mm_sub_epi8(Diag, Diag); + error = ( *(a-(i/2)) != *(b-(lenb-1)) ); + Diag = _mm_insert_epi16(Diag,error,0); + + Down = _mm_insert_epi16(Down,1,0); + + Side = _mm_insert_epi16(Side,1,0); + + tmp = _mm_srli_si128(R1,2); + + R0 = _mm_min_epi16(R1+Down, _mm_srli_si128(R0,2)+Diag); + R0 = _mm_min_epi16(R0,tmp+Side); + + i0 = _mm_extract_epi16(R0, 0); + + totalError = min(totalError, i0); + + if(totalError > e || totalError == 0) + return -1; + return totalError; +} + +void initBestMapping(int totalReadNumber) +{ + int i = 0; + bestHitMappingInfo = getMem(totalReadNumber * sizeof(BestFullMappingInfo)); + for(i = 0; i < totalReadNumber; i++) { + bestHitMappingInfo[i].loc = -1; + } +} + + +void finalizeBestSingleMapping() +{ + int i = 0; + char *_tmpQual, *_tmpSeq; + char rqual[SEQ_LENGTH + 1]; + rqual[SEQ_LENGTH]='\0'; + + for(i = 0; i < _msf_seqListSize; i++) + { + if(_msf_seqList[i].hits[0] != 0) + { + if (bestHitMappingInfo[i].dir) + { + reverse(_msf_seqList[i].qual, rqual, SEQ_LENGTH); + _tmpQual = rqual; + _tmpSeq = _msf_seqList[i].rseq; + } + else + { + _tmpQual = _msf_seqList[i].qual; + _tmpSeq = _msf_seqList[i].seq; + } + + + _msf_output.QNAME = _msf_seqList[i].name; + _msf_output.FLAG = 16 * bestHitMappingInfo[i].dir; + _msf_output.RNAME = bestHitMappingInfo[i].chr; + + _msf_output.POS = bestHitMappingInfo[i].loc; + _msf_output.MAPQ = 255; + _msf_output.CIGAR = bestHitMappingInfo[i].cigar ; + _msf_output.MRNAME = "*"; + _msf_output.MPOS = 0; + _msf_output.ISIZE = 0; + + + _msf_output.SEQ = _tmpSeq; + _msf_output.QUAL = _tmpQual; + + _msf_output.optSize = 2; + _msf_output.optFields = _msf_optionalFields; + + _msf_optionalFields[0].tag = "NM"; + _msf_optionalFields[0].type = 'i'; + _msf_optionalFields[0].iVal = bestHitMappingInfo[i].err; + + _msf_optionalFields[1].tag = "MD"; + _msf_optionalFields[1].type = 'Z'; + _msf_optionalFields[1].sVal = bestHitMappingInfo[i].md; + + output(_msf_output); + } + } + freeMem(bestHitMappingInfo, _msf_seqListSize * sizeof(FullMappingInfo)); +} +/**********************************************/ +int compare (const void *a, const void *b) +{ + return ((Pair *)a)->hv - ((Pair *)b)->hv; + /*char *s1 = ((Pair *)a)->hv; + char *s2 = ((Pair *)b)->hv; + int i = 0; + + int diff = 0; + int sign = 0; + + for(i = 0; i < SEQ_LENGTH; i++) + { + diff += (s1[i] != s2[i]); + if(s1[i] > s2[i]) + sign++; + else if(s1[i] < s2[i]) + sign--; + } + + return diff*sign;*/ +// return strncmp(s1, s2,SEQ_LENGTH); + +} +/**********************************************/ +void preProcessReads() +{ + int i = 0; + + _msf_sort_seqList = getMem(_msf_seqListSize * sizeof(Pair)); + for(i = 0; i < _msf_seqListSize; i++) + { + _msf_sort_seqList[i].hv = hashVal(_msf_seqList[i].seq); + + _msf_sort_seqList[i].readNumber = i; + } + + qsort(_msf_sort_seqList, _msf_seqListSize, sizeof(Pair), compare); + + /* + for(i = 0; i < _msf_seqListSize; i++) + { + //printf("%s\n", _msf_sort_seqList[i].hv); + } + */ + + _msf_map_sort_seqList = getMem(_msf_seqListSize * sizeof(int)); + + for(i = 0; i < _msf_seqListSize; i++) + _msf_map_sort_seqList[_msf_seqList[i].readNumber] = i; + +} +/**********************************************/ + +int verifySingleEnd(int index, char* seq, int offset) +{ + int curOff = 0; + int i; + + char *ref; + + int err; + int errCnt =0; + int errCntOff = 0; + int NCntOff = 0; + + ref = _msf_refGen + index - 1; + + verificationCnt++; + + for (i = 0; i < SEQ_LENGTH; i++) + { + err = *ref != *seq; + errCnt += err; + if (errCnt > errThreshold) + { + + return -1; + } + + if (i >= _msf_samplingLocs[curOff] && i <= _msf_samplingLocsEnds[curOff]) + { + errCntOff += err; + NCntOff += (*seq == 'N'); + } + else if (curOff < _msf_samplingLocsSize && i>=_msf_samplingLocs[curOff+1]) + { + + if (errCntOff == 0 && NCntOff == 0 && offset > curOff) + { + return -1; + } + + errCntOff = 0; + NCntOff = 0; + curOff++; + + if ( i >= _msf_samplingLocs[curOff]) + { + errCntOff += err; + NCntOff += (*seq == 'N'); + } + } + + ref++; + seq++; + } + return errCnt; +} + +/*********************************************/ +void initFAST(Read *seqList, int seqListSize, int *samplingLocs, int samplingLocsSize, char *genFileName) +{ + int i; + + if (_msf_optionalFields == NULL) + { + _msf_op = getMem(SEQ_LENGTH); + if (pairedEndMode) + { + _msf_optionalFields = getMem(8*sizeof(OPT_FIELDS)); + } + else + { + _msf_optionalFields = getMem(2*sizeof(OPT_FIELDS)); + } + + for (i=0; i<200;i++) + { + sprintf(_msf_numbers[i],"%d%c",i, '\0'); + } + sprintf(_msf_cigar, "%dM", SEQ_LENGTH); + } + + if (_msf_samplingLocsEnds == NULL) + { + _msf_samplingLocs = samplingLocs; + _msf_samplingLocsSize = samplingLocsSize; + + _msf_samplingLocsEnds = getMem(sizeof(int)*_msf_samplingLocsSize); + for (i=0; i<_msf_samplingLocsSize; i++) + { + _msf_samplingLocsEnds[i]=_msf_samplingLocs[i]+WINDOW_SIZE-1; + } + + _msf_seqList = seqList; + _msf_seqListSize = seqListSize; + + preProcessReads(); + + _msf_oeaMapping = getMem(_msf_seqListSize * sizeof(int)); + for(i = 0; i < _msf_seqListSize; i++) + { + _msf_oeaMapping[i] = 0; + } + + _msf_discordantMapping = getMem(_msf_seqListSize * sizeof(int)); + for(i = 0; i < _msf_seqListSize; i++) + { + _msf_discordantMapping[i] = 0; + } + + } + + if (_msf_refGenName == NULL) + { + _msf_refGenName = getMem(4*SEQ_LENGTH); + } + _msf_refGen = getRefGenome(); + _msf_refGenLength = strlen(_msf_refGen); + + _msf_refGenOffset = getRefGenomeOffset(); + snprintf(_msf_refGenName, 4*SEQ_LENGTH,"%s%c", getRefGenomeName(), '\0'); + _msf_refGenName[strlen(getRefGenomeName())] = '\0'; + + + if (_msf_verifiedLocs != NULL){ + freeMem(_msf_verifiedLocs, sizeof(int) * (_msf_refGenLength+1)); + } + + _msf_verifiedLocs = (int *) getMem(sizeof(int)*(_msf_refGenLength+1)); + + for (i=0; i<=_msf_refGenLength; i++) + _msf_verifiedLocs[i] = _msf_seqListSize*10+1; + + + + if (pairedEndMode && _msf_seqHits == NULL) + { + + _msf_mappingInfo = getMem(seqListSize * sizeof (MappingInfo)); + + for (i=0; i<seqListSize; i++) + { + //_msf_mappingInfo[i].next = getMem(sizeof(MappingLocations)); + _msf_mappingInfo[i].next = NULL; + _msf_mappingInfo[i].size = 0; + } + + _msf_seqHits = getMem((_msf_seqListSize) * sizeof(int)); + + + for (i=0; i<_msf_seqListSize; i++) + { + _msf_seqHits[i] = 0; + } + + _msf_readHasConcordantMapping = getMem(_msf_seqListSize / 2 * sizeof(char)); + for(i = 0; i < _msf_seqListSize/2; i++) + { + _msf_readHasConcordantMapping[i] = 0; + } + + initLoadingRefGenome(genFileName); + } + + if (_msf_refGenOffset == 0) + { + _msf_refGenBeg = 1; + } + else + { + _msf_refGenBeg = CONTIG_OVERLAP - SEQ_LENGTH + 2; + } + _msf_refGenEnd = _msf_refGenLength - SEQ_LENGTH + 1; + + +} +/**********************************************/ +void finalizeFAST() +{ + freeMem(_msf_seqHits, (_msf_seqListSize) * sizeof(int)); + freeMem(_msf_refGenName, 4*SEQ_LENGTH); + + + /* + int i; + for (i=0; i<_msf_rIndexSize; i++) + { + freeMem(_msf_rIndex[i].seqInfo, _msf_rIndex[i].seqInfo[0]+1); + } + freeMem(_msf_rIndex, _msf_rIndexSize);*/ + + + freeMem(_msf_map_sort_seqList, sizeof(Pair) * _msf_seqListSize); + freeMem(_msf_sort_seqList, sizeof(int) * _msf_seqListSize); + +} + +/* + Will apply the Levenshtein Dynamic programming. + Different from verifySingleEndEditDistance fucntion + as in this fucntion only one dynamic table is made while + in verifySingleEndEditDistance two dynamic table is made + for each right and left string +*/ +int editDistance(int refIndex, char *seq, int seqLength, char *matrix) +{ + int i = 0; + int size = 0; + int error = 0; + int rIndex = 0; + int directionIndex = 0; + + int min = 0; + int minIndex =0; + + int tempUp = 0; + int tempDown = 0; + + char *ref; + + int errorString = 0; + /* + 1: Up + 2: Side + 3: Diagnoal Match + 4: Diagnoal Mismatch + */ + + int upValue; + int diagValue; + int sideValue; + + ref = _msf_refGen + refIndex - 1; + + rIndex = 1; + + for(i=0; i <= errThreshold; i++) + { + score[0][i] = i; + score[i][0] = i; + } + + while(rIndex <= seqLength +errThreshold) + { + tempUp = ((rIndex - errThreshold) > 0 ? ((rIndex > seqLength) ? seqLength - errThreshold :rIndex - errThreshold) : 1 ); + tempDown = ((rIndex >= seqLength-errThreshold ) ? seqLength+1 :rIndex + errThreshold + 1); + for(i = tempUp ; i < tempDown ; i++) + { + errorString = (*(ref+rIndex-1) == *(seq+i-1)); + + upValue = score[i-1][rIndex]+1; + diagValue = score[i-1][rIndex-1]+ !errorString; + sideValue = score[i][rIndex-1]+1; + + if(i != tempUp && i != tempDown-1) + score[i][rIndex] = min3(sideValue, diagValue , upValue); + + else if( (i == ((rIndex - errThreshold) > 0 ? rIndex - errThreshold : 1)) && rIndex <= seqLength ) + score[i][rIndex] = min(sideValue, diagValue); + else if(rIndex > seqLength && (i == seqLength - errThreshold) ) + score[i][rIndex] = sideValue; + else + score[i][rIndex] = min(diagValue , upValue); + + if(i == tempUp) + error = score[i][rIndex]; + else if(error > score[i][rIndex]) + error = score[i][rIndex]; + } + rIndex++; + } + + min = score[seqLength][seqLength+errThreshold]; + minIndex = seqLength + errThreshold; + + // Find the Best error for all the possible ways. + for(i = 1; i <= 2*errThreshold; i++) + { + if(min >= score[seqLength][seqLength+errThreshold-i] && seqLength+errThreshold-i > 0) + { + min = score[seqLength][seqLength+errThreshold-i]; + minIndex = seqLength+errThreshold-i; + } + } + + error = score[seqLength][minIndex]; + + directionIndex = seqLength; + rIndex = minIndex; + while(directionIndex != 0 || rIndex != 0) + { + + if(rIndex == 0) + { + if(score[directionIndex][rIndex] - score[directionIndex-1][rIndex] == 1) + { + matrix[size] = *(seq+directionIndex-1); + size++; + matrix[size] = 'I'; + directionIndex--; + } + } + else if(directionIndex == 0) + { + if(score[directionIndex][rIndex] - score[directionIndex][rIndex-1] == 1) + { + matrix[size] = *(ref+rIndex-1); + size++; + matrix[size] = 'D'; + rIndex--; + } + } + else if(directionIndex-rIndex == errThreshold) + { + if(score[directionIndex][rIndex] - score[directionIndex-1][rIndex] == 1) + { + matrix[size] = *(seq+directionIndex-1); + size++; + matrix[size] = 'I'; + directionIndex--; + } + else if( score[directionIndex][rIndex] - score[directionIndex-1][rIndex-1] == 1 ) + { + matrix[size] = *(ref+rIndex-1); + rIndex--; + directionIndex--; + } + else + { + matrix[size] = 'M'; + rIndex--; + directionIndex--; + } + + } + else if(rIndex - directionIndex == errThreshold) + { + if(score[directionIndex][rIndex] - score[directionIndex][rIndex-1] == 1) + { + matrix[size] = *(ref+rIndex-1); + size++; + matrix[size] = 'D'; + rIndex--; + } + else if( score[directionIndex][rIndex] - score[directionIndex-1][rIndex-1] == 1 ) + { + matrix[size] = *(ref+rIndex-1); + rIndex--; + directionIndex--; + } + else + { + matrix[size] = 'M'; + rIndex--; + directionIndex--; + } + } + else + { + if(score[directionIndex][rIndex] - score[directionIndex-1][rIndex] == 1 && directionIndex != 0) + { + matrix[size] = *(seq+directionIndex-1); + size++; + matrix[size] = 'I'; + directionIndex--; + } + else if(score[directionIndex][rIndex] - score[directionIndex][rIndex-1] == 1 && rIndex != 0) + { + matrix[size] = *(ref+rIndex-1); + size++; + matrix[size] = 'D'; + rIndex--; + } + else if( score[directionIndex][rIndex] - score[directionIndex-1][rIndex-1] == 1 ) + { + matrix[size] = *(ref+rIndex-1); + rIndex--; + directionIndex--; + } + else + { + matrix[size] = 'M'; + rIndex--; + directionIndex--; + } + } + size++; + } + + matrix[size] = '\0'; + + char returnString[200]; + + returnString[0] = '\0'; + reverse(matrix, returnString, size); + sprintf(matrix, "%s", returnString); + + return error; +} + +/* + Will apply the Levenshtein Dynamic programming. + in both right and left direction as long as the + threshould error is reached or end of string length + +*/ +int msfHashVal(char *seq) +{ + int i=0; + int val=0, numericVal=0; + + while(i<6) + { + switch (seq[i]) + { + case 'A': + numericVal = 0; + break; + case 'C': + numericVal = 1; + break; + case 'G' : + numericVal = 2; + break; + case 'T': + numericVal = 3; + break; + default: + return -1; + break; + } + val = (val << 2)|numericVal; + i++; + } + return val; +} + + + +int verifySingleEndEditDistance2(int refIndex, char *lSeq, int lSeqLength, char *rSeq, int rSeqLength, int segLength, char *matrix, int *map_location, short *seqHashValue) +{ + int i = 0; + + char * ref; + char * tempref; + + int rIndex = 0; //reference Index + + int e = errThreshold; + int error = 0; + int error1 = 0; + int totalError = 0; + + + /* + 1: Up + 2: Side + 3: Diagnoal Match + 4: Diagnoal Mismatch + */ + + + int minIndex1 = 0; + int minIndex2 = 0; + + + int directionIndex = 0; + + int size = 0; + + int startIndex1 = 0; + + rIndex = 1; + + + char matrixR[200]; + char matrixL[200]; + + ref = _msf_refGen + refIndex - 1; + tempref = _msf_refGen + refIndex - 1; + + int jumpIndex = 0; + + if(rSeqLength != 0) + { + error1 = forwardEditDistance2SSE2(ref+segLength+jumpIndex, rSeqLength-jumpIndex, rSeq+jumpIndex, rSeqLength-jumpIndex); + if(error1 == -1) + return -1; + } + + + if(lSeqLength != 0) + { + error = backwardEditDistance2SSE2(ref-1, lSeqLength, lSeq+lSeqLength-1, lSeqLength); + if(error == -1) + { + return -1; + } + } + + matrixL[0] = '\0'; + matrixR[0] = '\0'; + + + ref = _msf_refGen + refIndex - 1; + + if(error1+error > errThreshold) + return -1; + + ref = _msf_refGen + refIndex - 1; + + rIndex = startIndex1+1; + + int i0 = 0; + int i1 = 0; + int i2 = 0; + + __m128i R0; + __m128i R1; + + __m128i Side1, Side2,Side; //side matrix + __m128i Down1, Down2,Down; //down matrix + __m128i Diag; // + + __m128i tmp; + + /* initialize */ + R0 = _mm_setzero_si128 (); + R1 = _mm_setzero_si128 (); + Diag = _mm_setzero_si128 (); + Side1 = _mm_setzero_si128 (); + Side2 = _mm_setzero_si128 (); + Down1 = _mm_setzero_si128 (); + Down2 = _mm_setzero_si128 (); + Down = _mm_setzero_si128 (); + Side = _mm_setzero_si128 (); + tmp = _mm_setzero_si128 (); + /* end initialize */ + + int mismatch[3] = {0,0,0}; + + if(lSeqLength != 0) + { + char *a; + char *b; + + a = ref-1; + b = lSeq+lSeqLength-1; + + R0 = _mm_insert_epi16(R0,0,0); + + score[0][0] = 0; + + R1 = _mm_insert_epi16(R1,1,0); + R1 = _mm_insert_epi16(R1,1,1); + + score[1][0] = 1; + direction1[1][0] = 1; + score[0][1] = 1; + direction1[0][1] = 2; + + mismatch[0] = ((a[0]) != (b[0])); + + Diag = _mm_insert_epi16(Diag,2*e,0); + Diag = _mm_insert_epi16(Diag,mismatch[0],1); + Diag = _mm_insert_epi16(Diag,2*e,2); + + Side1 = _mm_insert_epi16(Side1,1,0); + Side1 = _mm_insert_epi16(Side1,1,1); + Side1 = _mm_insert_epi16(Side1,2*e,2); + + Side2 = _mm_insert_epi16(Side2,2*e,0); + Side2 = _mm_insert_epi16(Side2,1,1); + Side2 = _mm_insert_epi16(Side2,1,2); + + Down1 = _mm_insert_epi16(Down1,1,0); + Down1 = _mm_insert_epi16(Down1,1,1); + Down1 = _mm_insert_epi16(Down1,2*e,2); + + Down2 = _mm_insert_epi16(Down2,2*e,0); + Down2 = _mm_insert_epi16(Down2,1,1); + Down2 = _mm_insert_epi16(Down2,1,2); + + tmp = _mm_slli_si128(R1,2); + + R0 = _mm_min_epi16(R1+Side1, R0+Diag); + R0 = _mm_min_epi16(R0,tmp+Down2); + + i0 = _mm_extract_epi16(R0, 0); + i1 = _mm_extract_epi16(R0, 1); + i2 = _mm_extract_epi16(R0, 2); + + score[0][2] = i0; + score[1][1] = i1; + score[2][0] = i2; + + direction1[0][2] = 2; + direction1[1][1] = ((mismatch[0] == 0)? 3 : 4); + direction1[2][0] = 1; + + for (i = 3; i < 2*lSeqLength; i++) + { + if(i % 2 ==1) + { + Diag = _mm_sub_epi8(Diag, Diag); + mismatch[0] = ( *(a-((i+1)/2-1)) != *(b-((i-1)/2-1)) ); + Diag = _mm_insert_epi16(Diag,mismatch[0],0); + mismatch[1] = ( *(a-((i-1)/2-1)) != *(b-((i+1)/2-1)) ); + Diag = _mm_insert_epi16(Diag,mismatch[1],1); + + tmp = _mm_srli_si128(R0,2); + + R1 = _mm_min_epi16(tmp+Side1, R1+Diag); + R1 = _mm_min_epi16(R1,R0+Down1); + + i0 = _mm_extract_epi16(R1, 0); + i1 = _mm_extract_epi16(R1, 1); + + score[i/2][i/2+1] = i0; + score[i/2+1][i/2] = i1; + + direction1[i/2][i/2+1] = (score[i/2][i/2+1]==score[i/2-1][i/2] && mismatch[0] == 0) ? 3 : + (score[i/2][i/2+1]-score[i/2-1][i/2+1]==1)? 1 : + (score[i/2][i/2+1]-score[i/2][i/2]==1) ? 2 : 4; + + direction1[i/2+1][i/2] = (score[i/2+1][i/2]==score[i/2][i/2-1] && mismatch[1] == 0) ? 3 : + (score[i/2+1][i/2]-score[i/2][i/2]==1) ? 1 : + (score[i/2+1][i/2]-score[i/2+1][i/2-1]==1)? 2 : 4; + + if(i > 2 * lSeqLength - 2) + { + error = min(error, i1); + if(error == i1) + minIndex1 = i-lSeqLength; + } + } + + else if(i % 2 == 0) + { + mismatch[0] = ( *(a-(i/2)) != *(b-(i/2-2)) ); + Diag = _mm_insert_epi16(Diag,mismatch[0],0); + mismatch[1] = ( *(a-(i/2-1)) != *(b-(i/2-1)) ); + Diag = _mm_insert_epi16(Diag,mismatch[1],1); + mismatch[2] = ( *(a-(i/2-2)) != *(b-(i/2)) ); + Diag = _mm_insert_epi16(Diag,mismatch[2],2); + + tmp = _mm_slli_si128(R1,2); + + R0 = _mm_min_epi16(R1+Side1, R0+Diag); + R0 = _mm_min_epi16(R0,tmp+Down2); + + i0 = _mm_extract_epi16(R0, 0); + i1 = _mm_extract_epi16(R0, 1); + i2 = _mm_extract_epi16(R0, 2); + + score[i/2-1][i/2+1] = i0; + score[i/2][i/2] = i1; + score[i/2+1][i/2-1] = i2; + + direction1[i/2-1][i/2+1] = (score[i/2-1][i/2+1]==score[i/2-2][i/2] && mismatch[0] == 0) ? 3 : (score[i/2-1][i/2+1]-score[i/2-1][i/2]==1) ? 2 : 4; + + direction1[i/2][i/2] = (score[i/2][i/2]==score[i/2-1][i/2-1] && mismatch[1] == 0) ? 3 : + (score[i/2][i/2]-score[i/2-1][i/2]==1) ? 1 : + (score[i/2][i/2]-score[i/2][i/2-1]==1) ? 2 : 4; + + direction1[i/2+1][i/2-1] = (score[i/2+1][i/2-1]==score[i/2][i/2-2] && mismatch[2] == 0) ? 3 : + (score[i/2+1][i/2-1]-score[i/2][i/2-1]==1) ? 1 : 4; + + if( (i/2) % segLength == 0 && i1 == 0) // the segment has been processed no need to process it again + { + return -1; + } + + if(i == 2 * lSeqLength - 2) + { + error = i2; + minIndex1 = i-lSeqLength; + } + } + } + + Down1 = _mm_insert_epi16(Down1,2*e,0); + + //fill the first part of the error + mismatch[0] = ( *(a-(i/2)) != *(b-(i/2-2)) ); + Diag = _mm_insert_epi16(Diag,mismatch[0],0); + mismatch[1] = ( *(a-(i/2-1)) !=*(b-(i/2-1)) ); + Diag = _mm_insert_epi16(Diag,mismatch[1],1); + Diag = _mm_insert_epi16(Diag,2*e,2); + + R0 = _mm_min_epi16(R1+Side1, R0+Diag); + R0 = _mm_min_epi16(R0,_mm_slli_si128(R1,2)+Down1); + + i0 = _mm_extract_epi16(R0, 0); + i1 = _mm_extract_epi16(R0, 1); + + error = min(error, i1); + if(error == i1) + minIndex1 = i-lSeqLength; + + score[i/2-1][i/2+1] = i0; + score[i/2][i/2] = i1; + + direction1[i/2-1][i/2+1] = (score[i/2-1][i/2+1]==score[i/2-2][i/2] && mismatch[0] == 0) ? 3 : + (score[i/2-1][i/2+1]-score[i/2-1][i/2]) ? 2 : 4; + + direction1[i/2][i/2] = (score[i/2][i/2]==score[i/2-1][i/2-1] && mismatch[1] == 0) ? 3 : + (score[i/2][i/2]-score[i/2-1][i/2]==1) ? 1 : + (score[i/2][i/2]-score[i/2][i/2-1]==1)? 2 : 4; + + //fill the second part of the error + i++; + Diag = _mm_sub_epi8(Diag, Diag); + Diag = _mm_insert_epi16(Diag,2*e,0); + mismatch[0] = ( *(a-(i/2)) != *(b-(lSeqLength-1)) ); + Diag = _mm_insert_epi16(Diag,mismatch[0],1); + Diag = _mm_insert_epi16(Diag,2*e,2); + + R1 = _mm_min_epi16(R0+Side1, _mm_slli_si128(R1,2)+Diag); + R1 = _mm_min_epi16(R1,_mm_slli_si128(R0,2)+Down1); + + i0 = _mm_extract_epi16(R1, 0); + i1 = _mm_extract_epi16(R1, 1); + + error = min(error, i1); + if(error == i1) + minIndex1 = i-lSeqLength; + + score[i/2-1][i/2+2] = i0; + score[i/2][i/2+1] = i1; + + direction1[i/2-1][i/2+2] = (score[i/2-1][i/2+2]==score[i/2-2][i/2+1] && mismatch[0] == 0) ? 3 : + (score[i/2-1][i/2+2]-score[i/2-1][i/2+1]==1) ? 2 : 4; + + direction1[i/2][i/2+1] = (score[i/2][i/2+1]==score[i/2-1][i/2]) ? 3 : + (score[i/2][i/2+1]-score[i/2-1][i/2+1]==1)? 1 : + (score[i/2][i/2+1]-score[i/2][i/2]==1)? 2 : 4; + + //fill the last the last element of the matrix + i++; + Diag = _mm_sub_epi8(Diag, Diag); + mismatch[0] = ( *(a-(i/2)) != *(b-(lSeqLength-1)) ); + Diag = _mm_insert_epi16(Diag,mismatch[0],0); + + Down = _mm_insert_epi16(Down,1,0); + + Side = _mm_insert_epi16(Side,1,0); + + tmp = _mm_srli_si128(R1,2); + + R0 = _mm_min_epi16(R1+Down, R0+Diag); + R0 = _mm_min_epi16(R0,tmp+Side); + + i0 = _mm_extract_epi16(R0, 0); + + error = min(error, i0); + if(error == 0) + return -1; + if(error == i0) + minIndex1 = i-lSeqLength; + if(mismatch[0] == 0) + direction1[lSeqLength][lSeqLength+errThreshold] = 3; + else + { + if(score[lSeqLength][lSeqLength+errThreshold] - score[lSeqLength][lSeqLength+errThreshold-1] == 1) + direction1[lSeqLength][lSeqLength+errThreshold] = 2; + else if(score[lSeqLength][lSeqLength+errThreshold] - score[lSeqLength-1][lSeqLength+errThreshold] == 1) + direction1[lSeqLength][lSeqLength+errThreshold] = 1; + else + direction1[lSeqLength][lSeqLength+errThreshold] = 4; + } + } + error1 = error; + error = 0; + + directionIndex = lSeqLength; + rIndex = minIndex1; + + + *map_location = ((lSeqLength == 0) ? refIndex : refIndex - rIndex) ; + + ref = ref + segLength; + + if(rSeqLength <= e) + { + char *a; + char *b; + + int tmp_index = 0; + + a = ref; + b = rSeq; + + for(tmp_index = 0; tmp_index < rSeqLength; tmp_index++) + { + matrixR[tmp_index] = (a[tmp_index]==b[tmp_index]) ? 'M' : a[tmp_index] ; + } + matrixR[tmp_index] = '\0'; + } + else if(rSeqLength != 0 && rSeqLength >= e) + { + char *a; + char *b; + + a = ref; + b = rSeq; + + R0 = _mm_sub_epi8(R0, R0); + R1 = _mm_sub_epi8(R1, R1); + + R0 = _mm_insert_epi16(R0,0,0); + + score[0][0] = 0; + + R1 = _mm_insert_epi16(R1,1,0); + R1 = _mm_insert_epi16(R1,1,1); + + score[1][0] = 1; + direction2[1][0] = 1; + score[0][1] = 1; + direction2[0][1] = 2; + + mismatch[0] = ((a[0]) != (b[0])); + + Diag = _mm_insert_epi16(Diag,2*e,0); + Diag = _mm_insert_epi16(Diag,mismatch[0],1); + Diag = _mm_insert_epi16(Diag,2*e,2); + + Side1 = _mm_insert_epi16(Side1,1,0); + Side1 = _mm_insert_epi16(Side1,1,1); + Side1 = _mm_insert_epi16(Side1,2*e,2); + + Side2 = _mm_insert_epi16(Side2,2*e,0); + Side2 = _mm_insert_epi16(Side2,1,1); + Side2 = _mm_insert_epi16(Side2,1,2); + + Down1 = _mm_insert_epi16(Down1,1,0); + Down1 = _mm_insert_epi16(Down1,1,1); + Down1 = _mm_insert_epi16(Down1,2*e,2); + + Down2 = _mm_insert_epi16(Down2,2*e,0); + Down2 = _mm_insert_epi16(Down2,1,1); + Down2 = _mm_insert_epi16(Down2,1,2); + + tmp = _mm_slli_si128(R1,2); + + R0 = _mm_min_epi16(R1+Side1, R0+Diag); + R0 = _mm_min_epi16(R0,tmp+Down2); + + i0 = _mm_extract_epi16(R0, 0); + i1 = _mm_extract_epi16(R0, 1); + i2 = _mm_extract_epi16(R0, 2); + + score[0][2] = i0; + score[1][1] = i1; + score[2][0] = i2; + + direction2[0][2] = 2; + direction2[1][1] = ((mismatch[0] == 0)? 3 : 4); + direction2[2][0] = 1; + + + for (i = 3; i < 2*rSeqLength; i++) + { + if(i % 2 ==1) + { + Diag = _mm_sub_epi8(Diag, Diag); + mismatch[0] = ((a[(i+1)/2-1]) != (b[(i-1)/2-1])); + Diag = _mm_insert_epi16(Diag,mismatch[0],0); + mismatch[1] = ((a[(i-1)/2-1]) != (b[(i+1)/2-1])); + Diag = _mm_insert_epi16(Diag,mismatch[1],1); + + tmp = _mm_srli_si128(R0,2); + + R1 = _mm_min_epi16(tmp+Side1, R1+Diag); + R1 = _mm_min_epi16(R1,R0+Down1); + + i0 = _mm_extract_epi16(R1, 0); + i1 = _mm_extract_epi16(R1, 1); + + score[i/2][i/2+1] = i0; + score[i/2+1][i/2] = i1; + + direction2[i/2][i/2+1] = (score[i/2][i/2+1]==score[i/2-1][i/2] && mismatch[0] == 0) ? 3 : + (score[i/2][i/2+1]-score[i/2-1][i/2+1]==1)? 1 : + (score[i/2][i/2+1]-score[i/2][i/2]==1) ? 2 : 4; + + direction2[i/2+1][i/2] = (score[i/2+1][i/2]==score[i/2][i/2-1] && mismatch[1] == 0) ? 3 : + (score[i/2+1][i/2]-score[i/2][i/2]==1) ? 1 : + (score[i/2+1][i/2]-score[i/2+1][i/2-1]==1)? 2 : 4; + + + if(i > 2 * rSeqLength - 2) + { + error = min(error, i1); + if(error == i1) + minIndex2 = i-rSeqLength; + } + } + + else if(i % 2 == 0) + { + mismatch[0] = ((a[i/2]) != (b[i/2-2])); + Diag = _mm_insert_epi16(Diag,mismatch[0],0); + mismatch[1] = ((a[i/2-1]) != (b[i/2-1])); + Diag = _mm_insert_epi16(Diag,mismatch[1],1); + mismatch[2] = ((a[i/2-2]) != (b[i/2])); + Diag = _mm_insert_epi16(Diag,mismatch[2],2); + + tmp = _mm_slli_si128(R1,2); + + R0 = _mm_min_epi16(R1+Side1, R0+Diag); + R0 = _mm_min_epi16(R0,tmp+Down2); + + i0 = _mm_extract_epi16(R0, 0); + i1 = _mm_extract_epi16(R0, 1); + i2 = _mm_extract_epi16(R0, 2); + + score[i/2-1][i/2+1] = i0; + score[i/2][i/2] = i1; + score[i/2+1][i/2-1] = i2; + + direction2[i/2-1][i/2+1] = (score[i/2-1][i/2+1]==score[i/2-2][i/2] && mismatch[0] == 0) ? 3 : + (score[i/2-1][i/2+1]-score[i/2-1][i/2]==1) ? 2 : 4; + + direction2[i/2][i/2] = (score[i/2][i/2]==score[i/2-1][i/2-1] && mismatch[1] == 0) ? 3 : + (score[i/2][i/2]-score[i/2-1][i/2]==1) ? 1 : + (score[i/2][i/2]-score[i/2][i/2-1]==1) ? 2 : 4; + + direction2[i/2+1][i/2-1] = (score[i/2+1][i/2-1]==score[i/2][i/2-2] && mismatch[2]==0) ? 3 : + (score[i/2+1][i/2-1]-score[i/2][i/2-1]==1) ? 1 : 4; + + + if(i == 2 * rSeqLength - 2) + { + error = i2; + minIndex2 = i-rSeqLength; + } + } + } + + Down1 = _mm_insert_epi16(Down1,2*e,0); + + //fill the first part of the error + mismatch[0] = ((a[i/2]) != (b[i/2-2])); + Diag = _mm_insert_epi16(Diag,mismatch[0],0); + mismatch[1] = ((a[i/2-1]) != (b[i/2-1])); + Diag = _mm_insert_epi16(Diag,mismatch[1],1); + Diag = _mm_insert_epi16(Diag,2*e,2); + + R0 = _mm_min_epi16(R1+Side1, R0+Diag); + R0 = _mm_min_epi16(R0,_mm_slli_si128(R1,2)+Down1); + + i0 = _mm_extract_epi16(R0, 0); + i1 = _mm_extract_epi16(R0, 1); + + error = min(error, i1); + if(error == i1) + minIndex2 = i-rSeqLength; + + score[i/2-1][i/2+1] = i0; + score[i/2][i/2] = i1; + + direction2[i/2-1][i/2+1] = (score[i/2-1][i/2+1]==score[i/2-2][i/2] && mismatch[0] == 0) ? 3 : + (score[i/2-1][i/2+1]-score[i/2-1][i/2]==1) ? 2 : 4; + + direction2[i/2][i/2] = (score[i/2][i/2]==score[i/2-1][i/2-1] && mismatch[1] == 0) ? 3 : + (score[i/2][i/2]-score[i/2-1][i/2]==1) ? 1 : + (score[i/2][i/2]-score[i/2][i/2-1]==1)? 2 : 4; + + + //fill the second part of the error + i++; + Diag = _mm_sub_epi8(Diag, Diag); + Diag = _mm_insert_epi16(Diag,2*e,0); + mismatch[0] = ((a[i/2]) != (b[rSeqLength-1])); + Diag = _mm_insert_epi16(Diag,mismatch[0],1); + Diag = _mm_insert_epi16(Diag,2*e,2); + + R1 = _mm_min_epi16(R0+Side1, _mm_slli_si128(R1,2)+Diag); + R1 = _mm_min_epi16(R1,_mm_slli_si128(R0,2)+Down1); + + i0 = _mm_extract_epi16(R1, 0); + i1 = _mm_extract_epi16(R1, 1); + + error = min(error, i1); + if(error == i1) + minIndex2 = i-rSeqLength; + + score[i/2-1][i/2+2] = i0; + score[i/2][i/2+1] = i1; + + direction2[i/2-1][i/2+2] = (score[i/2-1][i/2+2]==score[i/2-2][i/2+1] && mismatch[0] == 0) ? 3 : + (score[i/2-1][i/2+2]-score[i/2-1][i/2+1]==1) ? 2 : 3; + + direction2[i/2][i/2+1] = (score[i/2][i/2+1]==score[i/2-1][i/2] && mismatch[0] == 0) ? 3 : + (score[i/2][i/2+1]-score[i/2-1][i/2+1]==1)? 1 : + (score[i/2][i/2+1]-score[i/2][i/2]==1)? 2 : 4; + + + //fill the last the last element of the matrix + i++; + Diag = _mm_sub_epi8(Diag, Diag); + mismatch[0] = ((a[i/2]) != (b[rSeqLength-1])); + Diag = _mm_insert_epi16(Diag,mismatch[0],0); + + Down = _mm_sub_epi8(Down, Down); + Down = _mm_insert_epi16(Down,1,0); + + Side = _mm_sub_epi8(Side, Side); + Side = _mm_insert_epi16(Side,1,0); + + tmp = _mm_srli_si128(R1,2); + + R0 = _mm_min_epi16(R1+Down, R0+Diag); + R0 = _mm_min_epi16(R0,tmp+Side); + + i0 = _mm_extract_epi16(R0, 0); + + error = min(error, i0); + if(error == i0) + minIndex2 = i-rSeqLength; + + if(mismatch[0] == 0) + direction2[rSeqLength][rSeqLength+errThreshold] = 3; + else + { + if(score[rSeqLength][rSeqLength+errThreshold] - score[rSeqLength][rSeqLength+errThreshold-1] == 1) + direction2[lSeqLength][lSeqLength+errThreshold] = 2; + else if(score[rSeqLength][rSeqLength+errThreshold] - score[rSeqLength-1][rSeqLength+errThreshold] == 1) + direction2[rSeqLength][rSeqLength+errThreshold] = 1; + else + direction2[rSeqLength][rSeqLength+errThreshold] = 4; + } + + } + + totalError = error1 + error; + + size = 0; + directionIndex = rSeqLength; + rIndex = minIndex2; + + + if(rSeqLength > e) + { + while(directionIndex != 0 || rIndex != 0) + { + + if(direction2[directionIndex][rIndex] == 3) + { + matrixR[size] = 'M'; + rIndex--; + directionIndex--; + } + else if(direction2[directionIndex][rIndex] == 4) + { + matrixR[size] = *(ref+rIndex-1); + rIndex--; + directionIndex--; + } + else if(direction2[directionIndex][rIndex] == 2) + { + matrixR[size] = *(ref+rIndex-1); + size++; + matrixR[size] = 'D'; + rIndex--; + } + else + { + matrixR[size] = *(rSeq+directionIndex-1); + size++; + matrixR[size] = 'I'; + directionIndex--; + } + size++; + } + matrixR[size] = '\0'; + } + size = 0; + directionIndex = lSeqLength; + rIndex = minIndex1; + + while(directionIndex != 0 || rIndex != 0) + { + + if(direction1[directionIndex][rIndex] == 3) + { + matrixL[size] = 'M'; + rIndex--; + directionIndex--; + } + else if(direction1[directionIndex][rIndex] == 4) + { + matrixL[size] = *(tempref-rIndex); + rIndex--; + directionIndex--; + } + else if(direction1[directionIndex][rIndex] == 2) + { + matrixL[size] = 'D'; + size++; + matrixL[size] = *(tempref-rIndex); + rIndex--; + } + else + { + matrixL[size] = 'I'; + size++; + matrixL[size] = *(lSeq+lSeqLength-directionIndex); + directionIndex--; + } + + size++; + } + + matrixL[size] = '\0'; + + char middle[200]; + middle[0] = '\0'; + + for(i = 0; i < segLength; i++) + middle[i] = 'M'; + middle[segLength] = '\0'; + + char rmatrixR[200]; + + reverse(matrixR, rmatrixR, strlen(matrixR)); + + sprintf(matrix, "%s%s%s", matrixL, middle, rmatrixR); + + return totalError; +} + +int verifySingleEndEditDistance4(int refIndex, char *lSeq, int lSeqLength, char *rSeq, int rSeqLength, int segLength, char *matrix, int *map_location, short *seqHashValue) +{ + + int i = 0; + + char * ref; + char * tempref; + + int rIndex = 0; //reference Index + + int error = 0; + int error1 = 0; + + int error2 = 0; + int error3 = 0; + int totalError = 0; + int errorSegment = 0; + + int ERROR_BOUND = errThreshold; + + + /* + 1: Up + 2: Side + 3: Diagnoal Match + 4: Diagnoal Mismatch + */ + + int min = 0; + int minIndex1 = 0; + int minIndex2 = 0; + + int directionIndex = 0; + + + int size = 0; + + ref = _msf_refGen + refIndex - 1; + tempref = _msf_refGen + refIndex - 1; + + + if(lSeqLength != 0) + { + error3 = backwardEditDistance4SSE2(ref-1, lSeqLength, lSeq+lSeqLength-1, lSeqLength); + if(error3 == -1 || error3 == 0){ + return -1; + } + } + + if(rSeqLength != 0) + { + error2 = forwardEditDistance4SSE2(ref+segLength, rSeqLength, rSeq, rSeqLength); + if(error2 == -1) + return -1; + } + + if(error2 + error3 > errThreshold) + return -1; + + rIndex = 1; + + int prevError = 0; + + int tempUp = 0; + int tempDown = 0; + + int errorString = 0; + + int upValue; + int diagValue; + int sideValue; + + while(rIndex <= lSeqLength+errThreshold && lSeqLength != 0) + { + tempUp = ((rIndex - ERROR_BOUND) > 0 ? ((rIndex > lSeqLength) ? lSeqLength - ERROR_BOUND :rIndex - ERROR_BOUND) : 1 ); + tempDown = ((rIndex >= lSeqLength-ERROR_BOUND ) ? lSeqLength+1 :rIndex + ERROR_BOUND + 1); + for(i = tempUp ; i < tempDown ; i++) + { + errorString = (*(ref-rIndex) == *(lSeq+lSeqLength-i)); + + upValue = scoreB[i-1][rIndex]+1; + diagValue = scoreB[i-1][rIndex-1]+ !errorString; + sideValue = scoreB[i][rIndex-1]+1; + + if(i != tempUp && i != tempDown-1) + scoreB[i][rIndex] = min3(sideValue, diagValue , upValue); + + else if( (i == ((rIndex - ERROR_BOUND) > 0 ? rIndex - ERROR_BOUND : 1)) && rIndex <= lSeqLength ) + scoreB[i][rIndex] = min(sideValue, diagValue); + else if(rIndex > lSeqLength && (i == lSeqLength - ERROR_BOUND) ) + scoreB[i][rIndex] = sideValue; + else + scoreB[i][rIndex] = min(diagValue , upValue); + + if(i == tempUp) + error = scoreB[i][rIndex]; + else if(error > scoreB[i][rIndex]) + error = scoreB[i][rIndex]; + } + if(rIndex <= lSeqLength) + { + errorSegment = error-prevError; + } + rIndex++; + } + + if(lSeqLength != 0) + { + min = scoreB[lSeqLength][lSeqLength+errThreshold]; + minIndex1 = lSeqLength + errThreshold; + + // Find the Best error for all the possible ways. + for(i = 1; i <= 2*errThreshold; i++) + { + if(min >= scoreB[lSeqLength][lSeqLength+errThreshold-i] && lSeqLength+errThreshold-i > 0) + { + min = scoreB[lSeqLength][lSeqLength+errThreshold-i]; + minIndex1 = lSeqLength+errThreshold-i; + } + } + error = scoreB[lSeqLength][minIndex1]; + } + + error1 = error; + + error = 0; + errorSegment = 0; + + directionIndex = lSeqLength; + rIndex = minIndex1; + + + *map_location = ((lSeqLength == 0) ? refIndex : refIndex - rIndex) ; + + ref = ref + segLength; + + if(rSeqLength != 0) + { + rIndex = 1; + while(rIndex <= rSeqLength+errThreshold-error1) + { + tempUp = (rIndex - ERROR_BOUND) > 0 ? ((rIndex > rSeqLength) ? rSeqLength - ERROR_BOUND :rIndex - ERROR_BOUND) : 1; + tempDown = ((rIndex >= rSeqLength- ERROR_BOUND ) ? rSeqLength+1 :rIndex + ERROR_BOUND + 1); + for(i = tempUp; i < tempDown ; i++) + { + errorString = (*(ref+rIndex-1) == *(rSeq+i-1)); + + upValue = scoreF[i-1][rIndex]+1; + diagValue = scoreF[i-1][rIndex-1]+ !errorString; + sideValue = scoreF[i][rIndex-1]+1; + + if(i != tempUp && i != tempDown-1) + scoreF[i][rIndex] = min3(sideValue, diagValue , upValue); + else if( (i == ((rIndex - ERROR_BOUND ) > 0 ? rIndex - ERROR_BOUND : 1)) && rIndex <= rSeqLength ) + scoreF[i][rIndex] = min(sideValue, diagValue); + else if(rIndex > rSeqLength && (i == rSeqLength - ERROR_BOUND) ) + scoreF[i][rIndex] = sideValue; + else + scoreF[i][rIndex] = min(diagValue , upValue); + + if(i == tempUp) + error = scoreF[i][rIndex]; + if(error > scoreF[i][rIndex]) + error = scoreF[i][rIndex]; + } + if(rIndex <= rSeqLength) + { + errorSegment = error; + } + + rIndex++; + } + + min = scoreF[rSeqLength][rSeqLength+errThreshold-error1]; + minIndex2 = rSeqLength + errThreshold-error1; + + // Find the Best error for all the possible ways. + for(i = 1; i <= 2*(errThreshold-error1); i++) + { + if(min > scoreF[rSeqLength][rSeqLength+errThreshold-error1-i] && rSeqLength+errThreshold-error1-i > 0) + { + min = scoreF[rSeqLength][rSeqLength+errThreshold-error1-i]; + minIndex2 = rSeqLength+errThreshold-error1-i; + } + } + error = scoreF[rSeqLength][minIndex2]; + } + + totalError = error + error1; + + if(errThreshold > 4) + printf("ERROR in errorThreshold.\n"); + + + if(totalError != error2 + error3 && totalError > errThreshold) + { + printf("ErrorF=%d, ErrorB=%d Error=%d Error=%d\n", error2,error3,error1,error); + + scanf("%d", &i); + } + + char matrixR[200]; + char matrixL[200]; + + matrixR[0] = '\0'; + matrixL[0] = '\0'; + + size = 0; + directionIndex = rSeqLength; + rIndex = minIndex2; + + while(directionIndex != 0 || rIndex != 0) + { + if(directionIndex-rIndex == errThreshold) + { + if(scoreF[directionIndex][rIndex] - scoreF[directionIndex-1][rIndex] == 1) + { + matrixR[size] = *(rSeq+directionIndex-1); + size++; + matrixR[size] = 'I'; + directionIndex--; + } + else if( scoreF[directionIndex][rIndex] - scoreF[directionIndex-1][rIndex-1] == 1 ) + { + matrixR[size] = *(ref+rIndex-1); + rIndex--; + directionIndex--; + } + else + { + matrixR[size] = 'M'; + rIndex--; + directionIndex--; + } + + } + else if(rIndex - directionIndex == errThreshold) + { + if(scoreF[directionIndex][rIndex] - scoreF[directionIndex][rIndex-1] == 1) + { + matrixR[size] = *(ref+rIndex-1); + size++; + matrixR[size] = 'D'; + rIndex--; + } + else if( scoreF[directionIndex][rIndex] - scoreF[directionIndex-1][rIndex-1] == 1 ) + { + matrixR[size] = *(ref+rIndex-1); + rIndex--; + directionIndex--; + } + else + { + matrixR[size] = 'M'; + rIndex--; + directionIndex--; + } + } + else + { + if(scoreF[directionIndex][rIndex] - scoreF[directionIndex-1][rIndex] == 1 && directionIndex != 0) + { + matrixR[size] = *(rSeq+directionIndex-1); + size++; + matrixR[size] = 'I'; + directionIndex--; + } + else if(scoreF[directionIndex][rIndex] - scoreF[directionIndex][rIndex-1] == 1 && rIndex != 0) + { + matrixR[size] = *(ref+rIndex-1); + size++; + matrixR[size] = 'D'; + rIndex--; + } + else if( scoreF[directionIndex][rIndex] - scoreF[directionIndex-1][rIndex-1] == 1 ) + { + matrixR[size] = *(ref+rIndex-1); + rIndex--; + directionIndex--; + } + else + { + matrixR[size] = 'M'; + rIndex--; + directionIndex--; + } + } + size++; + } + matrixR[size] = '\0'; + + size = 0; + directionIndex = lSeqLength; + rIndex = minIndex1; + + + while(directionIndex != 0 || rIndex != 0) + { + if(directionIndex-rIndex == errThreshold) + { + if(scoreB[directionIndex][rIndex] - scoreB[directionIndex-1][rIndex] == 1) + { + matrixL[size] = 'I'; + size++; + matrixL[size] = *(lSeq+lSeqLength-directionIndex); + directionIndex--; + } + else if( scoreB[directionIndex][rIndex] - scoreB[directionIndex-1][rIndex-1] == 1 ) + { + matrixL[size] = *(tempref-rIndex); + rIndex--; + directionIndex--; + } + else + { + matrixL[size] = 'M'; + rIndex--; + directionIndex--; + } + + } + else if(rIndex - directionIndex == errThreshold) + { + if(scoreB[directionIndex][rIndex] - scoreB[directionIndex][rIndex-1] == 1) + { + matrixL[size] = 'D'; + size++; + matrixL[size] = *(tempref-rIndex); + rIndex--; + } + else if( scoreB[directionIndex][rIndex] - scoreB[directionIndex-1][rIndex-1] == 1 ) + { + matrixL[size] = *(tempref-rIndex); + rIndex--; + directionIndex--; + } + else + { + matrixL[size] = 'M'; + rIndex--; + directionIndex--; + } + } + else + { + if(scoreB[directionIndex][rIndex] - scoreB[directionIndex-1][rIndex] == 1 && directionIndex != 0) + { + matrixL[size] = 'I'; + size++; + matrixL[size] = *(lSeq+lSeqLength-directionIndex); + directionIndex--; + } + else if(scoreB[directionIndex][rIndex] - scoreB[directionIndex][rIndex-1] == 1 && rIndex != 0) + { + matrixL[size] = 'D'; + size++; + matrixL[size] = *(tempref-rIndex); + rIndex--; + } + else if( scoreB[directionIndex][rIndex] - scoreB[directionIndex-1][rIndex-1] == 1 ) + { + matrixL[size] = *(tempref-rIndex); + rIndex--; + directionIndex--; + } + else + { + matrixL[size] = 'M'; + rIndex--; + directionIndex--; + } + } + + size++; + } + + matrixL[size] = '\0'; + char middle[200]; + middle[0] = '\0'; + + for(i = 0; i < segLength; i++) + middle[i] = 'M'; + middle[segLength] = '\0'; + + char rmatrixR[200]; + + reverse(matrixR, rmatrixR, strlen(matrixR)); + + sprintf(matrix, "%s%s%s", matrixL, middle, rmatrixR); + + return totalError; + +} + +int verifySingleEndEditDistanceExtention(int refIndex, char *lSeq, int lSeqLength, char *rSeq, int rSeqLength, int segLength, + char *matrix, int *map_location, short *seqHashValue) +{ + int i = 0; + + char * ref; + char * tempref; + + int rIndex = 0; //reference Index + + int error = 0; + int error1 = 0; + + int error2 = 0; + int error3 = 0; + int totalError = 0; + int errorSegment = 0; + + int ERROR_BOUND = min(4, errThreshold); + + + /* + 1: Up + 2: Side + 3: Diagnoal Match + 4: Diagnoal Mismatch + */ + + int min = 0; + int minIndex1 = 0; + int minIndex2 = 0; + + int directionIndex = 0; + + + int size = 0; + + ref = _msf_refGen + refIndex - 1; + tempref = _msf_refGen + refIndex - 1; + + + if(lSeqLength != 0) + { + error3 = backwardEditDistanceSSE2Extention(ref-1, lSeqLength, lSeq+lSeqLength-1, lSeqLength); + if(error3 == -1){ + return -1; + } + } + + if(rSeqLength != 0) + { + error2 = forwardEditDistanceSSE2Extention(ref+segLength, rSeqLength, rSeq, rSeqLength); + if(error2 == -1) + return -1; + } + + if(error2 + error3 > errThreshold) + return -1; + + rIndex = 1; + + int prevError = 0; + + int tempUp = 0; + int tempDown = 0; + + int errorString = 0; + + int upValue; + int diagValue; + int sideValue; + if(lSeqLength > ERROR_BOUND) + { + while(rIndex <= lSeqLength+ERROR_BOUND && lSeqLength != 0) + { + tempUp = ((rIndex - ERROR_BOUND) > 0 ? ((rIndex > lSeqLength) ? lSeqLength - ERROR_BOUND :rIndex - ERROR_BOUND) : 1 ); + tempDown = ((rIndex >= lSeqLength-ERROR_BOUND ) ? lSeqLength+1 :rIndex + ERROR_BOUND + 1); + for(i = tempUp ; i < tempDown ; i++) + { + errorString = (*(ref-rIndex) == *(lSeq+lSeqLength-i)); + + upValue = scoreB[i-1][rIndex]+1; + diagValue = scoreB[i-1][rIndex-1]+ !errorString; + sideValue = scoreB[i][rIndex-1]+1; + + if(i != tempUp && i != tempDown-1) + scoreB[i][rIndex] = min3(sideValue, diagValue , upValue); + + else if( (i == ((rIndex - ERROR_BOUND) > 0 ? rIndex - ERROR_BOUND : 1)) && rIndex <= lSeqLength ) + scoreB[i][rIndex] = min(sideValue, diagValue); + else if(rIndex > lSeqLength && (i == lSeqLength - ERROR_BOUND) ) + scoreB[i][rIndex] = sideValue; + else + scoreB[i][rIndex] = min(diagValue , upValue); + + if(i == tempUp) + error = scoreB[i][rIndex]; + else if(error > scoreB[i][rIndex]) + error = scoreB[i][rIndex]; + } + if(rIndex <= lSeqLength) + { + errorSegment = error-prevError; + } + rIndex++; + } + + if(lSeqLength != 0) + { + min = scoreB[lSeqLength][lSeqLength+ERROR_BOUND]; + minIndex1 = lSeqLength + ERROR_BOUND; + + // Find the Best error for all the possible ways. + for(i = 1; i <= 2*ERROR_BOUND; i++) + { + if(min >= scoreB[lSeqLength][lSeqLength+ERROR_BOUND-i] && lSeqLength+ERROR_BOUND-i > 0) + { + min = scoreB[lSeqLength][lSeqLength+ERROR_BOUND-i]; + minIndex1 = lSeqLength+ERROR_BOUND-i; + } + } + error = scoreB[lSeqLength][minIndex1]; + } + } + else + { + int j = 0; + for(i = 1; i <= lSeqLength; i++) + { + for(j = 1; j <= lSeqLength; j++) + { + scoreB[i][j] = min3(scoreB[i-1][j-1]+ (*(ref-j) != *(lSeq+lSeqLength-i) ),scoreB[i][j-1]+1 ,scoreB[i-1][j]+1); + } + } + error = scoreB[lSeqLength][lSeqLength]; + minIndex1 = lSeqLength; + + } + error1 = error; + + error = 0; + errorSegment = 0; + + directionIndex = lSeqLength; + rIndex = minIndex1; + + *map_location = ((lSeqLength == 0) ? refIndex : refIndex - rIndex) ; + + ref = ref + segLength; + + if(rSeqLength != 0 && rSeqLength > ERROR_BOUND) + { + ERROR_BOUND = min(ERROR_BOUND, rSeqLength); + + if(rSeqLength == ERROR_BOUND) + { + for(i=0; i < 2*ERROR_BOUND; i++) + scoreF[0][i] = i; + } + + rIndex = 1; + while(rIndex <= rSeqLength+ERROR_BOUND) + { + tempUp = (rIndex - ERROR_BOUND) > 0 ? ((rIndex > rSeqLength) ? rSeqLength - ERROR_BOUND :rIndex - ERROR_BOUND) : 1; + tempDown = ((rIndex >= rSeqLength- ERROR_BOUND ) ? rSeqLength+1 :rIndex + ERROR_BOUND + 1); + for(i = tempUp; i < tempDown ; i++) + { + errorString = (*(ref+rIndex-1) == *(rSeq+i-1)); + upValue = scoreF[i-1][rIndex]+1; + diagValue = scoreF[i-1][rIndex-1]+ !errorString; + sideValue = scoreF[i][rIndex-1]+1; + + if(i != tempUp && i != tempDown-1) + scoreF[i][rIndex] = min3(sideValue, diagValue , upValue); + else if( (i == ((rIndex - ERROR_BOUND ) > 0 ? rIndex - ERROR_BOUND : 1)) && rIndex <= rSeqLength ) + scoreF[i][rIndex] = min(sideValue, diagValue); + else if(rIndex > rSeqLength && (i == rSeqLength - ERROR_BOUND) ) + scoreF[i][rIndex] = sideValue; + else + scoreF[i][rIndex] = min(diagValue , upValue); + + if(i == tempUp) + error = scoreF[i][rIndex]; + if(error > scoreF[i][rIndex]) + error = scoreF[i][rIndex]; + } + if(rIndex <= rSeqLength) + { + errorSegment = error; + } + rIndex++; + } + min = scoreF[rSeqLength][rSeqLength+ERROR_BOUND]; + minIndex2 = rSeqLength + ERROR_BOUND; + + // Find the Best error for all the possible ways. + for(i = 1; i <= 2*ERROR_BOUND; i++) + { + if(min > scoreF[rSeqLength][rSeqLength+ERROR_BOUND-i] && rSeqLength+ERROR_BOUND-i > 0) + { + min = scoreF[rSeqLength][rSeqLength+ERROR_BOUND-i]; + minIndex2 = rSeqLength+ERROR_BOUND-i; + } + } + error = scoreF[rSeqLength][minIndex2]; + } + else + { + int j = 0; + for(i = 1; i <= rSeqLength; i++) + { + for(j = 1; j <= rSeqLength; j++) + { + scoreF[i][j] = min3(scoreF[i-1][j-1]+ (*(ref+j-1) != *(rSeq+i-1) ),scoreF[i][j-1]+1 ,scoreF[i-1][j]+1); + } + } + error = scoreF[rSeqLength][rSeqLength]; + minIndex2 = rSeqLength; + } + + totalError = error + error1; + + if(totalError != error2+error3) + { + for(i = 0; i < lSeqLength; i++) + printf("%c", *(tempref-1-i)); + printf("\n"); + for(i = 0; i < lSeqLength; i++) + printf("%c", *(lSeq+i)); + printf("\n"); + + for(i = 0; i < rSeqLength; i++) + printf("%c", *(tempref+segLength+i)); + printf("\n"); + + for(i = 0; i < rSeqLength; i++) + printf("%c", *(rSeq+i)); + printf("\n"); + + printf("ERROR=%d\n", totalError); + printf("ERROR_SSE=%d\n", error3+error2); + + printf("ERROR_SSE_back=%d E_SSE_forw=%d\n", error3, error2); + printf("ERROR_back=%d E_forw=%d\n", error1, error); + + } + + char matrixR[200]; + char matrixL[200]; + + matrixR[0] = '\0'; + matrixL[0] = '\0'; + + size = 0; + directionIndex = rSeqLength; + rIndex = minIndex2; + + + while(directionIndex != 0 || rIndex != 0) + { + if(directionIndex-rIndex == errThreshold) + { + if(scoreF[directionIndex][rIndex] - scoreF[directionIndex-1][rIndex] == 1) + { + matrixR[size] = *(rSeq+directionIndex-1); + size++; + matrixR[size] = 'I'; + directionIndex--; + } + else if( scoreF[directionIndex][rIndex] - scoreF[directionIndex-1][rIndex-1] == 1 ) + { + matrixR[size] = *(ref+rIndex-1); + rIndex--; + directionIndex--; + } + else + { + matrixR[size] = 'M'; + rIndex--; + directionIndex--; + } + + } + else if(rIndex - directionIndex == errThreshold) + { + if(scoreF[directionIndex][rIndex] - scoreF[directionIndex][rIndex-1] == 1) + { + matrixR[size] = *(ref+rIndex-1); + size++; + matrixR[size] = 'D'; + rIndex--; + } + else if( scoreF[directionIndex][rIndex] - scoreF[directionIndex-1][rIndex-1] == 1 ) + { + matrixR[size] = *(ref+rIndex-1); + rIndex--; + directionIndex--; + } + else + { + matrixR[size] = 'M'; + rIndex--; + directionIndex--; + } + } + else + { + if(scoreF[directionIndex][rIndex] - scoreF[directionIndex-1][rIndex] == 1 && directionIndex != 0) + { + matrixR[size] = *(rSeq+directionIndex-1); + size++; + matrixR[size] = 'I'; + directionIndex--; + } + else if(scoreF[directionIndex][rIndex] - scoreF[directionIndex][rIndex-1] == 1 && rIndex != 0) + { + matrixR[size] = *(ref+rIndex-1); + size++; + matrixR[size] = 'D'; + rIndex--; + } + else if( scoreF[directionIndex][rIndex] - scoreF[directionIndex-1][rIndex-1] == 1 ) + { + matrixR[size] = *(ref+rIndex-1); + rIndex--; + directionIndex--; + } + else + { + matrixR[size] = 'M'; + rIndex--; + directionIndex--; + } + } + size++; + } + matrixR[size] = '\0'; + + size = 0; + directionIndex = lSeqLength; + rIndex = minIndex1; + + + while(directionIndex != 0 || rIndex != 0) + { + if(directionIndex-rIndex == errThreshold) + { + if(scoreB[directionIndex][rIndex] - scoreB[directionIndex-1][rIndex] == 1) + { + matrixL[size] = 'I'; + size++; + matrixL[size] = *(lSeq+lSeqLength-directionIndex); + directionIndex--; + } + else if( scoreB[directionIndex][rIndex] - scoreB[directionIndex-1][rIndex-1] == 1 ) + { + matrixL[size] = *(tempref-rIndex); + rIndex--; + directionIndex--; + } + else + { + matrixL[size] = 'M'; + rIndex--; + directionIndex--; + } + + } + else if(rIndex - directionIndex == errThreshold) + { + if(scoreB[directionIndex][rIndex] - scoreB[directionIndex][rIndex-1] == 1) + { + matrixL[size] = 'D'; + size++; + matrixL[size] = *(tempref-rIndex); + rIndex--; + } + else if( scoreB[directionIndex][rIndex] - scoreB[directionIndex-1][rIndex-1] == 1 ) + { + matrixL[size] = *(tempref-rIndex); + rIndex--; + directionIndex--; + } + else + { + matrixL[size] = 'M'; + rIndex--; + directionIndex--; + } + } + else + { + if(scoreB[directionIndex][rIndex] - scoreB[directionIndex-1][rIndex] == 1 && directionIndex != 0) + { + matrixL[size] = 'I'; + size++; + matrixL[size] = *(lSeq+lSeqLength-directionIndex); + directionIndex--; + } + else if(scoreB[directionIndex][rIndex] - scoreB[directionIndex][rIndex-1] == 1 && rIndex != 0) + { + matrixL[size] = 'D'; + size++; + matrixL[size] = *(tempref-rIndex); + rIndex--; + } + else if( scoreB[directionIndex][rIndex] - scoreB[directionIndex-1][rIndex-1] == 1 ) + { + matrixL[size] = *(tempref-rIndex); + rIndex--; + directionIndex--; + } + else + { + matrixL[size] = 'M'; + rIndex--; + directionIndex--; + } + } + size++; + } + matrixL[size] = '\0'; + + char middle[200]; + middle[0] = '\0'; + for(i = 0; i < segLength; i++) + middle[i] = 'M'; + middle[segLength] = '\0'; + + char rmatrixR[200]; + + reverse(matrixR, rmatrixR, strlen(matrixR)); + + sprintf(matrix, "%s%s%s", matrixL, middle, rmatrixR); + + + return totalError; + +} + + +int verifySingleEndEditDistance(int refIndex, char *lSeq, int lSeqLength, char *rSeq, int rSeqLength, int segLength, char *matrix, int *map_location, short *seqHashValue) +{ + + int i = 0; + + char * ref; + char * tempref; + + int rIndex = 0; //reference Index + + int error = 0; + int error1 = 0; + + int error2 = 0; + int error3 = 0; + + int totalError = 0; + int errorSegment = 0; + + int ERROR_BOUND = errThreshold; + + /* + 1: Up + 2: Side + 3: Diagnoal Match + 4: Diagnoal Mismatch + */ + + int min = 0; + int minIndex1 = 0; + int minIndex2 = 0; + + int directionIndex = 0; + + + int size = 0; + + ref = _msf_refGen + refIndex - 1; + tempref = _msf_refGen + refIndex - 1; + + + if(rSeqLength != 0) + { + if(errThreshold %2 == 1) + error2 = forwardEditDistanceSSE2Odd(ref+segLength, rSeqLength, rSeq, rSeqLength); + else + error2 = forwardEditDistanceSSE2G(ref+segLength, rSeqLength, rSeq, rSeqLength); + if(error2 == -1) + return -1; + } + + if(lSeqLength != 0) + { + if(errThreshold % 2 == 1) + error3 = backwardEditDistanceSSE2Odd(ref-1, lSeqLength, lSeq+lSeqLength-1, lSeqLength); + else + error3 = backwardEditDistanceSSE2G(ref-1, lSeqLength, lSeq+lSeqLength-1, lSeqLength); + if(error3 == -1 || error3 == 0){ + return -1; + } + } + + if(error3 + error2 > errThreshold) + return -1; + + for(i = 0 ; i < errThreshold + 1; i++) + { + scoreB[0][i] = i; + scoreB[i][0] = i; + } + + rIndex = 1; + int prevError = 0; + + int tempUp = 0; + int tempDown = 0; + + int errorString = 0; + + int upValue; + int diagValue; + int sideValue; + + while(rIndex <= lSeqLength+errThreshold && lSeqLength != 0) + { + tempUp = ((rIndex - ERROR_BOUND) > 0 ? ((rIndex > lSeqLength) ? lSeqLength - ERROR_BOUND :rIndex - ERROR_BOUND) : 1 ); + tempDown = ((rIndex >= lSeqLength-ERROR_BOUND ) ? lSeqLength+1 :rIndex + ERROR_BOUND + 1); + for(i = tempUp ; i < tempDown ; i++) + { + errorString = (*(ref-rIndex) == *(lSeq+lSeqLength-i)); + + upValue = scoreB[i-1][rIndex]+1; + diagValue = scoreB[i-1][rIndex-1]+ !errorString; + sideValue = scoreB[i][rIndex-1]+1; + + if(i != tempUp && i != tempDown-1) + scoreB[i][rIndex] = min3(sideValue, diagValue , upValue); + + else if( (i == ((rIndex - ERROR_BOUND) > 0 ? rIndex - ERROR_BOUND : 1)) && rIndex <= lSeqLength ) + scoreB[i][rIndex] = min(sideValue, diagValue); + else if(rIndex > lSeqLength && (i == lSeqLength - ERROR_BOUND) ) + scoreB[i][rIndex] = sideValue; + else + scoreB[i][rIndex] = min(diagValue , upValue); + + if(i == tempUp) + error = scoreB[i][rIndex]; + else if(error > scoreB[i][rIndex]) + error = scoreB[i][rIndex]; + } + if(rIndex <= lSeqLength) + { + errorSegment = error-prevError; + } + rIndex++; + } + if(lSeqLength != 0) + { + min = scoreB[lSeqLength][lSeqLength+errThreshold]; + minIndex1 = lSeqLength + errThreshold; + + // Find the Best error for all the possible ways. + for(i = 1; i <= 2*errThreshold; i++) + { + if(min >= scoreB[lSeqLength][lSeqLength+errThreshold-i] && lSeqLength+errThreshold-i > 0) + { + min = scoreB[lSeqLength][lSeqLength+errThreshold-i]; + minIndex1 = lSeqLength+errThreshold-i; + } + } + error = scoreB[lSeqLength][minIndex1]; + } + + error1 = error; + + error = 0; + errorSegment = 0; + + directionIndex = lSeqLength; + rIndex = minIndex1; + + *map_location = ((lSeqLength == 0) ? refIndex : refIndex - rIndex) ; + + ref = ref + segLength; + + if(rSeqLength != 0) + { + for(i = 0 ; i < errThreshold + 1; i++) + { + scoreF[0][i] = i; + scoreF[i][0] = i; + } + + + rIndex = 1; + while(rIndex <= rSeqLength+errThreshold-error1) + { + tempUp = (rIndex - ERROR_BOUND) > 0 ? ((rIndex > rSeqLength) ? rSeqLength - ERROR_BOUND :rIndex - ERROR_BOUND) : 1; + tempDown = ((rIndex >= rSeqLength- ERROR_BOUND ) ? rSeqLength+1 :rIndex + ERROR_BOUND + 1); + for(i = tempUp; i < tempDown ; i++) + { + errorString = (*(ref+rIndex-1) == *(rSeq+i-1)); + + upValue = scoreF[i-1][rIndex]+1; + diagValue = scoreF[i-1][rIndex-1]+ !errorString; + sideValue = scoreF[i][rIndex-1]+1; + + if(i != tempUp && i != tempDown-1) + scoreF[i][rIndex] = min3(sideValue, diagValue , upValue); + else if( (i == ((rIndex - ERROR_BOUND ) > 0 ? rIndex - ERROR_BOUND : 1)) && rIndex <= rSeqLength ) + scoreF[i][rIndex] = min(sideValue, diagValue); + else if(rIndex > rSeqLength && (i == rSeqLength - ERROR_BOUND) ) + scoreF[i][rIndex] = sideValue; + else + scoreF[i][rIndex] = min(diagValue , upValue); + + if(i == tempUp) + error = scoreF[i][rIndex]; + if(error > scoreF[i][rIndex]) + error = scoreF[i][rIndex]; + } + if(rIndex <= rSeqLength) + { + errorSegment = error; + } + rIndex++; + } + + min = scoreF[rSeqLength][rSeqLength+errThreshold-error1]; + minIndex2 = rSeqLength + errThreshold-error1; + + // Find the Best error for all the possible ways. + for(i = 1; i <= 2*(errThreshold-error1); i++) + { + if(min > scoreF[rSeqLength][rSeqLength+errThreshold-error1-i] && rSeqLength+errThreshold-error1-i > 0) + { + min = scoreF[rSeqLength][rSeqLength+errThreshold-error1-i]; + minIndex2 = rSeqLength+errThreshold-error1-i; + } + } + error = scoreF[rSeqLength][minIndex2]; + } + + totalError = error + error1; + + + if(totalError != error2 + error3 && totalError > errThreshold) + { + for(i = 0; i < lSeqLength; i++) + printf("%c", *(tempref-1-i)); + printf("\n"); + for(i = 0; i < lSeqLength; i++) + printf("%c", *(lSeq+i)); + printf("\n"); + + for(i = 0; i < rSeqLength; i++) + printf("%c", *(tempref+segLength+i)); + printf("\n"); + + for(i = 0; i < rSeqLength; i++) + printf("%c", *(rSeq+i)); + printf("\n"); + + + printf("SSEF=%d SSEB%d\n", error2, error3); + printf("F=%d B=%d\n", error, error1); + scanf("%d", &i); + } + + char matrixR[200]; + char matrixL[200]; + + matrixR[0] = '\0'; + matrixL[0] = '\0'; + + size = 0; + directionIndex = rSeqLength; + rIndex = minIndex2; + + while(directionIndex != 0 || rIndex != 0) + { + if(directionIndex-rIndex == errThreshold) + { + if(scoreF[directionIndex][rIndex] - scoreF[directionIndex-1][rIndex] == 1) + { + matrixR[size] = *(rSeq+directionIndex-1); + size++; + matrixR[size] = 'I'; + directionIndex--; + } + else if( scoreF[directionIndex][rIndex] - scoreF[directionIndex-1][rIndex-1] == 1 ) + { + matrixR[size] = *(ref+rIndex-1); + rIndex--; + directionIndex--; + } + else + { + matrixR[size] = 'M'; + rIndex--; + directionIndex--; + } + + } + else if(rIndex - directionIndex == errThreshold) + { + if(scoreF[directionIndex][rIndex] - scoreF[directionIndex][rIndex-1] == 1) + { + matrixR[size] = *(ref+rIndex-1); + size++; + matrixR[size] = 'D'; + rIndex--; + } + else if( scoreF[directionIndex][rIndex] - scoreF[directionIndex-1][rIndex-1] == 1 ) + { + matrixR[size] = *(ref+rIndex-1); + rIndex--; + directionIndex--; + } + else + { + matrixR[size] = 'M'; + rIndex--; + directionIndex--; + } + } + else + { + if(scoreF[directionIndex][rIndex] - scoreF[directionIndex-1][rIndex] == 1 && directionIndex != 0) + { + matrixR[size] = *(rSeq+directionIndex-1); + size++; + matrixR[size] = 'I'; + directionIndex--; + } + else if(scoreF[directionIndex][rIndex] - scoreF[directionIndex][rIndex-1] == 1 && rIndex != 0) + { + matrixR[size] = *(ref+rIndex-1); + size++; + matrixR[size] = 'D'; + rIndex--; + } + else if( scoreF[directionIndex][rIndex] - scoreF[directionIndex-1][rIndex-1] == 1 ) + { + matrixR[size] = *(ref+rIndex-1); + rIndex--; + directionIndex--; + } + else + { + matrixR[size] = 'M'; + rIndex--; + directionIndex--; + } + } + size++; + } + matrixR[size] = '\0'; + + size = 0; + directionIndex = lSeqLength; + rIndex = minIndex1; + + + while(directionIndex != 0 || rIndex != 0) + { + if(directionIndex-rIndex == errThreshold) + { + if(scoreB[directionIndex][rIndex] - scoreB[directionIndex-1][rIndex] == 1) + { + matrixL[size] = 'I'; + size++; + matrixL[size] = *(lSeq+lSeqLength-directionIndex); + directionIndex--; + } + else if( scoreB[directionIndex][rIndex] - scoreB[directionIndex-1][rIndex-1] == 1 ) + { + matrixL[size] = *(tempref-rIndex); + rIndex--; + directionIndex--; + } + else + { + matrixL[size] = 'M'; + rIndex--; + directionIndex--; + } + + } + else if(rIndex - directionIndex == errThreshold) + { + if(scoreB[directionIndex][rIndex] - scoreB[directionIndex][rIndex-1] == 1) + { + matrixL[size] = 'D'; + size++; + matrixL[size] = *(tempref-rIndex); + rIndex--; + } + else if( scoreB[directionIndex][rIndex] - scoreB[directionIndex-1][rIndex-1] == 1 ) + { + matrixL[size] = *(tempref-rIndex); + rIndex--; + directionIndex--; + } + else + { + matrixL[size] = 'M'; + rIndex--; + directionIndex--; + } + } + else + { + if(scoreB[directionIndex][rIndex] - scoreB[directionIndex-1][rIndex] == 1 && directionIndex != 0) + { + matrixL[size] = 'I'; + size++; + matrixL[size] = *(lSeq+lSeqLength-directionIndex); + directionIndex--; + } + else if(scoreB[directionIndex][rIndex] - scoreB[directionIndex][rIndex-1] == 1 && rIndex != 0) + { + matrixL[size] = 'D'; + size++; + matrixL[size] = *(tempref-rIndex); + rIndex--; + } + else if( scoreB[directionIndex][rIndex] - scoreB[directionIndex-1][rIndex-1] == 1 ) + { + matrixL[size] = *(tempref-rIndex); + rIndex--; + directionIndex--; + } + else + { + matrixL[size] = 'M'; + rIndex--; + directionIndex--; + } + } + size++; + } + matrixL[size] = '\0'; + char middle[200]; + middle[0] = '\0'; + for(i = 0; i < segLength; i++) + middle[i] = 'M'; + middle[segLength] = '\0'; + + char rmatrixR[200]; + + reverse(matrixR, rmatrixR, strlen(matrixR)); + + sprintf(matrix, "%s%s%s", matrixL, middle, rmatrixR); + + return totalError; +} + + +int addCigarSize(int cnt){ + if (cnt<10) return 1; + else if (cnt < 100) return 2; + return 3; +} + +/* + Generate Cigar from the back tracking matrix +*/ +void generateCigar(char *matrix, int matrixLength, char *cigar) +{ + int i = 0; + + int counterM=0; + int counterI=0; + int counterD=0; + + int cigarSize = 0; + + cigar[0] = '\0'; + + while(i < matrixLength) + { + if(matrix[i]=='M') + { + counterM++; + if(counterI != 0) + { + sprintf(cigar, "%s%dI", cigar, counterI); + cigarSize += addCigarSize(counterI) + 1; + cigar[cigarSize] = '\0'; + counterI=0; + } + else if(counterD != 0) + { + sprintf(cigar, "%s%dD", cigar, counterD); + cigarSize += addCigarSize(counterD) + 1; + cigar[cigarSize] = '\0'; + counterD=0; + } + } + else if(matrix[i] == 'I') + { + if(counterM != 0) + { + sprintf(cigar, "%s%dM", cigar, counterM); + cigarSize += addCigarSize(counterM) + 1; + cigar[cigarSize] = '\0'; + counterM = 0; + } + else if(counterD != 0) + { + sprintf(cigar, "%s%dD", cigar, counterD); + cigarSize += addCigarSize(counterD) + 1; + cigar[cigarSize] = '\0'; + counterD=0; + } + counterI++; + i++; + + } + else if (matrix[i] == 'D') + { + if(counterM != 0) + { + sprintf(cigar, "%s%dM", cigar, counterM); + cigarSize += addCigarSize(counterM) + 1; + cigar[cigarSize] = '\0'; + counterM = 0; + } + else if(counterI != 0) + { + sprintf(cigar, "%s%dI", cigar, counterI); + cigarSize += addCigarSize(counterI) + 1; + cigar[cigarSize] = '\0'; + counterI=0; + } + + counterD++; + i++; + + } + else + { + counterM++; + if(counterI != 0) + { + sprintf(cigar, "%s%dI", cigar, counterI); + cigarSize += addCigarSize(counterI) + 1; + cigar[cigarSize] = '\0'; + counterI=0; + } + else if(counterD != 0) + { + sprintf(cigar, "%s%dD", cigar, counterD); + cigarSize += addCigarSize(counterD) + 1; + cigar[cigarSize] = '\0'; + counterD=0; + } + } + i++; + } + + if(counterM != 0) + { + sprintf(cigar, "%s%dM", cigar, counterM); + cigarSize += addCigarSize(counterM) + 1; + cigar[cigarSize] = '\0'; + counterM = 0; + } + else if(counterI != 0) + { + sprintf(cigar, "%s%dI", cigar, counterI); + cigarSize += addCigarSize(counterI) + 1; + cigar[cigarSize] = '\0'; + counterI = 0; + } + else if(counterD != 0) + { + sprintf(cigar, "%s%dD", cigar, counterD); + cigarSize += addCigarSize(counterD) + 1; + cigar[cigarSize] = '\0'; + counterD = 0; + } + + cigar[cigarSize] = '\0'; +} + +/* + Creates the Cigar output from the mismatching positions format [0-9]+(([ACTGN]|\^[ACTGN]+)[0-9]+)* +*/ +void generateCigarFromMD(char *mismatch, int mismatchLength, char *cigar) +{ + int i = 0; + int j = 0; + + int start = 0; + int cigarSize = 0; + + cigar[0] = '\0'; + + while(i < mismatchLength) + { + if(mismatch[i] >= '0' && mismatch[i] <= '9') + { + start = i; + + while(mismatch[i] >= '0' && mismatch[i] <= '9' && i < mismatchLength) + i++; + + int value = atoi(mismatch+start); + for(j = 0; j < value-1; j++) + { + cigar[cigarSize] = 'M'; + cigarSize++; + } + cigar[cigarSize] = 'M'; + } + else if(mismatch[i] == '^') + { + cigar[cigarSize] = 'I'; + i++; + } + else if(mismatch[i] == '\'') + { + cigar[cigarSize] = 'D'; + i++; + } + else + { + cigar[cigarSize] = 'M'; + cigarSize++; + } + cigarSize++; + i++; + } + cigar[cigarSize] = '\0'; +} + +void generateSNPSAM(char *matrix, int matrixLength, char *outputSNP) +{ + + int i = 0; + + int counterM = 0; + int counterD = 0; + + char delete[100]; + + int snpSize = 0; + + outputSNP[0] = '\0'; + delete[0] = '\0'; + + + while(i < matrixLength) + { + if(matrix[i]=='M') + { + counterM++; + if(counterD != 0) + { + delete[counterD] = '\0'; + counterD=0; + sprintf(outputSNP, "%s^%s", outputSNP,delete); + snpSize += strlen(delete) + 1; + outputSNP[snpSize] = '\0'; + delete[0] = '\0'; + } + } + else if(matrix[i] == 'D') + { + if(counterM != 0) + { + sprintf(outputSNP, "%s%d", outputSNP, counterM); + snpSize += addCigarSize(counterM); + outputSNP[snpSize] = '\0'; + counterM=0; + delete[counterD] = matrix[i+1]; + i++; + counterD++; + } + else if(counterD != 0) + { + delete[counterD] = matrix[i+1]; + counterD++; + i++; + } + else + { + delete[counterD] = matrix[i+1]; + counterD++; + i++; + } + } + else if(matrix[i] == 'I') + { + if(counterM != 0) + { + // sprintf(outputSNP, "%s%d\0", outputSNP, counterM); + //counterM++; + } + else if(counterD != 0) + { + delete[counterD] = '\0'; + sprintf(outputSNP, "%s^%s", outputSNP, delete); + snpSize += strlen(delete) + 1; + outputSNP[snpSize] = '\0'; + counterD = 0; + delete[0] = '\0'; + } + i++; + + } + else + { + if(counterM != 0) + { + sprintf(outputSNP, "%s%d", outputSNP, counterM); + snpSize += addCigarSize(counterM); + outputSNP[snpSize] = '\0'; + counterM = 0; + } + if(counterD != 0) + { + delete[counterD] = '\0'; + counterD=0; + sprintf(outputSNP, "%s^%s", outputSNP, delete); + snpSize += strlen(delete) + 1; + outputSNP[snpSize] = '\0'; + delete[0] = '\0'; + } + sprintf(outputSNP,"%s%c",outputSNP,matrix[i]); + snpSize += 1; + outputSNP[snpSize] = '\0'; + } + i++; + } + + if(counterM != 0) + { + sprintf(outputSNP, "%s%d", outputSNP, counterM); + snpSize += addCigarSize(counterM); + outputSNP[snpSize] = '\0'; + counterM = 0; + } + else if(counterD != 0) + { + delete[counterD] = '\0'; + sprintf(outputSNP, "%s^%s", outputSNP, delete); + snpSize += strlen(delete) + 1; + outputSNP[snpSize] = '\0'; + counterD = 0; + } + + outputSNP[snpSize] = '\0'; +} +/**********************************************/ + +/* + direction = 0 forward + 1 backward + +*/ + +void mapSingleEndSeq(unsigned int *l1, int s1, int readNumber, int readSegment, int direction) +{ + int j = 0; + int z = 0; + int *locs = (int *) l1; + char *_tmpSeq, *_tmpQual; + char rqual[SEQ_LENGTH+1]; + rqual[SEQ_LENGTH]='\0'; + + int genLoc = 0; + int leftSeqLength = 0; + int rightSeqLength = 0; + int middleSeqLength = 0; + + char matrix[200]; + char editString[200]; + char cigar[MAX_CIGAR_SIZE]; + + short *_tmpHashValue; + + if (direction) + { + reverse(_msf_seqList[readNumber].qual, rqual, SEQ_LENGTH); + _tmpQual = rqual; + _tmpSeq = _msf_seqList[readNumber].rseq; + _tmpHashValue = _msf_seqList[readNumber].rhashValue; + } + else + { + _tmpQual = _msf_seqList[readNumber].qual; + _tmpSeq = _msf_seqList[readNumber].seq; + _tmpHashValue = _msf_seqList[readNumber].hashValue; + } + + int readId = 2*readNumber+direction; + for (z=0; z<s1; z++) + { + + + int map_location = 0; + int a = 0; + int o = readSegment; + + genLoc = locs[z];//-_msf_samplingLocs[o]; + + + if ( genLoc-_msf_samplingLocs[o] < _msf_refGenBeg || + genLoc-_msf_samplingLocs[o] > _msf_refGenEnd || + _msf_verifiedLocs[genLoc-_msf_samplingLocs[o]] == readId || + _msf_verifiedLocs[genLoc-_msf_samplingLocs[o]] == -readId + ) + continue; + int err = -1; + + + map_location = 0; + + leftSeqLength = _msf_samplingLocs[o]; + middleSeqLength = WINDOW_SIZE; + a = leftSeqLength + middleSeqLength; + rightSeqLength = SEQ_LENGTH - a; + + if(errThreshold == 2) + err = verifySingleEndEditDistance2(genLoc, _tmpSeq, leftSeqLength, + _tmpSeq + a, rightSeqLength, + middleSeqLength, matrix, &map_location, _tmpHashValue); + else if(errThreshold == 4) + err = verifySingleEndEditDistance4(genLoc, _tmpSeq, leftSeqLength, + _tmpSeq + a, rightSeqLength, + middleSeqLength, matrix, &map_location, _tmpHashValue); + else if(errThreshold ==3) + err = verifySingleEndEditDistance(genLoc, _tmpSeq, leftSeqLength, + _tmpSeq + a, rightSeqLength, + middleSeqLength, matrix, &map_location, _tmpHashValue); + /*else if(errThreshold == 6) + err = verifySingleEndEditDistance(genLoc, _tmpSeq, leftSeqLength, + _tmpSeq + a, rightSeqLength, + middleSeqLength, matrix, &map_location, _tmpHashValue); + */ + else + err = verifySingleEndEditDistanceExtention(genLoc, _tmpSeq, leftSeqLength, + _tmpSeq + a, rightSeqLength, + middleSeqLength, matrix, &map_location, _tmpHashValue); + + if(err != -1) + { + generateSNPSAM(matrix, strlen(matrix), editString); + generateCigar(matrix, strlen(matrix), cigar); + } + + if(err != -1 && !bestMode) + { + + mappingCnt++; + + int j = 0; + int k = 0; + for(k = 0; k < readSegment+1; k++) + { + for(j = -errThreshold ; j <= errThreshold; j++) + { + if(genLoc-(k*(_msf_samplingLocs[1]-_msf_samplingLocs[0]))+j >= _msf_refGenBeg && + genLoc-(k*(_msf_samplingLocs[1]-_msf_samplingLocs[0]))+j <= _msf_refGenEnd) + _msf_verifiedLocs[genLoc-(k*(_msf_samplingLocs[1]-_msf_samplingLocs[0]))+j] = readId; + } + } + _msf_seqList[readNumber].hits[0]++; + + _msf_output.QNAME = _msf_seqList[readNumber].name; + _msf_output.FLAG = 16 * direction; + _msf_output.RNAME = _msf_refGenName; + _msf_output.POS = map_location + _msf_refGenOffset; + _msf_output.MAPQ = 255; + _msf_output.CIGAR = cigar; + _msf_output.MRNAME = "*"; + _msf_output.MPOS = 0; + _msf_output.ISIZE = 0; + _msf_output.SEQ = _tmpSeq; + _msf_output.QUAL = _tmpQual; + + _msf_output.optSize = 2; + _msf_output.optFields = _msf_optionalFields; + + _msf_optionalFields[0].tag = "NM"; + _msf_optionalFields[0].type = 'i'; + _msf_optionalFields[0].iVal = err; + + _msf_optionalFields[1].tag = "MD"; + _msf_optionalFields[1].type = 'Z'; + _msf_optionalFields[1].sVal = editString; + + output(_msf_output); + + + if (_msf_seqList[readNumber].hits[0] == 1) + { + mappedSeqCnt++; + } + + if ( maxHits == 0 ) + { + _msf_seqList[readNumber].hits[0] = 2; + } + + + if ( maxHits!=0 && _msf_seqList[readNumber].hits[0] == maxHits) + { + completedSeqCnt++; + break; + } + + } + else if(err != -1 && bestMode) + { + mappingCnt++; + _msf_seqList[readNumber].hits[0]++; + + if (_msf_seqList[readNumber].hits[0] == 1) + { + mappedSeqCnt++; + } + + if ( maxHits == 0 ) + { + _msf_seqList[readNumber].hits[0] = 2; + } + + if(err < bestHitMappingInfo[readNumber].err || bestHitMappingInfo[readNumber].loc == -1) + { + setFullMappingInfo(readNumber, map_location + _msf_refGenOffset, direction, err, 0, editString, _msf_refGenName, cigar ); + } + } + else + { + for(j = -errThreshold ; j <= errThreshold; j++) + { + if(genLoc+j > _msf_refGenBeg && + genLoc+j < _msf_refGenEnd) + _msf_verifiedLocs[genLoc+j] = -readId; + } + } + } +} + + +int mapAllSingleEndSeq() +{ + int i = 0; + int j = 0; + int k = 0; + + + unsigned int *locs = NULL; + + + int prev_hash = 0; + + for(i = 0; i < _msf_seqListSize; i++) + { + for(j = 0; j < _msf_samplingLocsSize; j++) + { + k = _msf_sort_seqList[i].readNumber; +// if(j != 0) +// if(strncmp(_msf_seqList[k].seq+_msf_samplingLocs[j], _msf_seqList[k].seq+_msf_samplingLocs[j-1], segSize) == 0) +// continue; +// if(prev_hash == hashVal(_msf_seqList[k].seq+_msf_samplingLocs[j])) +// continue; + locs = getCandidates ( hashVal(_msf_seqList[k].seq+_msf_samplingLocs[j])); + if ( locs != NULL) + { + mapSingleEndSeq(locs+1, locs[0],k ,j, 0); + } + prev_hash = hashVal(_msf_seqList[k].seq+_msf_samplingLocs[j]); + } + } + i = 0; + + for(i = 0; i < _msf_seqListSize; i++) + { + for(j = 0; j < _msf_samplingLocsSize; j++) + { + k = _msf_sort_seqList[i].readNumber; + +// if(j != 0) +// if(strncmp(_msf_seqList[k].rseq+_msf_samplingLocs[j], _msf_seqList[k].rseq+_msf_samplingLocs[j-1], segSize) == 0) +// continue; +// if(prev_hash == hashVal(_msf_seqList[k].seq+_msf_samplingLocs[j])) +// continue; + locs = getCandidates ( hashVal(_msf_seqList[k].rseq+_msf_samplingLocs[j])); + if ( locs != NULL) + { + mapSingleEndSeq(locs+1, locs[0],k ,j, 1); + } + prev_hash = hashVal(_msf_seqList[k].seq+_msf_samplingLocs[j]); + } + } + return 1; +} + + +/**********************************************/ +/**********************************************/ +/**********************************************/ +/**********************************************/ +/**********************************************/ +int compareOut (const void *a, const void *b) +{ + FullMappingInfo *aInfo = (FullMappingInfo *)a; + FullMappingInfo *bInfo = (FullMappingInfo *)b; + return aInfo->loc - bInfo->loc; +} + + + +/**********************************************/ + +/* + direction 0: Forward + 1: Reverse +*/ + +void mapPairEndSeqList(unsigned int *l1, int s1, int readNumber, int readSegment, int direction) +{ + int z = 0; + int *locs = (int *) l1; + char *_tmpSeq; + + char rqual[SEQ_LENGTH+1]; + + char matrix[200]; + char editString[200]; + char cigar[MAX_CIGAR_SIZE]; + + short *_tmpHashValue; + + int leftSeqLength = 0; + int middleSeqLength = 0; + int rightSeqLength =0; + int a = 0; + + rqual[SEQ_LENGTH]='\0'; + + + int r = readNumber; + + char d = (direction==1)?-1:1; + + if (d==-1) + { + _tmpSeq = _msf_seqList[readNumber].rseq; + _tmpHashValue = _msf_seqList[r].rhashValue; + } + else + { + _tmpSeq = _msf_seqList[readNumber].seq; + _tmpHashValue = _msf_seqList[r].hashValue; + } + + int readId = 2*readNumber+direction; + for (z=0; z<s1; z++) + { + int genLoc = locs[z];//-_msf_samplingLocs[o]; + int err = -1; + int map_location = 0; + int o = readSegment; + + leftSeqLength = _msf_samplingLocs[o]; + middleSeqLength = WINDOW_SIZE; + a = leftSeqLength + middleSeqLength; + rightSeqLength = SEQ_LENGTH - a; + + if(genLoc - leftSeqLength < _msf_refGenBeg || genLoc + rightSeqLength + middleSeqLength > _msf_refGenEnd || + _msf_verifiedLocs[genLoc-_msf_samplingLocs[o]] == readId || _msf_verifiedLocs[genLoc-_msf_samplingLocs[o]] == -readId) + continue; + + if(errThreshold == 2) + err = verifySingleEndEditDistance2(genLoc, _tmpSeq, leftSeqLength, + _tmpSeq + a, rightSeqLength, + middleSeqLength, matrix, &map_location, _tmpHashValue); + else if(errThreshold == 4) + err = verifySingleEndEditDistance4(genLoc, _tmpSeq, leftSeqLength, + _tmpSeq + a, rightSeqLength, + middleSeqLength, matrix, &map_location, _tmpHashValue); + else if(errThreshold ==3) + err = verifySingleEndEditDistance(genLoc, _tmpSeq, leftSeqLength, + _tmpSeq + a, rightSeqLength, + middleSeqLength, matrix, &map_location, _tmpHashValue); + /*else if(errThreshold == 6) + err = verifySingleEndEditDistance(genLoc, _tmpSeq, leftSeqLength, + _tmpSeq + a, rightSeqLength, + middleSeqLength, matrix, &map_location, _tmpHashValue);*/ + else + err = verifySingleEndEditDistanceExtention(genLoc, _tmpSeq, leftSeqLength, + _tmpSeq + a, rightSeqLength, + middleSeqLength, matrix, &map_location, _tmpHashValue); + + + if (err != -1) + { + int j = 0; + int k = 0; + + for(k = 0; k < readSegment+1; k++) + { + for(j = -errThreshold ; j <= errThreshold; j++) + { + if(genLoc-(k*(_msf_samplingLocs[1]-_msf_samplingLocs[0]))+j >= _msf_refGenBeg && + genLoc-(k*(_msf_samplingLocs[1]-_msf_samplingLocs[0]))+j <= _msf_refGenEnd) + _msf_verifiedLocs[genLoc-(k*(_msf_samplingLocs[1]-_msf_samplingLocs[0]))+j] = readId; + } + } + + + generateSNPSAM(matrix, strlen(matrix), editString); + generateCigar(matrix, strlen(matrix), cigar); + + MappingLocations *parent = NULL; + MappingLocations *child = _msf_mappingInfo[r].next; + + genLoc = map_location + _msf_refGenOffset; + int i = 0; + for (i=0; i<(_msf_mappingInfo[r].size/MAP_CHUNKS); i++) + { + parent = child; + child = child->next; + } + + if (child==NULL) + { + MappingLocations *tmp = getMem(sizeof(MappingLocations)); + + tmp->next = NULL; + tmp->loc[0]=genLoc * d; + tmp->err[0]=err; + + tmp->cigarSize[0] = strlen(cigar); + sprintf(tmp->cigar[0],"%s", cigar); + + tmp->mdSize[0] = strlen(editString); + sprintf(tmp->md[0],"%s", editString); + + if (parent == NULL) + _msf_mappingInfo[r].next = tmp; + else + parent->next = tmp; + } + else + { + if(strlen(cigar) > SEQ_LENGTH || strlen(editString) > SEQ_LENGTH) + { + printf("ERROR in %d read size(After mapping) exceedes cigar=%d md =%d cigar=%s md =%s\n", r, (int)strlen(cigar), (int)strlen(editString), cigar, editString); + } + + child->loc[_msf_mappingInfo[r].size % MAP_CHUNKS] = genLoc * d; + child->err[_msf_mappingInfo[r].size % MAP_CHUNKS] = err; + + child->cigarSize[_msf_mappingInfo[r].size % MAP_CHUNKS] = strlen(cigar); + sprintf(child->cigar[_msf_mappingInfo[r].size % MAP_CHUNKS],"%s",cigar); + + child->mdSize[_msf_mappingInfo[r].size % MAP_CHUNKS] = strlen(editString); + sprintf(child->md[_msf_mappingInfo[r].size % MAP_CHUNKS],"%s",editString); + } + _msf_mappingInfo[r].size++; + + } + else + { + _msf_verifiedLocs[genLoc] = -readId; + } + + } +} + +/**********************************************/ +void mapPairedEndSeq() +{ + int i = 0; + int j = 0; + int k = 0; + + unsigned int *locs = NULL; + while ( i < _msf_seqListSize ) + { + for(j = 0; j < _msf_samplingLocsSize; j++) + { + k = _msf_sort_seqList[i].readNumber; + locs = getCandidates ( hashVal(_msf_seqList[k].seq+_msf_samplingLocs[j])); + if ( locs != NULL) + { + mapPairEndSeqList(locs+1, locs[0],k ,j, 0); + } + } + i++; + } + i = 0; + + while ( i < _msf_seqListSize ) + { + for(j = 0; j < _msf_samplingLocsSize; j++) + { + k = _msf_sort_seqList[i].readNumber; + locs = getCandidates ( hashVal(_msf_seqList[k].rseq+_msf_samplingLocs[j])); + if ( locs != NULL) + { + mapPairEndSeqList(locs+1, locs[0],k ,j, 1); + } + } + + i++; + } + char fname1[FILE_NAME_LENGTH]; + char fname2[FILE_NAME_LENGTH]; + MappingLocations *cur; + int tmpOut; + int lmax=0, rmax=0; + + sprintf(fname1, "%s__%s__%s__%d__1.tmp",mappingOutputPath, _msf_refGenName, mappingOutput, _msf_openFiles); + sprintf(fname2, "%s__%s__%s__%d__2.tmp",mappingOutputPath, _msf_refGenName, mappingOutput, _msf_openFiles); + + FILE* out; + FILE* out1 = fileOpen(fname1, "w"); + FILE* out2 = fileOpen(fname2, "w"); + + _msf_openFiles++; + + for (i=0; i<_msf_seqListSize; i++) + { + + if (i%2==0) + { + out = out1; + + if (lmax < _msf_mappingInfo[i].size) + { + lmax = _msf_mappingInfo[i].size; + } + } + else + { + out = out2; + if (rmax < _msf_mappingInfo[i].size) + { + rmax = _msf_mappingInfo[i].size; + } + } + + tmpOut = fwrite(&(_msf_mappingInfo[i].size), sizeof(int), 1, out); + if (_msf_mappingInfo[i].size > 0) + { + cur = _msf_mappingInfo[i].next; + for (j=0; j < _msf_mappingInfo[i].size; j++) + { + if ( j>0 && j%MAP_CHUNKS==0) + { + cur = cur->next; + } + if(cur->cigarSize[j % MAP_CHUNKS] > SEQ_LENGTH || cur->mdSize[j % MAP_CHUNKS] > SEQ_LENGTH) + { + printf("ERROR in %d read size exceeds cigar=%d md =%d cigar=%s md =%s\n", i, cur->cigarSize[j % MAP_CHUNKS], cur->mdSize[j % MAP_CHUNKS], cur->cigar[j % MAP_CHUNKS], cur->md[j % MAP_CHUNKS]); + } + + tmpOut = fwrite(&(cur->loc[j % MAP_CHUNKS]), sizeof(int), 1, out); + + tmpOut = fwrite(&(cur->err[j % MAP_CHUNKS]), sizeof(int), 1, out); + + tmpOut = fwrite(&(cur->cigarSize[j % MAP_CHUNKS]), sizeof(int), 1, out); + tmpOut = fwrite((cur->cigar[j % MAP_CHUNKS]), sizeof(char), (cur->cigarSize[j % MAP_CHUNKS]), out); + + tmpOut = fwrite(&(cur->mdSize[j % MAP_CHUNKS]), sizeof(int), 1, out); + tmpOut = fwrite((cur->md[j % MAP_CHUNKS]), sizeof(char), (cur->mdSize[j % MAP_CHUNKS]), out); + + } + _msf_mappingInfo[i].size = 0; + //_msf_mappingInfo[i].next = NULL; + } + } + + _msf_maxLSize += lmax; + _msf_maxRSize += rmax; + + fclose(out1); + fclose(out2); + +} + +void outputPairFullMappingInfo(FILE *fp, int readNumber) +{ + + char *seq1, *seq2, *rseq1, *rseq2, *qual1, *qual2; + char rqual1[SEQ_LENGTH+1], rqual2[SEQ_LENGTH+1]; + + rqual1[SEQ_LENGTH] = rqual2[SEQ_LENGTH] = '\0'; + + seq1 = _msf_seqList[readNumber*2].seq; + rseq1 = _msf_seqList[readNumber*2].rseq; + qual1 = _msf_seqList[readNumber*2].qual; + + reverse(_msf_seqList[readNumber*2].qual, rqual1, SEQ_LENGTH); + + seq2 = _msf_seqList[readNumber*2+1].seq; + rseq2 = _msf_seqList[readNumber*2+1].rseq; + qual2 = _msf_seqList[readNumber*2+1].qual; + + reverse(_msf_seqList[readNumber*2+1].qual, rqual2, SEQ_LENGTH); + + + if(bestHitMappingInfo[readNumber*2].loc == -1 && bestHitMappingInfo[readNumber*2+1].loc == -1) + return; + else + { + + char *seq; + char *qual; + char d1; + char d2; + int isize; + int proper=0; + // ISIZE CALCULATION + // The distance between outer edges + isize = abs(bestHitMappingInfo[readNumber*2].loc - bestHitMappingInfo[readNumber*2+1].loc)+SEQ_LENGTH - 2; + + if (bestHitMappingInfo[readNumber*2].loc - bestHitMappingInfo[readNumber*2+1].loc > 0) + { + isize *= -1; + } + d1 = (bestHitMappingInfo[readNumber*2].dir == -1)?1:0; + d2 = (bestHitMappingInfo[readNumber*2+1].dir == -1)?1:0; + + if ( d1 ) + { + seq = rseq1; + qual = rqual1; + } + else + { + seq = seq1; + qual = qual1; + } + if ( (bestHitMappingInfo[readNumber*2].loc < bestHitMappingInfo[readNumber*2+1].loc && !d1 && d2) || + (bestHitMappingInfo[readNumber*2].loc > bestHitMappingInfo[readNumber*2+1].loc && d1 && !d2) ) + { + proper = 2; + } + else + { + proper = 0; + } + + _msf_output.POS = bestHitMappingInfo[readNumber*2].loc; + _msf_output.MPOS = bestHitMappingInfo[readNumber*2+1].loc; + _msf_output.FLAG = 1+proper+16*d1+32*d2+64; + _msf_output.ISIZE = isize; + _msf_output.SEQ = seq, + _msf_output.QUAL = qual; + _msf_output.QNAME = _msf_seqList[readNumber*2].name; + _msf_output.RNAME = bestHitMappingInfo[readNumber*2].chr; + _msf_output.MAPQ = 255; + _msf_output.CIGAR = bestHitMappingInfo[readNumber*2].cigar; + _msf_output.MRNAME = "="; + + _msf_output.optSize = 2; + _msf_output.optFields = _msf_optionalFields; + + _msf_optionalFields[0].tag = "NM"; + _msf_optionalFields[0].type = 'i'; + _msf_optionalFields[0].iVal = bestHitMappingInfo[readNumber*2].err; + + _msf_optionalFields[1].tag = "MD"; + _msf_optionalFields[1].type = 'Z'; + _msf_optionalFields[1].sVal = bestHitMappingInfo[readNumber*2].md; + + outputSAM(fp, _msf_output); + output(_msf_output); + + if ( d2 ) + { + seq = rseq2; + qual = rqual2; + } + else + { + seq = seq2; + qual = qual2; + } + + _msf_output.POS = bestHitMappingInfo[readNumber*2+1].loc; + _msf_output.MPOS = bestHitMappingInfo[readNumber*2].loc; + _msf_output.FLAG = 1+proper+16*d2+32*d1+128; + _msf_output.ISIZE = -isize; + _msf_output.SEQ = seq, + _msf_output.QUAL = qual; + _msf_output.QNAME = _msf_seqList[readNumber*2].name; + _msf_output.RNAME = bestHitMappingInfo[readNumber*2].chr; + _msf_output.MAPQ = 255; + _msf_output.CIGAR = bestHitMappingInfo[readNumber*2+1].cigar; + _msf_output.MRNAME = "="; + + _msf_output.optSize = 2; + _msf_output.optFields = _msf_optionalFields; + + _msf_optionalFields[0].tag = "NM"; + _msf_optionalFields[0].type = 'i'; + _msf_optionalFields[0].iVal = bestHitMappingInfo[readNumber*2+1].err; + + _msf_optionalFields[1].tag = "MD"; + _msf_optionalFields[1].type = 'Z'; + _msf_optionalFields[1].sVal = bestHitMappingInfo[readNumber*2+1].md; + + outputSAM(fp, _msf_output); + output(_msf_output); + } +} + + +/* +Find the closet one to the c + @return 0: if the x1 is closer to c + 1: if the x2 is closer to c + 2: if both distance are equal + -1: if error +*/ +int findNearest(int x1, int x2, int c) +{ + + if (abs(x1 - c) > abs(x2 - c) ) + return 0; + else if ( abs(x1 - c) < abs(x2 - c) ) + return 1; + else if ( abs(x1 - c) == abs(x2 - c) ) + return 2; + else + return -1; +} + +void initBestConcordantDiscordant(int readNumber) +{ + char bestConcordantFileName[FILE_NAME_LENGTH]; + char bestDiscordantFileName[FILE_NAME_LENGTH]; + + //OPEN THE BEST CONCORDANT FILE + //BEGIN{Farhad Hormozdiari} + sprintf(bestConcordantFileName, "%s%s__BEST.CONCORDANT", mappingOutputPath, mappingOutput); + bestConcordantFILE = fileOpen(bestConcordantFileName, "w"); + //END{Farhad Hormozdiari} + + + //OPEN THE BEST DISCORDANT FILE + //BEGIN{Farhad Hormozdiari} + sprintf(bestDiscordantFileName, "%s%s__BEST.DISCORDANT", mappingOutputPath, mappingOutput); + bestDiscordantFILE = fileOpen(bestDiscordantFileName, "w"); + //END{Farhad Hormozdiari} + + initBestMapping(readNumber); +} + +void finalizeBestConcordantDiscordant() +{ + int i = 0; + + for(i = 0; i<_msf_seqListSize/2; i++) + { + if(_msf_readHasConcordantMapping[i]==1) + outputPairFullMappingInfo(bestConcordantFILE, i); + else + outputPairFullMappingInfo(bestDiscordantFILE, i); + } + + fclose(bestConcordantFILE); + fclose(bestDiscordantFILE); + + freeMem(bestHitMappingInfo, _msf_seqListSize * sizeof(FullMappingInfo)); +} + +void setFullMappingInfo(int readNumber, int loc, int dir, int err, int score, char *md, char * refName, char *cigar) +{ + bestHitMappingInfo[readNumber].loc = loc; + bestHitMappingInfo[readNumber].dir = dir; + bestHitMappingInfo[readNumber].err = err; + bestHitMappingInfo[readNumber].score = score; + + strncpy(bestHitMappingInfo[readNumber].md, md, strlen(md)); + strncpy(bestHitMappingInfo[readNumber].chr, refName, strlen(refName)); + strncpy(bestHitMappingInfo[readNumber].cigar, cigar, strlen(cigar)); +} + + +void setPairFullMappingInfo(int readNumber, FullMappingInfo mi1, FullMappingInfo mi2) +{ + + bestHitMappingInfo[readNumber*2].loc = mi1.loc; + bestHitMappingInfo[readNumber*2].dir = mi1.dir; + bestHitMappingInfo[readNumber*2].err = mi1.err; + bestHitMappingInfo[readNumber*2].score = mi1.score; + snprintf(bestHitMappingInfo[readNumber*2].chr, MAX_REF_SIZE, "%s", _msf_refGenName); + + strncpy(bestHitMappingInfo[readNumber*2].md, mi1.md, strlen(mi1.md)); + strncpy(bestHitMappingInfo[readNumber*2].cigar, mi1.cigar, strlen(mi1.cigar)); + + /* + sprintf(bestHitMappingInfo[readNumber*2].md, "%s\0", mi1.md); + sprintf(bestHitMappingInfo[readNumber*2].cigar, "%s\0", mi1.cigar); + */ + + + bestHitMappingInfo[readNumber*2+1].loc = mi2.loc; + bestHitMappingInfo[readNumber*2+1].dir = mi2.dir; + bestHitMappingInfo[readNumber*2+1].err = mi2.err; + bestHitMappingInfo[readNumber*2+1].score = mi2.score; + + snprintf(bestHitMappingInfo[readNumber*2+1].chr, MAX_REF_SIZE, "%s", _msf_refGenName); + + /* + sprintf(bestHitMappingInfo[readNumber*2+1].md, "%s\0", mi2.md); + sprintf(bestHitMappingInfo[readNumber*2+1].cigar, "%s\0", mi2.cigar); + */ + + strncpy(bestHitMappingInfo[readNumber*2+1].md, mi2.md, strlen(mi2.md)); + strncpy(bestHitMappingInfo[readNumber*2+1].cigar, mi2.cigar, strlen(mi2.cigar)); + +} + +/**********************************************/ +void outputPairedEnd() +{ + int i = 0; + + char cigar[MAX_CIGAR_SIZE]; + + int tmpOut; + + loadRefGenome(&_msf_refGen, &_msf_refGenName, &tmpOut); + + FILE* in1[_msf_openFiles]; + FILE* in2[_msf_openFiles]; + + char fname1[_msf_openFiles][FILE_NAME_LENGTH]; + char fname2[_msf_openFiles][FILE_NAME_LENGTH]; + + // discordant + FILE *out=NULL, *out1=NULL; + + char fname3[FILE_NAME_LENGTH]; + char fname4[FILE_NAME_LENGTH]; + + int meanDistanceMapping = 0; + + char *rqual1; + char *rqual2; + + rqual1 = getMem((SEQ_LENGTH+1)*sizeof(char)); + rqual2 = getMem((SEQ_LENGTH+1)*sizeof(char)); + + if (pairedEndDiscordantMode) + { + sprintf(fname3, "%s__%s__disc", mappingOutputPath, mappingOutput); + sprintf(fname4, "%s__%s__oea", mappingOutputPath, mappingOutput); + out = fileOpen(fname3, "a"); + out1 = fileOpen(fname4, "a"); + } + + FullMappingInfo *mi1 = getMem(sizeof(FullMappingInfo) * _msf_maxLSize); + FullMappingInfo *mi2 = getMem(sizeof(FullMappingInfo) * _msf_maxRSize); + + _msf_fileCount[_msf_maxFile] = 0; + for (i=0; i<_msf_openFiles; i++) + { + sprintf(fname1[i], "%s__%s__%s__%d__1.tmp", mappingOutputPath, _msf_refGenName, mappingOutput, i); + sprintf(_msf_fileName[_msf_maxFile][_msf_fileCount[_msf_maxFile]][0], "%s", fname1[i]); + + sprintf(fname2[i], "%s__%s__%s__%d__2.tmp", mappingOutputPath, _msf_refGenName, mappingOutput, i); + sprintf(_msf_fileName[_msf_maxFile][_msf_fileCount[_msf_maxFile]][1], "%s", fname2[i]); + + in1[i] = fileOpen(fname1[i], "r"); + in2[i] = fileOpen(fname2[i], "r"); + _msf_fileCount[_msf_maxFile]++; + } + _msf_maxFile++; + + int size; + int j, k; + int size1, size2; + + meanDistanceMapping = (pairedEndDiscordantMode==1)? (minPairEndedDiscordantDistance+maxPairEndedDiscordantDistance)/2 + SEQ_LENGTH + : (minPairEndedDistance + maxPairEndedDistance) / 2 + SEQ_LENGTH; + + for (i=0; i<_msf_seqListSize/2; i++) + { + size1 = size2 = 0; + for (j=0; j<_msf_openFiles; j++) + { + tmpOut = fread(&size, sizeof(int), 1, in1[j]); + if ( size > 0 ) + { + for (k=0; k<size; k++) + { + mi1[size1+k].dir = 1; + tmpOut = fread (&(mi1[size1+k].loc), sizeof(int), 1, in1[j]); + tmpOut = fread (&(mi1[size1+k].err), sizeof(int), 1, in1[j]); + + tmpOut = fread (&(mi1[size1+k].cigarSize), sizeof(int), 1, in1[j]); + tmpOut = fread ((mi1[size1+k].cigar), sizeof(char), mi1[size1+k].cigarSize, in1[j]); + mi1[size1+k].cigar[mi1[size1+k].cigarSize] = '\0'; + + tmpOut = fread (&(mi1[size1+k].mdSize), sizeof(int), 1, in1[j]); + tmpOut = fread ((mi1[size1+k].md), sizeof(char), (mi1[size1+k].mdSize), in1[j]); + mi1[size1+k].md[mi1[size1+k].mdSize] = '\0'; + + if (mi1[size1+k].loc<1) + { + mi1[size1+k].loc *= -1; + mi1[size1+k].dir = -1; + } + } + qsort(mi1+size1, size, sizeof(FullMappingInfo), compareOut); + size1+=size; + } + } + + for (j=0; j<_msf_openFiles; j++) + { + tmpOut = fread(&size, sizeof(int), 1, in2[j]); + if ( size > 0 ) + { + for (k=0; k<size; k++) + { + mi2[size2+k].dir = 1; + tmpOut = fread (&(mi2[size2+k].loc), sizeof(int), 1, in2[j]); + tmpOut = fread (&(mi2[size2+k].err), sizeof(int), 1, in2[j]); + + tmpOut = fread (&(mi2[size2+k].cigarSize), sizeof(int), 1, in2[j]); + tmpOut = fread ((mi2[size2+k].cigar), sizeof(char), mi2[size2+k].cigarSize, in2[j]); + mi2[size2+k].cigar[mi2[size2+k].cigarSize] = '\0'; + + tmpOut = fread (&(mi2[size2+k].mdSize), sizeof(int), 1, in2[j]); + tmpOut = fread ((mi2[size2+k].md), sizeof(char), mi2[size2+k].mdSize, in2[j]); + mi2[size2+k].md[mi2[size2+k].mdSize] = '\0'; + + if (mi2[size2+k].loc<1) + { + mi2[size2+k].loc *= -1; + mi2[size2+k].dir = -1; + } + } + qsort(mi2+size2, size, sizeof(FullMappingInfo), compareOut); + size2+=size; + } + } + + int lm, ll, rl, rm; + int pos = 0; + + if (pairedEndDiscordantMode) + { + + for (j=0; j<size1; j++) + { + lm = mi1[j].loc - maxPairEndedDiscordantDistance + 1; + ll = mi1[j].loc - minPairEndedDiscordantDistance + 1; + rl = mi1[j].loc + minPairEndedDiscordantDistance - 1; + rm = mi1[j].loc + maxPairEndedDiscordantDistance - 1; + + while (pos<size2 && mi2[pos].loc < lm) + { + pos++; + } + + k = pos; + while (k<size2 && mi2[k].loc<=rm) + { + if ( mi2[k].loc <= ll || mi2[k].loc >= rl) + { + if ( (mi1[j].loc < mi2[k].loc && mi1[j].dir==1 && mi2[k].dir == -1) || + (mi1[j].loc > mi2[k].loc && mi1[j].dir==-1 && mi2[k].dir == 1) ) + { + _msf_seqList[i*2].hits[0]=1; + _msf_seqList[i*2+1].hits[0]=1; + + if(nosamMode != 0) + { + size1=0; + size2=0; + } + + break; + } + } + k++; + } + } + + _msf_seqHits[i*2] += size1; + _msf_seqHits[i*2+1] += size2; + + + if (_msf_seqHits[i*2+1] * _msf_seqHits[i*2] > DISCORDANT_CUT_OFF && nosamMode != 0) + { + _msf_seqList[i*2].hits[0]=1; + _msf_seqList[i*2+1].hits[0]=1; + size1=0; + size2=0; + } + + + + + int tmp = 0; + int rNo = 0; + int loc = 0; + int err = 0; + float sc = 0; + char l = 0; + + //write the OEA data + if(_msf_seqHits[i*2] == 0 ) + { + for(k = 0;k < size2 && _msf_oeaMapping[i*2+1] < maxOEAOutput ;k++) + { + rNo = i*2+1; + loc = mi2[k].loc*mi2[k].dir; + err = mi2[k].err; + sc = mi2[k].score; + + l = strlen(_msf_refGenName); + + tmp = fwrite(&rNo, sizeof(int), 1, out1); + + tmp = fwrite(&l, sizeof(char), 1, out1); + tmp = fwrite(_msf_refGenName, sizeof(char), l, out1); + + tmp = fwrite(&loc, sizeof(int), 1, out1); + tmp = fwrite(&err, sizeof(int), 1, out1); + tmp = fwrite(&sc, sizeof(float), 1, out1); + + if(mi2[k].cigarSize > SEQ_LENGTH || mi2[k].cigarSize <= 0) + printf("ERROR CIGAR size=%d %s\n", mi2[k].cigarSize, _msf_seqList[i*2+1].seq); + + tmp = fwrite (&(mi2[k].cigarSize), sizeof(int), 1, out1); + tmp = fwrite ((mi2[k].cigar), sizeof(char), mi2[k].cigarSize, out1); + + tmp = fwrite (&(mi2[k].mdSize), sizeof(int), 1, out1); + tmp = fwrite ((mi2[k].md), sizeof(char), mi2[k].mdSize, out1); + + _msf_oeaMapping[i*2+1]++; + } + } + if(_msf_seqHits[i*2+1] == 0) + { + for(j = 0;j < size1 && _msf_oeaMapping[i*2] < maxOEAOutput;j++) + { + rNo = i*2; + loc = mi1[j].loc*mi1[j].dir; + err = mi1[j].err; + sc = mi1[j].score; + + l = strlen(_msf_refGenName); + + tmp = fwrite(&rNo, sizeof(int), 1, out1); + + tmp = fwrite(&l, sizeof(char), 1, out1); + tmp = fwrite(_msf_refGenName, sizeof(char), l, out1); + + tmp = fwrite(&loc, sizeof(int), 1, out1); + tmp = fwrite(&err, sizeof(int), 1, out1); + tmp = fwrite(&sc, sizeof(float), 1, out1); + + if(mi1[j].cigarSize > SEQ_LENGTH || mi1[j].cigarSize <= 0 ) + printf("ERROR %d %s\n", mi1[j].cigarSize, _msf_seqList[i*2+1].seq); + + tmp = fwrite (&(mi1[j].cigarSize), sizeof(int), 1, out1); + tmp = fwrite ((mi1[j].cigar), sizeof(char), mi1[j].cigarSize, out1); + + tmp = fwrite (&(mi1[j].mdSize), sizeof(int), 1, out1); + tmp = fwrite ((mi1[j].md), sizeof(char), mi1[j].mdSize, out1); + + _msf_oeaMapping[i*2]++; + } + } + } + + char *seq1, *seq2, *rseq1, *rseq2, *qual1, *qual2; + + + + + rqual1[SEQ_LENGTH] = '\0'; + rqual2[SEQ_LENGTH] = '\0'; + rqual1[0] = '\0'; + rqual2[0] = '\0'; + + + + seq1 = _msf_seqList[i*2].seq; + rseq1 = _msf_seqList[i*2].rseq; + qual1 = _msf_seqList[i*2].qual; + + + + strncpy(rqual1, _msf_seqList[i*2].qual, SEQ_LENGTH); + + seq2 = _msf_seqList[i*2+1].seq; + rseq2 = _msf_seqList[i*2+1].rseq; + qual2 = _msf_seqList[i*2+1].qual; + + + strncpy(rqual2, _msf_seqList[i*2+1].qual, SEQ_LENGTH); + + if (pairedEndDiscordantMode) + { + for (k=0; k<size1; k++) + { + mi1[k].score = calculateScore(mi1[k].loc, (mi1[k].dir==-1)?rseq1:seq1, (mi1[k].dir==-1)?rqual1:qual1, mi1[k].cigar); + } + + for (k=0; k<size2; k++) + { + mi2[k].score = calculateScore(mi2[k].loc, (mi2[k].dir==-1)?rseq2:seq2, (mi2[k].dir==-1)?rqual2:qual2, mi2[k].cigar); + } + + } + + + if (pairedEndDiscordantMode) + { + for (j=0; j<size1; j++) + { + for(k = 0; k < size2; k++) + { + if( + (mi2[k].loc-mi1[j].loc >= minPairEndedDiscordantDistance && + mi2[k].loc-mi1[j].loc <= maxPairEndedDiscordantDistance && + mi1[j].dir > 0 && mi2[k].dir < 0 ) + + || + + (mi1[j].loc-mi2[k].loc >= minPairEndedDiscordantDistance && + mi1[j].loc-mi2[k].loc <= maxPairEndedDiscordantDistance && + mi1[j].dir < 0 && mi2[k].dir > 0) + ) + { + //POSSIBLE CONCORDANT + if(_msf_readHasConcordantMapping[i] == 0) + { + setPairFullMappingInfo(i, mi1[j], mi2[k]); + _msf_readHasConcordantMapping[i] = 1; + _msf_seqList[i*2].hits[0] = 1; + _msf_seqList[i*2+1].hits[0] = 1; + } + else + { + if(bestHitMappingInfo[i*2].err + bestHitMappingInfo[i*2+1].err >= mi1[j].err + mi2[k].err) + { + + if( bestHitMappingInfo[i*2].err + bestHitMappingInfo[i*2+1].err == + mi1[j].err + mi2[k].err && + findNearest(abs(bestHitMappingInfo[i*2+1].loc - bestHitMappingInfo[i*2].loc), + abs(mi2[k].loc - mi1[j].loc), + meanDistanceMapping + ) == 0 ) + { + continue; + } + setPairFullMappingInfo(i, mi1[j], mi2[k]); + } + } + } + //DISCORDANT TO TEMP FILE FOR POST PROCESSIING + else if(_msf_readHasConcordantMapping[i] == 0 && + _msf_seqHits[i*2] != 0 && + _msf_seqHits[i*2+1] != 0) + { + + int tmp; + int rNo = i; + int loc = mi1[j].loc*mi1[j].dir; + int err = mi1[j].err; + float sc = mi1[j].score; + + char l = strlen(_msf_refGenName); + + if(_msf_discordantMapping[i*2] < maxDiscordantOutput) + { + + tmp = fwrite(&rNo, sizeof(int), 1, out); + + tmp = fwrite(&l, sizeof(char), 1, out); + tmp = fwrite(_msf_refGenName, sizeof(char), l, out); + + tmp = fwrite(&loc, sizeof(int), 1, out); + tmp = fwrite(&err, sizeof(int), 1, out); + tmp = fwrite(&sc, sizeof(float), 1, out); + + tmp = fwrite (&(mi1[j].cigarSize), sizeof(int), 1, out); + tmp = fwrite ((mi1[j].cigar), sizeof(char), mi1[j].cigarSize, out); + + tmp = fwrite (&(mi1[j].mdSize), sizeof(int), 1, out); + tmp = fwrite ((mi1[j].md), sizeof(char), mi1[j].mdSize, out); + + + loc = mi2[k].loc*mi2[k].dir; + err = mi2[k].err; + sc = mi2[k].score; + + tmp = fwrite(&loc, sizeof(int), 1, out); + tmp = fwrite(&err, sizeof(int), 1, out); + tmp = fwrite(&sc, sizeof(float), 1, out); + + tmp = fwrite (&(mi2[k].cigarSize), sizeof(int), 1, out); + tmp = fwrite ((mi2[k].cigar), sizeof(char), mi2[k].cigarSize, out); + + tmp = fwrite (&(mi2[k].mdSize), sizeof(int), 1, out); + tmp = fwrite ((mi2[k].md), sizeof(char), mi2[k].mdSize, out); + + + _msf_discordantMapping[i*2]++; + } + //SET THE BEST DISCORDANT + //BEGIN {Farhad Hormozdiari} + if( bestHitMappingInfo[i*2].loc == -1 && + bestHitMappingInfo[i*2+1].loc == -1 && + _msf_readHasConcordantMapping[i] == 0) + { + setPairFullMappingInfo(i, mi1[j], mi2[k]); + _msf_seqList[i*2].hits[0] = 1; + _msf_seqList[i*2+1].hits[0] = 1; + } + else if( bestHitMappingInfo[i*2].err + bestHitMappingInfo[i*2+1].err >= mi1[j].err + mi2[k].err + && _msf_readHasConcordantMapping[i] == 0) + { + if(bestHitMappingInfo[i*2].err + bestHitMappingInfo[i*2+1].err == mi1[j].err + mi2[k].err && + findNearest( abs(bestHitMappingInfo[i*2+1].loc - bestHitMappingInfo[i*2].loc), + abs(mi1[j].loc - mi2[k].loc), + meanDistanceMapping + ) == 0 + ) + { + continue; + } + setPairFullMappingInfo(i, mi1[j], mi2[k]); + } + //END {Farhad Hormozdiari} + } + } + } + } + else + { + for (j=0; j<size1; j++) + { + for(k = 0; k < size2; k++) + { + if((mi2[k].loc-mi1[j].loc >= minPairEndedDistance && + mi2[k].loc-mi1[j].loc <= maxPairEndedDistance && + mi1[j].dir > 0 && mi2[k].dir < 0) + || + (mi1[j].loc-mi2[k].loc >= minPairEndedDistance && + mi1[j].loc-mi2[k].loc <= maxPairEndedDistance && + mi1[j].dir < 0 && mi2[k].dir > 0) + ) + { + char *seq; + char *qual; + char d1; + char d2; + int isize; + int proper=0; + // ISIZE CALCULATION + // The distance between outer edges + isize = abs(mi1[j].loc - mi2[k].loc)+SEQ_LENGTH-2; + if (mi1[j].loc - mi2[k].loc > 0) + { + isize *= -1; + } + + d1 = (mi1[j].dir == -1)?1:0; + d2 = (mi2[k].dir == -1)?1:0; + + //SET THE READ HAS CONCORDANT MAPPING + _msf_readHasConcordantMapping[i] = 1; + + if ( d1 ) + { + seq = rseq1; + qual = rqual1; + } + else + { + seq = seq1; + qual = qual1; + } + + if ((mi1[j].loc < mi2[k].loc && !d1 && d2) || + (mi1[j].loc > mi2[k].loc && d1 && !d2) ) + { + proper = 2; + } + else + { + proper = 0; + } + + + _msf_output.POS = mi1[j].loc; + _msf_output.MPOS = mi2[k].loc; + _msf_output.FLAG = 1+proper+16*d1+32*d2+64; + _msf_output.ISIZE = isize; + _msf_output.SEQ = seq, + _msf_output.QUAL = qual; + _msf_output.QNAME = _msf_seqList[i*2].name; + _msf_output.RNAME = _msf_refGenName; + _msf_output.MAPQ = 255; + _msf_output.CIGAR = cigar; + _msf_output.MRNAME = "="; + + _msf_output.optSize = 2; + _msf_output.optFields = _msf_optionalFields; + + _msf_optionalFields[0].tag = "NM"; + _msf_optionalFields[0].type = 'i'; + _msf_optionalFields[0].iVal = mi1[j].err; + + _msf_optionalFields[1].tag = "MD"; + _msf_optionalFields[1].type = 'Z'; + _msf_optionalFields[1].sVal = mi1[j].md; + + if(!bestMode) + output(_msf_output); + + if ( d2 ) + { + seq = rseq2; + qual = rqual2; + } + else + { + seq = seq2; + qual = qual2; + } + + _msf_output.POS = mi2[k].loc; + _msf_output.MPOS = mi1[j].loc; + _msf_output.FLAG = 1+proper+16*d2+32*d1+128; + _msf_output.ISIZE = -isize; + _msf_output.SEQ = seq, + _msf_output.QUAL = qual; + _msf_output.QNAME = _msf_seqList[i*2].name; + _msf_output.RNAME = _msf_refGenName; + _msf_output.MAPQ = 255; + _msf_output.CIGAR = cigar; + _msf_output.MRNAME = "="; + + _msf_output.optSize = 2; + _msf_output.optFields = _msf_optionalFields; + + _msf_optionalFields[0].tag = "NM"; + _msf_optionalFields[0].type = 'i'; + _msf_optionalFields[0].iVal = mi2[k].err;; + + _msf_optionalFields[1].tag = "MD"; + _msf_optionalFields[1].type = 'Z'; + _msf_optionalFields[1].sVal = mi2[k].md; + + if(!bestMode) + output(_msf_output); + //SET THE BEST CONCORDANT + //BEGIN {Farhad Hormozdiari} + if(bestHitMappingInfo[i*2].loc == -1 && bestHitMappingInfo[i*2+1].loc == -1) + { + setPairFullMappingInfo(i, mi1[j], mi2[k]); + } + else + { + if(bestHitMappingInfo[i*2].err + bestHitMappingInfo[i*2+1].err >= mi1[j].err + mi2[k].err) + { + + if( bestHitMappingInfo[i*2].err + bestHitMappingInfo[i*2+1].err == mi1[j].err + mi2[k].err && + findNearest(abs(bestHitMappingInfo[i*2+1].loc - bestHitMappingInfo[i*2].loc), + abs(mi2[k].loc - mi1[j].loc), + meanDistanceMapping + ) == 0 ) + { + continue; + } + setPairFullMappingInfo(i, mi1[j], mi2[k]); + } + } + //END {Farhad Hormozdiari} + } + } + } + + } + } + + freeMem(rqual1, 0); + freeMem(rqual2, 0); + + if (pairedEndDiscordantMode) + { + fclose(out); + fclose(out1); + } + + for (i=0; i<_msf_openFiles; i++) + { + fclose(in1[i]); + fclose(in2[i]); + + unlink(fname1[i]); + unlink(fname2[i]); + } + + freeMem(mi1, sizeof(FullMappingInfo)*_msf_maxLSize); + freeMem(mi2, sizeof(FullMappingInfo)*_msf_maxRSize); + + _msf_openFiles = 0; +} + +/**********************************************/ +/**********************************************/ +/**********************************************/ +/**********************************************/ +float str2int(char *str, int index1, int index2) +{ + char tmp[200]; + strncpy(tmp, &str[index1], index2-index1); + tmp[index2-index1] = '\0'; + return atol(tmp); +} + +float calculateScore(int index, char *seq, char *qual,char *md) +{ + int i; + int j; + char *ref; + char *ver; + + ref = _msf_refGen + index-1; + ver = seq; + float score = 1; + + char tmp[200]; + int value = 0; + int end = 0; + int index1 = 0; + int index2 = 0; + + i=0; + while(1) + { + + if(i>=strlen(md)) + break; + + index1 = i; + + while(md[i] >='0' && md[i]<='9') + { + i++; + } + + index2 = i; + + value = str2int(md, index1,index2); + + if(md[i]=='M') + { + for(j=0;j<value;j++) + { + tmp[end]='M'; + end++; + } + } + else if(md[i]=='I') + { + for(j=0;j<value;j++) + { + tmp[end]='I'; + end++; + } + + } + else if(md[i] == 'D') + { + for(j=0;j<value;j++) + { + tmp[end]='D'; + end++; + } + } + i++; + } + + tmp[end] = '\0'; + + j = 0; + + for (i = 0; i < end; i++) + { + if(tmp[i] == 'M') + { + if (*ref != *ver) + { + score *= 0.001 + 1/pow( 10, ((qual[j]-33)/10.0) ); + } + + ref++; + ver++; + j++; + } + else if(tmp[i] == 'I') + { + ver++; + j++; + } + else if(tmp[i] == 'D') + { + ref++; + } + } + + return score; +} + +int matoi(char *str, int start, int end) +{ + int i = 0; + char tmp[200]; + + for(i=0;i < end-start; i++) + tmp[i] = str[start+i]; + tmp[i]='\0'; + + return atoi(tmp); +} + +void convertCigarToMatrix(char *cigar, int cigar_size, char * matrix) +{ + int i = 0; + int j = 0; + + int start = 0; + int size = 0; + + matrix[0] = '\0'; + + while(i < cigar_size) + { + if(cigar[i] >= '0' && cigar[i] <= '9') + { + start = i; + + while(cigar[i] >= '0' && cigar[i] <= '9' && i < cigar_size) + i++; + + int value = matoi(cigar, start, i); + for(j = 0; j < value; j++) + { + if(cigar[i] == 'M') + matrix[size] = 'M'; + else if(cigar[i] == 'D') + matrix[size] ='D'; + else if(cigar[i] == 'I') + matrix[size] = 'I'; + size++; + } + } + i++; + } + matrix[size] = '\0'; +} + + + +void convertMDToMatrix(char *md, int md_size, char * matrix) +{ + int i = 0; + int j = 0; + + int start = 0; + int size = 0; + + matrix[0] = '\0'; + + while(i < md_size) + { + if(md[i] >= '0' && md[i] <= '9') + { + start = i; + + while(md[i] >= '0' && md[i] <= '9' && i < md_size) + i++; + + int value = matoi(md, start, i); + for(j = 0; j < value; j++) + { + matrix[size] = 'M'; + size++; + } + i--; + } + else if(md[i] == '^') + { + matrix[size] = 'D'; + size++; + } + else + { + matrix[size] = md[i]; + size++; + } + //size++; + i++; + } + matrix[size] = '\0'; +} + + +void convertMDCigarToMatrix(char *cigar, int cigar_size, char *md, int md_size, char *matrix) +{ + int i = 0; + int j = 0; + + int size = 0; + + char tmp1[200]; + char tmp2[200]; + convertMDToMatrix(md,md_size, tmp2); + + convertCigarToMatrix(cigar, cigar_size,tmp1); + + + + while(i < strlen(tmp1)) + { + if(tmp1[i]=='M') + { + if(j < strlen(tmp2)) + { + if(tmp2[j]=='M') + { + matrix[size]='M'; + size++; + } + if(tmp2[j]!='M') + { + matrix[size]=tmp2[j]; + size++; + } + } + else + { + matrix[size]='M'; + size++; + } + } + else if(tmp1[i] == 'D') + { + matrix[size]='D'; + size++; + j++; + matrix[size]=tmp2[j]; + size++; + + } + else if(tmp1[i] == 'I') + { + matrix[size]='I'; + size++; + } + + i++; + if(j < strlen(tmp2)) + j++; + } + + if(strlen(tmp1)) + + matrix[size] = '\0'; + +} + +void convertInsertion(char * in_matrix, char * seq, char *out_matrix) +{ + int i = 0; + int j = 0; + int size = 0; + + while( i < strlen(in_matrix)) + { + if(in_matrix[i] == 'M') + { + out_matrix[size] = 'M'; + size++; + j++; + } + else if(in_matrix[i] == 'D') + { + out_matrix[size] = 'D'; + size++; + + i++; + j++; + + out_matrix[size] = seq[j]; + j++; + size++; + } + else if(in_matrix[i] == 'I') + { + out_matrix[size] = 'I'; + size++; + out_matrix[size] = seq[j]; + size++; + j++; + } + else + { + out_matrix[size] = in_matrix[i]; + size++; + j++; + } + i++; + } + out_matrix[size] = '\0'; +} + +/**********************************************/ +void outputPairedEndDiscPP() +{ + char tmp_matrix1[200]; + char tmp_matrix2[200]; + + char matrix1[200]; + char matrix2[200]; + + char cigar1[200]; + char editString1[200]; + + char cigar2[200]; + char editString2[200]; + + char seq1[SEQ_LENGTH+1]; + char qual1[SEQ_LENGTH+1]; + + char seq2[SEQ_LENGTH+1]; + char qual2[SEQ_LENGTH+1]; + + char genName[SEQ_LENGTH]; + char fname1[FILE_NAME_LENGTH]; + char fname2[FILE_NAME_LENGTH]; + char l; + int l_size; + int loc1, loc2; + int err1, err2; + char dir1, dir2; + float sc1, sc2, lsc=0; + int flag = 0; + int rNo,lrNo = -1; + int tmp; + FILE *in, *out; + + sprintf(fname1, "%s__%s__disc", mappingOutputPath, mappingOutput); + sprintf(fname2, "%s%s_DIVET.vh", mappingOutputPath, mappingOutput); + + in = fileOpen(fname1, "r"); + out = fileOpen(fname2, "w"); + + if (in != NULL) + { + flag = fread(&rNo, sizeof(int), 1, in); + } + else + { + flag = 0; + } + + seq1[SEQ_LENGTH] = '\0'; + qual1[SEQ_LENGTH] = '\0'; + + seq2[SEQ_LENGTH] = '\0'; + qual2[SEQ_LENGTH] = '\0'; + + while (flag) + { + tmp = fread(&l, sizeof(char), 1, in); + tmp = fread(genName, sizeof(char), l, in); + genName[(int)l]='\0'; + tmp = fread(&loc1, sizeof(int), 1, in); + tmp = fread(&err1, sizeof(int), 1, in); + tmp = fread(&sc1, sizeof(float), 1, in); + + //tmp = fwrite (&(mi2[k].cigarSize), sizeof(int), 1, out); + + tmp = fread(&l_size, sizeof(int), 1, in); + tmp = fread(cigar1, sizeof(char), l_size, in); + cigar1[(int)l_size]='\0'; + //tmp = fwrite ((mi2[k].cigar), sizeof(char), mi2[k].cigarSize, out); + + //tmp = fwrite (&(mi2[k].mdSize), sizeof(int), 1, out); + tmp = fread(&l_size, sizeof(int), 1, in); + tmp = fread(editString1, sizeof(char), l_size, in); + editString1[(int)l_size]='\0'; + //tmp = fwrite ((mi2[k].md), sizeof(char), mi2[k].mdSize, out); + + tmp = fread(&loc2, sizeof(int), 1, in); + tmp = fread(&err2, sizeof(int), 1, in); + tmp = fread(&sc2, sizeof(float), 1, in); + + tmp = fread(&l_size, sizeof(int), 1, in); + tmp = fread(cigar2, sizeof(char), l_size, in); + cigar2[(int)l_size]='\0'; + + tmp = fread(&l_size, sizeof(int), 1, in); + tmp = fread(editString2, sizeof(char), l_size, in); + editString2[(int)l_size]='\0'; + + convertMDCigarToMatrix(cigar1, strlen(cigar1), editString1, strlen(editString1), tmp_matrix1); + convertMDCigarToMatrix(cigar2, strlen(cigar2), editString2, strlen(editString2), tmp_matrix2); + + + if(_msf_readHasConcordantMapping[rNo] == 0) + { + + dir1 = dir2 = 'F'; + + strncpy(seq1, _msf_seqList[rNo*2].seq, SEQ_LENGTH); + strncpy(seq2, _msf_seqList[rNo*2+1].seq, SEQ_LENGTH); + + if (loc1 < 0) + { + dir1 = 'R'; + loc1 = -loc1; + + strncpy(seq1, _msf_seqList[rNo*2].rseq, SEQ_LENGTH); + } + + if (loc2 < 0) + { + dir2 = 'R'; + loc2 = -loc2; + + strncpy(seq2, _msf_seqList[rNo*2+1].rseq, SEQ_LENGTH); + } + + convertInsertion(tmp_matrix1, seq1, matrix1); + convertInsertion(tmp_matrix2, seq2, matrix2); + + + if (rNo != lrNo) + { + int j; + for (j=0; j<SEQ_LENGTH; j++) + { + lsc += _msf_seqList[rNo*2].qual[j]+_msf_seqList[rNo*2+1].qual[j]; + } + lsc /= 2*SEQ_LENGTH; + lsc -= 33; + lrNo = rNo; + } + + char event = '\0'; + + + if ( dir1 == dir2 ) + { + event = 'V'; + } + else + { + if (loc1 < loc2) + { + + if (dir1 == 'R' && dir2 == 'F') + { + event = 'E'; + + } + else if ( loc2 - loc1 >= maxPairEndedDiscordantDistance ) + { + event = 'D'; + } + else + { + event = 'I'; + } + } + else if (loc2 < loc1) + { + if (dir2 == 'R' && dir1 == 'F') + { + event = 'E'; + } + else if ( loc1 - loc2 >= maxPairEndedDiscordantDistance ) + { + event = 'D'; + } + else + { + event = 'I'; + } + } + } + _msf_seqList[rNo*2].hits[0] = 2; + if(event != 'E') + fprintf(out, "%s\t%s\t%d\t%d\t%c\t%d\t%d\t%c\t%c\t%d\t%0.0f\t%e\n", + _msf_seqList[rNo*2].name, genName, loc1, (loc1+SEQ_LENGTH-1), dir1, + loc2, (loc2+SEQ_LENGTH-1), dir2, event, (err1+err2), lsc, sc1*sc2); + + } + flag = fread(&rNo, sizeof(int), 1, in); + } + + fclose(in); + fclose(out); + + unlink(fname1); +} + +void finalizeOEAReads(char *fileName) +{ + FILE *fp_out1; + FILE * in; + + char genName[SEQ_LENGTH]; + + char fname1[FILE_NAME_LENGTH]; + char fname2[FILE_NAME_LENGTH]; + + char l=0; + int loc1=0; + + int err1; + + char d; + + float sc1=0; + int flag = 0; + int rNo=-1; + int tmp=0; + + int cigarSize = 0; + int mdSize = 0; + + char cigar[SEQ_LENGTH+1]; + char md[SEQ_LENGTH+1]; + + char *seq1, *seq2, *qual1, *qual2; + char *rqual1, *rqual2; + + seq1=NULL; seq2=NULL; qual1=NULL; qual2=NULL; + + rqual1 = getMem(200*sizeof(char)); + rqual2 = getMem(200*sizeof(char)); + + rqual1[0] = '\0'; + rqual2[0] = '\0'; + + sprintf(fname1, "%s%s_OEA", mappingOutputPath, mappingOutput); + + fp_out1 = fileOpen(fname1, "w"); + + in = NULL; + if (pairedEndDiscordantMode){ + sprintf(fname2, "%s__%s__oea", mappingOutputPath, mappingOutput); + + in = fileOpen(fname2, "r"); + } + + + if (in != NULL) + { + flag = fread(&rNo, sizeof(int), 1, in); + } + else + { + flag = 0; + } + + while (flag) + { + cigar[0] = '\0'; + md[0] = '\0'; + + tmp = fread(&l, sizeof(char), 1, in); + tmp = fread(genName, sizeof(char), l, in); + + genName[(int)l]='\0'; + + + tmp = fread(&loc1, sizeof(int), 1, in); + tmp = fread(&err1, sizeof(int), 1, in); + tmp = fread(&sc1, sizeof(float), 1, in); + + tmp = fread (&cigarSize, sizeof(int), 1, in); + tmp = fread (cigar, sizeof(char), cigarSize, in); + + cigar[cigarSize] = '\0'; + + tmp = fread (&mdSize, sizeof(int), 1, in); + tmp = fread (md, sizeof(char), mdSize, in); + md[mdSize] = '\0'; + + d = 1; + + if(loc1 < 0) + { + d = -1; + loc1 *= -1; + + seq1 = _msf_seqList[rNo].rseq; + reverse(_msf_seqList[rNo].qual, rqual1, SEQ_LENGTH); + rqual1[SEQ_LENGTH] = '\0'; + } + else + { + seq1 = _msf_seqList[rNo].seq; + qual1 = _msf_seqList[rNo].qual; + } + + if(rNo % 2 == 0) + { + seq2 = _msf_seqList[rNo+1].seq; + qual2 = _msf_seqList[rNo+1].qual; + } + else + { + seq2 = _msf_seqList[rNo-1].seq; + qual2 = _msf_seqList[rNo-1].qual; + } + + if(_msf_seqHits[rNo] != 0 && _msf_seqHits[(rNo%2==0)?rNo+1:rNo-1] == 0) + { + _msf_output.POS = loc1; + _msf_output.MPOS = 0; + _msf_output.FLAG = (rNo % 2 ==0)? 1+4+32*d+128 : 1+8+16*d+64 ; + _msf_output.ISIZE = 0; + _msf_output.SEQ = seq1; + _msf_output.QUAL = qual1; + _msf_output.QNAME = _msf_seqList[rNo].name; + _msf_output.RNAME = genName; + _msf_output.MAPQ = 255; + _msf_output.CIGAR = cigar; + _msf_output.MRNAME = "="; + + + _msf_output.optSize = 4; + _msf_output.optFields = _msf_optionalFields; + + _msf_optionalFields[0].tag = "NM"; + _msf_optionalFields[0].type = 'i'; + _msf_optionalFields[0].iVal = err1; + + _msf_optionalFields[1].tag = "MD"; + _msf_optionalFields[1].type = 'Z'; + _msf_optionalFields[1].sVal = md; + + + + //for the OEA reads + _msf_optionalFields[2].tag = "NS"; + _msf_optionalFields[2].type = 'Z'; + _msf_optionalFields[2].sVal = seq2; + + + _msf_optionalFields[3].tag = "NQ"; + _msf_optionalFields[3].type = 'Z'; + _msf_optionalFields[3].sVal = qual2; + + outputSAM(fp_out1, _msf_output); + + _msf_seqList[rNo].hits[0] = -1; + _msf_seqList[(rNo%2==0)?rNo+1:rNo-1].hits[0] = -1; + } + flag = fread(&rNo, sizeof(int), 1, in); + } + + freeMem(rqual1, 0); + freeMem(rqual2, 0); + + unlink(fname2); + + fclose(fp_out1); +} + +/* + +void outputOEA(char *fileName1, FILE * fp_out, int readSegment) +{ + int i = 0; + int j = 0; + + char *index; + + int size1 = 0; + + FILE *fp1; + + char geneFileName1[FILE_NAME_LENGTH]; + + char matrix[200]; + char cigar[MAX_CIGAR_SIZE]; + char editString[200]; + + FullMappingInfoLink *miL = getMem(_msf_seqListSize * sizeof(FullMappingInfoLink)); + + if(fileName1 != NULL) + { + + fp1 = fileOpen(fileName1, "r"); + + index = strstr(fileName1, "__"); + strncpy(geneFileName1, index + 2 * sizeof(char), strstr(index + 2, "__") - index - 2); + geneFileName1[strstr(index + 2, "__") - index - 2] = '\0'; + + for(i = 0; i < _msf_seqListSize / 2; i++) + { + fread(&size1, sizeof(int), 1, fp1); + + miL[i].mi = getMem(size1 * sizeof(FullMappingInfo) ); + + miL[i].size = size1; + + for(j = 0; j < size1; j++) + { + fread(&(miL[i].mi[j].loc), sizeof(int), 1, fp1); + + fread (&(miL[i].mi[j].err), sizeof(int), 1, fp1); + + fread (&(miL[i].mi[j].cigarSize), sizeof(int), 1, fp1); + fread ((miL[i].mi[j].cigar), sizeof(char), miL[i].mi[j].cigarSize+1, fp1); + + fread (&(miL[i].mi[j].mdSize), sizeof(int), 1, fp1); + fread ((miL[i].mi[j].md), sizeof(char), miL[i].mi[j].mdSize+1, fp1); + + miL[i].mi[j].dir = 1; + if(miL[i].mi[j].loc < 1) + { + miL[i].mi[j].loc *= -1; + miL[i].mi[j].dir = -1; + } + } + + int tmpSize = (readSegment==0) ? _msf_seqHits[i*2+1] : _msf_seqHits[i*2]; + + if(_msf_seqHits[i*2+readSegment] == 0 && size1 != 0 && _msf_oeaMapping[i*2+(readSegment == 0 ? 1: 0)] <= maxOEAOutput) + { + int d1 = 0; + + char *seq, *qual; + char *seq1, *seq2, *rseq1, *rseq2, *qual1, *qual2; + char rqual1[SEQ_LENGTH+1], rqual2[SEQ_LENGTH+1]; + + rqual1[SEQ_LENGTH] = rqual2[SEQ_LENGTH] = '\0'; + seq1 = _msf_seqList[i*2].seq; + rseq1 = _msf_seqList[i*2].rseq; + qual1 = _msf_seqList[i*2].qual; + reverse(_msf_seqList[i*2].qual, rqual1, SEQ_LENGTH); + + seq2 = _msf_seqList[i*2+1].seq; + rseq2 = _msf_seqList[i*2+1].rseq; + qual2 = _msf_seqList[i*2+1].qual; + reverse(_msf_seqList[i*2+1].qual, rqual2, SEQ_LENGTH); + + for(j = 0; j < size1 && _msf_oeaMapping[i*2+(readSegment == 0 ? 1: 0)] <= maxOEAOutput; j++) + { + d1 = (miL[i].mi[j].dir == -1)?1:0; + + if(readSegment == 0) + { + if ( d1 ) + { + seq = rseq2; + qual = rqual2; + } + else + { + seq = seq2; + qual = qual2; + } + } + else + { + if ( d1 ) + { + seq = rseq1; + qual = rqual1; + } + else + { + seq = seq1; + qual = qual1; + } + } + + _msf_oeaMapping[i*2+(readSegment == 0 ? 1: 0)]++; + + _msf_output.POS = (readSegment==1)?miL[i].mi[j].loc:0; + _msf_output.MPOS = (readSegment==0)?miL[i].mi[j].loc:0; + _msf_output.FLAG = (readSegment==0)? 1+4+32*d1+128 : 1+8+16*d1+64 ; + _msf_output.ISIZE = 0; + _msf_output.SEQ = seq, + _msf_output.QUAL = qual; + _msf_output.QNAME = _msf_seqList[i*2+(readSegment==0?1:0)].name; + _msf_output.RNAME = geneFileName1; + _msf_output.MAPQ = 255; + _msf_output.CIGAR = miL[i].mi[j].cigar; + _msf_output.MRNAME = "="; + //_msf_output.NSEQ = (readSegment == 0)?seq1:seq2; + //_msf_output.NQUAL = (readSegment == 0)?qual1:qual2; + + + _msf_output.optSize = 4; + _msf_output.optFields = _msf_optionalFields; + + _msf_optionalFields[0].tag = "NM"; + _msf_optionalFields[0].type = 'i'; + _msf_optionalFields[0].iVal = miL[i].mi[j].err; + + _msf_optionalFields[1].tag = "MD"; + _msf_optionalFields[1].type = 'Z'; + _msf_optionalFields[1].sVal = miL[i].mi[j].md; + + + + //for the OEA reads + _msf_optionalFields[2].tag = "NS"; + _msf_optionalFields[2].type = 'Z'; + _msf_optionalFields[2].sVal = (readSegment == 0)?seq1:seq2; + + + _msf_optionalFields[3].tag = "NQ"; + _msf_optionalFields[3].type = 'Z'; + _msf_optionalFields[3].sVal = (readSegment == 0)?qual1:qual2; + + outputSAM(fp_out, _msf_output); + + } + } + } + + } + + for(i = 0; i < _msf_seqListSize / 2; i++) + { + freeMem(miL[i].mi, miL[i].size * sizeof(FullMappingInfo)); + } + + freeMem(miL, _msf_seqListSize * sizeof(FullMappingInfoLink)); + + fclose(fp1); +} + +void finalizeOEAReads(char *fileName) +{ + + int i = 0; + int k = 0; + + FILE *fp_out1; + char fname1[200]; + + _msf_oeaMapping = getMem(_msf_seqListSize * sizeof(int)); + for(i = 0; i < _msf_seqListSize; i++) + { + _msf_oeaMapping[i] = 0; + } + + sprintf(fname1, "%s%s_OEA", mappingOutputPath, mappingOutput); + + fp_out1 = fileOpen(fname1, "w"); + for(i = 0; i < _msf_maxFile; i++) + { + for(k = 0; k < _msf_fileCount[i]; k++) + { + outputOEA(_msf_fileName[i][k][1], fp_out1, 0); + }// for k + } //for i + + + for(i = 0; i < _msf_maxFile; i++) + { + for(k = 0; k < _msf_fileCount[i]; k++) + { + outputOEA(_msf_fileName[i][k][0], fp_out1, 1); + }// for k + } //for i + + fclose(fp_out1); + +} +*/ + +void outputTransChromosal(char *fileName1, char *fileName2, FILE * fp_out) +{ + int i = 0; + int j = 0; + int k = 0; + + char *index; + + int size1 = 0; + int size2 = 0; + + FILE *fp1 = NULL; + FILE *fp2 = NULL; + + char geneFileName1[FILE_NAME_LENGTH]; + char geneFileName2[FILE_NAME_LENGTH]; + + FullMappingInfoLink *miL = getMem(_msf_seqListSize * sizeof(FullMappingInfoLink)); + FullMappingInfoLink *miR = getMem(_msf_seqListSize * sizeof(FullMappingInfoLink)); + + + if(fileName1 != NULL && fileName2 != NULL) + { + + fp1 = fileOpen(fileName1, "r"); + fp2 = fileOpen(fileName2, "r"); + + index = strstr(fileName1, "__"); + strncpy(geneFileName1, index + 2 * sizeof(char), strstr(index + 2, "__") - index - 2); + geneFileName1[strstr(index + 2, "__") - index - 2] = '\0'; + + index = strstr(fileName2, "__"); + strncpy(geneFileName2, index + 2 * sizeof(char), strstr(index + 2, "__") - index - 2); + geneFileName2[strstr(index + 2, "__") - index - 2] = '\0'; + + + for(i = 0; i < _msf_seqListSize / 2; i++) + { + fread(&size1, sizeof(int), 1, fp1); + fread(&size2, sizeof(int), 1, fp2); + + miL[i].mi = getMem(size1 * sizeof(FullMappingInfo) ); + miR[i].mi = getMem(size2 * sizeof(FullMappingInfo) ); + + miL[i].size = size1; + miR[i].size = size2; + + for(j = 0; j < size1; j++) + { + fread(&(miL[i].mi[j].loc), sizeof(int), 1, fp1); + + fread (&(miL[i].mi[j].err), sizeof(int), 1, fp1); + + fread (&(miL[i].mi[j].cigarSize), sizeof(int), 1, fp1); + fread ((miL[i].mi[j].cigar), sizeof(char), miL[i].mi[j].cigarSize+1, fp1); + + fread (&(miL[i].mi[j].mdSize), sizeof(int), 1, fp1); + fread ((miL[i].mi[j].md), sizeof(char), miL[i].mi[j].mdSize+1, fp1); + + miL[i].mi[j].dir = 1; + if(miL[i].mi[j].loc < 1) + { + miL[i].mi[j].loc *= -1; + miL[i].mi[j].dir = -1; + } + } + for(k = 0; k < size2; k++) + { + fread(&(miR[i].mi[k].loc), sizeof(int), 1, fp2); + + fread (&(miR[i].mi[k].err), sizeof(int), 1, fp2); + + fread (&(miR[i].mi[k].cigarSize), sizeof(int), 1, fp2); + fread ((miR[i].mi[k].cigar), sizeof(char), miR[i].mi[k].cigarSize+1, fp2); + + fread (&(miR[i].mi[k].mdSize), sizeof(int), 1, fp2); + fread ((miR[i].mi[k].md), sizeof(char), miR[i].mi[k].mdSize+1, fp2); + + miR[i].mi[k].dir = 1; + if(miR[i].mi[k].loc < 1) + { + miR[i].mi[k].loc *= -1; + miR[i].mi[k].dir = -1; + } + } + if(_msf_readHasConcordantMapping[i] == 0 && size1 != 0 && size2 != 0 && (size1 * size2 < MAX_TRANS_CHROMOSAL_OUTPUT)) + { + int d1 = 0; + int d2 = 0; + char *seq, *qual; + char *seq1, *seq2, *rseq1, *rseq2, *qual1, *qual2; + char rqual1[SEQ_LENGTH+1], rqual2[SEQ_LENGTH+1]; + rqual1[SEQ_LENGTH] = rqual2[SEQ_LENGTH] = '\0'; + seq1 = _msf_seqList[i*2].seq; + rseq1 = _msf_seqList[i*2].rseq; + qual1 = _msf_seqList[i*2].qual; + reverse(_msf_seqList[i*2].qual, rqual1, SEQ_LENGTH); + + seq2 = _msf_seqList[i*2+1].seq; + rseq2 = _msf_seqList[i*2+1].rseq; + qual2 = _msf_seqList[i*2+1].qual; + reverse(_msf_seqList[i*2+1].qual, rqual2, SEQ_LENGTH); + + for(j = 0; j < size1; j++) + { + d1 = (miL[i].mi[j].dir == -1)?1:0; + + if ( d1 ) + { + seq = rseq1; + qual = rqual1; + } + else + { + seq = seq1; + qual = qual1; + } + + for(k = 0; k < size2; k++) + { + + d2 = (miR[i].mi[k].dir == -1)?1:0; + + _msf_output.POS = miL[i].mi[j].loc; + _msf_output.MPOS = miR[i].mi[k].loc; + _msf_output.FLAG = 0; + _msf_output.ISIZE = 0; + _msf_output.SEQ = seq, + _msf_output.QUAL = qual; + _msf_output.QNAME = _msf_seqList[i*2].name; + _msf_output.RNAME = geneFileName1; + _msf_output.MAPQ = 255; + _msf_output.CIGAR = miL[i].mi[j].cigar; + _msf_output.MRNAME = "="; + + _msf_output.optSize = 2; + _msf_output.optFields = _msf_optionalFields; + + _msf_optionalFields[0].tag = "NM"; + _msf_optionalFields[0].type = 'i'; + _msf_optionalFields[0].iVal = miL[i].mi[j].err; + + _msf_optionalFields[1].tag = "MD"; + _msf_optionalFields[1].type = 'Z'; + _msf_optionalFields[1].sVal = miL[i].mi[j].md; + + + if ( d2 ) + { + seq = rseq2; + qual = rqual2; + } + else + { + seq = seq2; + qual = qual2; + } + + outputSAM(fp_out, _msf_output); + + + _msf_output.POS = miR[i].mi[k].loc; + _msf_output.MPOS = miL[i].mi[j].loc; + _msf_output.FLAG = 0; + _msf_output.ISIZE = 0; + _msf_output.SEQ = seq, + _msf_output.QUAL = qual; + _msf_output.QNAME = _msf_seqList[i*2+1].name; + _msf_output.RNAME = geneFileName2; + _msf_output.MAPQ = 255; + _msf_output.CIGAR = miR[i].mi[k].cigar; + _msf_output.MRNAME = "="; + + _msf_output.optSize = 2; + _msf_output.optFields = _msf_optionalFields; + + _msf_optionalFields[0].tag = "NM"; + _msf_optionalFields[0].type = 'i'; + _msf_optionalFields[0].iVal = miR[i].mi[k].err; + + _msf_optionalFields[1].tag = "MD"; + _msf_optionalFields[1].type = 'Z'; + _msf_optionalFields[1].sVal = miR[i].mi[k].md; + + outputSAM(fp_out, _msf_output); + + } + } + } + } + + } + + for(i = 0; i < _msf_seqListSize / 2; i++) + { + freeMem(miL[i].mi, miL[i].size * sizeof(FullMappingInfo)); + freeMem(miR[i].mi, miR[i].size * sizeof(FullMappingInfo)); + } + + freeMem(miL, _msf_seqListSize * sizeof(FullMappingInfoLink)); + freeMem(miR, _msf_seqListSize * sizeof(FullMappingInfoLink)); + + fclose(fp1); + fclose(fp2); +} + +/* + if flag is 1 it will output all the possible trans chromsal mapping + otherwise only tmp file will be delete + +*/ + +void outputAllTransChromosal(int flag) +{ + + int i = 0; + int j = 0; + int k = 0; + int l = 0; + + FILE *fp_out = NULL; + char fname1[200]; + + if(flag) + { + fp_out = fileOpen(fname1, "w"); + + sprintf(fname1, "%s%s_TRANSCHROMOSOMAL", mappingOutputPath, mappingOutput); + + // for(i = 0; i < _msf_maxFile; i++) + // { + i = 0; + for(j = i+1; j < _msf_maxFile; j++) + { + if(i != j) + { + for(k = 0; k < _msf_fileCount[i]; k++) + { + for(l = 0; l < _msf_fileCount[j]; l++) + { + outputTransChromosal(_msf_fileName[i][k][0], _msf_fileName[j][l][1], fp_out); + }// for l + }// for k + }// if + }// for j + // } //for i + } + + for(i = 0; i < _msf_maxFile; i++) + { + for(j = 0; j < _msf_fileCount[i]; j++) + { + unlink(_msf_fileName[i][j][0]); + unlink(_msf_fileName[i][j][1]); + } + } + if(flag) + fclose(fp_out); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mrfast-2.1.0.4/MrFAST.h Tue Feb 21 10:29:47 2012 -0500 @@ -0,0 +1,209 @@ +/* + * Copyright (c) <2008 - 2012>, University of Washington, Simon Fraser University + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * - Neither the names of the University of Washington, Simon Fraser University, + * nor the names of its contributors may be + * used to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +/* + Authors: + Farhad Hormozdiari + Faraz Hach + Can Alkan + Emails: + farhadh AT uw DOT edu + fhach AT cs DOT sfu DOT ca + calkan AT uw DOT edu + */ + + + +#ifndef __MR_FAST__ +#define __MR_FAST__ + +#include "Reads.h" + +#define MAP_CHUNKS 15 +#define MAX_CIGAR_SIZE 100 + + +// Pair is used to pre-processing and making the read index table +typedef struct +{ + int hv; + //char hv[50]; + int readNumber; +} Pair; + +typedef struct +{ + int hv; + unsigned int *seqInfo; +} ReadIndexTable; + + +typedef struct +{ + int loc; + char dir; + int err; + float score; + char md[MAX_CIGAR_SIZE]; + char chr[20]; + char cigar[MAX_CIGAR_SIZE]; + int cigarSize; + int mdSize; +} FullMappingInfo; + +typedef struct +{ + int loc; + char dir; + int err; + float score; + char md[MAX_CIGAR_SIZE]; + char chr[20]; + char cigar[MAX_CIGAR_SIZE]; + int cigarSize; + int mdSize; +} BestFullMappingInfo; + +typedef struct lc +{ + char md[MAP_CHUNKS][MAX_CIGAR_SIZE]; + int mdSize[MAP_CHUNKS]; + + char cigar[MAP_CHUNKS][MAX_CIGAR_SIZE]; + int cigarSize[MAP_CHUNKS]; + + int err[MAP_CHUNKS]; + int loc[MAP_CHUNKS]; + struct lc *next; +} MappingLocations; + +typedef struct inf +{ + int size; + MappingLocations *next; +} MappingInfo; + +typedef struct +{ + FILE * fp; + char name[400]; +} FILE_STRUCT; + +typedef struct +{ + FullMappingInfo *mi; + int size; +} FullMappingInfoLink; + + +typedef struct +{ + char readString[200]; + char ref[200]; + int err; + char matrix[200]; +} extraCaching; + +extern long long verificationCnt; +extern long long mappingCnt; +extern long long mappedSeqCnt; +extern long long completedSeqCnt; + +void initFAST( Read *seqList, + int seqListSize, + int *samplingLocs, + int samplingLocsSize, + char *fileName); + +void initVerifiedLocs(); +void initLookUpTable(); +void initBestMapping(); +void initBestConcordantDiscordant(int readNumber); + +void finalizeFAST(); +void finalizeBestSingleMapping(); +void finalizeBestConcordantDiscordant(); +void finalizeOEAReads(char *); + + +int mapAllSingleEndSeq(); +void mapSingleEndSeq(unsigned int *l1, int s1, int readNumber, int readSegment, int direction); +void mapPairedEndSeqList(unsigned int *l1, int s1, int readNumber, int readSegment, int direction); + +void mapPairedEndSeq(); + +void outputPairedEnd(); +void outputPairedEndDiscPP(); + + +void outputPairFullMappingInfo(FILE *fp, int readNumber); +void setPairFullMappingInfo(int readNumber, FullMappingInfo mi1, FullMappingInfo mi2); +void setFullMappingInfo(int readNumber, int loc, int dir, int err, int score, char *md, char * refName, char *cigar); + +void outputAllTransChromosal(); +void outputTransChromosal(char *fileName1, char *fileName2, FILE * fp_out); + +void generateSNPSAM(char *matrix, int matrixLength, char *outputSNP); +void generateCigar(char *matrix, int matrixLength, char *cigar); +void generateCigarFromMD(char *mistmatch, int mismatchLength, char *cigar); + +int msfHashVal(char *seq); + +int backwardEditDistance2SSE2(char *a, int lena, char *b,int lenb); +int forwardEditDistance2SSE2(char *a, int lena, char *b,int lenb); + +int forwardEditDistanceSSE2G(char *a, int lena, char *b,int lenb); +int backwardEditDistanceSSE2G(char *a, int lena, char *b,int lenb); + +int forwardEditDistance4SSE2(char *a, int lena, char *b,int lenb); +int backwardEditDistance4SSE2(char *a, int lena, char *b,int lenb); + +int forwardEditDistanceSSE2Extention(char *a, int lena, char *b,int lenb); +int backwardEditDistanceSSE2Extention(char *a, int lena, char *b,int lenb); + + +/***********************************/ + +int editDistance(int refIndex, char *seq, int seqLength, char *matrix); + +int verifySingleEndEditDistance(int refIndex, char *lSeq, int lSeqLength, char *rSeq, int rSeqLength, int segLength, + char *matrix, int *map_location, short *seqHashValue); + +int verifySingleEndEditDistance2(int refIndex, char *lSeq, int lSeqLength, char *rSeq, int rSeqLength, int segLength, + char *matrix, int *map_location, short *seqHashValue); + +int verifySingleEndEditDistance4(int refIndex, char *lSeq, int lSeqLength, char *rSeq, int rSeqLength, int segLength, + char *matrix, int *map_location, short *seqHashValue); + +int verifySingleEndEditDistanceExtention(int refIndex, char *lSeq, int lSeqLength, char *rSeq, int rSeqLength, int segLength, + char *matrix, int *map_location, short *seqHashValue); + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mrfast-2.1.0.4/Output.c Tue Feb 21 10:29:47 2012 -0500 @@ -0,0 +1,231 @@ +/* + * Copyright (c) <2008 - 2012>, University of Washington, Simon Fraser University + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * - Neither the names of the University of Washington, Simon Fraser University, + * nor the names of its contributors may be + * used to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + Authors: + Farhad Hormozdiari + Faraz Hach + Can Alkan + Emails: + farhadh AT uw DOT edu + fhach AT cs DOT sfu DOT ca + calkan AT uw DOT edu +*/ + + +#include <stdio.h> +#include <stdlib.h> +#include <zlib.h> +#include <string.h> +#include "Common.h" +#include "Output.h" + +FILE *_out_fp; +gzFile _out_gzfp; + +char buffer[300000]; +int bufferSize = 0; + + +void finalizeGZOutput() +{ + gzclose(_out_gzfp); +} + +void finalizeTXOutput() +{ + fclose(_out_fp); +} + + +void gzOutputQ(SAM map) +{ + gzprintf(_out_gzfp, "%s\t%d\t%s\t%d\t%d\t%s\t%s\t%d\t%d\t%s\t%s", + map.QNAME, + map.FLAG, + map.RNAME, + map.POS, + map.MAPQ, + map.CIGAR, + map.MRNAME, + map.MPOS, + map.ISIZE, + map.SEQ, + map.QUAL); + + int i; + + for ( i = 0; i < map.optSize; i++) + { + switch (map.optFields[i].type) + { + case 'A': + gzprintf(_out_gzfp, "\t%s:%c:%c", map.optFields[i].tag, map.optFields[i].type, map.optFields[i].cVal); + break; + case 'i': + gzprintf(_out_gzfp, "\t%s:%c:%d", map.optFields[i].tag, map.optFields[i].type, map.optFields[i].iVal); + break; + case 'f': + gzprintf(_out_gzfp, "\t%s:%c:%f", map.optFields[i].tag, map.optFields[i].type, map.optFields[i].fVal); + break; + case 'Z': + case 'H': + gzprintf(_out_gzfp, "\t%s:%c:%s", map.optFields[i].tag, map.optFields[i].type, map.optFields[i].sVal); + break; + } + } + gzprintf(_out_gzfp, "\n"); +} + +void outputSAM(FILE *fp, SAM map) +{ + fprintf(fp, "%s\t%d\t%s\t%d\t%d\t%s\t%s\t%d\t%d\t%s\t%s", + map.QNAME, + map.FLAG, + map.RNAME, + map.POS, + map.MAPQ, + map.CIGAR, + map.MRNAME, + map.MPOS, + map.ISIZE, + map.SEQ, + map.QUAL); + + + int i; + + for ( i = 0; i < map.optSize; i++) + { + switch (map.optFields[i].type) + { + case 'A': + fprintf(fp, "\t%s:%c:%c", map.optFields[i].tag, map.optFields[i].type, map.optFields[i].cVal); + break; + case 'i': + fprintf(fp, "\t%s:%c:%d", map.optFields[i].tag, map.optFields[i].type, map.optFields[i].iVal); + break; + case 'f': + fprintf(fp, "\t%s:%c:%f", map.optFields[i].tag, map.optFields[i].type, map.optFields[i].fVal); + break; + case 'Z': + case 'H': + fprintf(fp, "\t%s:%c:%s", map.optFields[i].tag, map.optFields[i].type, map.optFields[i].sVal); + break; + } + } + + fprintf(fp, "\n"); + +} + +void outputQ(SAM map) +{ + + fprintf(_out_fp, "%s\t%d\t%s\t%d\t%d\t%s\t%s\t%d\t%d\t%s\t%s", + map.QNAME, + map.FLAG, + map.RNAME, + map.POS, + map.MAPQ, + map.CIGAR, + map.MRNAME, + map.MPOS, + map.ISIZE, + map.SEQ, + map.QUAL); + + + int i; + + for ( i = 0; i < map.optSize; i++) + { + switch (map.optFields[i].type) + { + case 'A': + fprintf(_out_fp, "\t%s:%c:%c", map.optFields[i].tag, map.optFields[i].type, map.optFields[i].cVal); + break; + case 'i': + fprintf(_out_fp, "\t%s:%c:%d", map.optFields[i].tag, map.optFields[i].type, map.optFields[i].iVal); + break; + case 'f': + fprintf(_out_fp, "\t%s:%c:%f", map.optFields[i].tag, map.optFields[i].type, map.optFields[i].fVal); + break; + case 'Z': + case 'H': + fprintf(_out_fp, "\t%s:%c:%s", map.optFields[i].tag, map.optFields[i].type, map.optFields[i].sVal); + break; + } + } + + fprintf(_out_fp, "\n"); +} + +int initOutput ( char *fileName, int compressed) +{ + if (compressed) + { + char newFileName[strlen(fileName)+4]; + sprintf(newFileName, "%s.gz", fileName); + + _out_gzfp = fileOpenGZ(newFileName, "w1f"); + if (_out_gzfp == Z_NULL) + { + return 0; + } + + finalizeOutput = &finalizeGZOutput; + + output = &gzOutputQ; + } + else + { + _out_fp = fileOpen(fileName, "w"); + if (_out_fp == NULL) + { + return 0; + } + + finalizeOutput = &finalizeTXOutput; + output = &outputQ; + } + buffer[0] = '\0'; + return 1; +} + +FILE* getOutputFILE() +{ + if(_out_fp != NULL) + return _out_fp; + else if(_out_gzfp != NULL) + return _out_gzfp; + else + return NULL; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mrfast-2.1.0.4/Output.h Tue Feb 21 10:29:47 2012 -0500 @@ -0,0 +1,85 @@ +/* + * Copyright (c) <2008 - 2012>, University of Washington, Simon Fraser University + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * - Neither the names of the University of Washington, Simon Fraser University, + * nor the names of its contributors may be + * used to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + Authors: + Farhad Hormozdiari + Faraz Hach + Can Alkan + Emails: + farhadh AT uw DOT edu + fhach AT cs DOT sfu DOT ca + calkan AT uw DOT edu + */ + + + +#ifndef __OUTPUT__ +#define __OUTPUT__ + +#define FORWARD 0 +#define REVERSE 1 + +typedef struct +{ + char *tag; + char type; + char cVal; + int iVal; + float fVal; + char *sVal; +} OPT_FIELDS; + +typedef struct +{ + char *QNAME; + short FLAG; + char *RNAME; + int POS; + unsigned char MAPQ; + char *CIGAR; + char *MRNAME; + int MPOS; + int ISIZE; + char *SEQ; + char *QUAL; + + int optSize; + OPT_FIELDS *optFields; +} SAM; + +int initOutput(char *fileName, int compressed); +void (*finalizeOutput)(); +void (*output)(SAM map); +void outputSAM(FILE *fp, SAM map); + +FILE * getOutputFILE(); + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mrfast-2.1.0.4/Reads.c Tue Feb 21 10:29:47 2012 -0500 @@ -0,0 +1,773 @@ +/* + * Copyright (c) <2008 - 2012>, University of Washington, Simon Fraser University + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * - Neither the names of the University of Washington, Simon Fraser University, + * nor the names of its contributors may be + * used to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + Authors: + Farhad Hormozdiari + Faraz Hach + Can Alkan + Emails: + farhadh AT uw DOT edu + fhach AT cs DOT sfu DOT ca + calkan AT uw DOT edu + */ + + + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> +#include <zlib.h> +#include "Common.h" +#include "Reads.h" + +#define CHARCODE(a) (a=='A' ? 0 : (a=='C' ? 1 : (a=='G' ? 2 : (a=='T' ? 3 : 4)))) + +FILE *_r_fp1; +FILE *_r_fp2; +gzFile _r_gzfp1; +gzFile _r_gzfp2; +Read *_r_seq; +int _r_seqCnt; +int *_r_samplingLocs; + +/**********************************************/ +char *(*readFirstSeq)(char *); +char *(*readSecondSeq)(char *); +/**********************************************/ +char *readFirstSeqTXT( char *seq ) +{ + return fgets(seq, SEQ_MAX_LENGTH, _r_fp1); +} + +/**********************************************/ +char *readSecondSeqTXT( char *seq ) +{ + return fgets(seq, SEQ_MAX_LENGTH, _r_fp2); +} +/**********************************************/ +char *readFirstSeqGZ( char *seq ) +{ + return gzgets(_r_gzfp1, seq, SEQ_MAX_LENGTH); +} + +/**********************************************/ +char *readSecondSeqGZ( char *seq ) +{ + return gzgets(_r_gzfp2, seq, SEQ_MAX_LENGTH); +} +/**********************************************/ +int toCompareRead(const void * elem1, const void * elem2) +{ + return strcmp(((Read *)elem1)->seq, ((Read *)elem2)->seq); +} +/**********************************************/ +int readAllReads(char *fileName1, + char *fileName2, + int compressed, + unsigned char *fastq, + unsigned char pairedEnd, + Read **seqList, + unsigned int *seqListSize) +{ + double startTime=getTime(); + + char seq1[SEQ_MAX_LENGTH]; + char rseq1[SEQ_MAX_LENGTH]; + char name1[SEQ_MAX_LENGTH]; + char qual1[SEQ_MAX_LENGTH]; + char seq2[SEQ_MAX_LENGTH]; + char rseq2[SEQ_MAX_LENGTH]; + char name2[SEQ_MAX_LENGTH]; + char qual2[SEQ_MAX_LENGTH]; + + char dummy[SEQ_MAX_LENGTH]; + char ch; + int err1, err2; + int nCnt; + int discarded = 0; + int seqCnt = 0; + int maxCnt = 0; + int i; + Read *list = NULL; + + int clipped = 0; + + if (!compressed) + { + _r_fp1 = fileOpen( fileName1, "r"); + + if (_r_fp1 == NULL) + { + return 0; + } + + ch = fgetc(_r_fp1); + + if ( pairedEnd && fileName2 != NULL ) + { + _r_fp2 = fileOpen ( fileName2, "r" ); + if (_r_fp2 == NULL) + { + return 0; + } + } + else + { + _r_fp2 = _r_fp1; + } + + readFirstSeq = &readFirstSeqTXT; + readSecondSeq = &readSecondSeqTXT; + } + else + { + + _r_gzfp1 = fileOpenGZ (fileName1, "r"); + + if (_r_gzfp1 == NULL) + { + return 0; + } + + ch = gzgetc(_r_gzfp1); + + if ( pairedEnd && fileName2 != NULL ) + { + _r_gzfp2 = fileOpenGZ ( fileName2, "r" ); + if (_r_gzfp2 == NULL) + { + return 0; + } + } + else + { + _r_gzfp2 = _r_gzfp1; + } + + readFirstSeq = &readFirstSeqGZ; + readSecondSeq = &readSecondSeqGZ; + } + + if (ch == '>') + *fastq = 0; + else + *fastq = 1; + + // Counting the number of lines in the file + while (readFirstSeq(dummy)) maxCnt++; + + if (!compressed) + { + rewind(_r_fp1); + } + else + { + gzrewind(_r_gzfp1); + } + + // Calculating the Maximum # of sequences + if (*fastq) + { + maxCnt /= 4; + } + else + { + maxCnt /= 2; + } + + if (pairedEnd && fileName2 != NULL ) + maxCnt *= 2; + + list = getMem(sizeof(Read)*maxCnt); + + while( readFirstSeq(name1) ) + { + err1 = 0; + err2 = 0; + readFirstSeq(seq1); + name1[strlen(name1)-1] = '\0'; + + if ( *fastq ) + { + readFirstSeq(dummy); + readFirstSeq(qual1); + qual1[strlen(qual1)-1] = '\0'; + } + else + { + sprintf(qual1, "*"); + } + + // Cropping + if (cropSize > 0) + { + seq1[cropSize] = '\0'; + if ( *fastq ) + qual1[cropSize] = '\0'; + } + + + nCnt = 0; + for (i=0; i<strlen(seq1); i++) + { + seq1[i] = toupper (seq1[i]); + if (seq1[i] == 'N') + { + nCnt++; + } + else if (isspace(seq1[i])) + { + + seq1[i] = '\0'; + break; + } + } + + if (nCnt > errThreshold) + { + err1 = 1; + } + + // Reading the second seq of pair-ends + if (pairedEnd) + { + readSecondSeq(name2); + readSecondSeq(seq2); + name2[strlen(name2)-1] = '\0'; + + + if ( *fastq ) + { + readSecondSeq(dummy); + readSecondSeq(qual2); + + qual2[strlen(qual2)-1] = '\0'; + } + else + { + sprintf(qual2, "*"); + } + + + // Cropping + if (cropSize > 0) + { + seq2[cropSize] = '\0'; + if ( *fastq ) + qual2[cropSize] = '\0'; + } + + + nCnt = 0; + for (i=0; i<strlen(seq2); i++) + { + seq2[i] = toupper (seq2[i]); + if (seq2[i] == 'N') + { + nCnt++; + + } + else if (isspace(seq2[i])) + { + seq2[i] = '\0'; + } + } + if (nCnt > errThreshold) + { + err2 = 1; + } + + + if (strlen(seq1) < strlen(seq2)) { + seq2[strlen(seq1)] = '\0'; + if ( *fastq ) + qual2[strlen(seq1)] = '\0'; + if (!clipped) clipped = 2; + } + else if (strlen(seq1) > strlen(seq2)){ + seq1[strlen(seq2)] = '\0'; + if ( *fastq ) + qual1[strlen(seq2)] = '\0'; + if (!clipped) clipped = 1; + } + + if (clipped == 1 || clipped == 2){ + fprintf(stdout, "[PE mode warning] Sequence lengths are different, read #%d is clipped to match.\n", clipped); + clipped = 3; + } + + + + } + + if (!pairedEnd && !err1) + { + int _mtmp = strlen(seq1); + list[seqCnt].hits = getMem (1+3*_mtmp+3+strlen(name1)+1); + list[seqCnt].seq = list[seqCnt].hits + 1; + list[seqCnt].rseq = list[seqCnt].seq + _mtmp+1; + list[seqCnt].qual = list[seqCnt].rseq + _mtmp+1; + list[seqCnt].name = list[seqCnt].qual + _mtmp+1; + + list[seqCnt].hashValue = getMem(sizeof(short)*_mtmp); + list[seqCnt].rhashValue = getMem(sizeof(short)*_mtmp); + + list[seqCnt].readNumber = seqCnt; + + reverseComplete(seq1, rseq1, _mtmp); + rseq1[_mtmp] = '\0'; + int i; + + list[seqCnt].hits[0] = 0; + + for (i=0; i<=_mtmp; i++) + { + list[seqCnt].seq[i] = seq1[i]; + list[seqCnt].rseq[i] = rseq1[i] ; + list[seqCnt].qual[i] = qual1[i]; + } + + + //MAKE HASH VALUE + short code = 0; + + for(i=0; i < 4; i++) + code = code * 5 + CHARCODE(list[seqCnt].seq[i]); + list[seqCnt].hashValue[0] = code; + + + for(i = 1; i < _mtmp-3; i++) + { + list[seqCnt].hashValue[i] = (list[seqCnt].hashValue[i-1] - 125 * CHARCODE(seq1[i-1])) * 5 + CHARCODE(seq1[i+3]); + } + + + code = 0; + for(i=0; i < 4; i++) + code = code * 5 + CHARCODE(list[seqCnt].rseq[i]); + list[seqCnt].rhashValue[0] = code; + + + for(i = 1; i < _mtmp-3; i++) + { + list[seqCnt].rhashValue[i] = (list[seqCnt].rhashValue[i-1] - 125 * CHARCODE(rseq1[i-1])) * 5 + CHARCODE(rseq1[i+3]); + } + + int j = 0; + int tmpSize = _mtmp / (errThreshold+1); + + list[seqCnt].hashValSampleSize = getMem(sizeof(int)*(errThreshold+1)); + for(i=0; i < errThreshold+1; i++) + { + code = 0; + for(j = 0; j < tmpSize; j++) + { + code = code * 5 + CHARCODE(list[seqCnt].seq[i*tmpSize+j]); + } + list[seqCnt].hashValSampleSize[i] = code; + } + + sprintf(list[seqCnt].name,"%s%c", ((char*)name1)+1,'\0'); + + seqCnt++; + + } + else if (pairedEnd && !err1 && !err2) + { + + // Naming Conventions X/1, X/2 OR X + int tmplen = strlen(name1); + if (strcmp(name1, name2) != 0) + { + tmplen = strlen(name1)-2; + } + + //first seq + int _mtmp = strlen(seq1); + list[seqCnt].hits = getMem (1+3*_mtmp+3+tmplen+1); + list[seqCnt].seq = list[seqCnt].hits + 1; + list[seqCnt].rseq = list[seqCnt].seq + _mtmp+1; + list[seqCnt].qual = list[seqCnt].rseq + _mtmp+1; + list[seqCnt].name = list[seqCnt].qual + _mtmp+1; + + list[seqCnt].hashValue = getMem(sizeof(short)*_mtmp); + list[seqCnt].rhashValue = getMem(sizeof(short)*_mtmp); + list[seqCnt].readNumber = seqCnt; + + reverseComplete(seq1, rseq1, _mtmp); + rseq1[_mtmp] = '\0'; + int i; + + list[seqCnt].hits[0] = 0; + + for (i=0; i<=_mtmp; i++) + { + list[seqCnt].seq[i] = seq1[i]; + list[seqCnt].rseq[i] = rseq1[i] ; + list[seqCnt].qual[i] = qual1[i]; + } + + + name1[tmplen]='\0'; + + //MAKE HASH VALUE + short code = 0; + + for(i=0; i < 4; i++) + code = code * 5 + CHARCODE(list[seqCnt].seq[i]); + list[seqCnt].hashValue[0] = code; + + + for(i = 1; i < _mtmp-3; i++) + { + list[seqCnt].hashValue[i] = (list[seqCnt].hashValue[i-1] - 125 * CHARCODE(seq1[i-1])) * 5 + CHARCODE(seq1[i+3]); + } + + + code = 0; + for(i=0; i < 4; i++) + code = code * 5 + CHARCODE(list[seqCnt].rseq[i]); + list[seqCnt].rhashValue[0] = code; + + + for(i = 1; i < _mtmp-3; i++) + { + list[seqCnt].rhashValue[i] = (list[seqCnt].rhashValue[i-1] - 125 * CHARCODE(rseq1[i-1])) * 5 + CHARCODE(rseq1[i+3]); + } + + int j = 0; + int tmpSize = _mtmp / (errThreshold+1); + + list[seqCnt].hashValSampleSize = getMem(sizeof(int)*(errThreshold+1)); + for(i=0; i < errThreshold+1; i++) + { + code = 0; + for(j = 0; j < tmpSize; j++) + { + code = code * 5 + CHARCODE(list[seqCnt].seq[i*tmpSize+j]); + } + list[seqCnt].hashValSampleSize[i] = code; + } + + sprintf(list[seqCnt].name,"%s%c", ((char*)name1)+1,'\0'); + + + seqCnt++; + + //second seq + list[seqCnt].hits = getMem (1+3*_mtmp+3+tmplen+1); + list[seqCnt].seq = list[seqCnt].hits + 1; + list[seqCnt].rseq = list[seqCnt].seq + _mtmp+1; + list[seqCnt].qual = list[seqCnt].rseq + _mtmp+1; + list[seqCnt].name = list[seqCnt].qual + _mtmp+1; + + list[seqCnt].hashValue = getMem(sizeof(short)*_mtmp); + list[seqCnt].rhashValue = getMem(sizeof(short)*_mtmp); + list[seqCnt].readNumber = seqCnt; + + reverseComplete(seq2, rseq2, _mtmp); + rseq2[_mtmp] = '\0'; + + list[seqCnt].hits[0] = 0; + + for (i=0; i<=_mtmp; i++) + { + list[seqCnt].seq[i] = seq2[i]; + list[seqCnt].rseq[i] = rseq2[i] ; + list[seqCnt].qual[i] = qual2[i]; + } + + + name2[tmplen]='\0'; + + //MAKE HASH VALUE + code = 0; + + for(i=0; i < 4; i++) + code = code * 5 + CHARCODE(list[seqCnt].seq[i]); + list[seqCnt].hashValue[0] = code; + + + for(i = 1; i < _mtmp-3; i++) + { + list[seqCnt].hashValue[i] = (list[seqCnt].hashValue[i-1] - 125 * CHARCODE(seq1[i-1])) * 5 + CHARCODE(seq1[i+3]); + } + + + code = 0; + for(i=0; i < 4; i++) + code = code * 5 + CHARCODE(list[seqCnt].rseq[i]); + list[seqCnt].rhashValue[0] = code; + + + for(i = 1; i < _mtmp-3; i++) + { + list[seqCnt].rhashValue[i] = (list[seqCnt].rhashValue[i-1] - 125 * CHARCODE(rseq1[i-1])) * 5 + CHARCODE(rseq1[i+3]); + } + + j = 0; + tmpSize = _mtmp / (errThreshold+1); + + list[seqCnt].hashValSampleSize = getMem(sizeof(int)*(errThreshold+1)); + for(i=0; i < errThreshold+1; i++) + { + code = 0; + for(j = 0; j < tmpSize; j++) + { + code = code * 5 + CHARCODE(list[seqCnt].seq[i*tmpSize+j]); + } + list[seqCnt].hashValSampleSize[i] = code; + } + + sprintf(list[seqCnt].name,"%s%c", ((char*)name2)+1,'\0'); + + seqCnt++; + + } + else + { + discarded++; + } + } + + if (seqCnt > 0) + { + SEQ_LENGTH = strlen(list[0].seq); + } + else + { + fprintf(stdout, "ERROR: No reads can be found for mapping\n"); + return 0; + } + + + // Closing Files + if (!compressed) + { + fclose(_r_fp1); + if ( pairedEnd && fileName2 != NULL ) + { + fclose(_r_fp2); + } + } + else + { + gzclose(_r_gzfp1); + if ( pairedEnd && fileName2 != NULL) + { + gzclose(_r_fp2); + } + } + + //qsort(list, seqCnt, sizeof(Read), toCompareRead); + + adjustQual(list, seqCnt); + + *seqList = list; + *seqListSize = seqCnt; + + + _r_seq = list; + _r_seqCnt = seqCnt; + + if ( pairedEnd ) discarded *= 2; + + if (seqCnt>1) + fprintf(stdout, "%d sequences are read in %0.2f. (%d discarded) [Mem:%0.2f M]\n", seqCnt, (getTime()-startTime), discarded, getMemUsage()); + else + fprintf(stdout, "%d sequence is read in %0.2f. (%d discarded) [Mem:%0.2f M]\n", seqCnt, (getTime()-startTime), discarded, getMemUsage()); + + + + return 1; +} +/**********************************************/ +void loadSamplingLocations(int **samplingLocs, int * samplingLocsSize) +{ + int i; + int samLocsSize = errThreshold + 1; + int *samLocs = getMem(sizeof(int)*samLocsSize); + + for (i=0; i<samLocsSize; i++) + { + samLocs[i] = (SEQ_LENGTH / samLocsSize) *i; + if ( samLocs[i] + WINDOW_SIZE > SEQ_LENGTH) + samLocs[i] = SEQ_LENGTH - WINDOW_SIZE; + } + + // Outputing the sampling locations + + /* + + int j; + for (i=0; i<SEQ_LENGTH; i++) + { + fprintf(stdout, "-"); + } + fprintf(stdout, "\n"); + + for ( i=0; i<samLocsSize; i++ ) + { + for ( j=0; j<samLocs[i]; j++ ) + { + fprintf(stdout," "); + } + for (j=0; j<WINDOW_SIZE; j++) + { + fprintf(stdout,"+"); + } + fprintf(stdout, "\n"); + fflush(stdout); + } + + + for ( i=0; i<SEQ_LENGTH; i++ ) + { + fprintf(stdout, "-"); + } + fprintf(stdout, "\n"); + + */ + + *samplingLocs = samLocs; + *samplingLocsSize = samLocsSize; + _r_samplingLocs = samLocs; +} + +void finalizeReads(char *fileName) +{ + FILE *fp1=NULL; + + if (fileName != NULL) + { + fp1 = fileOpen(fileName, "w"); + } + if (pairedEndMode) + _r_seqCnt /=2; + + int i=0; + for (i = 0; i < _r_seqCnt; i++) + { + if (pairedEndMode && _r_seq[2*i].hits[0] == 0 && _r_seq[2*i+1].hits[0] == 0 && strcmp(_r_seq[2*i].qual,"*")!=0) + { + fprintf(fp1,"@%s/1\n%s\n+\n%s\n@%s/2\n%s\n+\n%s\n", _r_seq[i*2].name, _r_seq[i*2].seq, _r_seq[i*2].qual, _r_seq[i*2].name, _r_seq[i*2+1].seq, _r_seq[i*2+1].qual); + } + else if (pairedEndMode && _r_seq[2*i].hits[0] == 0 && _r_seq[2*i+1].hits[0] == 0) + { + fprintf(fp1, ">%s/1\n%s\n>%s/2\n%shits=%d\n", _r_seq[i*2].name, _r_seq[i*2].seq, _r_seq[i*2].name, _r_seq[i*2+1].seq, _r_seq[2*i+1].hits[0]); + } + else if (!pairedEndMode && _r_seq[i].hits[0] == 0 && strcmp(_r_seq[i].qual, "*")!=0) + { + fprintf(fp1,"@%s\n%s\n+\n%s\n", _r_seq[i].name, _r_seq[i].seq, _r_seq[i].qual); + } + else if (!pairedEndMode && _r_seq[i].hits[0] == 0) + { + fprintf(fp1,">%s\n%s\n", _r_seq[i].name, _r_seq[i].seq); + } + } + + fclose(fp1); + if (pairedEndMode) + _r_seqCnt *= 2; + + for (i = 0; i < _r_seqCnt; i++) + { + freeMem(_r_seq[i].hits,0); + } + + + freeMem(_r_seq,0); + freeMem(_r_samplingLocs,0); +} + +void adjustQual(Read *list, int seqCnt){ + /* This function will automatically determine the phred_offset and readjust quality values if needed */ +} + + + +/*void finalizeOEAReads(char *fileName) +{ + FILE *fp1=NULL; + FILE *fp2=NULL; + + //printf("OEA%s\n", fileName); + char fileNameOEA1[200]; + char fileNameOEA2[200]; + sprintf(fileNameOEA1, "%s_OEA1", fileName); + sprintf(fileNameOEA2, "%s_OEA2", fileName); + + + if (fileName != NULL) + { + fp1 = fileOpen(fileNameOEA1, "w"); + fp2 = fileOpen(fileNameOEA2, "w"); + } + if (pairedEndMode) + _r_seqCnt /=2; + + int i=0; + printf("%d\n", _r_seqCnt); + for (i = 0; i < _r_seqCnt; i++) + { + if (pairedEndMode && _r_seq[2*i].hits[0] == 0 && _r_seq[2*i+1].hits[0] != 0 && strcmp(_r_seq[2*i].qual, "*")==0) + { + fprintf(fp1,">%s/1\n%s\n>%s/2\n%s\n", _r_seq[i*2].name, _r_seq[i*2].seq, _r_seq[i*2].name, _r_seq[i*2+1].seq); + } + else if (pairedEndMode && _r_seq[2*i].hits[0] != 0 && _r_seq[2*i+1].hits[0] == 0 && strcmp(_r_seq[2*i].qual, "*")==0) + { + fprintf(fp2, ">%s/1\n%s\n>%s/2\n%s\n", _r_seq[i*2].name, _r_seq[i*2].seq, _r_seq[i*2].name, _r_seq[i*2+1].seq); + } + else if (pairedEndMode && _r_seq[2*i].hits[0] == 0 && _r_seq[2*i+1].hits[0] != 0 && strcmp(_r_seq[2*i].qual, "*")!=0) + { + fprintf(fp1,"@%s\n%s\n+\n%s\n@%s\n%s\n+\n%s\n", _r_seq[2*i].name, + _r_seq[2*i].seq, + _r_seq[2*i].qual, + _r_seq[2*i+1].name, + _r_seq[2*i+1].seq, + _r_seq[2*i+1].qual); + } + else if ( pairedEndMode && _r_seq[2*i].hits[0] != 0 && _r_seq[2*i+1].hits[0] == 0 && strcmp(_r_seq[2*i].qual, "*")!=0 ) + { + fprintf(fp2,"@%s\n%s\n+\n%s\n@%s\n%s\n+\n%s\n", _r_seq[2*i].name, + _r_seq[2*i].seq, + _r_seq[2*i].qual, + _r_seq[2*i+1].name, + _r_seq[2*i+1].seq, + _r_seq[2*i+1].qual); + } + } + + fclose(fp1); + fclose(fp2); + +}*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mrfast-2.1.0.4/Reads.h Tue Feb 21 10:29:47 2012 -0500 @@ -0,0 +1,65 @@ +/* + * Copyright (c) <2008 - 2012>, University of Washington, Simon Fraser University + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * - Neither the names of the University of Washington, Simon Fraser University, + * nor the names of its contributors may be + * used to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +/* + Authors: + Farhad Hormozdiari + Faraz Hach + Can Alkan + Emails: + farhadh AT uw DOT edu + fhach AT cs DOT sfu DOT ca + calkan AT uw DOT edu + */ + + +#ifndef __READ__ +#define __READ__ + +typedef struct +{ + char *name; + char *seq; + char *rseq; + char *qual; + char *hits; + int readNumber; + short *hashValue; + short *rhashValue; + int *hashValSampleSize; +} Read; + +int readAllReads(char *fileName1, char *fileName2, int compressed, unsigned char *fastq, unsigned char pe, Read **seqList, unsigned int *seqListSize); +void loadSamplingLocations(int **samplingLocs, int *samplingLocsSize); +void finalizeReads(char *fileName); +void adjustQual(Read *list, int seqCnt); + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mrfast-2.1.0.4/RefGenome.c Tue Feb 21 10:29:47 2012 -0500 @@ -0,0 +1,157 @@ +/* + * Copyright (c) <2008 - 2012>, University of Washington, Simon Fraser University + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * - Neither the names of the University of Washington, Simon Fraser University, + * nor the names of its contributors may be + * used to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + Authors: + Farhad Hormozdiari + Faraz Hach + Can Alkan + Emails: + farhadh AT uw DOT edu + fhach AT cs DOT sfu DOT ca + calkan AT uw DOT edu + */ + + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> +#include "Common.h" +#include "RefGenome.h" + +FILE *_rg_fp; +char *_rg_gen; +char *_rg_name; +int _rg_offset; +int _rg_contGen; + +/**********************************************/ +int initLoadingRefGenome(char *fileName) +{ + char ch; + _rg_fp = fileOpen (fileName, "r"); + if (fscanf(_rg_fp, "%c", &ch)) + { + if (ch == '>') + { + _rg_contGen = 0; + _rg_offset = 0; + _rg_gen = getMem(CONTIG_MAX_SIZE); + _rg_name = getMem(CONTIG_NAME_SIZE); + return 1; + } + } + return 0; +} +/**********************************************/ +void finalizeLoadingRefGenome() +{ + freeMem(_rg_gen, CONTIG_MAX_SIZE); + freeMem(_rg_name, CONTIG_NAME_SIZE); + fclose(_rg_fp); +} +/**********************************************/ +int loadRefGenome(char **refGen, char **refGenName, int *refGenOff) +{ + char ch; + int i; + int returnVal = 0; + int actualSize=0; + int size; + char *tmp; + + // New Conting + if (!_rg_contGen) + { + size = 0; + tmp = fgets(_rg_name, SEQ_MAX_LENGTH, _rg_fp); + } + else + { + size=strlen(_rg_gen); + for( i = 0 ; i < CONTIG_OVERLAP ; i++ ) + { + + _rg_gen[i] = _rg_gen[size-CONTIG_OVERLAP+i]; + if (_rg_gen[i] != 'N') + actualSize++; + } + size = CONTIG_OVERLAP; + } + while( fscanf(_rg_fp, "%c", &ch) > 0 ) + { + if (ch == '>') + { + _rg_contGen = 0; + returnVal = 1; + break; + } + else if (!isspace(ch)) + { + ch = toupper(ch); + _rg_gen[size++] = ch; + if (ch != 'N') + { + actualSize++; + } + if (actualSize == CONTIG_SIZE || size == CONTIG_MAX_SIZE) + { + _rg_contGen = 1; + returnVal=1; + break; + } + } + + } + + _rg_gen[size] = '\0'; + for (i=strlen(_rg_name)-1; i >= 0; i--) + if (!isspace(_rg_name[i])) + break; + _rg_name[i+1] = '\0'; + + *refGenOff = _rg_offset; + *refGenName = _rg_name; + *refGen = _rg_gen; + + if (_rg_contGen == 1) + { + _rg_offset += size-CONTIG_OVERLAP; + } + else + { + _rg_offset = 0; + } + + + return returnVal; +} +/**********************************************/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mrfast-2.1.0.4/RefGenome.h Tue Feb 21 10:29:47 2012 -0500 @@ -0,0 +1,51 @@ +/* + * Copyright (c) <2008 - 2012>, University of Washington, Simon Fraser University + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * - Neither the names of the University of Washington, Simon Fraser University, + * nor the names of its contributors may be + * used to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + Authors: + Farhad Hormozdiari + Faraz Hach + Can Alkan + Emails: + farhadh AT uw DOT edu + fhach AT cs DOT sfu DOT ca + calkan AT uw DOT edu + */ + + + +#ifndef _REF_GENOME_ +#define _REF_GENOME_ + +int initLoadingRefGenome(char *fileName); +void finalizeLoadingRefGenome(); +int loadRefGenome(char **refGen, char **refGenName, int *refGenOff); + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mrfast-2.1.0.4/baseFAST.c Tue Feb 21 10:29:47 2012 -0500 @@ -0,0 +1,376 @@ +/* + * Copyright (c) <2008 - 2012>, University of Washington, Simon Fraser University + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * - Neither the names of the University of Washington, Simon Fraser University, + * nor the names of its contributors may be + * used to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + Authors: + Farhad Hormozdiari + Faraz Hach + Can Alkan + Emails: + farhadh AT uw DOT edu + fhach AT cs DOT sfu DOT ca + calkan AT uw DOT edu +*/ + + + + + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <math.h> +#include "Common.h" +#include "CommandLineParser.h" +#include "Reads.h" +#include "Output.h" +#include "HashTable.h" +#include "MrFAST.h" + +char *versionNumber = "2.1"; // Current Version +unsigned char seqFastq; + +int main(int argc, char *argv[]) +{ + if (!parseCommandLine(argc, argv)) + return 1; + + configHashTable(); + /**************************************************** + * INDEXING + ***************************************************/ + if (indexingMode) + { + int i; + /******************************** + * Regular Mode + ********************************/ + configHashTable(); + for (i = 0; i < fileCnt; i++) + { + generateHashTable(fileName[i][0], fileName[i][1]); + } + } + /**************************************************** + * SEARCHING + ***************************************************/ + else + { + Read *seqList; + unsigned int seqListSize; + int fc; + int samplingLocsSize; + int *samplingLocs; + double totalLoadingTime = 0; + double totalMappingTime = 0; + double startTime; + double loadingTime; + double mappingTime; + double lstartTime; + double ppTime = 0.0; + double tmpTime;; + char *prevGen = getMem(CONTIG_NAME_SIZE); + prevGen[0]='\0'; + char *curGen; + int flag; + double maxMem=0; + char fname1[FILE_NAME_LENGTH]; + char fname2[FILE_NAME_LENGTH]; + char fname3[FILE_NAME_LENGTH]; + char fname4[FILE_NAME_LENGTH]; + char fname5[FILE_NAME_LENGTH]; + + char outputFileName[FILE_NAME_LENGTH]; + // Loading Sequences & Sampling Locations + startTime = getTime(); + if (!readAllReads(seqFile1, seqFile2, seqCompressed, &seqFastq, pairedEndMode, &seqList, &seqListSize)) + { + return 1; + } + + loadSamplingLocations(&samplingLocs, &samplingLocsSize); + totalLoadingTime += getTime()-startTime; + + if (pairedEndMode) + { + //Switching to Inferred Size + minPairEndedDistance = minPairEndedDistance - SEQ_LENGTH + 2; + maxPairEndedDistance = maxPairEndedDistance - SEQ_LENGTH + 2; + if (pairedEndDiscordantMode) + { + maxPairEndedDiscordantDistance = maxPairEndedDiscordantDistance - SEQ_LENGTH + 2; + minPairEndedDiscordantDistance = minPairEndedDiscordantDistance - SEQ_LENGTH + 2; + } + + sprintf(fname1, "__%s__1", mappingOutput); + sprintf(fname2, "__%s__2", mappingOutput); + sprintf(fname3, "__%s__disc", mappingOutput); + sprintf(fname4, "__%s__oea1", mappingOutput); + sprintf(fname5, "__%s__oea2", mappingOutput); + unlink(fname1); + unlink(fname2); + unlink(fname3); + unlink(fname4); + unlink(fname5); + } + + sprintf(outputFileName, "%s%s",mappingOutputPath , mappingOutput); + // Preparing output + initOutput(outputFileName, outCompressed); + + fprintf(stdout, "-----------------------------------------------------------------------------------------------------------\n"); + fprintf(stdout, "| %15s | %15s | %15s | %15s | %15s %15s |\n","Genome Name","Loading Time", "Mapping Time", "Memory Usage(M)","Total Mappings","Mapped reads"); + fprintf(stdout, "-----------------------------------------------------------------------------------------------------------\n"); + + /******************************** + * Regular Mode + ********************************/ + if (!pairedEndMode) + { + initLookUpTable(); + if(bestMode) + initBestMapping(seqListSize); + + for (fc = 0; fc <fileCnt; fc++) + { + if (!initLoadingHashTable(fileName[fc][1])) + { + return 1; + } + + mappingTime = 0; + loadingTime = 0; + prevGen[0] = '\0'; + flag = 1; + + do + { + flag = loadHashTable ( &tmpTime, errThreshold); // Reading a fragment + curGen = getRefGenomeName(); + + // First Time + if (flag && prevGen[0]== '\0') + { + sprintf(prevGen, "%s", curGen); + } + + if ( !flag || strcmp(prevGen, curGen)!=0) + { + + fprintf(stdout, "| %15s | %15.2f | %15.2f | %15.2f | %15lld %15lld |\n", + prevGen,loadingTime, mappingTime, maxMem, mappingCnt , mappedSeqCnt); + fflush(stdout); + + totalMappingTime += mappingTime; + totalLoadingTime += loadingTime; + + loadingTime = 0; + mappingTime = 0; + maxMem = 0; + + if (!flag) + { + break; + } + } + else if (progressRep && mappingTime != 0) + { + fprintf(stdout, "| %15s | %15.2f | %15.2f | %15.2f | %15lld %15lld |\n", + prevGen,loadingTime, mappingTime, maxMem, mappingCnt , mappedSeqCnt); + fflush(stdout); + } + + sprintf(prevGen, "%s", curGen); + + loadingTime += tmpTime; +// lstartTime = getTime(); + + initFAST(seqList, seqListSize, samplingLocs, samplingLocsSize, fileName[fc][0]); + + lstartTime = getTime(); + + + mapAllSingleEndSeq(); + + + + mappingTime += getTime() - lstartTime; + if (maxMem < getMemUsage()) + { + maxMem = getMemUsage(); + } + } while (flag); + + } // end for; + if(bestMode) + finalizeBestSingleMapping(); + finalizeFAST(); + finalizeLoadingHashTable(); + + } + // Pairedend Mapping Mode + else + { + initLookUpTable(); + if(pairedEndMode) + initBestConcordantDiscordant(seqListSize); + for (fc = 0; fc < fileCnt; fc++) + { + if (!initLoadingHashTable(fileName[fc][1])) + { + return 1; + } + mappingTime = 0; + loadingTime = 0; + prevGen[0] = '\0'; + flag = 1; + + do + { + flag = loadHashTable ( &tmpTime , errThreshold); // Reading a fragment + curGen = getRefGenomeName(); + + // First Time + if (flag && prevGen[0]== '\0') + { + sprintf(prevGen, "%s", curGen); + } + + if ( !flag || strcmp(prevGen, curGen)!=0) + { + + // DISCORDANT + lstartTime = getTime(); + outputPairedEnd(); + mappingTime += getTime() - lstartTime; + //DISCORDANT + + fprintf(stdout, "| %15s | %15.2f | %15.2f | %15.2f | %15lld %15lld |\n", + prevGen,loadingTime, mappingTime, maxMem, mappingCnt , mappedSeqCnt); + fflush(stdout); + + totalMappingTime += mappingTime; + totalLoadingTime += loadingTime; + + loadingTime = 0; + mappingTime = 0; + maxMem = 0; + + if (!flag) + { + break; + } + } + else if (progressRep && mappingTime != 0) + { + fprintf(stdout, "| %15s | %15.2f | %15.2f | %15.2f | %15lld %15lld |\n", + prevGen,loadingTime, mappingTime, maxMem, mappingCnt , mappedSeqCnt); + fflush(stdout); + } + + sprintf(prevGen, "%s", curGen); + + loadingTime += tmpTime; + lstartTime = getTime(); + + initFAST(seqList, seqListSize, samplingLocs, samplingLocsSize, fileName[fc][0]); + + mapPairedEndSeq(); + + mappingTime += getTime() - lstartTime; + if (maxMem < getMemUsage()) + { + maxMem = getMemUsage(); + } + + } while (flag); + + } // end for; + + if(pairedEndMode) + { + sprintf(outputFileName, "%s%s",mappingOutputPath , mappingOutput); + finalizeOEAReads(outputFileName); + outputAllTransChromosal(transChromosal); + finalizeBestConcordantDiscordant(); + } + + finalizeLoadingHashTable(); + + if (pairedEndDiscordantMode) + { + lstartTime = getTime(); + outputPairedEndDiscPP(); + ppTime = getTime() - lstartTime; + } + finalizeFAST(); + } //else + + finalizeOutput(); + + fprintf(stdout, "-----------------------------------------------------------------------------------------------------------\n"); + fprintf(stdout, "%19s%16.2f%18.2f\n\n", "Total:",totalLoadingTime, totalMappingTime); + if (pairedEndDiscordantMode) + fprintf(stdout, "Post Processing Time: %18.2f \n", ppTime); + fprintf(stdout, "%-30s%10.2f\n","Total Time:", totalMappingTime+totalLoadingTime); + fprintf(stdout, "%-30s%10d\n","Total No. of Reads:", seqListSize); + fprintf(stdout, "%-30s%10lld\n","Total No. of Mappings:", mappingCnt); + fprintf(stdout, "%-30s%10.0f\n\n","Avg No. of locations verified:", ceil((float)verificationCnt/seqListSize)); + + int cof = (pairedEndMode)?2:1; + + if (progressRep && maxHits != 0) + { + int frequency[maxHits+1]; + int i; + for ( i=0 ; i <= maxHits; i++) + { + frequency[i] = 0; + } + + + for (fc = 0; fc < seqListSize; fc++) + { + frequency[(int)(*(seqList[fc*cof].hits))]++; + } + frequency[maxHits] = completedSeqCnt; + for ( i=0 ; i <= maxHits; i++) + { + fprintf(stdout, "%-30s%10d%10d%10.2f%%\n","Reads Mapped to ", i, frequency[i], 100*(float)frequency[i]/(float)seqListSize); + } + } + + + finalizeReads(unmappedOutput); + freeMem(prevGen, CONTIG_NAME_SIZE); + } + + return 1; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mrfast-2.1.0.4/header Tue Feb 21 10:29:47 2012 -0500 @@ -0,0 +1,41 @@ +/* + * Copyright (c) <2008 - 2012>, University of Washington, Simon Fraser University + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. + * - Neither the name of the <ORGANIZATION> nor the names of its contributors may be + * used to endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + Authors: + Farhad Hormozdiari + Faraz Hach + Can Alkan + Emails: + farhadh AT uw DOT edu + fhach AT cs DOT sfu + calkan AT gmail DOT com + */ + +