Store Sequence sequence location in a shared_ptr class
[mussa.git] / alg / sequence.hpp
index dc9d594a1f572753f73ced6a5de056db5b6c0209..09c53c4bf3a1a911e793add0a8730335285b437a 100644 (file)
 #include <boost/serialization/vector.hpp>
 
 #include <boost/shared_ptr.hpp>
+#include <boost/enable_shared_from_this.hpp>
 
 #include <iostream>
 
-#include "alg/alphabet.hpp"
+#include "alphabet.hpp"
+#include "seq.hpp"
+#include "seq_span.hpp"
 
 // Sequence data class
 
@@ -85,40 +88,21 @@ private:
 };
 BOOST_CLASS_EXPORT(motif);
 
-//! the only purpose of this class is that the shared_ptr template 
-//! functions need the serialization support to be in-class.
-class seq_string : public std::string
-{
-public:
-  typedef std::string::iterator iterator;
-  typedef std::string::reverse_iterator reverse_iterator;
-  typedef std::string::const_iterator const_iterator;
-  typedef std::string::const_reverse_iterator const_reverse_iterator;
-private:
-  friend class boost::serialization::access;
-  template<class Archive>
-  void serialize(Archive& ar, const unsigned int /*version*/) {
-    //ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(std::string);
-    ar & boost::serialization::make_nvp("bases",
-          boost::serialization::base_object<std::string>(*this)
-    );
-  }
-};
 
 //! sequence track for mussa.
 class Sequence 
 {
 public:
-  typedef std::string::value_type value_type;
-  typedef std::string::difference_type difference_type;
-  typedef std::string::iterator iterator;
-  typedef std::string::reverse_iterator reverse_iterator;
-  typedef std::string::const_iterator const_iterator;
-  typedef std::string::const_reverse_iterator const_reverse_iterator;
-  typedef std::string::reference reference;
-  typedef std::string::const_reference const_reference;
-  typedef std::string::size_type size_type;
-  static const size_type npos = std::string::npos;
+  typedef SeqString::value_type value_type;
+  typedef SeqString::difference_type difference_type;
+  typedef SeqString::iterator iterator;
+  typedef SeqString::reverse_iterator reverse_iterator;
+  typedef SeqString::const_iterator const_iterator;
+  typedef SeqString::const_reverse_iterator const_reverse_iterator;
+  typedef SeqString::reference reference;
+  typedef SeqString::const_reference const_reference;
+  typedef SeqString::size_type size_type;
+  static const size_type npos = SeqString::npos;
   enum strand_type { UnknownStrand, PlusStrand, MinusStrand, BothStrand };
   enum alphabet_ref { reduced_dna_alphabet, reduced_rna_alphabet, reduced_nucleic_alphabet, 
                       nucleic_alphabet, protein_alphabet };
@@ -127,6 +111,8 @@ public:
   Sequence(const char* seq, alphabet_ref a = reduced_nucleic_alphabet);
   Sequence(const std::string& seq, alphabet_ref a = reduced_nucleic_alphabet);
   Sequence(const Sequence& seq);
+  Sequence(const Sequence *);
+  Sequence(const SeqSpanRef&, alphabet_ref a = reduced_nucleic_alphabet); 
   ~Sequence();
   //! assignment to constant sequences
   Sequence &operator=(const Sequence&);
@@ -145,28 +131,35 @@ public:
                              strand_type strand=UnknownStrand);
 
   //! retrive element at specific position
-  const_reference at(size_type n) const;
+  const_reference at(size_type i) const { return seq->at(i); }
   //! clear the sequence and its annotations
   void clear();
-  //! return c pointer to the sequence data
-  const char *c_str() const;
+  //! return a non-null terminated c pointer to the sequence data
+  const char *data() const { return seq->data(); }
   //! forward iterator
-  const_iterator begin() const;
+  const_iterator begin() const { return seq->begin(); }
   //! last iterator
-  const_iterator end() const;
+  const_iterator end() const { return seq->end(); }
   //! is our sequence empty?
-  bool empty() const;
+  bool empty() const { return (seq) ? seq->empty() : true ; }
+  //! find first 
+  size_type find_first_not_of(const std::string& q, size_type index=0) { return seq->find_first_not_of(q, index); } 
   //! how many base pairs are there in our sequence
