NVBIO
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
sink_inl.h
Go to the documentation of this file.
1 /*
2  * nvbio
3  * Copyright (c) 2011-2014, NVIDIA CORPORATION. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  * * Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * * Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  * * Neither the name of the NVIDIA CORPORATION nor the
13  * names of its contributors may be used to endorse or promote products
14  * derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19  * DISCLAIMED. IN NO EVENT SHALL NVIDIA CORPORATION BE LIABLE FOR ANY
20  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 #pragma once
29 
30 #include <nvbio/basic/types.h>
31 #include <nvbio/basic/simd.h>
32 
33 namespace nvbio {
34 namespace aln {
35 
36 // A sink for valid alignments, mantaining only a single best alignment
37 //
38 template <typename ScoreType>
40 BestSink<ScoreType>::BestSink() : score( Field_traits<ScoreType>::min() ), sink( make_uint2( uint32(-1), uint32(-1) ) ) {}
41 
42 // invalidate
43 //
44 template <typename ScoreType>
47 {
49  sink = make_uint2( uint32(-1), uint32(-1) );
50 }
51 
52 // store a valid alignment
53 //
54 // \param score alignment's score
55 // \param sink alignment's end
56 //
57 template <typename ScoreType>
59 void BestSink<ScoreType>::report(const ScoreType _score, const uint2 _sink)
60 {
61  // NOTE: we must use <= here because otherwise we won't pick the bottom-right most one
62  // in case there's multiple optimal scores
63  if (score <= _score)
64  {
65  score = _score;
66  sink = _sink;
67  }
68 }
69 
70 // A sink for valid alignments, mantaining the best two alignments
71 //
72 template <typename ScoreType>
75  score1( Field_traits<ScoreType>::min() ),
76  score2( Field_traits<ScoreType>::min() ),
77  sink1( make_uint2( uint32(-1), uint32(-1) ) ),
78  sink2( make_uint2( uint32(-1), uint32(-1) ) ),
79  m_distinct_dist( distinct_dist ) {}
80 
81 // invalidate
82 //
83 template <typename ScoreType>
86 {
89  sink1 = make_uint2( uint32(-1), uint32(-1) );
90  sink2 = make_uint2( uint32(-1), uint32(-1) );
91 }
92 
93 // store a valid alignment
94 //
95 // \param score alignment's score
96 // \param sink alignment's end
97 //
98 template <typename ScoreType>
100 void Best2Sink<ScoreType>::report(const ScoreType score, const uint2 sink)
101 {
102  // NOTE: we must use <= here because otherwise we won't pick the bottom-right most one
103  // in case there's multiple optimal scores
104  if (score1 <= score)
105  {
106  score1 = score;
107  sink1 = sink;
108  }
109  else if (score2 <= score && (sink.x + m_distinct_dist < sink1.x || sink.x > sink1.x + m_distinct_dist))
110  {
111  score2 = score;
112  sink2 = sink;
113  }
114 }
115 
116 // A sink for valid alignments, mantaining the best two alignments
117 //
118 template <typename ScoreType, uint32 N>
120 BestColumnSink<ScoreType,N>::BestColumnSink(const uint32 column_width, const ScoreType min_score) :
121  m_column_width( column_width ),
122  m_min_score( min_score )
123 {
124  invalidate();
125 }
126 
127 // invalidate
128 //
129 template <typename ScoreType, uint32 N>
132 {
133  for (uint32 i = 0; i <= N; ++i)
134  {
135  scores[i] = Field_traits<ScoreType>::min();
136  sinks[i] = make_uint2( uint32(-1), uint32(-1) );
137  }
138 }
139 
140 // store a valid alignment
141 //
142 // \param score alignment's score
143 // \param sink alignment's end
144 //
145 template <typename ScoreType, uint32 N>
147 void BestColumnSink<ScoreType,N>::report(const ScoreType score, const uint2 sink)
148 {
149  if (score < m_min_score)
150  return;
151 
152  const uint32 col = nvbio::min( sink.x / m_column_width, N-1u );
153 
154  if (scores[col] <= score)
155  {
156  scores[col] = score;
157  sinks[col] = sink;
158  }
159 }
160 
161 // return the index of the best and second-best alignments
162 //
163 template <typename ScoreType, uint32 N>
165 void BestColumnSink<ScoreType,N>::best2(uint32& i1, uint32& i2, const uint32 min_dist) const
166 {
167  ScoreType s1 = Field_traits<ScoreType>::min();
168  ScoreType s2 = Field_traits<ScoreType>::min();
169  i1 = N;
170  i2 = N;
171 
172  // look for the best hit
173  for (uint32 i = 0; i < N; ++i)
174  {
175  if (s1 < scores[i])
176  {
177  s1 = scores[i];
178  i1 = i;
179  }
180  }
181 
182  // check whether we found a valid score
183  if (s1 == Field_traits<ScoreType>::min())
184  return;
185 
186  // look for the second hit, at a minimum distance from the best
187  for (uint32 i = 0; i < N; ++i)
188  {
189  if ((s2 < scores[i]) &&
190  ((sinks[i].x + min_dist <= sinks[i1].x) ||
191  (sinks[i].x >= sinks[i1].x + min_dist)))
192  {
193  s2 = scores[i];
194  i2 = i;
195  }
196  }
197 }
198 
199 } // namespace aln
200 } // namespace nvbio