1 // Code for the -*- C++ -*- namespace Sequence::PolyTableSlice<T>
4 Copyright (C) 2003-2009 Kevin Thornton, krthornt[]@[]uci.edu
6 Remove the brackets to email me.
8 This file is part of libsequence.
10 libsequence is free software: you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation, either version 3 of the License, or
13 (at your option) any later version.
15 libsequence is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 long with libsequence. If not, see <http://www.gnu.org/licenses/>.
25 #include <Sequence/stateCounter.hpp>
33 PolyTableSlice<T>::PolyTableSlice( const PolyTable::const_site_iterator beg,
34 const PolyTable::const_site_iterator end,
35 const unsigned & window_size_S,
36 const unsigned & step_len )
37 : windows( std::vector<range>() )
40 throw std::logic_error("window size cannot be 0");
42 throw std::logic_error("step_len cannot be 0");
43 if(!std::is_sorted(beg,end,[](const polymorphicSite & a,
44 const polymorphicSite & b)
46 return a.first<b.first;
49 throw std::runtime_error("range (beg,end) must be sorted in increasing order");
51 process_windows_fixed(beg,end,window_size_S,step_len);
55 PolyTableSlice<T>::PolyTableSlice( const PolyTable::const_site_iterator beg,
56 const PolyTable::const_site_iterator end,
57 const unsigned nwindows)
58 : windows( std::vector<range>() )
60 if(!std::is_sorted(beg,end,[](const polymorphicSite & a,
61 const polymorphicSite & b)
63 return a.first<b.first;
66 throw std::runtime_error("range (beg,end) must be sorted in increasing order");
68 if( end-beg < nwindows )
70 std::cerr << "here\n";
71 process_windows_fixed(beg,end,1,1);
75 unsigned snp_per_window = unsigned(std::ceil(double(end-beg)/double(nwindows)));
76 process_windows_fixed(beg,end,snp_per_window,snp_per_window);
81 PolyTableSlice<T>::PolyTableSlice( const PolyTable::const_site_iterator beg,
82 const PolyTable::const_site_iterator end,
83 const double & window_size,
84 const double & step_len,
85 const double & starting_pos,
86 const double & ending_pos)
87 : windows( std::vector<range>() )
90 throw std::logic_error("window_size must be > 0");
92 throw std::logic_error("step_len must be > 0");
93 if(!std::is_sorted(beg,end,[](const polymorphicSite & a,
94 const polymorphicSite & b)
96 return a.first<b.first;
99 throw std::runtime_error("range (beg,end) must be sorted in increasing order");
101 process_windows(beg,end,window_size,step_len,starting_pos,ending_pos);
106 void PolyTableSlice<T>::process_windows_fixed(const PolyTable::const_site_iterator beg,
107 const PolyTable::const_site_iterator end,
108 const unsigned & window_size_S,
109 const unsigned & window_step_len )
111 std::vector<PolyTable::const_site_iterator> variable_pos;
113 //Step 1: record which sites are actually polymorphic,
114 //in case PolyTable contains invariant pos'ns
115 for(auto begc = beg; begc < end ; ++begc )
117 stateCounter counts = std::for_each( begc->second.begin(),
120 if (counts.nStates() > 1) //is a polymorphic site
122 variable_pos.push_back(begc);
125 variable_pos.push_back(end);
126 if(!variable_pos.empty())
128 for( auto vpitr = variable_pos.begin() ; vpitr < variable_pos.end() ; vpitr += window_step_len )
130 windows.emplace_back( std::make_pair(*vpitr, (window_step_len < std::distance(*vpitr,end)) ? *(vpitr+window_size_S) : end) );
136 void PolyTableSlice<T>::process_windows( const PolyTable::const_site_iterator beg,
137 const PolyTable::const_site_iterator end,
138 const double & window_size,
139 const double & step_len,
140 const double & starting_pos,
141 const double & ending_pos)
143 double wbeg = starting_pos;
145 //Obtain ptr to first element with position >= wbeg
146 auto wbeg_itr = std::lower_bound(beg,end,wbeg,
147 [](const polymorphicSite & __p, const double & __value){
148 return __p.first < __value;
150 int nwindows=int((ending_pos-wbeg)/step_len);
151 for(int win = 0 ; win < nwindows ; ++win)
153 double wend = wbeg + window_size;
154 //ptr to first element with position > wend
155 auto wend_itr = std::lower_bound(wbeg_itr,end,wend,
156 [](const polymorphicSite & __p, const double & __value){
157 return __p.first <= __value;
159 windows.push_back( std::make_pair(wbeg_itr,wend_itr) );
160 //update window begin data:
161 //Update the starting position of next window
163 //Update pointer to first data lement whose pos'n is >= wbeg
164 wbeg_itr = std::lower_bound(wbeg_itr,end,wbeg,
165 [](const polymorphicSite & __p, const double & __value){
166 return __p.first < __value;
172 typename PolyTableSlice<T>::const_iterator PolyTableSlice<T>::cbegin() const
174 return windows.begin();
178 typename PolyTableSlice<T>::const_iterator PolyTableSlice<T>::cend() const
180 return windows.end();
184 T PolyTableSlice<T>::get_slice(const_iterator itr) const
186 if (itr >= windows.end())
187 throw(std::out_of_range("PolyTableSlice<T>::get_slice() -- iterator out of range"));
188 if(itr->first != itr->second)
191 rv.assign(itr->first,itr->second);
198 typename std::vector<typename PolyTableSlice<T>::range>::size_type PolyTableSlice<T>::size() const
200 return windows.size();
204 T PolyTableSlice<T>::operator[](const unsigned & i) const
206 if (i > windows.size())
207 throw(std::out_of_range("PolyTableSlice::operator[] -- subscript out of range"));
208 if(windows[i].first != windows[i].second)
211 rv.assign(windows[i].first,windows[i].second);