-  size_type size() const;
+  size_type size() const { return (seq) ? seq->size() : 0; }
   //! alias for size (used by string)
-  size_type length() const;
+  size_type length() const { return size(); }
+  //! reverse iterator
+  const_reverse_iterator rbegin() const { return seq->rbegin(); }
+  //! reverse end iterator
+  const_reverse_iterator rend() const { return seq->rend(); }
+  //! is our sequence empty?
   //! start position relative to "base" sequence
-  size_type start() const;
+  size_type start() const { return seq->parentStart(); }
   //! one past the last position relative to "base" sequence
-  size_type stop() const;
+  size_type stop() const { return seq->parentStop(); }
 
   //! return a subsequence, copying over any appropriate annotation
-  Sequence subseq(int start=0, int count = std::string::npos);
+  Sequence subseq(size_type start=0, size_type count = npos) const;
   //! reverse a character
   std::string create_reverse_map() const;
   //! return a reverse compliment (this needs to be improved?)
@@ -202,13 +195,13 @@ public:
                   alphabet_ref a, 
                   int seq_num=1, 
                              int start_index=0, int end_index=0);
-  void load_fasta(std::iostream& file, 
+  void load_fasta(std::istream& file, 
                   int seq_num=1, int start_index=0, int end_index=0);
   //! load sequence from stream
   //! \throw mussa_load_error
   //! \throw sequence_empty_error
   //! \throw sequence_empty_file_error
-  void load_fasta(std::iostream& file, 
+  void load_fasta(std::istream& file, 
                   alphabet_ref a,
                   int seq_num=1, 
                              int start_index=0, int end_index=0);
@@ -218,7 +211,10 @@ public:
   //! load sequence annotations
   //! \throws mussa_load_error 
   void load_annot(std::fstream& data_stream, int start_index, int end_index);
-  bool parse_annot(std::string data, int start_index=0, int end_index=0);
+  //! parse annotation file
+  /*! \throws annotation_load_error 
+   */
+  void parse_annot(std::string data, int start_index=0, int end_index=0);
   //! add an annotation to our list of annotations
   void add_annotation(const annot& a);
   const std::list<annot>& annotations() const;
@@ -236,19 +232,12 @@ public:
                      std::list<Sequence>::iterator end);
   
   void save(boost::filesystem::fstream &save_file);
-  void load_museq(boost::filesystem::path load_file_path, int seq_num); 
+  void load_museq(boost::filesystem::path load_file_path, int seq_num);
   
-private:
-  //! parent sequence
-  Sequence *parent;
-  //! hold a shared pointer to our sequence string
-  boost::shared_ptr<seq_string> seq;
+protected:  
+  SeqSpanRef seq;
   //! which alphabet we're using
   alphabet_ref alphabet;
-  //! start offset into the sequence
-  size_type seq_start;
-  //! number of basepairs of the shared sequence we represent
-  size_type seq_count;
   //! strand orientation
   strand_type strand;
   //! fasta header
@@ -261,6 +250,9 @@ private:
   //! a seperate list for motifs since we're currently not saving them
   std::list<motif> motif_list;
 
+  //! copy over all our annotation children
+  void copy_children(Sequence &, size_type start, size_type count) const;
+
   void motif_scan(const Sequence& a_motif, std::vector<int> * motif_match_starts) const;
   std::string rc_motif(std::string a_motif) const;
   //! look for a string sequence type and and it to an annotation list
@@ -270,11 +262,8 @@ private:
   friend class boost::serialization::access;
   template<class Archive>
   void serialize(Archive& ar, const unsigned int /*version*/) {
-    ar & BOOST_SERIALIZATION_NVP(parent);
     ar & BOOST_SERIALIZATION_NVP(seq);
     ar & BOOST_SERIALIZATION_NVP(alphabet);
-    ar & BOOST_SERIALIZATION_NVP(seq_start);
-    ar & BOOST_SERIALIZATION_NVP(seq_count);
     ar & BOOST_SERIALIZATION_NVP(strand);
     ar & BOOST_SERIALIZATION_NVP(header);
     ar & BOOST_SERIALIZATION_NVP(species);
@@ -283,5 +272,4 @@ private:
   }
 };
 BOOST_CLASS_EXPORT(Sequence);
-
 #endif