5a2da1268d3a62cf807f323d7e39bb450fea5841
[mussa.git] / alg / seq_span.hpp
1 #ifndef SEQ_SPAN_HPP_
2 #define SEQ_SPAN_HPP_
3
4 #include <string>
5
6 #include <boost/serialization/base_object.hpp>
7 #include <boost/serialization/export.hpp>
8 #include <boost/serialization/list.hpp>
9 #include <boost/serialization/nvp.hpp>
10 #include <boost/serialization/string.hpp>
11 #include <boost/serialization/shared_ptr.hpp>
12 #include <boost/serialization/utility.hpp>
13 #include <boost/serialization/version.hpp>
14 #include <boost/serialization/vector.hpp>
15
16 #include <boost/shared_ptr.hpp>
17 #include <boost/enable_shared_from_this.hpp>
18
19 //! These classes provide for the internal implementation for the Sequence class
20 #include "seq.hpp"
21
22 class SeqSpan;
23 typedef boost::shared_ptr<SeqSpan> SeqSpanRef;
24
25 //! Track what segment of a sequence we're looking at
26 class SeqSpan : public boost::enable_shared_from_this<SeqSpan> {
27 public:
28   typedef SeqString::difference_type difference_type;
29   typedef SeqString::iterator iterator;
30   typedef SeqString::reverse_iterator reverse_iterator;
31   typedef SeqString::const_iterator const_iterator;
32   typedef SeqString::const_reverse_iterator const_reverse_iterator;
33   typedef SeqString::reference reference;
34   typedef SeqString::const_reference const_reference;
35   typedef SeqString::size_type size_type;
36   typedef SeqString::value_type value_type;
37   static const size_type npos = SeqString::npos;
38   //! Define strand types
39   /**!
40    *  Unknown strand is treated as "either" strand
41    *  Plus refers to the initially created strand
42    *  Minus is the opposite strand
43    *  Both is for any feature that applies to "both" strands
44    *    (which may not actually be useful) 
45    *  Same strand is only used when creating a subsequence
46    *    and implies the subsequence has the same orientation as the parent
47    *  Opposite is only used for creating a subsequence
48    *    and implies the subsequence has the opposite orientation as the parent
49    *  Single indicates that this is single stranded and there can't be
50    *    an opposite strand.
51    */ 
52   enum strand_type { UnknownStrand, MinusStrand, PlusStrand, 
53                      BothStrand, SameStrand, OppositeStrand, SingleStrand };
54
55 public:
56   SeqSpan(const SeqSpan &);
57   SeqSpan(const SeqSpan *);
58   explicit SeqSpan(const std::string &, 
59                AlphabetRef a = dna_alphabet,
60                strand_type strand=PlusStrand
61            );
62   SeqSpan(const SeqSpanRef, 
63           size_type start=0, 
64           size_type count=npos, 
65           strand_type strand=SameStrand);
66
67   //! assignment
68   SeqSpan& operator=(const SeqSpan&);
69   //! output
70   friend std::ostream& operator<<(std::ostream&, const SeqSpan&);
71   //! equality 
72   friend bool operator==(const SeqSpan&, const SeqSpan&);
73   friend bool operator!=(const SeqSpan&, const SeqSpan&);
74     
75   const Alphabet& get_alphabet() const { return seq->get_alphabet(); }
76   //! \defgroup string_operators
77   //! @{
78   //! retrive element at specific position
79   const_reference at(size_type n) const;
80   //! retrieve element at specific location
81   const_reference operator[](SeqSpan::size_type i) const;
82   //! return c pointer to the sequence data
83   const char *data() const;
84   //! forward iterator
85   const_iterator begin() const;
86   //! last iterator
87   const_iterator end() const;
88   //! is our sequence empty?
89   bool empty() const;
90   //! find first 
91   size_type find_first_not_of(const std::string&, size_type index=0) const; 
92   //! how many base pairs are there in our sequence
93   size_type size() const { return seq_count; }
94   //! alias for size (used by string)
95   size_type length() const { return size(); }
96   //! reverse iterator
97   const_reverse_iterator rbegin() const;
98   //! reverse end iterator
99   const_reverse_iterator rend() const;
100   //! @}
101   
102   //! start position relative to root sequence
103   size_type start() const { return seq_start; }
104   //! set position relative to root sequence
105   void setStart(size_type);
106   //! one past the last position relative to the root sequence
107   size_type stop() const { return seq_start + seq_count; }
108   //! set one past the last position relative to the root sequence.
109   void setStop(size_type);
110   strand_type strand() const { return seq_strand; }
111   
112   //! get start position relative to the parent sequence
113   size_type parentStart() const;
114   //! set start position relative to parent sequence
115   void setParentStart(size_type);
116   //! get stop position relative to the parent sequence
117   size_type parentStop() const;
118   //! set stop position relative to parent sequence
119   void setParentStop(size_type);
120   size_type parentSize() const { return (parent) ? parent->size() : size(); }
121   
122
123   //! return a subsequence, copying over any appropriate annotation
124   SeqSpanRef subseq(size_type start=0, 
125                     size_type count = std::string::npos, 
126                     strand_type = PlusStrand);
127   //! get sequence
128   std::string sequence() const; 
129   //! are both sequences derived from the same sequence tree?
130   static bool isFamily(const SeqSpan& a, const SeqSpan& b);
131   
132   //! fill in our rc_seq variable 
133   void initialize_rc_seq() const;
134   
135   friend class Sequence;
136 private:
137   //! do not statically initialize, only create with new
138   SeqSpan() {};
139 protected:
140   //! keep a reference to the sequence container 
141   SeqStringRef seq;
142   //! where our start location is in the full sequence
143   size_type seq_start;
144   //! how big we ware
145   size_type seq_count;  
146   //! strand orientation
147   strand_type seq_strand;
148   
149   //! keep a reference to who our parent span is 
150   SeqSpanRef parent;
151
152   //! hold a reverse complement version of our sequence if needed
153   SeqStringRef rc_seq;
154   
155   // boost::serialization support
156   friend class boost::serialization::access;
157   template<class Archive>
158   void serialize(Archive& ar, const unsigned int /*version*/) {
159     ar & BOOST_SERIALIZATION_NVP(seq);
160     ar & BOOST_SERIALIZATION_NVP(seq_start);
161     ar & BOOST_SERIALIZATION_NVP(seq_count);
162     ar & BOOST_SERIALIZATION_NVP(seq_strand);
163     ar & BOOST_SERIALIZATION_NVP(parent);
164   }
165 };
166 #endif /*SEQ_SPAN_HPP_*/