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