Пример #1
0
			ReturnValue np(iter_a const a, iter_a const ae, iter_b const b, iter_b const be, index_type const maxd = std::numeric_limits<index_type>::max())
			{
				assert ( ae-a >= 0 );
				assert ( be-b >= 0 );

				size_t const an = ae-a;
				size_t const bn = be-b;

				if ( ! an || ! bn )
				{
					return ReturnValue(0,0,0);
				}

				size_t const sn = std::max(an,bn);
				// number of diagonals
				index_type const numdiag = (sn<<1)+1;

				if ( numdiag > static_cast<index_type>(DE.size()) )
				{
					DE.resize(numdiag);
					DO.resize(numdiag);
				}

				NPElement * DP = DE.begin() + sn;
				NPElement * DN = DO.begin() + sn;

				// diagonal containing bottom right of matrix
				int64_t fdiag = std::numeric_limits<int64_t>::max();

				// how far do we get without an error?
				{
					index_type const s = slide<iter_a,iter_b,false>(a,ae,b,be,0);
					DP[0].offset = s;
				}

				if ( DP[0].offset >= static_cast<int64_t>(std::min(an,bn)) )
				{
					assert ( DP[0].offset == static_cast<int64_t>(std::min(an,bn)) );

					uint64_t const n = std::min(an,bn);
					return ReturnValue(n,n,0);
				}

				index_type d = 1;

				assert ( DP[0].offset < static_cast<int64_t>(std::min(an,bn)) );

				{
					index_type const p = DP[0].offset;
					index_type const s = slide<iter_a,iter_b,true>(a,ae,b+1,be,p);
					DN[-1].offset = p + s;
				}
				{
					index_type const p = DP[0].offset+1;
					index_type const s = slide<iter_a,iter_b,false>(a,ae,b,be,p);
					DN[ 0].offset = p + s;
				}
				{
					index_type const p = DP[0].offset;
					index_type const s = slide<iter_a,iter_b,false>(a+1,ae,b,be,p);
					DN[ 1].offset = p + s;
				}
				d += 1;
				std::swap(DP,DN);

				for ( ; d < maxd ; ++d )
				{
					// std::cerr << "d=" << d << std::endl;

					bool done = false;

					for ( int64_t di = -d+1; di <= d-1; ++di )
					{
						int64_t const apos = std::max( di,static_cast<int64_t>(0))+DP[di].offset;
						int64_t const bpos = std::max(-di,static_cast<int64_t>(0))+DP[di].offset;
						assert ( apos >= 0 );
						assert ( bpos >= 0 );

						assert ( static_cast< uint64_t >(apos) <= an );
						assert ( static_cast< uint64_t >(bpos) <= bn );

						// std::cerr << "d=" << d << " di=" << di << " apos=" << apos << " bpos=" << bpos << " an=" << an << " bn=" << bn << std::endl;

						if (
							static_cast< uint64_t >(apos) == an
							||
							static_cast< uint64_t >(bpos) == bn
						)
						{
							fdiag = di;
							done = true;
						}
					}
					if ( done )
					{
						break;
					}

					iter_a aa = a;
					iter_b bb = b + d;

					{
						// extend below
						index_type const p = DP[-d+1].offset;
						index_type const s = slide<iter_a,iter_b,true>(aa,ae,bb,be,p);
						DN[-d].offset   = p + s;

						bb -= 1;
					}

					{
						index_type const top  = DP[-d+2].offset;
						index_type const diag = DP[-d+1].offset;

						if ( diag+1 >= top )
						{
							index_type const p = diag+1;
							index_type const s = slide<iter_a,iter_b,true>(aa,ae,bb,be,p);
							DN[-d+1].offset = p + s;
						}
						else
						{
							index_type const p = top;
							index_type const s = slide<iter_a,iter_b,true>(aa,ae,bb,be,p);
							DN[-d+1].offset = p + s;
						}

						bb -= 1;
					}

					for ( index_type di = -d+2; di < 0; ++di )
					{
						index_type const left = DP[di-1].offset;
						index_type const diag = DP[di].offset;
						index_type const top  = DP[di+1].offset;

						if ( diag >= left )
						{
							if ( diag+1 >= top )
							{
								index_type const p = diag+1;
								index_type const s = slide<iter_a,iter_b,true>(aa,ae,bb,be,p);
								DN[di].offset = p + s;
							}
							else
							{
								index_type const p = top;
								index_type const s = slide<iter_a,iter_b,true>(aa,ae,bb,be,p);
								DN[di].offset = p + s;
							}
						}
						else
						{
							if ( left+1 >= top )
							{
								index_type const p = left+1;
								index_type const s = slide<iter_a,iter_b,true>(aa,ae,bb,be,p);
								DN[di].offset = p + s;
							}
							else
							{
								index_type const p = top;
								index_type const s = slide<iter_a,iter_b,true>(aa,ae,bb,be,p);
								DN[di].offset = p + s;
							}
						}

						bb -= 1;
					}

					{
						index_type const left = DP[-1].offset;
						index_type const diag = DP[0].offset;
						index_type const top = DP[1].offset;

						if ( diag >= left )
						{
							if ( diag >= top )
							{
								index_type const p = diag+1;
								index_type const s = slide<iter_a,iter_b,false>(aa,ae,bb,be,p);
								DN[0].offset = p + s;
							}
							else
							{
								index_type const p = top+1;
								index_type const s = slide<iter_a,iter_b,false>(aa,ae,bb,be,p);
								DN[0].offset = p + s;
							}
						}
						else
						{
							if ( left >= top )
							{
								index_type const p = left+1;
								index_type const s = slide<iter_a,iter_b,false>(aa,ae,bb,be,p);
								DN[0].offset = p + s;
							}
							else
							{
								index_type const p = top+1;
								index_type const s = slide<iter_a,iter_b,false>(aa,ae,bb,be,p);
								DN[0].offset = p + s;
							}
						}

						aa += 1;
					}

					for ( index_type di = 1; di <= d-2 ; ++di )
					{
						index_type const left = DP[di-1].offset;
						index_type const diag = DP[di].offset;
						index_type const top  = DP[di+1].offset;

						if ( diag+1 >= left )
						{
							if ( diag >= top )
							{
								index_type const p = diag+1;
								index_type const s = slide<iter_a,iter_b,false>(aa,ae,bb,be,p);
								DN[di].offset = p + s;
							}
							else
							{
								index_type const p = top+1;
								index_type const s = slide<iter_a,iter_b,false>(aa,ae,bb,be,p);
								DN[di].offset = p + s;
							}
						}
						else
						{
							if ( left >= top+1 )
							{
								index_type const p = left;
								index_type const s = slide<iter_a,iter_b,false>(aa,ae,bb,be,p);
								DN[di].offset = p + s;
							}
							else
							{
								index_type const p = top+1;
								index_type const s = slide<iter_a,iter_b,false>(aa,ae,bb,be,p);
								DN[di].offset = p + s;
							}
						}

						aa += 1;
					}

					{
						index_type const left = DP[d-2].offset;
						index_type const diag = DP[d-1].offset;

						if ( diag+1 >= left )
						{
							index_type const p = diag+1;
							index_type const s = slide<iter_a,iter_b,false>(aa,ae,bb,be,p);
							DN[ d-1].offset = p + s;
						}
						else
						{
							index_type const p = left;
							index_type const s = slide<iter_a,iter_b,false>(aa,ae,bb,be,p);
							DN[ d-1].offset = p + s;
						}

						aa += 1;
					}

					{
						// extend above
						index_type const p = DP[ d-1].offset;
						index_type const s = slide<iter_a,iter_b,false>(aa,ae,bb,be,p);
						DN[d  ].offset = p + s;
					}

					std::swap(DP,DN);
				}

				index_type const ed = d-1;

				int64_t const apos = std::max( fdiag,static_cast<int64_t>(0))+DP[fdiag].offset;
				int64_t const bpos = std::max(-fdiag,static_cast<int64_t>(0))+DP[fdiag].offset;
				assert ( apos >= 0 );
				assert ( bpos >= 0 );

				return ReturnValue(apos,bpos,ed);
			}
