go back to sequence being its own class
[mussa.git] / alg / sequence.cpp
index bbd6292c75f90dd81977887b301485eabf2a712b..0d1594f686a26fc98ab21c234851ffae524439f4 100644 (file)
@@ -85,9 +85,9 @@ motif::~motif()
 }
 
 Sequence::Sequence()
:  std::string(),
-    header(""),
-    species("")
 :  seq(""),
+     header(""),
+     species("")
 {
 }
 
@@ -110,7 +110,7 @@ Sequence::Sequence(const std::string& seq)
 }
 
 Sequence::Sequence(const Sequence& o)
-  : std::string(o),
+  : seq(o.seq),
     header(o.header),
     species(o.species),
     annots(o.annots),
@@ -122,7 +122,7 @@ Sequence &Sequence::operator=(const Sequence& s)
 {
   if (this != &s) {
     //sequence = s.sequence;
-    assign(s);
+    seq = s.seq;
     header = s.header;
     species = s.species;
     annots = s.annots;
@@ -131,6 +131,20 @@ Sequence &Sequence::operator=(const Sequence& s)
   return *this;
 }
 
+/*
+Sequence::operator std::string()
+{
+  std::string s(seq.begin(), seq.end());
+  return s;
+}
+
+Sequence::operator std::string() const
+{
+  std::string s(seq.begin(), seq.end());
+  return s;
+}
+*/
+
 static void multiplatform_getline(std::istream& in, std::string& line)
 {
   line.clear();
@@ -245,8 +259,8 @@ void Sequence::set_filtered_sequence(const std::string &old_seq,
 
   if ( count == 0)
     count = old_seq.size() - start;
-  std::string::clear();
-  reserve(count);
+  seq.clear();
+  seq.reserve(count);
 
   // Make a conversion table
 
@@ -272,13 +286,10 @@ void Sequence::set_filtered_sequence(const std::string &old_seq,
   // finally, the actual conversion loop
   for(std::string::size_type seq_index = 0; seq_index < count; seq_index++)
   {
-    append(1, conversionTable[ (int)old_seq[seq_index+start]]);
+    seq.append(1, conversionTable[ (int)old_seq[seq_index+start]]);
   }
 }
 
-  // this doesn't work properly under gcc 3.x ... it can't recognize toupper
-  //transform(sequence.begin(), sequence.end(), sequence.begin(), toupper);
-
 void
 Sequence::load_annot(fs::path file_path, int start_index, int end_index)
 {
@@ -464,7 +475,7 @@ Sequence::subseq(int start, int count) const
   if ( count == npos || start+count > size()) {
     count = size()-start;
   }
-  Sequence new_seq(std::string::substr(start, count));
+  Sequence new_seq(seq.substr(start, count));
   new_seq.set_fasta_header(get_fasta_header());
   new_seq.set_species(get_species());
 
@@ -533,7 +544,7 @@ Sequence::rev_comp() const
   // finally, the actual conversion loop
   for(seq_i = len - 1; seq_i >= 0; seq_i--)
   {
-    table_i = (int) at(seq_i);
+    table_i = (int) seq.at(seq_i);
     rev_comp += conversionTable[table_i];
   }
 
@@ -573,15 +584,70 @@ Sequence::get_name() const
     return "";
 }
 
+void Sequence::set_sequence(const std::string& s) 
+{
+  set_filtered_sequence(s);
+}
+
+std::string Sequence::get_sequence() const
+{
+  return seq;
+}
+
+Sequence::const_reference Sequence::operator[](Sequence::size_type i) const
+{
+  return seq[i];
+}
+
+Sequence::const_reference Sequence::at(Sequence::size_type n) const
+{
+  return seq[n];
+}
+
 void
 Sequence::clear()
 {
-  std::string::clear();
-  header = "";
-  species = "";
+  seq.clear();
+  header.clear();
+  species.clear();
   annots.clear();
+  motif_list.clear();
+}
+
+Sequence::iterator Sequence::begin()
+{
+  return seq.begin();
+}
+
+Sequence::const_iterator Sequence::begin() const
+{
+  return seq.begin();
+}
+
+Sequence::iterator Sequence::end()
+{
+  return seq.end();
 }
 
+Sequence::const_iterator Sequence::end() const
+{
+  return seq.end();
+}
+
+bool Sequence::empty() const
+{
+  return seq.empty();
+}
+
+Sequence::size_type Sequence::size() const
+{
+  return seq.size();
+}
+
+Sequence::size_type Sequence::length() const
+{
+  return size();
+}
 void
 Sequence::save(fs::fstream &save_file)
                //std::string save_file_path)
@@ -631,7 +697,7 @@ Sequence::load_museq(fs::path load_file_path, int seq_num)
       seq_counter++;
   }
   getline(load_file, file_data_line);
-  assign(file_data_line);
+  seq.assign(file_data_line);
   getline(load_file, file_data_line);
   getline(load_file, file_data_line);
   if (file_data_line == "<Annotations>")
@@ -689,7 +755,7 @@ Sequence::load_museq(fs::path load_file_path, int seq_num)
 }
 
 std::string
-Sequence::rc_motif(std::string a_motif)
+Sequence::rc_motif(std::string a_motif) const
 {
   std::string rev_comp;
   char conversionTable[257];
@@ -737,7 +803,7 @@ Sequence::rc_motif(std::string a_motif)
 }
 
 std::string
-Sequence::motif_normalize(std::string a_motif)
+Sequence::motif_normalize(const std::string& a_motif)
 {
   std::string valid_motif;
   int seq_i, len;
@@ -798,7 +864,7 @@ void Sequence::add_motif(const Sequence& a_motif)
       motif_start_i != motif_starts.end();
       ++motif_start_i)
   {
-    motif_list.push_back(motif(*motif_start_i, a_motif));
+    motif_list.push_back(motif(*motif_start_i, a_motif.get_sequence()));
   }
 }
 
