libsequence  1.9.5
CoalescentRecombination.cc
1 /*
2 
3  Copyright (C) 2003-2009 Kevin Thornton, krthornt[]@[]uci.edu
4 
5  Remove the brackets to email me.
6 
7  This file is part of libsequence.
8 
9  libsequence is free software: you can redistribute it and/or modify
10  it under the terms of the GNU General Public License as published by
11  the Free Software Foundation, either version 3 of the License, or
12  (at your option) any later version.
13 
14  libsequence is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  GNU General Public License for more details.
18 
19  You should have received a copy of the GNU General Public License
20  long with libsequence. If not, see <http://www.gnu.org/licenses/>.
21 
22 */
23 
24 #include <Sequence/Coalescent/Recombination.hpp>
25 #include <cassert>
26 
27 #ifndef NDEBUG
28 namespace
29 {
30  bool arg_is_sorted( const Sequence::coalsim::arg * sample_history )
31  {
32  for( auto i = sample_history->begin() ;
33  i != sample_history->end() ;
34  ++i )
35  {
36  auto j=i;
37  ++j;
38  if( j != sample_history->end() )
39  {
40  if(i->beg > j->beg)
41  return false;
42  }
43  }
44  return true;
45  }
46 }
47 #endif
48 
49 namespace Sequence
50 {
51  namespace coalsim {
52  std::pair<int,int> pick_uniform_spot(const double & random_01,
53  const int & nlinks,
54  std::vector<chromosome>::const_iterator sample_begin,
55  const unsigned & current_nsam)
69  {
70  int pos = int(random_01*double(nlinks))+1;
71  int recombinant = 0;
72  while( (sample_begin+recombinant) <
73  (sample_begin+current_nsam) )
74  {
75  int len = (sample_begin+recombinant)->links();
76  if(pos <= len)break;
77  pos -= len;
78  recombinant++;
79  }
80  int rpos = (sample_begin+recombinant)->begin()->beg + pos - 1;
81  return std::make_pair(recombinant,rpos);
82  }
83 
84  int crossover( const int & current_nsam,
85  const int & chromo,
86  const int & pos,
87  std::vector<chromosome> * sample,
88  arg * sample_history)
101  {
102  std::vector<chromosome>::iterator sbegin = sample->begin();
103 
104  //1. Is pos within a segment, or between segments?
105  bool within = false;
106  //LINEAR SEARCH
107  chromosome::iterator seg = (sbegin+chromo)->begin();
108  for( ; pos >= seg->end ;++seg){};
109  assert(seg != (sbegin+chromo)->end());
110  within = (pos>=seg->beg) ? true:false;
111 
112  //2. make new chromosome segments for right-hand end
113  size_t ns = (sbegin+chromo)->nsegs - size_t(seg-(sbegin+chromo)->begin());
114  std::vector<segment> rtsegs(seg,seg+ns);
115 
116  //3. edit vector of segments for left-hand end
117  (sbegin+chromo)->nsegs = unsigned((int((seg)-(sbegin+chromo)->begin())) + int(within));
118  assert( (sbegin+chromo)->nsegs > 0 );
119 
120  //4. make sure begs and ends are happy
121  if(within)
122  {
123  rtsegs.begin()->beg = pos+1;
124  seg->end = pos;
125  }
126  else
127  {
128  rtsegs.begin()->beg = seg->beg;
129  }
130 
131  //rv is the number of links lost due to the crossover event
132  int rv = rtsegs.begin()->beg - ((sbegin+chromo)->end()-1)->end;
133 
134  //5. insert a new chromosom into the sample
135  //WARNING: all pointers and iterators declared above
136  //should be considered invalidated!
137  int tpop=(sbegin+chromo)->pop;
138  sample->insert(sbegin+current_nsam,chromosome(rtsegs,tpop));
139  //code below causes too much RAM usage (not sure why...)
140  // if(std::vector<chromosome>::size_type(current_nsam)+1 > sample->size())
141  // {
142  // sample->resize(current_nsam+100);
143  // sbegin = sample->begin();
144  // }
145  // *(sbegin+current_nsam) = chromosome(rtsegs,tpop);
146  assert( (sample->begin()+current_nsam)->nsegs == rtsegs.size()
147  && rtsegs.size() == ns );
148 
149  //6. insert a new marginal tree if necessary
150  if(within == true)
151  {
152  int beg_new_marg = rtsegs.begin()->beg;
153 
154  //find place in arg that is affected
155  arg::iterator argbeg = sample_history->begin();
156  arg::iterator titr=argbeg;
157  ++titr;
158  //LINEAR SEARCH
159  for( ; titr != sample_history->end()
160  && beg_new_marg > titr->beg-1 ; ++argbeg,++titr ){};
161  assert(argbeg!=sample_history->end());
162  if(argbeg->beg != beg_new_marg)
163  {
164  arg::iterator argt = sample_history->insert(titr,*(argbeg));
165  argt->beg = beg_new_marg;
166  assert(arg_is_sorted(sample_history));
167  }
168  }
169  return rv;
170  }
171  }
172 }
std::pair< int, int > pick_uniform_spot(const double &random_01, const int &nlinks, std::vector< chromosome >::const_iterator sample_begin, const unsigned &current_nsam)
Pick a crossover point for the model where recombination rates are constant across a recion...
std::list< marginal > arg
Ancestral Recombination Graph.
Definition: SimTypes.hpp:217
The namespace in which this library resides.
A chromosome is a container of segments.
Definition: SimTypes.hpp:92
A portion of a recombining chromosome.
Definition: SimTypes.hpp:83
int crossover(const int &current_nsam, const int &chromo, const int &pos, std::vector< chromosome > *sample, arg *sample_history)
Recombination function.