uint Aligner::mapOnLeftEndExhaustive(const string &read, vector<uNumber>& path, const pair<kmer, uint>& overlap , uint errors){ string unitig, readLeft(read.substr(0,overlap.second)); vector<uNumber> path2keep; if(readLeft.size()==0){return 0;} auto rangeUnitigs(getEnd(overlap.first)); uint miniMiss(errors+1),miniMissIndice(9); int offset(-2); bool ended(false); for(uint i(0); i<rangeUnitigs.size(); ++i){ unitig=(rangeUnitigs[i].first); //case the rest of the read is too small if(readLeft.size()+k-1 <= unitig.size()){ uint miss(missmatchNumber(unitig.substr(unitig.size()-readLeft.size()-k+1,readLeft.size()), readLeft, errors)); if(miss<miniMiss){ miniMiss=miss; miniMissIndice=i; offset=unitig.size()-readLeft.size()-k+1; ended=true; } }else{ //case the read is big enough we want to recover a true overlap uint miss(missmatchNumber(unitig.substr(0,unitig.size()-k+1), readLeft.substr(readLeft.size()-(unitig.size()-k+1)), errors)); if(miss<miniMiss){ kmer overlapNum(str2num(unitig.substr(0,k-1))); vector<uNumber> possiblePath; miss+=mapOnLeftEndExhaustive(read , possiblePath, {overlapNum,overlap.second-(unitig.size()-k+1)}, errors-miss); if(miss<miniMiss){ path2keep=possiblePath; miniMiss=miss; miniMissIndice=i; offset=-1; ended=false; } } } } if (miniMiss<=errors){ if(ended){ path.push_back(offset); }else{ path.insert(path.end(), path2keep.begin(),path2keep.end()); } path.push_back(rangeUnitigs[miniMissIndice].second); } return miniMiss; }
uint Aligner::checkBeginExhaustive(const string& read, pair<kmer, uint>& overlap, vector<uNumber>& path, uint errors){ if(overlap.second==0){path.push_back(0);return 0;} string readLeft(read.substr(0,overlap.second)),unitig; auto rangeUnitigs(getEnd(overlap.first)); uint minMiss(errors+1),indiceMinMiss(0); int offset(-2); bool ended(false); vector<uNumber> path2keep; for(uint i(0); i<rangeUnitigs.size(); ++i){ unitig=(rangeUnitigs[i].first); if(unitig.size()-k+1>=readLeft.size()){ uint miss(missmatchNumber(unitig.substr(unitig.size()-readLeft.size()-k+1,readLeft.size()),readLeft, errors)); if(miss<minMiss){ minMiss=miss; indiceMinMiss=i; ended=true; offset=(unitig.size()-readLeft.size()-k+1); } }else{ uint miss(missmatchNumber(unitig.substr(0,unitig.size()-k+1), readLeft.substr(readLeft.size()+k-1-unitig.size()), errors)); if(miss<minMiss){ kmer overlapNum(str2num(unitig.substr(0,k-1))); vector<uNumber> possiblePath; miss+=mapOnLeftEndExhaustive(read, possiblePath, {overlapNum,overlap.second-(unitig.size()-k+1)},errors-miss); if(miss<minMiss){ sucessML++; minMiss=miss; indiceMinMiss=i; path2keep=possiblePath; ended=false; } } } } if(minMiss<=errors){ if(ended){ path.push_back(offset); path.push_back(rangeUnitigs[indiceMinMiss].second); }else{ path.insert(path.end(), path2keep.begin(), path2keep.end()); path.push_back(rangeUnitigs[indiceMinMiss].second); } } return minMiss; }