@@ -813,40 +879,44 @@ const std::list<motif>& Sequence::motifs() const
 }
 
 std::vector<int>
-Sequence::find_motif(std::string a_motif)
+Sequence::find_motif(const std::string& a_motif) const
 {
   std::vector<int> motif_match_starts;
-  std::string a_motif_rc;
+  std::string norm_motif_rc;
 
   motif_match_starts.clear();
 
   //std::cout << "motif is: " << a_motif << std::endl;
-  a_motif = motif_normalize(a_motif);
+  std::string norm_motif = motif_normalize(a_motif);
   //std::cout << "motif is: " << a_motif << std::endl;
 
-  if (a_motif.size() > 0)
+  if (norm_motif.size() > 0)
   {
     //std::cout << "Sequence: none blank motif\n";
-    motif_scan(a_motif, &motif_match_starts);
+    motif_scan(norm_motif, &motif_match_starts);
 
-    a_motif_rc = rc_motif(a_motif);
+    norm_motif_rc = rc_motif(a_motif);
     // make sure not to do search again if it is a palindrome
-    if (a_motif_rc != a_motif) {
-      motif_scan(a_motif_rc, &motif_match_starts);
+    if (norm_motif_rc != norm_motif) {
+      motif_scan(norm_motif_rc, &motif_match_starts);
     }
   }
   return motif_match_starts;
 }
 
+std::vector<int>
+Sequence::find_motif(const Sequence& a_motif) const
+{
+  return find_motif(a_motif.get_sequence());
+}
+
 void
-Sequence::motif_scan(std::string a_motif, std::vector<int> * motif_match_starts)
+Sequence::motif_scan(std::string a_motif, std::vector<int> * motif_match_starts) const
 {
-   const char * seq_c;
+  std::string::const_iterator seq_c = seq.begin();
   std::string::size_type seq_i;
   int motif_i, motif_len;
 
-  // faster to loop thru the sequence as a old c std::string (ie char array)
-  seq_c = c_str();
   //std::cout << "Sequence: motif, seq len = " << sequence.length() << std::endl; 
   motif_len = a_motif.length();
 
@@ -946,9 +1016,48 @@ void Sequence::find_sequences(std::list<Sequence>::iterator start,
                               std::list<Sequence>::iterator end)
 {
   while (start != end) {
-    add_string_annotation(*start, start->get_fasta_header());
+    add_string_annotation(start->get_sequence(), start->get_fasta_header());
     ++start;
   }
 }
 
 
+std::ostream& operator<<(std::ostream& out, const Sequence& s)
+{
+  for(Sequence::const_iterator s_i = s.begin(); s_i != s.end(); ++s_i) {
+    out << *s_i;
+  }
+  return out;
+}
+
+bool operator<(const Sequence& x, const Sequence& y)
+{
+  Sequence::const_iterator x_i = x.begin();
+  Sequence::const_iterator y_i = y.begin();
+  
+  while(1) {
+    if( x_i == x.end() and y_i == y.end() ) {
+      return false;
+    } else if ( x_i == x.end() ) {
+      return true;
+    } else if ( y_i == y.end() ) {
+      return false;
+    } else if ( (*x_i) < (*y_i)) {
+      return true;
+    } else if ( (*x_i) > (*y_i) ) {
+      return false;
+    } else {
+      ++x_i;
+      ++y_i;
+    }
+  }
+}
+
+bool operator==(const Sequence& x, const Sequence& y) 
+{
+  if (x.seq == y.seq and x.annots == y.annots and x.motif_list == y.motif_list) {
+    return true;
+  } else {
+    return false;
+  }
+}