1 // ==========================================================================
2 //                 SeqAn - The Library for Sequence Analysis
3 // ==========================================================================
4 // Copyright (c) 2006-2018, Knut Reinert, FU Berlin
5 // All rights reserved.
6 //
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions are met:
9 //
10 //     * Redistributions of source code must retain the above copyright
11 //       notice, this list of conditions and the following disclaimer.
12 //     * Redistributions in binary form must reproduce the above copyright
13 //       notice, this list of conditions and the following disclaimer in the
14 //       documentation and/or other materials provided with the distribution.
15 //     * Neither the name of Knut Reinert or the FU Berlin nor the names of
16 //       its contributors may be used to endorse or promote products derived
17 //       from this software without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 // ARE DISCLAIMED. IN NO EVENT SHALL KNUT REINERT OR THE FU BERLIN BE LIABLE
23 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 // OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
29 // DAMAGE.
30 //
31 // ==========================================================================
32 // Author: Rene Rahn <rene.rahn@fu-berlin.de>
33 // ==========================================================================
34 // Adaptor methods to transcribe a set of trace segments into the
35 // alignment representing structure.
36 // ==========================================================================
37 
38 #ifndef SEQAN_INCLUDE_SEQAN_ALIGN_DP_TRACEBACK_ADAPTOR_H_
39 #define SEQAN_INCLUDE_SEQAN_ALIGN_DP_TRACEBACK_ADAPTOR_H_
40 
41 namespace seqan {
42 
43 // ----------------------------------------------------------------------------
44 // Function _writeTraceSegmentToFile()
45 // ----------------------------------------------------------------------------
46 
47 template <typename TFile, typename TSeq0Value, typename TSeq1Value>
_writeTraceSegmentToFile(TFile & file,TSeq0Value const & seq0Val,TSeq1Value const & seq1Val)48 inline void _writeTraceSegmentToFile(TFile & file, TSeq0Value const & seq0Val, TSeq1Value const & seq1Val)
49 {
50     file << '(' << seq0Val << ',' << seq1Val << ")\n";
51 }
52 
53 // ----------------------------------------------------------------------------
54 // Function _adaptTraceSegmentsTo()                                      [Gaps]
55 // ----------------------------------------------------------------------------
56 
57 template <typename TSourceHorizontal, typename TGapsSpecHorizontal, typename TSourceVertical,
58           typename TGapsSpecVertical, typename TPosition, typename TSize, typename TStringSpec>
59 void
_adaptTraceSegmentsTo(Gaps<TSourceHorizontal,TGapsSpecHorizontal> & gapsHorizontal,Gaps<TSourceVertical,TGapsSpecVertical> & gapsVertical,String<TraceSegment_<TPosition,TSize>,TStringSpec> const & traceSegments)60 _adaptTraceSegmentsTo(Gaps<TSourceHorizontal, TGapsSpecHorizontal> & gapsHorizontal,
61                       Gaps<TSourceVertical, TGapsSpecVertical> & gapsVertical,
62                       String<TraceSegment_<TPosition, TSize>, TStringSpec> const & traceSegments)
63 {
64     typedef Gaps<TSourceHorizontal, TGapsSpecHorizontal> TGapsHorizontal;
65     typedef Gaps<TSourceVertical, TGapsSpecVertical> TGapsVertical;
66     typedef typename Iterator<TGapsHorizontal>::Type TIteratorHorizontal;
67     typedef typename Iterator<TGapsVertical>::Type TIteratorVertical;
68     typedef TraceSegment_<TPosition, TSize> TTraceSegment;
69     typedef typename Iterator<String<TTraceSegment, TStringSpec> const>::Type TTraceIterator;
70 
71     clearGaps(gapsHorizontal);
72     clearClipping(gapsHorizontal);
73 
74     clearGaps(gapsVertical);
75     clearClipping(gapsVertical);
76 
77     // Set clipping to 0
78     if (empty(traceSegments))
79     {
80         setClippedBeginPosition(gapsHorizontal, 0);
81         setClippedEndPosition(gapsHorizontal, 0);
82         setClippedBeginPosition(gapsVertical, 0);
83         setClippedEndPosition(gapsVertical, 0);
84         return;
85     }
86 
87     TTraceIterator srcIter = end(traceSegments) - 1;
88     TTraceIterator srcEnd = begin(traceSegments) - 1;
89 
90     // we build the gap structure here.
91     // set the clipped begin position of the alignment.
92     setBeginPosition(gapsHorizontal, _getBeginHorizontal(value(srcIter))); // begin of source
93     setBeginPosition(gapsVertical, _getBeginVertical(value(srcIter)));
94 
95     TIteratorHorizontal it0 = begin(gapsHorizontal);
96     TIteratorVertical it1 = begin(gapsVertical);
97 
98     while (srcIter != srcEnd)
99     {
100         TSize segmentSize = value(srcIter)._length;
101         switch (value(srcIter)._traceValue)
102         {
103         case TraceBitMap_<>::HORIZONTAL:
104             insertGaps(it1, segmentSize);
105             break;
106 
107         case TraceBitMap_<>::VERTICAL:
108             insertGaps(it0, segmentSize);
109             break;
110         }
111         goFurther(it0, segmentSize);
112         goFurther(it1, segmentSize);
113         --srcIter;
114     }
115     setClippedEndPosition(gapsHorizontal, position(it0) + clippedBeginPosition(gapsHorizontal));
116     setClippedEndPosition(gapsVertical, position(it1) + clippedBeginPosition(gapsVertical));
117 }
118 
119 // ----------------------------------------------------------------------------
120 // Function _adaptTraceSegmentsTo()                            [AlignmentGraph]
121 // ----------------------------------------------------------------------------
122 
123 template <typename TStringSet, typename TCargo, typename TSpec, typename TSequenceIdH, typename TSequenceIdV,
124           typename TPosition, typename TSize, typename TStringSpec>
125 inline void
_adaptTraceSegmentsTo(Graph<Alignment<TStringSet,TCargo,TSpec>> & g,TSequenceIdH const & seqHId,TSequenceIdV const & seqVId,String<TraceSegment_<TPosition,TSize>,TStringSpec> const & traceSegments)126 _adaptTraceSegmentsTo(Graph<Alignment<TStringSet, TCargo, TSpec> > & g,
127                       TSequenceIdH const & seqHId,
128                       TSequenceIdV const & seqVId,
129                       String<TraceSegment_<TPosition, TSize>, TStringSpec> const & traceSegments)
130 {
131     typedef TraceSegment_<TPosition, TSize> TTraceSegment;
132     // check begin and end positions of the graph.
133 
134     // Not safe!
135 
136     if (empty(traceSegments))
137         return;
138 
139     // insert leading gaps
140     TTraceSegment traceBegin = traceSegments[length(traceSegments) - 1];
141     if (_getBeginVertical(traceBegin) != 0)
142         addVertex(g, seqVId, 0, _getBeginVertical(traceBegin));
143     if (_getBeginHorizontal(traceBegin) != 0)
144         addVertex(g, seqHId, 0, _getBeginHorizontal(traceBegin));
145 
146 
147     for (TSize i = 0; i < length(traceSegments); ++i)
148     {
149 
150         switch (traceSegments[i]._traceValue)
151         {
152         case TraceBitMap_<>::DIAGONAL:
153             addEdge(g, addVertex(g, seqHId, traceSegments[i]._horizontalBeginPos, traceSegments[i]._length),
154                     addVertex(g, seqVId, traceSegments[i]._verticalBeginPos, traceSegments[i]._length));
155             break;
156 
157         case TraceBitMap_<>::VERTICAL:
158             addVertex(g, seqVId, traceSegments[i]._verticalBeginPos, traceSegments[i]._length);
159             break;
160 
161         case TraceBitMap_<>::HORIZONTAL:
162             addVertex(g, seqHId, traceSegments[i]._horizontalBeginPos, traceSegments[i]._length);
163         }
164     }
165 
166     // insert trailing gaps
167     TTraceSegment traceEnd = traceSegments[0];
168 
169     if (_getEndVertical(traceEnd) != length(value(stringSet(g), idToPosition(stringSet(g), seqVId))))
170         addVertex(g, seqVId, _getEndVertical(traceEnd),
171                   length(value(stringSet(g), idToPosition(stringSet(g), seqVId))) - _getEndVertical(traceEnd));
172 
173     if (_getEndHorizontal(traceEnd) != length(value(stringSet(g), idToPosition(stringSet(g), seqHId))))
174         addVertex(g, seqHId, _getEndHorizontal(traceEnd),
175                   length(value(stringSet(g), idToPosition(stringSet(g), seqHId))) - _getEndHorizontal(traceEnd));
176 }
177 
178 // ----------------------------------------------------------------------------
179 // Function _adaptTraceSegmentsTo()                                      [File]
180 // ----------------------------------------------------------------------------
181 
182 template <typename TFile, typename TSequenceH, typename TSequenceV, typename TPosition, typename TSize,
183           typename TStringSpec>
184 inline void
_adaptTraceSegmentsTo(TFile & file,TSequenceH const & seqH,TSequenceV const & seqV,String<TraceSegment_<TPosition,TSize>,TStringSpec> const & traceSegments)185 _adaptTraceSegmentsTo(TFile & file,
186                       TSequenceH const & seqH,
187                       TSequenceV const & seqV,
188                       String<TraceSegment_<TPosition, TSize>, TStringSpec> const & traceSegments)
189 {
190     for (TSize k = length(traceSegments); k > (TSize) 0; --k)
191     {
192         switch (traceSegments[k - 1]._traceValue)
193         {
194             case TraceBitMap_<>::DIAGONAL:
195             {
196                 int j = traceSegments[k - 1]._verticalBeginPos;
197                 for (int i = traceSegments[k - 1]._horizontalBeginPos; i < (int) (traceSegments[k - 1]._horizontalBeginPos + traceSegments[k - 1]._length); ++i)
198                 {
199                     _writeTraceSegmentToFile(file, seqH[i], seqV[j]);
200                     ++j;
201                 }
202                 break;
203             }
204 
205             case TraceBitMap_<>::VERTICAL:
206             {
207                 for (int i = traceSegments[k - 1]._verticalBeginPos; i < (int) (traceSegments[k - 1]._verticalBeginPos + traceSegments[k - 1]._length); ++i)
208                     _writeTraceSegmentToFile(file, gapValue<char>(), seqV[i]);
209                 break;
210             }
211 
212             case TraceBitMap_<>::HORIZONTAL:
213             {
214                 for (int i = traceSegments[k - 1]._horizontalBeginPos; i < (int) (traceSegments[k - 1]._horizontalBeginPos + traceSegments[k - 1]._length); ++i)
215                     _writeTraceSegmentToFile(file, seqH[i], gapValue<char>());
216             }
217         }
218     }
219 }
220 
221 // ----------------------------------------------------------------------------
222 // Function _adaptTraceSegmentsTo()                                 [Fragments]
223 // ----------------------------------------------------------------------------
224 
225 template <typename TSize, typename TFragmentSpec, typename TStringSpec, typename TSequenceH, typename TSequenceV,
226           typename TPosition, typename TSize2, typename TStringSpec2>
227 inline void
_adaptTraceSegmentsTo(String<Fragment<TSize,TFragmentSpec>,TStringSpec> & matches,TSequenceH const & seqHId,TSequenceV const & seqVId,String<TraceSegment_<TPosition,TSize2>,TStringSpec2> const & traceSegments)228 _adaptTraceSegmentsTo(String<Fragment<TSize, TFragmentSpec>, TStringSpec> & matches,
229                       TSequenceH const & seqHId,
230                       TSequenceV const & seqVId,
231                       String<TraceSegment_<TPosition, TSize2>, TStringSpec2> const & traceSegments)
232 {
233     typedef Fragment<TSize, TFragmentSpec> TFragment;
234 
235     for (TSize2 i = 0; i < length(traceSegments); ++i)
236         if (traceSegments[i]._traceValue == TraceBitMap_<>::DIAGONAL)
237             appendValue(
238                 matches,
239                 TFragment(seqHId, traceSegments[i]._horizontalBeginPos, seqVId,
240                           traceSegments[i]._verticalBeginPos, traceSegments[i]._length),
241                 Generous());
242 }
243 
244 // ----------------------------------------------------------------------------
245 // Function _adaptTraceSegmentsTo()                             [VertexDescriptor]
246 // ----------------------------------------------------------------------------
247 
248 //// TODO (rmaerker): Check if we really need this!
249 //template <typename TVertexDescriptor, typename TSpec, typename TSequence0, typename TSequence1, typename TPosition,
250 //          typename TSize, typename TStringSpec>
251 //inline void
252 //_adaptTraceSegmentsTo(String<String<TVertexDescriptor, TSpec> > & /*nodeString*/,
253 //      TSequence0 const & /*seq0*/,
254 //      TSequence1 const & /*seq1*/,
255 //      String<TraceSegment_<TPosition, TSize>, TStringSpec> const & /*traceSegments*/)
256 //{
257 //    typedef String<TVertexDescriptor, TSpec> TVertexDescriptorString;
258 //    typedef typename Size<TSource>::Type TSize;
259 //    typedef typename Iterator<TVertexDescriptorString>::Type TStringIter;
260 //    TVertexDescriptor nilVertex = getNil<TVertexDescriptor>();
261 
262 
263 // TODO (rmaerker): see how to adapt this code here for the new structure.
264 //        // TraceBack values
265 //    TTraceValue Diagonal = 0; TTraceValue Horizontal = 1; TTraceValue Vertical = 2;
266 //
267 //    if (segLen == 0) return;
268 //        // Number of vertex descriptors in the first string at any position (e.g., group of 5 sequences = group of 5 vertex descriptors)
269 //    TSize len1 = length(getValue(getValue(str,0), 0));
270 //        // Number of vertex descriptors in the second string at any position (e.g., group of 5 sequences = group of 5 vertex descriptors)
271 //    TSize len2 = length(getValue(getValue(str,1), 0));
272 //
273 //        // Resize the node string
274 //    TSize index = length(nodeString);
275 //    resize(nodeString, index + segLen);
276 //
277 //    if (tv == Horizontal) {
278 //        for (int i = pos1 + segLen - 1; i>= (int) pos1;--i) {
279 //            resize(value(nodeString, index), len1 + len2, nilVertex);
280 //            TStringIter it = begin(value(nodeString, index));
281 //            for(TPos all = 0;all<len1;++all) {
282 //                *it = getValue(getValue(getValue(str,0),i), all);
283 //                goNext(it);
284 //            }
285 //            ++index;
286 //        }
287 //    }
288 //    else if (tv == Vertical) {
289 //        for (int i = pos2 + segLen - 1; i>= (int) pos2;--i) {
290 //            resize(value(nodeString, index), len1 + len2, nilVertex);
291 //            TStringIter it = begin(value(nodeString, index));
292 //            it+=len1;
293 //            for(TPos all = 0;all<len2;++all) {
294 //                *it = getValue(getValue(getValue(str,1),i), all);
295 //                goNext(it);
296 //            }
297 //            ++index;
298 //        }
299 //    }
300 //    else if (tv == Diagonal) {
301 //        int j = pos2 + segLen - 1;
302 //        for (int i = pos1 + segLen - 1; i>= (int) pos1;--i) {
303 //            resize(value(nodeString, index), len1 + len2);
304 //            TStringIter it = begin(value(nodeString, index));
305 //            for(TPos all = 0;all<len1;++all) {
306 //                *it = getValue(getValue(getValue(str,0),i), all);
307 //                goNext(it);
308 //            }
309 //            for(TPos all = 0;all<len2;++all) {
310 //                *it = getValue(getValue(getValue(str,1),j), all);
311 //                goNext(it);
312 //            }
313 //            ++index;
314 //            --j;
315 //        }
316 //    }
317 //}
318 
319 }  // namespace seqan
320 
321 #endif  // #ifndef SEQAN_INCLUDE_SEQAN_ALIGN_DP_TRACEBACK_ADAPTOR_H_
322