libsequence  1.9.5
CoalescentCoalesce.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/Coalesce.hpp>
25 #include <cstdlib>
26 
27 namespace Sequence
28 {
29  namespace coalsim {
30  bool isseg( chromosome::const_iterator seg, const unsigned & nsegs,
31  const int & pos, unsigned * offset )
48  {
49  //LINEAR SEARCH
50  for( ; (seg+*offset)->beg <= pos && (*offset) < nsegs; ++(*offset) )
51  if ((seg+*offset)->end>=pos) return true;
52  return false;
53  }
54 
55  int coalesce(const double & time,
56  const int & ttl_nsam,
57  const int & current_nsam,
58  const int & c1,
59  const int & c2,
60  const int & nsites,
61  int * nlinks,
62  std::vector<chromosome> * sample,
63  arg * sample_history)
91  {
92  int ch1=(c1<c2)?c1:c2, ch2=(c2>c1)?c2:c1;
93 
94  assert( (sample->begin()+ch1)->nsegs>0 );
95  assert( (sample->begin()+ch2)->nsegs>0 );
96 
97  std::vector<chromosome>::iterator sbegin=sample->begin();
98 
99  chromosome::iterator ch1beg = (sbegin+ch1)->begin(),
100  ch2beg=(sbegin+ch2)->begin();
101  unsigned seg1=0,seg2=0;
102 
103  //segment * tsp = (segment *)malloc(sample_history->size()*sizeof(segment));
104  segment * tsp = static_cast<segment*>(malloc(sample_history->size()*sizeof(segment)));
105  int tseg = -1;
106 
107  //iterate over marginal histories
108  int k=0,nsegs=int(sample_history->size());
109  arg::iterator imarg = sample_history->begin(),
110  jmarg=imarg;
111  ++jmarg;
112  for ( ; k<nsegs ; ++imarg,++jmarg,++k )
113  {
114  //ask if chromosomes ch1 and ch2 have segments
115  //that are part of the i-th marginal history
116  bool yes1 = isseg(ch1beg,(sbegin+ch1)->nsegs,imarg->beg,&seg1);
117  bool yes2 = isseg(ch2beg,(sbegin+ch2)->nsegs,imarg->beg,&seg2);
118  if( yes1 || yes2 )
119  {
120  tseg++;
121  (tsp+tseg)->beg = imarg->beg;
122  (tsp+tseg)->end = (k<(nsegs-1)) ? jmarg->beg-1 : nsites-1;
123 
124  if(yes1 && yes2)
125  {
126  imarg->nnodes++;
127  if( imarg->nnodes >= (2*ttl_nsam-2))
128  {
129  tseg--;
130  }
131  else
132  {
133  (tsp+tseg)->desc = imarg->nnodes;
134  }
135  marginal::iterator mi = imarg->begin();
136  (mi+imarg->nnodes)->time = time;
137  (mi+(ch1beg+seg1)->desc)->abv = imarg->nnodes;
138  (mi+(ch2beg+seg2)->desc)->abv = imarg->nnodes;
139  assert( (mi+(ch1beg+seg1)->desc)->abv <= int(2*ttl_nsam-2) );
140  assert( (mi+(ch2beg+seg2)->desc)->abv <= int(2*ttl_nsam-2) );
141  }
142  else
143  {
144  (tsp+tseg)->desc = (yes1==true) ? (ch1beg+seg1)->desc : (ch2beg+seg2)->desc;
145  assert( (tsp+tseg)->desc < 2*ttl_nsam-1 );
146  }
147  }
148  }
149  *nlinks -= (sbegin+ch1)->links();
150  int flag=0;
151  if(tseg < 0)
152  {
153  free(tsp);
154  (sbegin+ch1)->swap_with(*(sbegin+current_nsam-1));
155  if(ch2 == current_nsam-1)
156  {
157  ch2=ch1;
158  }
159  flag=1;
160  assert( (sbegin+ch1)->nsegs>0 );
161  assert( (sbegin+ch2)->nsegs>0 );
162  }
163  else
164  {
165  assert( (sbegin+ch1) < sample->end() );
166  (sbegin+ch1)->assign_allocated_segs(tsp,unsigned(tseg+1));
167  *nlinks += (sbegin+ch1)->links();
168  }
169 
170  *nlinks -= (sbegin+ch2)->links();
171  (sbegin+ch2)->swap_with(*(sbegin+current_nsam-1-flag));
172  return ((tseg<0)?2:1);
173  }
174  }
175 }
std::list< marginal > arg
Ancestral Recombination Graph.
Definition: SimTypes.hpp:217
The namespace in which this library resides.
bool isseg(chromosome::const_iterator seg, const unsigned &nsegs, const int &pos, unsigned *offset)
ask if a chromosome beginning at seg and containing nsegs contains a segment containing the position ...
A portion of a recombining chromosome.
Definition: SimTypes.hpp:83
int coalesce(const double &time, const int &ttl_nsam, const int &current_nsam, const int &c1, const int &c2, const int &nsites, int *nlinks, std::vector< chromosome > *sample, arg *sample_history)
Common ancestor routine for coalescent simulation. Merges chromosome segments and updates marginal tr...