libsequence  1.9.5
phylipData.tcc
1 // Code for the -*- C++ -*- namespace Sequence::phylipData<T>
2 
3 /*
4 
5 Copyright (C) 2003-2009 Kevin Thornton, krthornt[]@[]uci.edu
6 
7 Remove the brackets to email me.
8 
9 This file is part of libsequence.
10 
11 libsequence is free software: you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation, either version 3 of the License, or
14 (at your option) any later version.
15 
16 libsequence is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20 
21 You should have received a copy of the GNU General Public License
22 long with libsequence. If not, see <http://www.gnu.org/licenses/>.
23 
24 */
25 
26 #include <Sequence/phylipData.hpp>
27 #include <string>
28 #include <iterator>
29 #include <utility>
30 #include <algorithm>
31 #include <cctype>
32 
33 namespace Sequence
34 {
35  template < typename T >
36  std::istream & phylipData < T >::read (std::istream & s)
37  {
38  std::string notAllowed = {"()[]:;,"}; //characters not allowed in sequence name
39  unsigned nsam,nsites;
40  s >> nsam >> nsites >> std::ws;
41  std::vector<T> _data(nsam);
42  std::string name(10,' '),temp;
43 
44  for(unsigned i = 0 ; i < nsam ; ++i)
45  {
46  s.read( &name[0], 10*sizeof(char) ); //A name is 10 characters
47  for( auto c : notAllowed )
48  {
49  if(name.find(c) != std::string::npos)
50  {
51  throw std::runtime_error("Sequence::phylipData::read -- invalid character found in sequence name");
52  }
53  }
54  std::getline(s,temp);
55  temp.erase( std::remove_if(temp.begin(),temp.end(),[](const char & __ch){ return std::isspace(__ch);}), temp.end() );
56  _data[i] = T(name,temp);
57  }
58  s >> std::ws;
59  while(!s.eof())
60  {
61  for ( unsigned i = 0 ; !s.eof() && i < nsam ; ++i )
62  {
63  std::getline(s,temp);
64  s >> std::ws;
65  temp.erase( std::remove_if(temp.begin(),temp.end(),[](const char & __ch){ return std::isspace(__ch);}), temp.end() );
66  _data[i].seq+=temp;
67  }
68  }
69  this->assign(std::move(_data));
70  return s;
71  }
72 
73  template < typename T >
74  std::ostream & phylipData < T >::print (std::ostream & s) const
75  {
76  size_t nsam = this->size();
77  s << nsam
78  << '\t'
79  << (*this)[0].seq.size() << '\n';
80 
81  for( auto __t = this->begin() ; __t != this->end() ; ++__t )
82  {
83  if ( __t->name.length() >= 10 )
84  {
85  std::copy( __t->name.begin(),
86  __t->name.begin()+10,
87  std::ostream_iterator<char>(s,""));
88  }
89  else //it is too short
90  {
91  std::copy( __t->name.begin(),
92  __t->name.end(),
93  std::ostream_iterator<char>(s,""));
94  for( decltype(__t->name.size()) i = __t->name.size() ; i < 10 ; ++i )
95  {
96  s << ' ';
97  }
98  }
99  s << __t->seq;
100  if( __t < this->end() - 1 ) s << '\n';
101  }
102  return s;
103  }
104 
105 
106 template<typename T>
107 phylipData<T> & phylipData<T>::operator=( const AlignStream<T> & rhs)
108 /*!
109  An "assignment operator" member function.
110  If a phylipData object was constructed with a value of
111  0 for the sequence name length, this function
112  will set _namelen to the max sequence name contained in \a rhs.
113  If the object was constructed with a value k > 0, the
114  sequence name length will remain unchanged.
115 */
116 {
117  this->assign(rhs.begin(),rhs.end());
118  return *this;
119 }
120 
121 }