]> git.donarmstrong.com Git - mothur.git/blobdiff - decalc.cpp
working on search=dist in chimera.slayer
[mothur.git] / decalc.cpp
index 0b9f466a55e3e42175260468713d34702d8d2831..3a8c9d5711fa56631a4cac6cac70658fc2ad27f9 100644 (file)
@@ -12,7 +12,7 @@
 #include "dist.h"
 #include "eachgapdist.h"
 #include "ignoregaps.h"
-
+#include "eachgapdist.h"
 
 //***************************************************************************************************************
 void DeCalculator::setMask(string ms) { 
@@ -683,9 +683,9 @@ float DeCalculator::getCoef(vector<float> obs, vector<float> qav) {
 }
 //***************************************************************************************************************
 //gets closest matches to each end, since chimeras will most likely have different parents on each end
-vector<Sequence*> DeCalculator::findClosest(Sequence* querySeq, vector<Sequence*> db, int& numWanted, vector<int>& indexes) {
+vector<Sequence*> DeCalculator::findClosest(Sequence* querySeq, vector<Sequence*>& thisTemplate, vector<Sequence*>& thisFilteredTemplate, int numWanted, int minSim) {
        try {
-               indexes.clear();
+               //indexes.clear();
                
                vector<Sequence*> seqsMatches;  
                
@@ -726,7 +726,7 @@ vector<Sequence*> DeCalculator::findClosest(Sequence* querySeq, vector<Sequence*
                        //if you are a base
                        if (isalpha(queryAligned[i])) {         baseCount++;    }
                        //if you have 1/3
-                       if (baseCount >= numBases) { rightSpot = i;  break; } //last 1/3
+                       if (baseCount > numBases + 1) { rightSpot = i;  break; } //last 1/3
                }
                
                //trim end
@@ -738,27 +738,28 @@ vector<Sequence*> DeCalculator::findClosest(Sequence* querySeq, vector<Sequence*
                                break;
                        }
                }
-               rightQuery = queryAligned.substr(rightSpot, (lastBaseSpot-rightSpot)); //sequence from pos spot to end
+               rightQuery = queryAligned.substr(rightSpot, (lastBaseSpot-rightSpot+1)); //sequence from pos spot to end
                
                Sequence queryLeft(querySeq->getName(), leftQuery);
                Sequence queryRight(querySeq->getName(), rightQuery);
+               
 //cout << querySeq->getName() << '\t' << leftSpot << '\t' << rightSpot << '\t' << firstBaseSpot << '\t' << lastBaseSpot << endl;
 //cout << queryUnAligned.length() << '\t' << queryLeft.getUnaligned().length() << '\t' << queryRight.getUnaligned().length() << endl;
-               for(int j = 0; j < db.size(); j++){
+               for(int j = 0; j < thisFilteredTemplate.size(); j++){
                        
-                       string dbAligned = db[j]->getAligned();
+                       string dbAligned = thisFilteredTemplate[j]->getAligned();
                        string leftDB = dbAligned.substr(firstBaseSpot, (leftSpot-firstBaseSpot+1)); //first 1/3 of the sequence
-                       string rightDB = dbAligned.substr(rightSpot, (lastBaseSpot-rightSpot)); //last 1/3 of the sequence
-                       
-                       Sequence dbLeft(db[j]->getName(), leftDB);
-                       Sequence dbRight(db[j]->getName(), rightDB);
+                       string rightDB = dbAligned.substr(rightSpot, (lastBaseSpot-rightSpot+1)); //last 1/3 of the sequence
+
+                       Sequence dbLeft(thisFilteredTemplate[j]->getName(), leftDB);
+                       Sequence dbRight(thisFilteredTemplate[j]->getName(), rightDB);
 
                        distcalculator->calcDist(queryLeft, dbLeft);
                        float distLeft = distcalculator->getDist();
                        
                        distcalculator->calcDist(queryRight, dbRight);
                        float distRight = distcalculator->getDist();
-                       
+
                        SeqDist subjectLeft;
                        subjectLeft.seq = NULL;
                        subjectLeft.dist = distLeft;
@@ -780,6 +781,7 @@ vector<Sequence*> DeCalculator::findClosest(Sequence* querySeq, vector<Sequence*
                //sort by smallest distance
                sort(distsRight.begin(), distsRight.end(), compareSeqDist);
                sort(distsLeft.begin(), distsLeft.end(), compareSeqDist);
+
                
                //merge results         
                map<string, string> seen;
@@ -788,51 +790,63 @@ vector<Sequence*> DeCalculator::findClosest(Sequence* querySeq, vector<Sequence*
                vector<SeqDist> dists;
                float lastRight = distsRight[0].dist;
                float lastLeft = distsLeft[0].dist;
-               int lasti = 0;
-               for (int i = 0; i < distsLeft.size(); i++) {
+
+               float maxDist = 1.0 - (minSim / 100.0);
+
+               for (int i = 0; i < numWanted+1; i++) {
+                       if (m->control_pressed) { return seqsMatches; }
+                       
                        //add left if you havent already
-                       it = seen.find(db[distsLeft[i].index]->getName());
-                       if (it == seen.end()) {  
+                       it = seen.find(thisTemplate[distsLeft[i].index]->getName());
+                       if (it == seen.end() && distsLeft[i].dist <= maxDist) {  
                                dists.push_back(distsLeft[i]);
-                               seen[db[distsLeft[i].index]->getName()] = db[distsLeft[i].index]->getName();
+                               seen[thisTemplate[distsLeft[i].index]->getName()] = thisTemplate[distsLeft[i].index]->getName();
                                lastLeft =  distsLeft[i].dist;
+//                             cout << "loop-left\t" << db[distsLeft[i].index]->getName() << '\t' << distsLeft[i].dist << endl;
                        }
 
                        //add right if you havent already
-                       it = seen.find(db[distsRight[i].index]->getName());
-                       if (it == seen.end()) {  
+                       it = seen.find(thisTemplate[distsRight[i].index]->getName());
+                       if (it == seen.end() && distsRight[i].dist <= maxDist) {  
                                dists.push_back(distsRight[i]);
-                               seen[db[distsRight[i].index]->getName()] = db[distsRight[i].index]->getName();
+                               seen[thisTemplate[distsRight[i].index]->getName()] = thisTemplate[distsRight[i].index]->getName();
                                lastRight =  distsRight[i].dist;
+//                             cout << "loop-right\t" << db[distsRight[i].index]->getName() << '\t' << distsRight[i].dist << endl;
                        }
                        
-                       if (dists.size() > numWanted) { lasti = i; break; } //you have enough results
+                       if (i == numWanted) { break; }
+                       
                }
                
-               //add in dups
-               lasti++;
-               int i = lasti;
-               while (i < distsLeft.size()) {  
-                       if (distsLeft[i].dist == lastLeft) {  dists.push_back(distsLeft[i]);  numWanted++; }
-                       else { break; }
-                       i++;
+               //are we still above the minimum similarity cutoff
+               if ((lastLeft >= minSim) || (lastRight >= minSim)) {
+                       //add in ties from left
+                       int i = numWanted;
+                       while (i < distsLeft.size()) {  
+                               if (distsLeft[i].dist == lastLeft) {  dists.push_back(distsLeft[i]);  }
+                               else { break; }
+                               i++;
+                       }
+                       
+                       //add in ties from right
+                       i = numWanted;
+                       while (i < distsRight.size()) {  
+                               if (distsRight[i].dist == lastRight) {  dists.push_back(distsRight[i]);  }
+                               else { break; }
+                               i++;
+                       }
                }
                
-               i = lasti;
-               while (i < distsRight.size()) {  
-                       if (distsRight[i].dist == lastRight) {  dists.push_back(distsRight[i]);  numWanted++; }
-                       else { break; }
-                       i++;
-               }
+               //cout << numWanted << endl;
+               for (int i = 0; i < dists.size(); i++) {
+//                     cout << db[dists[i].index]->getName() << '\t' << dists[i].dist << endl;
 
-               if (numWanted > dists.size()) { m->mothurOut("numwanted is larger than the number of template sequences, adjusting numwanted."); m->mothurOutEndLine(); numWanted = dists.size(); }
+                       if ((thisTemplate[dists[i].index]->getName() != querySeq->getName()) && (((1.0-dists[i].dist)*100) >= minSim)) {
+                               Sequence* temp = new Sequence(thisTemplate[dists[i].index]->getName(), thisTemplate[dists[i].index]->getAligned()); //have to make a copy so you can trim and filter without stepping on eachother.
+                               //cout << querySeq->getName() << '\t' << thisTemplate[dists[i].index]->getName()  << '\t' << dists[i].dist << endl;
+                               seqsMatches.push_back(temp);
+                       }
 
-//cout << numWanted << endl;
-               for (int i = 0; i < numWanted; i++) {
-//cout << dists[i].seq->getName() << '\t' << dists[i].dist << endl;
-                       Sequence* temp = new Sequence(db[dists[i].index]->getName(), db[dists[i].index]->getAligned()); //have to make a copy so you can trim and filter without stepping on eachother.
-                       seqsMatches.push_back(temp);
-                       indexes.push_back(dists[i].index);
                }
                
                return seqsMatches;