1 /*  $Id: fasta_aln_builder.cpp 103491 2007-05-04 17:18:18Z kazimird $
2 * ===========================================================================
3 *
4 *                            PUBLIC DOMAIN NOTICE
5 *               National Center for Biotechnology Information
6 *
7 *  This software/database is a "United States Government Work" under the
8 *  terms of the United States Copyright Act.  It was written as part of
9 *  the author's official duties as a United States Government employee and
10 *  thus cannot be copyrighted.  This software/database is freely available
11 *  to the public for use. The National Library of Medicine and the U.S.
12 *  Government have not placed any restriction on its use or reproduction.
13 *
14 *  Although all reasonable efforts have been taken to ensure the accuracy
15 *  and reliability of the software and data, the NLM and the U.S.
16 *  Government do not and cannot warrant the performance or results that
17 *  may be obtained by using this software or data. The NLM and the U.S.
18 *  Government disclaim all warranties, express or implied, including
19 *  warranties of performance, merchantability or fitness for any particular
20 *  purpose.
21 *
22 *  Please cite the author in any work or product based on this material.
23 *
24 * ===========================================================================
25 *
26 * Author:  Aaron Ucko
27 *
28 * File Description:
29 *   Helper class to build pairwise alignments, with double gaps
30 *   automatically spliced out.
31 *
32 * ===========================================================================
33 */
34 
35 #include <ncbi_pch.hpp>
36 #include "fasta_aln_builder.hpp"
37 
38 #include <objects/seqalign/Dense_seg.hpp>
39 #include <objects/seqalign/Seq_align.hpp>
40 #include <objects/seqloc/Seq_id.hpp>
41 
42 BEGIN_NCBI_SCOPE
BEGIN_SCOPE(objects)43 BEGIN_SCOPE(objects)
44 
45 CFastaAlignmentBuilder::CFastaAlignmentBuilder(CRef<CSeq_id> reference_id,
46                                                CRef<CSeq_id> other_id)
47     : m_DS(new CDense_seg), m_LastAlignmentPos(0), m_LastReferencePos(kNoPos),
48       m_LastOtherPos(kNoPos), m_LastState(eDoubleGap),
49       m_LastNonDGState(eDoubleGap)
50 {
51     m_DS->SetIds().push_back(reference_id);
52     m_DS->SetIds().push_back(other_id);
53 }
54 
55 
GetCompletedAlignment(void)56 CRef<CSeq_align> CFastaAlignmentBuilder::GetCompletedAlignment(void)
57 {
58     CRef<CSeq_align> sa(new CSeq_align);
59     sa->SetType(CSeq_align::eType_not_set);
60     sa->SetDim(2);
61     m_DS->SetNumseg(m_DS->GetLens().size());
62     sa->SetSegs().SetDenseg(*m_DS);
63     return sa;
64 }
65 
66 
67 inline
x_State(TSignedSeqPos reference_pos,TSignedSeqPos other_pos)68 CFastaAlignmentBuilder::EState CFastaAlignmentBuilder::x_State
69 (TSignedSeqPos reference_pos, TSignedSeqPos other_pos)
70 {
71     int state = eDoubleGap;
72     if (reference_pos != kNoPos) {
73         state |= eReferenceOnly;
74     }
75     if (other_pos != kNoPos) {
76         state |= eOtherOnly;
77     }
78     return static_cast<EState>(state);
79 }
80 
81 
82 inline
x_EnsurePos(TSignedSeqPos & pos,TSignedSeqPos last_pos,TSeqPos alignment_pos)83 void CFastaAlignmentBuilder::x_EnsurePos(TSignedSeqPos& pos,
84                                          TSignedSeqPos  last_pos,
85                                          TSeqPos        alignment_pos)
86 {
87     if (pos == kContinued) {
88         if (last_pos == kNoPos) {
89             pos = kNoPos;
90         } else {
91             pos = last_pos + alignment_pos - m_LastAlignmentPos;
92         }
93     }
94 }
95 
96 
AddData(TSeqPos alignment_pos,TSignedSeqPos reference_pos,TSignedSeqPos other_pos)97 void CFastaAlignmentBuilder::AddData(TSeqPos       alignment_pos,
98                                      TSignedSeqPos reference_pos,
99                                      TSignedSeqPos other_pos)
100 {
101     x_EnsurePos(reference_pos, m_LastReferencePos, alignment_pos);
102     x_EnsurePos(other_pos, m_LastOtherPos, alignment_pos);
103 
104     EState state = x_State(reference_pos, other_pos);
105 
106     if (m_LastState != eDoubleGap) {
107         m_DS->SetLens().back() += alignment_pos - m_LastAlignmentPos;
108     }
109     if (state != eDoubleGap  &&  state != m_LastNonDGState) {
110         // new segment
111         m_DS->SetStarts().push_back(reference_pos);
112         m_DS->SetStarts().push_back(other_pos);
113         m_DS->SetLens().push_back(0);
114         m_LastNonDGState = state;
115     }
116 
117     m_LastAlignmentPos = alignment_pos;
118     m_LastReferencePos = reference_pos;
119     m_LastOtherPos     = other_pos;
120     m_LastState        = state;
121 }
122 
123 
124 END_SCOPE(objects)
125 END_NCBI_SCOPE
126