00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <Sequence/stateCounter.hpp>
00026 #include <algorithm>
00027
00028 namespace Sequence
00029 {
00030 template<typename T>
00031 PolyTableSlice<T>::PolyTableSlice( const PolyTable::const_site_iterator beg,
00032 const PolyTable::const_site_iterator end,
00033 const unsigned & window_size_S,
00034 const unsigned & step_len )
00035 : currentSlice(T()),
00036 windows( std::vector<range>() ),
00037 windows_begin(windows.begin()),
00038 windows_end(windows.end())
00047 {
00048 process_windows(beg,end,window_size_S,step_len,1.,false,1.);
00049 }
00050
00051 template<typename T>
00052 PolyTableSlice<T>::PolyTableSlice( const PolyTable::const_site_iterator beg,
00053 const PolyTable::const_site_iterator end,
00054 const unsigned & window_size,
00055 const unsigned & step_len,
00056 const double & alignment_length,
00057 const double & physical_scale)
00058
00059 : currentSlice(T()),
00060 windows( std::vector<range>() ),
00061 windows_begin(windows.begin()),
00062 windows_end(windows.end())
00074 {
00075 process_windows(beg,end,window_size,step_len,
00076 alignment_length,true,physical_scale);
00077 }
00078
00079
00080
00081 template<typename T>
00082 void PolyTableSlice<T>::process_windows( const PolyTable::const_site_iterator beg,
00083 const PolyTable::const_site_iterator end,
00084 const unsigned & window_size,
00085 const unsigned & step_len,
00086 const double & alignment_length,
00087 const bool & is_physical,
00088 const double & physical_scale )
00089 {
00090 if (window_size > 0 && step_len > 0 )
00091 {
00092 if (end>beg)
00093 {
00094 unsigned nsites = end-beg;
00095 if (is_physical)
00096 {
00097 PolyTable::const_site_iterator b=beg,e=end;
00098 if (alignment_length>0. && physical_scale > 0.)
00099 {
00100 double currLen=0.,endOfWindow=0.;
00101 unsigned i = 0;
00102 currLen = double(i*step_len);
00103 while(currLen < alignment_length)
00104 {
00105 endOfWindow = currLen + double(window_size);
00106 unsigned off1=Sequence::SEQMAXUNSIGNED,
00107 off2=Sequence::SEQMAXUNSIGNED;
00108 size_t j=0;
00109 while ((b+j) < e)
00110 {
00111 if ( physical_scale*(b+j)->first > currLen &&
00112 physical_scale*(b+j)->first <= endOfWindow )
00113 {
00114 if (off1 == Sequence::SEQMAXUNSIGNED)
00115 {
00116 off1=j;
00117 off2=j+1;
00118 }
00119 else
00120 {
00121 ++off2;
00122 }
00123 ++j;
00124 }
00125 else ++j;
00126 if ( (b+j)>=e || physical_scale*(b+j)->first > endOfWindow )
00127 break;
00128 }
00129 if (off1 != Sequence::SEQMAXUNSIGNED)
00130 {
00131 windows.push_back( std::make_pair( (b+off1),(b+off2) ) );
00132 }
00133 else
00134 {
00135 windows.push_back( std::make_pair( end,end ) );
00136 }
00137 ++i;
00138 currLen = double(i*step_len);
00139 }
00140 }
00141 }
00142 else
00143 {
00144 unsigned jump=0,k=0;
00145 for (unsigned i=0 ; i<nsites ; i += jump)
00146 {
00147
00148
00149
00150
00151 jump=k=0;
00152 while(jump < step_len && i+k<nsites)
00153 {
00154 stateCounter counts = std::for_each( (beg+i+k)->second.begin(),
00155 (beg+i+k)->second.end(),
00156 stateCounter('-'));
00157 if (counts.nStates() > 1)
00158 {
00159 ++jump;
00160 }
00161 ++k;
00162 }
00163 windows.push_back( std::make_pair( (beg+i),(beg+i+k) ) );
00164
00165
00166
00167
00168
00169
00170
00171
00172 }
00173 }
00174 windows_begin = windows.begin();
00175 windows_end = windows.end();
00176 }
00177 }
00178 }
00179
00180 template<typename T>
00181 typename PolyTableSlice<T>::const_iterator PolyTableSlice<T>::begin() const
00182 {
00183 return windows_begin;
00184 }
00185
00186 template<typename T>
00187 typename PolyTableSlice<T>::const_iterator PolyTableSlice<T>::end() const
00188 {
00189 return windows_end;
00190 }
00191
00192 template<typename T>
00193 T PolyTableSlice<T>::get_slice(const_iterator itr) const
00194 throw(Sequence::SeqException)
00199 {
00200 if (itr >= windows_end)
00201 throw(Sequence::SeqException("PolyTableSlice<T>::get_slice() -- iterator out of range"));
00202 if(itr->first != itr->second)
00203 {
00204 currentSlice.assign(itr->first,itr->second);
00205 return currentSlice;
00206 }
00207 return T();
00208 }
00209
00210 template<typename T>
00211 unsigned PolyTableSlice<T>::size() const
00215 {
00216 return windows.size();
00217 }
00218
00219 template<typename T>
00220 T PolyTableSlice<T>::operator[](const unsigned & i) const
00221 throw (Sequence::SeqException)
00226 {
00227 if (i > windows.size())
00228 throw(Sequence::SeqException("PolyTableSlice::operator[] -- subscript out of range"));
00229 if(windows[i].first != windows[i].second)
00230 {
00231 currentSlice.assign(windows[i].first,windows[i].second);
00232 return currentSlice;
00233 }
00234 return T();
00235 }
00236 }