Пример #2
0
bool clipAdapters(
	libmaus2::bambam::BamAlignment & algn,
	libmaus2::autoarray::AutoArray<char> & R,
	libmaus2::autoarray::AutoArray<char> & Q,
	libmaus2::bambam::BamSeqEncodeTable const & seqenc,
	libmaus2::autoarray::AutoArray<libmaus2::bambam::cigar_operation> & cigop,
	libmaus2::bambam::BamAlignment::D_array_type & T
)
{
	// a3,as
	uint64_t const asclip = algn.hasAux("as") ? algn.getAuxAsNumber<int>("as") : 0;
	uint64_t const a3clip = algn.hasAux("a3") ? algn.getAuxAsNumber<int>("a3") : 0;
	uint64_t const aclip = std::max(asclip,a3clip);
	bool     const reverse = algn.isReverse();

	if ( aclip )
	{
		uint64_t const len = algn.decodeRead(R);
		algn.decodeQual(Q);

		if ( (len - aclip) > 1 )
		{
			if ( algn.isMapped() )
			{
				uint32_t const numcigop = algn.getCigarOperations(cigop);

				if ( numcigop == cigop.size() )
					cigop.resize(numcigop+1);

				if ( reverse )
				{
				    std::reverse(cigop.begin(),cigop.begin()+numcigop);
				}


				// can't just add a HC to the cigar
				uint32_t index;
				uint32_t hardclip = 0;
				uint32_t cig_type;
				int32_t  left     = aclip;
				int32_t  repos    = 0;

				for ( index = numcigop - 1; index > 0; index-- )
				{
				    	cig_type = bam_cigar_type(cigop[index].first);

					if ( cig_type == 0 )
					{
				    	    	hardclip += cigop[index].second;
					}
					else
					{
					    	if ( cig_type & 1 )
						{
						    	if ( cigop[index].second < left )
							{
					    	    	    	left -= cigop[index].second;
						    	}
							else
							{
							    	break;
						    	}
					    	}

				    	    	if ( cig_type & 2 )
						{
				    		    	// move pos if reversed
						    	repos += cigop[index].second;
					    	}
					}
				}

				cig_type = bam_cigar_type(cigop[index].first);

				if ( cigop[index].second != left )
				{
				    	cigop[index++].second -= left;
				}

 				cigop[index] = libmaus2::bambam::cigar_operation(libmaus2::bambam::BamFlagBase::LIBMAUS2_BAMBAM_CHARD_CLIP, aclip + hardclip);

			    	if ( numcigop > index + 1 )
				    	cigop.resize(index + 1);

				if ( reverse )
				{
				    std::reverse(cigop.begin(),cigop.begin() + index + 1);

				    // account for the last possible pos move
    	    	    	    	    if ( cig_type & 2 )
				    	    repos += left;

				    if ( repos )
				    {
				    	// clipping has moved the pos point
					algn.putPos(algn.getPos() + repos);
				    }

				}

				algn.replaceCigarString(cigop.begin(),index + 1,T);
			}


		    	if ( !reverse )
			{
				algn.replaceSequence(seqenc,R.begin(),Q.begin(),len-aclip,T);
				algn.putAuxString("qs",std::string(R.begin()+(len-aclip),R.begin()+len));
				algn.putAuxString("qq",std::string(Q.begin()+(len-aclip),Q.begin()+len));
			}
			else
			{
				algn.replaceSequence(seqenc, (R.begin() + aclip), (Q.begin() + aclip), len - aclip, T);
				algn.putAuxString("qs", std::string(R.begin(), R.begin() + aclip));
				algn.putAuxString("qq", std::string(Q.begin(), Q.begin() + aclip));
			}
		}
	}

	return true;
}
Пример #3
0
			void resize(uint64_t const n)
			{
				requests.resize(n);
			}