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