Revision eeda2a8b78a2253449769d4fa3c48d506b259a43 authored by Matthew Hartfield on 09 August 2018, 12:33:39 UTC, committed by Matthew Hartfield on 09 August 2018, 12:33:39 UTC
1 parent d1cd7ed
FacSexCoalescent.c
/* FacSexCoalescent.c
The facultative sex coalescent program, ported to C
Run the program without parameters to obtain a helpfile outlining basic instructions.
Further information is available in the README file, and the manual.
(see http://github.com/MattHartfield/FacSexCoalescent for more info.)
Simulation uses routines found with the GNU Scientific Library (GSL)
(http://www.gnu.org/software/gsl/)
Since GSL is distributed under the GNU General Public License
(http://www.gnu.org/copyleft/gpl.html), you must download it
separately from this file.
*/
/* Preprocessor statements */
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include <stddef.h>
#include <string.h>
#include <gsl/gsl_rng.h>
#include <gsl/gsl_randist.h>
#include <gsl/gsl_sf_lambert.h>
#include <sys/stat.h>
#include <sys/types.h>
#define INITBR 10
#define HUGEVAL 1000000
#define WARNQ 0.05
/* Function prototypes */
unsigned int isanyUI(unsigned int *vin, unsigned int size_t, unsigned int match);
unsigned int isanyD(double *vin, unsigned int size_t, double match, unsigned int offset);
unsigned int isallUI(unsigned int *vin, unsigned int size_t, unsigned int match, unsigned int offset);
unsigned int isallI(int *vin, unsigned int size_t, int match, unsigned int offset);
unsigned int isallD(double *vin, unsigned int size_t, double match);
double powDUI(double *Va, unsigned int *Vb, unsigned int size_t);
unsigned int sumUI(unsigned int *Vin, unsigned int size_t);
double sumT_D(double **Tin, unsigned int nrow, unsigned int ncol);
unsigned int isanylessD_2D(double **Tin, unsigned int nrow, unsigned int ncol, double match);
void vcopyUI(unsigned int *Vout, unsigned int *Vin, unsigned int size_t);
void vcopyI(int *Vout, int *Vin, unsigned int size_t);
void vcopyUI_I(int *Vout, unsigned int *Vin, unsigned int size_t);
void vcopyD(double *Vout, double *Vin, unsigned int size_t);
void rowsumD(double **Tin, unsigned int nrow, unsigned int ncol, double *Vout);
unsigned int matchUI(unsigned int *Vin, unsigned int size_t, unsigned int match);
void smultI_UI(int *Vout, unsigned int *Vin, unsigned int size_t, int scale);
void vsum_UI_I(unsigned int *Vbase, int *Vadd, unsigned int size_t);
void sselect_UI(unsigned int **Tin, unsigned int *Vout, unsigned int nrow, unsigned int matchcol, unsigned int datcol, unsigned int match, unsigned int dcol, unsigned int deme);
void sselect_UIV(unsigned int **Tin, unsigned int *Vout, unsigned int nrow, unsigned int matchcol, unsigned int datcol, unsigned int *match, unsigned int mlength, unsigned int mlength2, unsigned int dcol, unsigned int deme);
double sumrep(unsigned int n);
double sumrepsq(unsigned int n);
unsigned int maxUI(unsigned int *vin, unsigned int size_t);
unsigned int minUI(unsigned int *vin, unsigned int size_t, unsigned int offset);
int minI(int *vin, unsigned int size_t, unsigned int offset);
unsigned int first_neI(int *vin, unsigned int size_t, int target, unsigned int offset);
unsigned int first_neUI(unsigned int *vin, unsigned int size_t, unsigned int target, unsigned int offset);
unsigned int last_neI(int *vin, unsigned int size_t, int target, unsigned int offset);
unsigned int last_neUI(unsigned int *vin, unsigned int size_t, unsigned int target, unsigned int offset);
unsigned int trig(unsigned int x);
double KQ(double Q);
double singGC(unsigned int y, unsigned int k, double geemi, double geeme, double Qmi, double Qme, double sexC);
double pairGC(unsigned int x, unsigned int k, double geemi, double Qmi);
double P23(unsigned int y, unsigned int k, unsigned int Na);
double P4(unsigned int x, unsigned int k, unsigned int Na);
double P56(unsigned int y, unsigned int Na);
double P7(unsigned int x, unsigned int k, unsigned int Na);
double P8(unsigned int x, unsigned int y, unsigned int k, unsigned int Na);
double P9(unsigned int x, unsigned int y, unsigned int k, double geemi, double geeme, double Qmi, double Qme, double sexC, unsigned int nsites);
double P10(unsigned int x, unsigned int y, unsigned int k, double mee);
double P11(unsigned int y, unsigned int k, double sexC, double rec, double mrec, unsigned int lrec, unsigned int nlrec, unsigned int nlrec2);
double P12(unsigned int x, unsigned int k, double geemi, double Qmi, unsigned int nsites);
double P13(unsigned int x, unsigned int k, double mrec, unsigned int lrec, unsigned int nlrecx);
double invs1(double Si, double Qin);
double invt1(double Ti, double Qin);
double invs2(double Si, double Qin);
double invt2(double Ti, double Si, double Qin);
void probset2(unsigned int N, double gmi, double gme, double *sexC, double rec, double mrec, double Qmi, double Qme, unsigned int lrec, unsigned int *nlrec, unsigned int *nlrec2, unsigned int *nlrecx, double mig, unsigned int *Nwith, unsigned int *Nbet, unsigned int *kin, unsigned int sw, double **pr);
void rate_change(unsigned int N, unsigned int pST,double pLH, double pHL, double *sexH, double *sexL, unsigned int switch1, double *sexCN, double *sexCNInv, double *tts, unsigned int *npST,const gsl_rng *r);
void stchange2(unsigned int ev, unsigned int deme, unsigned int *kin, int *WCH, int *BCH);
void sexconv(unsigned int **Tin, unsigned int *rsex, unsigned int nsum, unsigned int Ntot, unsigned int Nid, unsigned int ex);
unsigned int coalesce(unsigned int **indvs, int **GType, double **CTms , int **TAnc, unsigned int **nlri, unsigned int **nlrix, double Ttot, unsigned int *Nwith, unsigned int *Nbet, unsigned int deme, unsigned int *rsex, unsigned int *nsex, unsigned int ex, unsigned int drec, unsigned int e2, unsigned int **breaks, unsigned int nsites, unsigned int *nbreaks, unsigned int NMax, unsigned int Itot, double gmi, double gme, double Qmi, double Qme, unsigned int *gcalt, double *sexC, int *WCHex, int *BCHex, const gsl_rng *r, unsigned int ei);
void cchange(unsigned int **indvs, int **GType, double **CTms, int **TAnc, unsigned int **breaks, unsigned int *csamp, unsigned int *par, unsigned int lsamp, unsigned int Ntot, unsigned int cst, unsigned int *cend, double Ttot, unsigned int isall);
unsigned int ccheck(unsigned int **indvs, int **GType, unsigned int **breaks, unsigned int nsites, unsigned int Ntot, unsigned int nbreaks);
void excoal(unsigned int **indvs, int **GType, unsigned int *par, unsigned int nbreaks, unsigned int npar, unsigned int Ntot, int *WCHex, int *BCHex, unsigned int deme);
unsigned int coalcalc(unsigned int **breaks, unsigned int nsites, unsigned int nbreaks, unsigned int start);
void sexsamp(unsigned int **indvs, unsigned int *rsex, unsigned int *nsex, unsigned int *Nwith, unsigned int Ntot, const gsl_rng *r);
void indv_sort(unsigned int **indvs, unsigned int nrow);
void indv_sortD(double **Tin, unsigned int nrow, unsigned int ncol, unsigned int tcol);
void Wait();
void TestTabs(unsigned int **indvs, int **GType, double **CTms, int **TAnc, unsigned int **breaks, unsigned int **nlri, unsigned int **nlrix, unsigned int NMax, unsigned int Itot, unsigned int Nbet, unsigned int Nwith, unsigned int nbreaks);
char * treemaker(double **TFin, double thetain, unsigned int mind2, unsigned int maxd2, double mind, double maxd, unsigned int Itot, unsigned int run, double gmi, double gme, unsigned int ismsp, unsigned int *nmutT, unsigned int prtrees, unsigned int ismut, double pburst, unsigned int mburst, double bdist, const gsl_rng *r);
void reccal(unsigned int **indvs, int **GType, unsigned int **breaks, unsigned int **nlri, unsigned int *Nbet, unsigned int *Nwith, unsigned int *rsex, unsigned int esex, unsigned int *lnrec, unsigned int nbreaks, unsigned int NMax, unsigned int sw, unsigned int run);
void reccalx(unsigned int **indvs, int **GType, unsigned int **breaks, unsigned int **nlrix, unsigned int *Nbet, unsigned int *Nwith, unsigned int *rsex, unsigned int esex, unsigned int *lnrec, unsigned int nbreaks, unsigned int NMax, unsigned int sw, unsigned int run);
void proberr(unsigned int est, double **pr, unsigned int *NW, unsigned int *NB, unsigned int *esx);
void proberr2(double **pr, unsigned int *NW, unsigned int *NB);
void proberr3(double **pr, unsigned int *NW, unsigned int *NB);
void printCT(double **CTms, unsigned int **breaks, unsigned int nbreaks, unsigned int nsites, unsigned int Itot, unsigned int run);
void manyr();
void usage();
void inputtest(unsigned int argno, unsigned int argmax, char *args[]);
/* Global variable declaration */
double rec = 0; /* Per-site recombination rate */
unsigned int nsites = 1; /* Number of sites (for recombination) */
unsigned int d = 1; /* Number of demes */
/* Function to replicate the 'any' func in R (unsigned int) */
unsigned int isanyUI(unsigned int *vin, unsigned int size_t, unsigned int match){
unsigned int i;
unsigned int res = 0;
for(i = 0; i < size_t; i++){
if(*(vin + i) == match){
res = 1;
}
}
return res;
}
/* Function to replicate the 'any' func in R (double) */
unsigned int isanyD(double *vin, unsigned int size_t, double match, unsigned int offset){
unsigned int i;
unsigned int res = 0;
for(i = offset; i < size_t; i++){
if(*(vin + i) == match){
res = 1;
}
}
return res;
}
/* Function to replicate the 'all' func in R (unsigned int) */
unsigned int isallUI(unsigned int *vin, unsigned int size_t, unsigned int match, unsigned int offset){
unsigned int i;
unsigned int res = 1;
for(i = offset; i < size_t; i++){
if(*(vin + i) != match){
res = 0;
}
}
return res;
}
/* Function to replicate the 'all' func in R (normal int) */
unsigned int isallI(int *vin, unsigned int size_t, int match, unsigned int offset){
unsigned int i;
unsigned int res = 1;
for(i = offset; i < size_t; i++){
if(*(vin + i) != match){
res = 0;
}
}
return res;
}
/* Function to replicate the 'all' func in R (double) */
unsigned int isallD(double *vin, unsigned int size_t, double match){
unsigned int i;
unsigned int res = 1;
for(i = 0; i < size_t; i++){
if(*(vin + i) != match){
res = 0;
}
}
return res;
}
/* Dot product of two vectors (double X UI) */
double powDUI(double *Va, unsigned int *Vb, unsigned int size_t){
unsigned int i;
double res = 1;
for(i = 0; i < size_t; i++){
res *= pow((*(Va + i)),(*(Vb + i)));
}
return res;
}
/* Summing vector (UI) */
unsigned int sumUI(unsigned int *Vin, unsigned int size_t){
unsigned int i;
unsigned int res = 0;
for(i = 0; i < size_t; i++){
res += *(Vin + i);
}
return res;
}
/* Summing entire table (double) */
double sumT_D(double **Tin, unsigned int nrow, unsigned int ncol){
unsigned int i, j;
double res = 0;
for(i = 0; i < nrow; i++){
for(j = 0; j < ncol; j++){
res += (*((*(Tin + i)) + j));
}
}
return res;
}
/* Is any entry of table less than input? */
unsigned int isanylessD_2D(double **Tin, unsigned int nrow, unsigned int ncol, double match){
unsigned int i, j;
double res = 0;
for(i = 0; i < nrow; i++){
for(j = 0; j < ncol; j++){
if(*((*(Tin + i)) + j) < match){
res = 1;
}
}
}
return res;
}
/* Copying vectors (UI) */
void vcopyUI(unsigned int *Vout, unsigned int *Vin, unsigned int size_t){
unsigned int x;
for(x = 0; x < d; x++){
*(Vout + x) = *(Vin + x);
}
}
/* Copying vectors (Int) */
void vcopyI(int *Vout, int *Vin, unsigned int size_t){
unsigned int x;
for(x = 0; x < d; x++){
*(Vout + x) = *(Vin + x);
}
}
/* Copying vectors (UInt -> Int) */
void vcopyUI_I(int *Vout, unsigned int *Vin, unsigned int size_t){
unsigned int x;
for(x = 0; x < d; x++){
*(Vout + x) = *(Vin + x);
}
}
/* Copying vectors (double) */
void vcopyD(double *Vout, double *Vin, unsigned int size_t){
unsigned int x;
for(x = 0; x < d; x++){
*(Vout + x) = *(Vin + x);
}
}
/* Calculating rowsums (double) */
void rowsumD(double **Tin, unsigned int nrow, unsigned int ncol, double *Vout){
unsigned int i, j;
for(i = 0; i < nrow; i++){
*(Vout + i) = 0;
for(j = 0; j < ncol; j++){
*(Vout + i) += *((*(Tin + i)) + j);
}
}
}
/* Replicating 'match' R function (UI) */
unsigned int matchUI(unsigned int *Vin, unsigned int size_t, unsigned int match){
unsigned int i;
unsigned int res = 0;
for(i = 0; i < size_t; i++){
if(*(Vin + i) == match){
res = i;
}
}
return res;
}
/* Multiplying vector by a scalar (Int) */
void smultI_UI(int *Vout, unsigned int *Vin, unsigned int size_t, int scale){
unsigned int i;
for(i = 0; i < size_t; i++){
*(Vout + i) = (scale)*(*(Vin + i));
}
}
/* Summing two vector (UI + Int) */
void vsum_UI_I(unsigned int *Vbase, int *Vadd, unsigned int size_t){
unsigned int i;
for(i = 0; i < size_t; i++){
*(Vbase + i) += *(Vadd + i);
}
}
/* Choosing UNIQUE elements from array that match certain pattern (UI) */
void sselect_UI(unsigned int **Tin, unsigned int *Vout, unsigned int nrow, unsigned int matchcol, unsigned int datcol, unsigned int match, unsigned int dcol, unsigned int deme){
unsigned int j, x = 0;
unsigned int count = 0;
unsigned int ny = 1; /* 'Not yet' - is element already present? */
for(j = 0; j < nrow; j++){
if((*((*(Tin + j)) + matchcol) == match) && (*((*(Tin + j)) + dcol) == deme) ){
/* Only add if not yet present */
ny = 1;
for(x = 0; x < count; x++){
if( *(Vout + x) == *((*(Tin + j)) + datcol)){
ny = 0;
}
}
if(ny == 1){
*(Vout + count) = *((*(Tin + j)) + datcol);
count++;
}
}
}
}
/* Choosing elements from array that match certain vector (UI) */
void sselect_UIV(unsigned int **Tin, unsigned int *Vout, unsigned int nrow, unsigned int matchcol, unsigned int datcol, unsigned int *match, unsigned int mlength, unsigned int mlength2, unsigned int dcol, unsigned int deme){
unsigned int j = 0;
unsigned int count = 0;
unsigned int count2 = 0;
while(count < mlength && count2 < mlength2){
for(j = 0; j < nrow; j++){
if((*((*(Tin + j)) + matchcol) == (*(match + count2))) && (*((*(Tin + j)) + dcol) == deme) ){
*(Vout + 2*count) = *((*(Tin + j)) + datcol);
*(Vout + 2*count+1) = *((*(Tin + j + 1)) + datcol);
count++;
count2++;
break;
}else if((*((*(Tin + j)) + matchcol) == *(match + count2)) && (*((*(Tin + j)) + dcol) != deme) ){
count2++;
break;
}
}
}
}
/* Sum of 1/i */
double sumrep(unsigned int n){
unsigned int count = 0;
unsigned int i;
for(i = 1; i < n; i++){
count += 1/(1.0*i);
}
return(count);
}
/* Sum of 1/i^2 */
double sumrepsq(unsigned int n){
unsigned int count = 0;
unsigned int i;
for(i = 1; i < n; i++){
count += 1/(1.0*i*i);
}
return(count);
}
/* Finding max of samples (UI) */
unsigned int maxUI(unsigned int *vin, unsigned int size_t){
unsigned int ret = 0;
unsigned int i = 0;
for(i = 0; i < size_t; i++){
if(*(vin + i) > ret){
ret = *(vin + i);
}
}
return ret;
}
/* Finding min of samples (UI) */
unsigned int minUI(unsigned int *vin, unsigned int size_t, unsigned int offset){
unsigned int ret = 0;
unsigned int i = 0;
for(i = 0; i < size_t; i++){
if(*(vin + i + offset) < ret){
ret = *(vin + i + offset);
}
}
return ret;
}
/* Finding min of samples (I) */
int minI(int *vin, unsigned int size_t, unsigned int offset){
int ret = 0;
unsigned int i = 0;
for(i = 0; i < size_t; i++){
if(*(vin + i + offset) < ret){
ret = *(vin + i + offset);
}
}
return ret;
}
/* First element not of type (I) */
unsigned int first_neI(int *vin, unsigned int size_t, int target, unsigned int offset){
int ret = 0;
unsigned int i = 0;
for(i = offset; i < size_t; i++){
if(*(vin + i) != target){
ret = i;
break;
}
}
return ret;
}
/* First element not of type (UI) */
unsigned int first_neUI(unsigned int *vin, unsigned int size_t, unsigned int target, unsigned int offset){
unsigned int ret = 0;
unsigned int i = 0;
for(i = offset; i < size_t; i++){
if(*(vin + i) != target){
ret = i;
break;
}
}
return ret;
}
/* Last element not of type (I) */
unsigned int last_neI(int *vin, unsigned int size_t, int target, unsigned int offset){
int ret = 0;
unsigned int i = 0;
for(i = offset; i < size_t; i++){
if(*(vin + i) != target){
ret = i;
}
}
return ret;
}
/* Last element not of type (UI) */
unsigned int last_neUI(unsigned int *vin, unsigned int size_t, unsigned int target, unsigned int offset){
unsigned int ret = 0;
unsigned int i = 0;
for(i = offset; i < size_t; i++){
if(*(vin + i) != target){
ret = i;
}
}
return ret;
}
/* 'Triangle function' calculation */
unsigned int trig(unsigned int x){
return (x*(x-1))/2.0;
}
/* 'K' function, for GC calculations */
double KQ(double Q){
return 1.0 - ((1.0 - exp(-Q))/(1.0*Q));
}
/* Partial GC prob calculations. For calculating overall GC prob, and subprobs of different events */
double singGC(unsigned int y, unsigned int k, double geemi, double geeme, double Qmi, double Qme, double sexC){
return y*(geemi*(2.0-KQ(Qmi)) + sexC*geeme*(2.0-KQ(Qme))) + 2*k*(geemi*(2.0-KQ(Qmi)) + geeme*(2.0-KQ(Qme)));
}
double pairGC(unsigned int x, unsigned int k, double geemi, double Qmi){
return 2.0*geemi*(2.0-KQ(Qmi))*(x-k);
}
/* Functions of each transition probability calculation */
double P23(unsigned int y, unsigned int k, unsigned int Na){
/* One of the paired samples is recreated: (x,y) -> (x-k+1, y + 2(k-1)).
OR A unique samples coalesces with another (either pre-existing or new): (x,y) -> (x-k, y + 2k - 1) */
return (k*y)/(1.0*Na) + trig(2.0*k)/(2.0*Na);
}
double P4(unsigned int x, unsigned int k, unsigned int Na){
/* A paired sample coaleses with new unique sample: (x,y) -> (x-k,y + 2k -1) */
return ((x-k)*2.0*k)/(1.0*Na);
}
double P56(unsigned int y, unsigned int Na){
/* Two pre-existing unique samples re-create a paired sample: (x,y) -> (x - k + 1, y + 2(k-1)).
OR Two pre-existing unique samples coalesce: (x,y) -> (x - k, y + 2k-1) */
return trig(y)/(2.0*Na);
}
double P7(unsigned int x, unsigned int k, unsigned int Na){
/* Two remaining paired samples doubly coalesce asexually: (x,y) -> (x-k-1,y+2k) */
unsigned int diff = 0;
diff = x-k;
return trig(diff)/(1.0*Na);
}
double P8(unsigned int x, unsigned int y, unsigned int k, unsigned int Na){
/* One of the x - k remaining paired samples can coalesce with a unique sample: (x,y) -> (x-k,y+2k-1) */
unsigned int diff = 0;
diff = x-k;
return (diff*y)/(1.0*Na);
}
double P9(unsigned int x, unsigned int y, unsigned int k, double geemi, double geeme, double Qmi, double Qme, double sexC, unsigned int nsites){
/* 'Disruptive' gene conversion event (I.e. where at least one bp is in sampled material) */
double outs = 0;
if(nsites == 1){
outs = 0;
}else if(nsites > 1){
outs = pairGC(x, k, geemi, Qmi) + singGC(y, k, geemi, geeme, Qmi, Qme, sexC);
}
return outs;
}
double P10(unsigned int x, unsigned int y, unsigned int k, double mee){
/* A sample migrates to another deme */
return mee*(x + y + k);
}
double P11(unsigned int y, unsigned int k, double sexC, double rec, double mrec, unsigned int lrec, unsigned int nlrec, unsigned int nlrec2){
/* One of the single samples splits by recombination, creates two new single samples: (x,y) -> (x-k,y+2k+1) */
return ((sexC*rec + mrec)*((lrec - 1)*(y) - nlrec) + (rec + mrec)*((lrec - 1)*(2*k) - nlrec2));
}
double P12(unsigned int x, unsigned int k, double geemi, double Qmi, unsigned int nsites){
/* Complete gene conversion, coalesces paired sample into single sample */
double outs = 0;
if(nsites == 1){
outs = geemi*(x-k);
}else if(nsites > 1){
outs = (2*geemi*(x-k)*(exp(-Qmi)/(1.0*Qmi)));
}
return outs;
}
double P13(unsigned int x, unsigned int k, double mrec, unsigned int lrec, unsigned int nlrecx){
/* Mitotic recombination acting on paired sample. Does not change sample partition, instead alters genealogy along samples */
return ((mrec)*((lrec - 1)*((x-k)) - nlrecx));
}
double invs1(double Si, double Qin){
/* Inversion of start point, if starting but not ending in tract */
return log(1 + (exp(Qin)-1)*Si)/(1.0*Qin);
}
double invt1(double Ti, double Qin){
/* Inversion of end point, if starting outside but ending in tract */
return (Qin - log(exp(Qin) + Ti - exp(Qin)*Ti))/(1.0*Qin);
}
double invs2(double Si, double Qin){
/* Inversion of start point, double GC event (2 bps) */
return exp(-Qin)*(-1.0 + Si + exp(Qin)*(Si*(Qin - 1.0) - gsl_sf_lambert_W0((-1.0)*exp(-Qin + Si*(Qin - 1.0) + exp(-Qin)*(Si-1.0)))))/(1.0*Qin);
}
double invt2(double Ti, double Si, double Qin){
/* Inversion of endpoint for double GC event (2 bps) */
return Si - (log(1.0 - Ti*(1.0 - exp(-Qin*(1.0 - Si)))))/(1.0*Qin);
}
/* Calculate probability change vectors each time OVER EACH DEME */
void probset2(unsigned int N, double gmi, double gme, double *sexC, double rec, double mrec, double Qmi, double Qme, unsigned int lrec, unsigned int *nlrec, unsigned int *nlrec2, unsigned int *nlrecx, double mig, unsigned int *Nwith, unsigned int *Nbet, unsigned int *kin, unsigned int sw, double **pr){
unsigned int x; /* Deme counter */
unsigned int ksum = 0; /* Total number of segregating events */
/* First calculate number of splits... */
for(x = 0; x < d; x++){
ksum += *(kin + x);
}
/* Calculate each transition probability, per deme */
for(x = 0; x < d; x++){
*((*(pr + 4)) + x) = P56(*(Nbet + x),N);
*((*(pr + 5)) + x) = P56(*(Nbet + x),N);
*((*(pr + 6)) + x) = P7(*(Nwith + x),*(kin + x),N);
*((*(pr + 7)) + x) = P8(*(Nwith + x),*(Nbet + x),*(kin + x),N);
*((*(pr + 8)) + x) = P9(*(Nwith + x),*(Nbet + x),*(kin + x),gmi,gme,Qmi,Qme,*(sexC + x),nsites);
*((*(pr + 9)) + x) = P10(*(Nwith + x),*(Nbet + x),*(kin + x),mig);
*((*(pr + 10)) + x) = P11(*(Nbet + x),*(kin + x),*(sexC + x),rec,mrec,lrec,*(nlrec + x),*(nlrec2 + x));
*((*(pr + 11)) + x) = P12(*(Nwith + x),*(kin + x),gmi,Qmi,nsites);
*((*(pr + 12)) + x) = P13(*(Nwith + x),*(kin + x),mrec,lrec,*(nlrecx + x));
/* Only activate the first three events if need to consider segregation via sex
(fourth is 'split pairs remain split') */
if(sw == 1){
if(ksum != 1){
*((*(pr + 1)) + x) = P23(*(Nbet + x),*(kin + x),N);
}else if(ksum == 1){
*((*(pr + 1)) + x) = 0;
}
*((*(pr + 2)) + x) = P23(*(Nbet + x),*(kin + x),N);
*((*(pr + 3)) + x) = P4(*(Nwith + x),*(kin + x),N);
/* Last entry is simply 1-(sum all other probs) */
if(x == 0){
*((*(pr + 0)) + x) = (1-sumT_D(pr,13,d));
}
}else if(sw == 0){
*((*(pr + 1)) + x) = 0;
*((*(pr + 2)) + x) = 0;
*((*(pr + 3)) + x) = 0;
*((*(pr + 0)) + x) = 0;
}
}
} /* End of 'probset2' function */
/* Function to change rates of sex given a state change */
void rate_change(unsigned int N, unsigned int pST,double pLH, double pHL, double *sexH, double *sexL, unsigned int switch1, double *sexCN, double *sexCNInv, double *tts, unsigned int *npST, const gsl_rng *r){
unsigned int x = 0; /* Deme counter */
/* Setting up transition time (tts, or 'time to switch') */
if(pST == 0){
for(x = 0; x < d; x++){
*(sexCN + x) = *(sexL + x);
*(sexCNInv + x) = 1.0 - (*(sexL + x));
}
*tts = gsl_ran_geometric(r,pLH)/(2.0*N*d);
*npST = 1;
}else if(pST == 1){
for(x = 0; x < d; x++){
*(sexCN + x) = *(sexH + x);
*(sexCNInv + x) = 1.0 - (*(sexH + x));
}
*tts = gsl_ran_geometric(r,pHL)/(2.0*N*d);
*npST = 0;
}else if(pST == 2){ /* If stepwise change, alter depending on whether already switched or not */
*npST = pST;
if(switch1 == 0){
for(x = 0; x < d; x++){
*(sexCN + x) = *(sexL + x);
*(sexCNInv + x) = 1.0 - (*(sexL + x));
}
*tts = pLH;
}else if(switch1 == 1){
for(x = 0; x < d; x++){
*(sexCN + x) = *(sexH + x);
*(sexCNInv + x) = 1.0 - (*(sexH + x));
}
*tts = (1.0/0.0);
}
}else if(pST == 3){ /* If constant, no time to sex switch */
for(x = 0; x < d; x++){
*(sexCN + x) = *(sexL + x);
*(sexCNInv + x) = 1.0 - (*(sexL + x));
}
*tts = (1.0/0.0);
*npST = pST;
}
} /* End of 'rate_change' function */
/* Function to determine how to change state numbers following an event,
taking into account events over all demes*/
void stchange2(unsigned int ev, unsigned int deme, unsigned int *kin, int *WCH, int *BCH){
int *oo3 = calloc(2,sizeof(int)); /* Extra change in pop due to event */
int *negk = calloc(d,sizeof(int)); /* Negative of k */
int *dblek = calloc(d,sizeof(int)); /* Double k */
/* Rescaling k */
smultI_UI(negk, kin, d, (-1));
smultI_UI(dblek, kin, d, 2);
/* Baseline sex events */
vcopyI(WCH, negk, d);
vcopyI(BCH, dblek, d);
/* Now deciding extra events depending on deme and event */
switch(ev)
{
case 0:
*(oo3 + 0) = 0;
*(oo3 + 1) = 0;
break;
case 1:
*(oo3 + 0) = 1;
*(oo3 + 1) = -2;
break;
case 2:
*(oo3 + 0) = 0;
*(oo3 + 1) = -1;
break;
case 3:
*(oo3 + 0) = 0;
*(oo3 + 1) = -1;
break;
case 4:
*(oo3 + 0) = 1;
*(oo3 + 1) = -2;
break;
case 5:
*(oo3 + 0) = 0;
*(oo3 + 1) = -1;
break;
case 6:
*(oo3 + 0) = -1;
*(oo3 + 1) = 0;
break;
case 7:
*(oo3 + 0) = 0;
*(oo3 + 1) = -1;
break;
case 8:
*(oo3 + 0) = 0;
*(oo3 + 1) = 0;
break;
case 9:
*(oo3 + 0) = 0;
*(oo3 + 1) = 0;
break;
case 10:
*(oo3 + 0) = 1;
*(oo3 + 1) = -1;
break;
case 11:
*(oo3 + 0) = -1;
*(oo3 + 1) = 1;
break;
case 12:
*(oo3 + 0) = 0;
*(oo3 + 1) = 0;
break;
default: /* If none of these cases chosen, exit with error message */
fprintf(stderr,"Error: Non-standard coalescent case selected ('stchange2').\n");
exit(1);
break;
}
*(WCH + deme) += *(oo3 + 0);
*(BCH + deme) += *(oo3 + 1);
free(dblek);
free(negk);
free(oo3);
} /* End of 'stchange' function */
/* For converting WH to BH */
void sexconv(unsigned int **Tin, unsigned int *rsex, unsigned int nsum, unsigned int Ntot, unsigned int Nid, unsigned int ex){
unsigned int j;
unsigned int count = 0;
unsigned int npc = 0;
while(count < nsum){
for(j = 0; j < Ntot; j++){
if( *((*(Tin + j)) + 1) == *(rsex + count) ){
*((*(Tin + j)) + 2) = 1;
*((*(Tin + j + 1)) + 2) = 1; /* Since other paired sample also split */
if(ex == 8 || ex == 10){
*((*(Tin + j + 1)) + 1) = Nid + npc; /* Placing sample in *same* individual with rec or GC */
npc++;
}
count++;
break;
}
}
}
}
/* Function to change status of samples following event change */
unsigned int coalesce(unsigned int **indvs, int **GType, double **CTms , int **TAnc, unsigned int **nlri, unsigned int **nlrix, double Ttot, unsigned int *Nwith, unsigned int *Nbet, unsigned int deme, unsigned int *rsex, unsigned int *nsex, unsigned int ex, unsigned int drec, unsigned int e2, unsigned int **breaks, unsigned int nsites, unsigned int *nbreaks, unsigned int NMax, unsigned int Itot, double gmi, double gme, double Qmi, double Qme, unsigned int *gcalt, double *sexC, int *WCHex, int *BCHex, const gsl_rng *r, unsigned int ei){
unsigned int NWtot = 2*sumUI(Nwith,d);
unsigned int NBtot = sumUI(Nbet,d);
unsigned int Ntot = NWtot + NBtot;
unsigned int Nindv = sumUI(Nwith,d) + sumUI(Nbet,d);
unsigned int NindvW = sumUI(Nwith,d);
unsigned int nsum = sumUI(nsex,d);
unsigned int j = 0;
unsigned int a = 0;
int x = 0;
unsigned int count = 0; /* For converting WH to BH samples */
unsigned int done = 0; /* For sampling right individual */
unsigned int rands = 0; /* Sample split by rec (event 10) */
unsigned int rands2 = 0; /* Sample that does not split fully (event 1; also used in event 8) */
unsigned int rands3 = 0; /* Other chromosome arm during mitotic rec event (event 12) */
unsigned int nos = 0; /* Sub-sample that does not split fully (event 1) */
unsigned int bhc = 0; /* Single sample that repairs (ev 1) or migrates (ev 9); */
unsigned int csamp = 0; /* Sample that coalesces */
unsigned int par = 0; /* Parental sample in coalescence */
unsigned int par2 = 0; /* Parental sample of paired coalescence (ev 2) */
unsigned int WHsel = 0; /* WH sample involved in event (ev 7) */
unsigned int isWH = 0; /* Is the sample from WH? (ev 7) */
unsigned int parNo = 0; /* Parent where coalescent occurs (event 6) */
unsigned int rsite = 0; /* Position of recombination breakpoint (event 10) */
unsigned int isyetbp = 0; /* Is breakpoint already present? (event 10) */
unsigned int isyetbp2 = 0; /* Is 2nd breakpoint already present? (event 8) */
unsigned int maxtr = 0; /* Max site in bp table before breakpoint (event 10) */
unsigned int mintr = 0; /* Start of GC event (event 8) */
unsigned int gt = 0; /* GC acting on single or paired sample? (event 8) */
int gcst = 0; /* GC start point (event 8) */
int gcend = 0; /* GC end point (event 8) */
unsigned int gcsamp = 0; /* Index of GC'ed sample (event 8) */
unsigned int gcsamp2 = 0; /* Index of GC'ed sample if paired sample involved (event 8) */
double NWd = 0; /* Weighted WH sample chosen (event 8) */
double NTd = 0; /* Total GC prob (ev 8) */
double gcMI = 0; /* Probability that single samp GC event is mitotic (event 8) */
double Qin = 0; /* Q value used in subsequent calcs (event 8) */
double gcst2 = 0; /* Initial start site for GC (event 8) */
double gcend2 = 0; /* Initial end site for GC (event 8) */
double p1bp = 0; /* Prob 1 breakpoint (event 8) */
unsigned int gcst3 = 0;
unsigned int gcS = 0; /* Type of GC evening on unpaired samples (event 8) */
unsigned int mindr = 0; /* Done choosing min tract point? (event 8) */
unsigned int proceed = 0; /* Proceed with gene conversion? (event 8) */
unsigned int maxck = 0; /* Check if end of bp correctly chosen (event 8) */
unsigned int iscoal = 0; /* Check if paired GC event leads to coalescence (event 8) */
unsigned int rpar = 0; /* Indv number of recombined sample (event 10) */
unsigned int gcbp = 0; /* Type of GC event (1 or 2 breakpoints; event 8) */
unsigned int achange = 0; /* Note whether to run extra coal check */
unsigned int length = 0; /* Length of sampled chrom (event 10) */
unsigned int start = 0; /* Start of sampled chrom (event 10) */
unsigned int ctype = 0; /* Coalesced type if mitotic rec creates non-ancestral tract (event 12) */
int tempGT = 0; /* Temporary storage of genotype entry during mitotic recombination (event 12) */
/* Then further actions based on other event */
switch(ex)
{
case 0: /* Event 0: 2k new samples created from paired samples. Nothing else to be done */
sexconv(indvs, rsex, nsum, Ntot, Nindv, ex);
break;
case 1: /* Event 1: One of the paired samples is recreated, no coalescence */
/* First choose sample that does not split fully */
while(done == 0){
gsl_ran_choose(r,&rands2,1,rsex,nsum,sizeof(unsigned int));
/* Then checking it is in the same deme as the action */
for(j = 0; j < Ntot; j++){
if( *((*(indvs + j)) + 1) == rands2 ){
if(*((*(indvs + j)) + 3) == deme){
done = 1;
}
}
}
}
/* Then setting BH samples */
nos = gsl_ran_bernoulli(r,0.5); /* Only sample that splits fully */
while(count < nsum){
for(j = 0; j < Ntot; j++){
if( *((*(indvs + j)) + 1) == *(rsex + count) ){
if(*(rsex + count) != rands2){
*((*(indvs + j)) + 2) = 1;
*((*(indvs + j + 1)) + 2) = 1;
*((*(indvs + j + 1)) + 1) = (Nindv + count);
count++;
}else if(*(rsex + count) == rands2){
*((*(indvs + j + nos)) + 2) = 1;
*((*(indvs + j + nos)) + 1) = (Nindv + count);
count++;
}
break;
}
}
}
/* Now; out of all single samples, choose one to rebind with the single sample */
unsigned int *singsamps = calloc((*(Nbet + deme) + 2*(*(nsex + deme)) - 1),sizeof(unsigned int)); /* For storing BH samples */
sselect_UI(indvs, singsamps, Ntot, 2, 0, 1, 3, deme);
gsl_ran_choose(r,&bhc,1,singsamps,(*(Nbet + deme) + 2*(*(nsex + deme)) - 1),sizeof(unsigned int));
for(j = 0; j < Ntot; j++){
if( *((*(indvs + j)) + 0) == bhc ){
*((*(indvs + j)) + 2) = 0;
*((*(indvs + j)) + 1) = rands2; /* Ensuring paired samples have same parents*/
break;
}
}
free(singsamps);
break;
case 2: /* Event 2: One of the unique samples coaleses with another unique one (either pre-existing or new) */
done = 0;
sexconv(indvs, rsex, nsum, Ntot, Nindv, ex);
unsigned int *singsamps2 = calloc((*(Nbet + deme) + 2*(*(nsex + deme))),sizeof(unsigned int)); /* For storing BH samples */
sselect_UI(indvs, singsamps2, Ntot, 2, 0, 1, 3, deme);
while(done == 0){
gsl_ran_choose(r,&csamp,1,singsamps2,(*(Nbet + deme) + 2*(*(nsex + deme))),sizeof(unsigned int)); /* One sample involved in coalescence (csamp) */
par = csamp;
while(par == csamp){ /* Ensuring par != csamp */
gsl_ran_choose(r,&par,1,singsamps2,(*(Nbet + deme) + 2*(*(nsex + deme))),sizeof(unsigned int)); /* Other sample involved in coalescence (par) */
}
/* Now checking that at least one of the two is from sample split by sex */
for(j = 0; j < Ntot; j++){
if( (*((*(indvs + j)) + 0) == csamp) || (*((*(indvs + j)) + 0) == par) ){
for(a = 0; a < nsum; a++){
if( (*((*(indvs + j)) + 1)) == *(rsex + a)){
done = 1;
break;
}
}
}
}
}
/* Now updating coalescent times */
cchange(indvs, GType, CTms, TAnc, breaks, &csamp, &par, 1, Ntot, 0, nbreaks, Ttot, 1);
/* Check if tracts have coalesced */
achange = ccheck(indvs,GType,breaks,nsites,Ntot,*nbreaks);
if(achange == 1){
excoal(indvs, GType, &par, *nbreaks, 1, Ntot, WCHex, BCHex, deme);
}
free(singsamps2);
break;
case 3: /* Event 3: A paired sample coaleses with new unique sample */
sexconv(indvs, rsex, nsum, Ntot, Nindv, ex);
unsigned int *singsamps3N = calloc(2*(*(nsex + deme)),sizeof(unsigned int)); /* For storing new BH samples */
unsigned int *singsamps3B = calloc( 2*((*(Nwith + deme) - (*(nsex + deme)))) ,sizeof(unsigned int)); /* For storing WH samples */
unsigned int *twosamps = calloc(2,sizeof(unsigned int)); /* Two samples in coalescence */
/* Creating vector of new unique samples created */
sselect_UIV(indvs, singsamps3N, Ntot, 1, 0, rsex, 2*(*(nsex + deme)), nsum, 3, deme);
/* Creating vector of existing paired samples */
sselect_UI(indvs, singsamps3B, Ntot, 2, 0, 0, 3, deme);
gsl_ran_choose(r,&twosamps[0],1,singsamps3N,(2*(*(nsex + deme))),sizeof(unsigned int)); /* Unique sample involved in coalescence */
gsl_ran_choose(r,&twosamps[1],1,singsamps3B,(2*((*(Nwith + deme) - (*(nsex + deme))))),sizeof(unsigned int)); /* Paired sample involved in coalescence */
gsl_ran_choose(r,&csamp,1,twosamps,2,sizeof(unsigned int)); /* One sample involved in coalescence (csamp) */
par = csamp;
while(par == csamp){ /* Ensuring par != csamp */
gsl_ran_choose(r,&par,1,twosamps,2,sizeof(unsigned int)); /* Other sample involved in coalescence (par) */
}
/* Correction if parential sample is unique sample */
unsigned int pcorr = 0;
for(j = 0; j < Ntot; j++){
if( (*((*(indvs + j)) + 0) == par) && (*((*(indvs + j)) + 2) == 1) ){
pcorr = 1;
par2 = j;
(*((*(indvs + j)) + 2) = 0);
break;
}
}
if(pcorr == 1){
for(j = 0; j < Ntot; j++){
if(*((*(indvs + j)) + 0) == csamp){
*((*(indvs + par2)) + 1) = *((*(indvs + j)) + 1);
break;
}
}
}
/* Now updating coalescent times */
cchange(indvs, GType, CTms, TAnc, breaks, &csamp, &par, 1, Ntot, 0, nbreaks, Ttot, 1);
/* Check if tracts have coalesced */
achange = ccheck(indvs,GType,breaks,nsites,Ntot,*nbreaks);
if(achange == 1){
excoal(indvs, GType, &par, *nbreaks, 1, Ntot, WCHex, BCHex, deme);
}
free(twosamps);
free(singsamps3B);
free(singsamps3N);
break;
case 4: /* Event 4: Two pre-existing unique samples re-create paired sample. */
done = 0;
unsigned int *singsamps4 = calloc(*(Nbet + deme),sizeof(unsigned int)); /* For storing BH samples */
unsigned int *twosing = calloc(2,sizeof(unsigned int));
sselect_UI(indvs, singsamps4, Ntot, 2, 0, 1, 3, deme);
/* Two sample involved in pairing */
gsl_ran_choose(r,twosing,2,singsamps4,*(Nbet + deme),sizeof(unsigned int));
gsl_ran_shuffle(r, twosing, 2, sizeof(unsigned int));
/* Now going through (twice!) and updating ancestry */
for(j = 0; j < Ntot; j++){
if(*((*(indvs + j)) + 0) == *(twosing + 0)){
par2 = j;
*((*(indvs + j)) + 2) = 0;
break;
}
}
for(j = 0; j < Ntot; j++){
if(*((*(indvs + j)) + 0) == *(twosing + 1)){
*((*(indvs + j)) + 2) = 0;
*((*(indvs + j)) + 1) = *((*(indvs + par2)) + 1);
break;
}
}
/* THEN convert WH to BH samples */
sexconv(indvs, rsex, nsum, Ntot, Nindv, ex);
free(twosing);
free(singsamps4);
break;
case 5: /* Event 5: Two pre-existing unique samples coalesce */
csamp = 0;
unsigned int *singsamps5 = calloc(*(Nbet + deme),sizeof(unsigned int)); /* For storing BH samples */
sselect_UI(indvs, singsamps5, Ntot, 2, 0, 1, 3, deme);
gsl_ran_choose(r,&csamp,1,singsamps5,(*(Nbet + deme)),sizeof(unsigned int)); /* One sample involved in coalescence (csamp) */
par = csamp;
while(par == csamp){ /* Ensuring par != csamp */
gsl_ran_choose(r,&par,1,singsamps5,(*(Nbet + deme)),sizeof(unsigned int)); /* Other sample involved in coalescence (par) */
}
/* Now updating coalescent times */
cchange(indvs, GType, CTms, TAnc, breaks, &csamp, &par, 1, Ntot, 0, nbreaks, Ttot, 1);
/* Check if tracts have coalesced */
achange = ccheck(indvs,GType,breaks,nsites,Ntot,*nbreaks);
if(achange == 1){
excoal(indvs, GType, &par, *nbreaks, 1, Ntot, WCHex, BCHex, deme);
}
/* THEN convert WH to BH samples */
sexconv(indvs, rsex, nsum, Ntot, Nindv, ex);
free(singsamps5);
break;
case 6: /* Event 6: Two remaining paired samples doubly coalesce asexually. */
/* Converting WH to BH samples */
sexconv(indvs, rsex, nsum, Ntot, Nindv, ex);
unsigned int *parsamps6 = calloc((*(Nwith + deme) - *(nsex + deme)),sizeof(unsigned int)); /* For storing WH indvs */
unsigned int *twopars6 = calloc(2,sizeof(unsigned int));
unsigned int *lhs = calloc(2,sizeof(unsigned int));
unsigned int *rhs = calloc(2,sizeof(unsigned int));
unsigned int *csamp2 = calloc(2,sizeof(unsigned int));
unsigned int *parT = calloc(2,sizeof(unsigned int));
sselect_UI(indvs, parsamps6, Ntot, 2, 1, 0, 3, deme);
/* Two parents involved in coalescence */
gsl_ran_choose(r,twopars6,2,parsamps6,(*(Nwith + deme) - *(nsex + deme)),sizeof(unsigned int));
gsl_ran_shuffle(r,twopars6, 2, sizeof(unsigned int));
/* Finding parents and partitioning samples (twice) */
for(j = 0; j < Ntot; j++){
if(*((*(indvs + j)) + 1) == *(twopars6 + 0)){
*(lhs + 0) = *((*(indvs + j)) + 0);
*(rhs + 0) = *((*(indvs + j + 1)) + 0);
break;
}
}
for(j = 0; j < Ntot; j++){
if(*((*(indvs + j)) + 1) == *(twopars6 + 1)){
*(lhs + 1) = *((*(indvs + j)) + 0);
*(rhs + 1) = *((*(indvs + j + 1)) + 0);
break;
}
}
/* Now assigning coalesced and parental samples respectively */
gsl_ran_choose(r,&csamp2[0],1,lhs,2,sizeof(unsigned int));
parT[0] = csamp2[0];
while(parT[0] == csamp2[0]){
gsl_ran_choose(r,&parT[0],1,lhs,2,sizeof(unsigned int));
}
gsl_ran_choose(r,&csamp2[1],1,rhs,2,sizeof(unsigned int));
parT[1] = csamp2[1];
while(parT[1] == csamp2[1]){
gsl_ran_choose(r,&parT[1],1,rhs,2,sizeof(unsigned int));
}
/* Now updating coalescent times */
cchange(indvs, GType, CTms, TAnc, breaks, csamp2, parT, 2, Ntot, 0, nbreaks, Ttot, 1);
/* Check if tracts have coalesced */
achange = ccheck(indvs,GType,breaks,nsites,Ntot,*nbreaks);
/* Making sure parent samples are in same individual */
for(j = 0; j < Ntot; j++){
if(*((*(indvs + j)) + 0) == parT[0]){
parNo = *((*(indvs + j)) + 1);
break;
}
}
for(j = 0; j < Ntot; j++){
if(*((*(indvs + j)) + 0) == parT[1]){
*((*(indvs + j)) + 1) = parNo;
break;
}
}
if(achange == 1){
excoal(indvs, GType, parT, *nbreaks, 2, Ntot, WCHex, BCHex, deme);
}
free(parT);
free(csamp2);
free(rhs);
free(lhs);
free(twopars6);
free(parsamps6);
break;
case 7: /* Event 7: One of the x - k remaining paired samples coalesces with a unique sample */
/* Converting WH to BH samples
(idea being that I later check if chosen BH originated from WH
- discard if so) */
sexconv(indvs, rsex, nsum, Ntot, Nindv, ex);
/* For storing WH indvs */
unsigned int *parsamps7 = calloc((*(Nwith + deme) - *(nsex + deme)),sizeof(unsigned int));
unsigned int *singsamps7 = calloc((*(Nbet + deme) + 2*(*(nsex + deme))),sizeof(unsigned int)); /* For storing BH samples */
unsigned int *twosamps7 = calloc(2,sizeof(unsigned int));
sselect_UI(indvs, parsamps7, Ntot, 2, 1, 0, 3, deme);
sselect_UI(indvs, singsamps7, Ntot, 2, 0, 1, 3, deme);
/* A paired sample involved in coalescence */
gsl_ran_choose(r,&WHsel,1,parsamps7,(*(Nwith + deme) - *(nsex + deme)),sizeof(unsigned int));
nos = gsl_ran_bernoulli(r,0.5); /* Which side involved in event */
/* Finding sample */
for(j = 0; j < Ntot; j++){
if(*((*(indvs + j)) + 1) == WHsel){
*(twosamps7 + 0) = *((*(indvs + j + nos)) + 0);
break;
}
}
/* Choosing BH sample */
while(done == 0){
gsl_ran_choose(r,&twosamps7[1],1,singsamps7,(*(Nbet + deme) + 2*(*(nsex + deme))),sizeof(unsigned int));
/* Checking that it didn't originate from WH */
for(j = 0; j < Ntot; j++){
if(*((*(indvs + j)) + 0) == *(twosamps7 + 1)){
/* ACTIONS */
isWH = 1;
for(a = 0; a < nsum; a++){
if( *((*(indvs + j)) + 1) == *(rsex + a)){
isWH = 0;
}
}
if(isWH == 1){
done = 1;
}
break;
}
}
}
/* Choosing csamp, par */
gsl_ran_choose(r,&csamp,1,twosamps7,2,sizeof(unsigned int)); /* One sample involved in coalescence (csamp) */
par = csamp;
while(par == csamp){ /* Ensuring par != csamp */
gsl_ran_choose(r,&par,1,twosamps7,2,sizeof(unsigned int)); /* Other sample involved in coalescence (par) */
}
/* Correction if parental sample is BH */
if(par == *(twosamps7 + 1)){
for(j = 0; j < Ntot; j++){
if(*((*(indvs + j)) + 0) == par){
*((*(indvs + j)) + 2) = 0;
*((*(indvs + j)) + 1) = WHsel; /* Same parent as WH sample */
break;
}
}
}
/* Now updating coalescent times */
cchange(indvs, GType, CTms, TAnc, breaks, &csamp, &par, 1, Ntot, 0, nbreaks, Ttot, 1);
/* Check if tracts have coalesced */
achange = ccheck(indvs,GType,breaks,nsites,Ntot,*nbreaks);
if(achange == 1){
excoal(indvs, GType, &par, *nbreaks, 1, Ntot, WCHex, BCHex, deme);
}
free(twosamps7);
free(singsamps7);
free(parsamps7);
break;
case 8: /* Event 8: (Partial) Gene conversion */
/* Converting WH to BH samples */
sexconv(indvs, rsex, nsum, Ntot, Nindv, ex);
/* First, is it a paired or single sample that is affected? */
NWd = pairGC(*(Nwith + deme), *(nsex + deme), gmi, Qmi);
NTd = NWd + singGC(*(Nbet + deme), *(nsex + deme), gmi, gme, Qmi, Qme, *(sexC + deme));
gt = gsl_ran_bernoulli(r,(NWd/(1.0*NTd)));
if(gt == 0){ /* Acts on single sample */
unsigned int *singsamps8 = calloc((*(Nbet + deme) + 2*(*(nsex + deme))),sizeof(unsigned int));
/* Obtaining list of samples to choose from */
sselect_UI(indvs, singsamps8, Ntot, 2, 0, 1, 3, deme);
/* Sample that undergoes GC */
gsl_ran_choose(r,&rands,1,singsamps8,(*(Nbet + deme) + 2*(*(nsex + deme))),sizeof(unsigned int));
for(j = 0; j < NMax; j++){
if( *((*(GType + j)) + 0) == rands){
gcsamp = j;
break;
}
}
/* Then choosing type of event */
gcMI = ((gmi*(2.0-KQ(Qmi))*((*(Nbet + deme)) + 2*(*(nsex + deme))))/(1.0*singGC(*(Nbet + deme), *(nsex + deme), gmi, gme, Qmi, Qme, *(sexC + deme))));
gcS = gsl_ran_bernoulli(r,gcMI);
if(gcS == 0){
Qin = Qme;
}else if(gcS == 1){
Qin = Qmi;
}
free(singsamps8);
}else if(gt == 1){ /* Acts on paired sample */
Qin = Qmi;
unsigned int *parsamps8 = calloc((*(Nwith + deme) - *(nsex + deme)),sizeof(unsigned int));
/* Obtaining list of samples to choose from */
sselect_UI(indvs, parsamps8, Ntot, 2, 1, 0, 3, deme);
/* Sample that undergoes GC */
gsl_ran_choose(r,&rands,1,parsamps8,(*(Nwith + deme) - *(nsex + deme)),sizeof(unsigned int));
rands2 = gsl_ran_bernoulli(r,0.5);
for(j = 0; j < Ntot; j++){
if( *((*(indvs + j)) + 1) == rands){
gcsamp = *((*(indvs + j + rands2)) + 0);
gcsamp2 = *((*(indvs + j + (rands2 + 1)%2)) + 0);
break;
}
}
free(parsamps8);
}
/* Now determining type of GC event. */
/* Does there exist one or two breakpoints? */
if(nsites == 2){
gcbp = 1;
}else if(nsites > 2){
p1bp = 2.0*((1-KQ(Qin))/(1.0*(2.0-KQ(Qin))));
gcbp = gsl_ran_bernoulli(r,p1bp);
}
if(gcbp == 0){ /* Two breakpoints */
gcst = 0;
gcend = nsites;
while(gcst == 0 || gcst >= (nsites-1)){
gcst2 = gsl_ran_flat(r, 0, 1);
gcst = (unsigned int)(invs2(gcst2,Qin)*nsites);
}
while(gcend == 0 || gcend == nsites || gcend == gcst){
gcend2 = gsl_ran_flat(r, 0, 1);
gcend = (unsigned int)(invt2(gcend2, (gcst/(1.0*nsites)), Qin)*nsites);
}
}else if(gcbp == 1){ /* One breakpoint */
gcst3 = gsl_ran_bernoulli(r,0.5);
if(gcst3 == 0){ /* Starts outside, ends in */
gcst = 0;
gcend = 0;
while(gcend == 0 || gcend == nsites){
gcend2 = gsl_ran_flat(r, 0, 1);
gcend = (unsigned int)(invt1(gcend2,Qin)*nsites);
}
}else if(gcst3 == 1){ /* Starts inside, ends out */
gcend = nsites;
gcst = 0;
while(gcst == 0 || gcst == nsites){
gcst2 = gsl_ran_flat(r, 0, 1);
gcst = (unsigned int)(invs1(gcst2,Qin)*nsites);
}
}
}
/* Finding block number associated with start point */
mindr = 0;
for(x = 0; x < *nbreaks; x++){
if( *((*(breaks + 0)) + x) == gcst){
isyetbp = 1;
}
if( *((*(breaks + 0)) + x) > gcst){
mintr = (x-1);
mindr = 1;
break;
}
}
if(mindr == 0){ /* GC start past end of current breakpoints, so need to force it */
mintr = ((*nbreaks)-1);
}
/* Inserting new, start BP if needed */
if((isyetbp != 1) && (*((*(GType + gcsamp)) + mintr + 1) != (-1))){
(*nbreaks)++;
for(x = *nbreaks-2; x >= (int)(mintr+1); x--){
*((*(breaks + 0)) + x + 1) = *((*(breaks + 0)) + x);
*((*(breaks + 1)) + x + 1) = *((*(breaks + 1)) + x);
}
*((*(breaks + 0)) + mintr + 1) = gcst;
*((*(breaks + 1)) + mintr + 1) = 0;
/* Adding new site to genotype; coalescent time; ancestry table */
for(j = 0; j < NMax; j++){
for(x = (*nbreaks-1); x > (int)(mintr); x--){
*((*(GType + j)) + x + 1) = *((*(GType + j)) + x);
if(j < Itot){
*((*(CTms + j)) + x + 1) = *((*(CTms + j)) + x);
*((*(TAnc + j)) + x + 1) = *((*(TAnc + j)) + x);
}
}
}
mintr++;
}
/* Finding block number associated with end point */
maxck = 0;
for(x = 0; x < *nbreaks; x++){
if( *((*(breaks + 0)) + x) == gcend){
isyetbp2 = 1;
}
if( *((*(breaks + 0)) + x) > gcend){
maxtr = (x-1);
maxck = 1;
break;
}
}
if(maxck == 0 && (gcend != nsites) && (gcend != 0)){ /* If endpoint not found amongst existing bps, must be at end */
maxtr = ((*nbreaks)-1);
}else if(maxck == 0 && (gcend == nsites)){
maxtr = (*nbreaks);
isyetbp2 = 1;
}
/* Inserting new, end BP if needed */
if((isyetbp2 != 1) && (*((*(GType + gcsamp)) + maxtr + 1) != (-1))){
(*nbreaks)++;
for(x = *nbreaks-2; x >= (int)(maxtr + 1); x--){
*((*(breaks + 0)) + x + 1) = *((*(breaks + 0)) + x);
*((*(breaks + 1)) + x + 1) = *((*(breaks + 1)) + x);
}
*((*(breaks + 0)) + maxtr + 1) = gcend;
*((*(breaks + 1)) + maxtr + 1) = 0;
/* Adding new site to genotype; coalescent time; ancestry table */
for(j = 0; j < NMax; j++){
for(x = (*nbreaks-1); x > (int)(maxtr); x--){
*((*(GType + j)) + x + 1) = *((*(GType + j)) + x);
if(j < Itot){
*((*(CTms + j)) + x + 1) = *((*(CTms + j)) + x);
*((*(TAnc + j)) + x + 1) = *((*(TAnc + j)) + x);
}
}
}
maxtr++;
}
/* ONLY PROCEED (in single-sample case) IF NOT ALL SITES EMPTY */
if(gt == 0 && (isallI((*(GType + gcsamp)), (maxtr + 1), (-1), (mintr + 1)) != 1) && ((isallI((*(GType + gcsamp)), (mintr + 1), (-1), 1) != 1) || (isallI((*(GType + gcsamp)), (*nbreaks + 1), (-1), (maxtr + 1)) != 1))){
proceed = 1;
}
if(proceed == 1){
*gcalt = 1;
/* First, checking parent number of existing sample, setting as paired */
for(j = 0; j < Ntot; j++){
if( *((*(indvs + j)) + 0) == gcsamp){
rpar = *((*(indvs + j)) + 1);
*((*(indvs + j)) + 2) = 0;
break;
}
}
/* Adding new sample to indv table */
*((*(indvs + NMax)) + 0) = NMax;
*((*(indvs + NMax)) + 1) = rpar;
*((*(indvs + NMax)) + 2) = 0;
*((*(indvs + NMax)) + 3) = deme;
/* Now creating the new sample genotype; updating all other tables */
for(x = (maxtr); x > (int)(mintr); x--){
*((*(GType + NMax)) + x) = *((*(GType + gcsamp)) + x);
*((*(GType + gcsamp)) + x) = (-1);
}
for(x = (*nbreaks); x > (int)(maxtr); x--){
*((*(GType + NMax)) + x) = (-1);
}
for(x = (mintr); x > (int)0; x--){
*((*(GType + NMax)) + x) = (-1);
}
*((*(GType + NMax)) + 0) = NMax;
}
/* With paired GC, we have part coalescence instead */
if(gt == 1){
csamp = gcsamp;
par = gcsamp2;
if(
( (isallI((*(GType + gcsamp)), (mintr+1), (-1), 1) == 1) )
&& ( (isallI((*(GType + gcsamp)), (*nbreaks+1), (-1), (maxtr+1)) == 1) )
){
iscoal = 1;
}
if(iscoal == 1){
*gcalt = 2;
/* Making sure remaining sample becomes BH */
for(j = 0; j < Ntot; j++){
if( *((*(indvs + j)) + 0) == gcsamp2){
*((*(indvs + j)) + 2) = 1;
break;
}
}
}
/* Now updating coalescent times */
cchange(indvs, GType, CTms, TAnc, breaks, &csamp, &par, 1, Ntot, mintr, &maxtr, Ttot, iscoal);
/* Check if tracts have coalesced */
achange = ccheck(indvs,GType,breaks,nsites,Ntot,*nbreaks);
if(achange == 1){
excoal(indvs, GType, &par, *nbreaks, 1, Ntot, WCHex, BCHex, deme);
}
}
break;
case 9: /* Event 9: Migration of a sample */
/* Converting WH to BH samples */
sexconv(indvs, rsex, nsum, Ntot, Nindv, ex);
if(e2 == 0){ /* WH sample migrates */
/* For storing WH indvs */
unsigned int *parsamps9 = calloc((*(Nwith + deme) + 1),sizeof(unsigned int));
/* Obtaining list of samples to choose from */
sselect_UI(indvs, parsamps9, Ntot, 2, 1, 0, 3, deme);
/* Sample that migrates */
gsl_ran_choose(r,&bhc,1,parsamps9,(*(Nwith + deme) + 1),sizeof(unsigned int));
for(j = 0; j < Ntot; j++){
if(*((*(indvs + j)) + 1) == bhc){
*((*(indvs + j)) + 3) = drec;
*((*(indvs + j + 1)) + 3) = drec; /* Altering deme accordingly */
break;
}
}
free(parsamps9);
}else if(e2 == 1){ /* BH sample migrates */
/* For storing BH samples */
unsigned int *singsamps9 = calloc((*(Nbet + deme) + 1),sizeof(unsigned int));
/* Obtaining list of samples to choose from */
sselect_UI(indvs, singsamps9, Ntot, 2, 0, 1, 3, deme);
/* Sample that migrates */
gsl_ran_choose(r,&bhc,1,singsamps9,(*(Nbet + deme) + 1),sizeof(unsigned int));
for(j = 0; j < Ntot; j++){
if(*((*(indvs + j)) + 0) == bhc){
*((*(indvs + j)) + 3) = drec; /* Altering deme accordingly */
break;
}
}
free(singsamps9);
}
break;
case 10: /* Event 10: Recombination - splitting a sample to create a new one */
/* Converting WH to BH samples */
sexconv(indvs, rsex, nsum, Ntot, Nindv, ex);
/* For storing BH weights */
double *weights10 = calloc((*(Nbet + deme) + 2*(*(nsex + deme))),sizeof(double));
double *singsamps10 = calloc((*(Nbet + deme) + 2*(*(nsex + deme))),sizeof(double));
double *startp = calloc((*(Nbet + deme) + 2*(*(nsex + deme))),sizeof(double));
/* Obtaining weights of each sample */
count = 0;
while(count < (*(Nbet + deme) + 2*(*(nsex + deme)))){
for(j = 0; j < (NBtot + 2*nsum); j++){
if( *((*(nlri + j)) + 3) == deme){
*(weights10 + count) = *((*(nlri + j)) + 2);
*(startp + count) = *((*(nlri + j)) + 1);
*(singsamps10 + count) = *((*(nlri + j)) + 0);
count++;
}
}
}
/* For storing BH samples */
unsigned int *singsamps10a = calloc((*(Nbet + deme) + 2*(*(nsex + deme))),sizeof(unsigned int));
/* Choosing single sample to be split in recombination */
gsl_ran_multinomial(r,(*(Nbet + deme) + 2*(*(nsex + deme))),1,weights10,singsamps10a);
/* Matching choice to sample */
for(j = 0; j < (*(Nbet + deme) + 2*(*(nsex + deme))); j++){
if(*(singsamps10a + j) == 1){
rands = *(singsamps10 + j);
length = *(weights10 + j);
start = *(startp + j);
break;
}
}
free(singsamps10a);
rsite = gsl_rng_uniform_int(r,length) + (start + 1);
if(*nbreaks == 1){
isyetbp = 0;
/* isbpend = 1; */
maxtr = 1;
}else if(*nbreaks > 1){
/* First, check if (1) rsite is already in existing table of breakpoints;
and (2) if so, breakpoint included at end of existing table */
isyetbp = 0;
maxtr = 0;
for(x = 0; x < *nbreaks; x++){
if( *((*(breaks + 0)) + x) == rsite){
isyetbp = 1;
}
if( *((*(breaks + 0)) + x) <= rsite){
maxtr = (x+1);
}
}
}
/* Adding new site and re-ordering tracts in other tables */
if((isyetbp != 1) && (*((*(GType + rands)) + maxtr) != (-1)) ){
(*nbreaks)++;
for(x = *nbreaks-2; x >= (int)(maxtr-1); x--){
*((*(breaks + 0)) + x + 1) = *((*(breaks + 0)) + x);
*((*(breaks + 1)) + x + 1) = *((*(breaks + 1)) + x);
}
*((*(breaks + 0)) + maxtr) = rsite;
*((*(breaks + 1)) + maxtr) = *((*(breaks + 1)) + maxtr - 1);
/* Adding new site to genotype; coalescent time; ancestry table */
for(j = 0; j < NMax; j++){
for(x = (*nbreaks-1); x >= (int)(maxtr); x--){
*((*(GType + j)) + x + 1) = *((*(GType + j)) + x);
if(j < Itot){
*((*(CTms + j)) + x + 1) = *((*(CTms + j)) + x);
*((*(TAnc + j)) + x + 1) = *((*(TAnc + j)) + x);
}
}
}
}else if((isyetbp == 1) || (*((*(GType + rands)) + maxtr) == (-1) )){
maxtr--;
}
/* First, checking parent number of existing sample, setting as paired */
for(j = 0; j < Ntot; j++){
if( *((*(indvs + j)) + 0) == rands){
rpar = *((*(indvs + j)) + 1);
*((*(indvs + j)) + 2) = 0;
break;
}
}
/* Adding new sample to indv table */
*((*(indvs + NMax)) + 0) = NMax;
*((*(indvs + NMax)) + 1) = rpar;
*((*(indvs + NMax)) + 2) = 0;
*((*(indvs + NMax)) + 3) = deme;
/* Now creating the new sample genotype */
for(j = 0; j < NMax; j++){
if( *((*(GType + j)) + 0) == rands ){
for(x = (*nbreaks); x > (int)maxtr; x--){
*((*(GType + NMax)) + x) = *((*(GType + j)) + x);
*((*(GType + j)) + x) = (-1);
}
break;
}
}
for(x = maxtr; x > (int)0; x--){
*((*(GType + NMax)) + x) = (-1);
}
*((*(GType + NMax)) + 0) = NMax;
free(startp);
free(singsamps10);
free(weights10);
break;
case 11:
/* Converting WH to BH samples */
sexconv(indvs, rsex, nsum, Ntot, Nindv, ex);
/* For storing WH indvs */
unsigned int *parsamps11 = calloc((*(Nwith + deme) - *(nsex + deme)),sizeof(unsigned int));
sselect_UI(indvs, parsamps11, Ntot, 2, 1, 0, 3, deme);
/* A paired sample involved in coalescence */
gsl_ran_choose(r,&WHsel,1,parsamps11,(*(Nwith + deme) - *(nsex + deme)),sizeof(unsigned int));
nos = gsl_ran_bernoulli(r,0.5); /* Which side involved in event */
/* Finding sample */
for(j = 0; j < Ntot; j++){
if(*((*(indvs + j)) + 1) == WHsel){
csamp = *((*(indvs + j + nos)) + 0);
par = *((*(indvs + j + (nos+1)%2)) + 0);
*((*(indvs + j + (nos+1)%2)) + 2) = 1; /* Setting 'par' as BH */
break;
}
}
/* Now updating coalescent times */
cchange(indvs, GType, CTms, TAnc, breaks, &csamp, &par, 1, Ntot, 0, nbreaks, Ttot, 1);
/* Check if tracts have coalesced */
achange = ccheck(indvs,GType,breaks,nsites,Ntot,*nbreaks);
if(achange == 1){
excoal(indvs, GType, &par, *nbreaks, 1, Ntot, WCHex, BCHex, deme);
}
free(parsamps11);
break;
case 12: /* Event 12: Mitotic Recombination - exchanging coalescent histories within paired samples */
/* Converting WH to BH samples */
sexconv(indvs, rsex, nsum, Ntot, Nindv, ex);
/* For storing WH weights */
double *weights12 = calloc((*(Nwith + deme) - *(nsex + deme)),sizeof(double));
double *parsamps12 = calloc((*(Nwith + deme) - *(nsex + deme)),sizeof(double));
double *startp12 = calloc((*(Nwith + deme) - *(nsex + deme)),sizeof(double));
/* Obtaining weights of each sample */
count = 0;
while(count < (*(Nwith + deme) - *(nsex + deme))){
for(j = 0; j < (NindvW - nsum); j++){
if( *((*(nlrix + j)) + 3) == deme){
*(weights12 + count) = *((*(nlrix + j)) + 2);
*(startp12 + count) = *((*(nlrix + j)) + 1);
*(parsamps12 + count) = *((*(nlrix + j)) + 0);
count++;
}
}
}
/* For storing BH samples */
unsigned int *parsamps12a = calloc(((*(Nwith + deme) - *(nsex + deme))),sizeof(unsigned int));
/* Choosing single sample to be split in recombination */
gsl_ran_multinomial(r,(*(Nwith + deme) - *(nsex + deme)),1,weights12,parsamps12a);
/* Matching choice to sample */
for(j = 0; j < ((*(Nwith + deme) - *(nsex + deme))); j++){
if(*(parsamps12a + j) == 1){
rands = *(parsamps12 + j);
length = *(weights12 + j);
start = *(startp12 + j);
break;
}
}
free(parsamps12a);
/* Then finding haplotypes associated with pair */
for(j = 0; j < Ntot; j++){
if(*((*(indvs + j)) + 1) == rands){
rands2 = *((*(indvs + j)) + 0);
rands3 = *((*(indvs + j + 1)) + 0);
break;
}
}
rsite = gsl_rng_uniform_int(r,length) + (start + 1);
/* printf("Indv %d has bp at %d\n",rands,rsite); */
if(*nbreaks == 1){
isyetbp = 0;
maxtr = 1;
}else if(*nbreaks > 1){
/* First, check if (1) rsite is already in existing table of breakpoints;
and (2) if so, breakpoint included at end of existing table */
isyetbp = 0;
maxtr = 0;
for(x = 0; x < *nbreaks; x++){
if( *((*(breaks + 0)) + x) == rsite){
isyetbp = 1;
}
if( *((*(breaks + 0)) + x) <= rsite){
maxtr = (x+1);
}
}
}
/* Adding new site and re-ordering tracts in other tables */
/* (Note also check ancestral state of other arm; if ancestral then should create a new breakpoint) */
if((isyetbp != 1) && ((*((*(GType + rands2)) + maxtr) != (-1)) || (*((*(GType + rands3)) + maxtr) != (-1))) ){
(*nbreaks)++;
for(x = *nbreaks-2; x >= (int)(maxtr-1); x--){
*((*(breaks + 0)) + x + 1) = *((*(breaks + 0)) + x);
*((*(breaks + 1)) + x + 1) = *((*(breaks + 1)) + x);
}
*((*(breaks + 0)) + maxtr) = rsite;
*((*(breaks + 1)) + maxtr) = *((*(breaks + 1)) + maxtr - 1);
/* Adding new site to genotype; coalescent time; ancestry table */
for(j = 0; j < NMax; j++){
for(x = (*nbreaks-1); x >= (int)(maxtr); x--){
*((*(GType + j)) + x + 1) = *((*(GType + j)) + x);
if(j < Itot){
*((*(CTms + j)) + x + 1) = *((*(CTms + j)) + x);
*((*(TAnc + j)) + x + 1) = *((*(TAnc + j)) + x);
}
}
}
}else if((isyetbp == 1) || ((*((*(GType + rands2)) + maxtr) == (-1) ) && (*((*(GType + rands3)) + maxtr) == (-1) ))){
maxtr--;
}
/* Now creating the new sample genotype, by swapping genealogies */
for(x = (*nbreaks); x > (int)maxtr; x--){
tempGT = *((*(GType + rands3)) + x);
*((*(GType + rands3)) + x) = *((*(GType + rands2)) + x);
*((*(GType + rands2)) + x) = tempGT;
}
/* Final check: if one GT only contains non-ancestral material, turn into BH sample */
if(
( (isallI((*(GType + rands2)), (*nbreaks+1), (-1), 1) == 1) )
|| ( (isallI((*(GType + rands3)), (*nbreaks+1), (-1), 1) == 1) )
){
if(isallI((*(GType + rands2)), (*nbreaks+1), (-1), 1) == 1){
ctype = rands2;
/* ntype = rands3; */
}else if(isallI((*(GType + rands3)), (*nbreaks+1), (-1), 1) == 1){
ctype = rands3;
/* ntype = rands2; */
}
achange = 1;
excoal(indvs, GType, &ctype, *nbreaks, 1, Ntot, WCHex, BCHex, deme);
/*
for(j = 0; j < Ntot; j++){
if( *((*(indvs + j)) + 0) == ctype){
*((*(indvs + j)) + 1) = HUGEVAL;
*((*(indvs + j)) + 2) = 2;
break;
}
}
*/
}
free(startp12);
free(parsamps12);
free(weights12);
break;
default: /* If none of these cases chosen, exit with error message */
fprintf(stderr,"Error: Non-standard coalescent case selected ('coalesce').\n");
exit(1);
break;
}
return(achange);
} /* End of coalescent routine */
/* Updating information following coalescent event */
void cchange(unsigned int **indvs, int **GType, double **CTms, int **TAnc, unsigned int **breaks, unsigned int *csamp, unsigned int *par, unsigned int lsamp, unsigned int Ntot, unsigned int cst, unsigned int *cend, double Ttot, unsigned int isall){
unsigned int j, i, x;
unsigned int crow = 0;
int tempval = 0;
for(i = 0; i < lsamp; i++){
/* Finding crow, prow */
for(j = 0; j < Ntot; j++){
if(*((*(indvs + j)) + 0) == *(csamp + i)){
crow = j;
break;
}
}
/* 'csamp' coalesces if ALL parts coalesce (so it's removed from the simulation) */
if(isall == 1){
*((*(indvs + crow)) + 1) = HUGEVAL;
*((*(indvs + crow)) + 2) = 2;
}
for(x = cst; x < (*cend); x++){
/* Updating coalescent time and parental sample */
tempval = -1;
if( (*((*(GType + (*(csamp + i)))) + (x+1))) != (-1) && (*((*(GType + (*(par + i)))) + (x+1))) != (-1) ){
tempval = *((*(GType + (*(csamp + i)))) + (x+1));
*((*(CTms + (tempval))) + (x+1)) = Ttot;
*((*(TAnc + (tempval))) + (x+1)) = (*((*(GType + (*(par + i)))) + (x+1)));
}
/* Updating genotype table */
if( (*((*(GType + (*(csamp + i)))) + (x+1))) != (-1) && (*((*(GType + (*(par + i)))) + (x+1))) == (-1)){
(*((*(GType + (*(par + i)))) + (x+1))) = (*((*(GType + (*(csamp + i)))) + (x+1)));
}
/* If coal event was via GC, then making coal'ed sample non-ancestral */
if(isall == 0 && (*((*(GType + (*(csamp + i)))) + (x+1))) != (-1)){
(*((*(GType + (*(csamp + i)))) + (x+1))) = (-1);
}
}
}
} /* End of 'cchange' function */
/* After coalescence, check if tracts have coalesced and make non-ancestral if need be */
unsigned int ccheck(unsigned int **indvs, int **GType, unsigned int **breaks, unsigned int nsites, unsigned int Ntot, unsigned int nbreaks){
unsigned int j, x; /* counters */
unsigned int achange = 0; /* Has there been 'a change'? */
unsigned int gcount = 0; /* count of extant tracts present */
unsigned int ridx = 0; /* Index of sample */
int isfst = -1; /* Is first indv that carries coal'ed material? */
/* Checking if tract has completely coalesced */
for(x = 0; x < nbreaks; x++){
isfst = (-1);
if( *((*(breaks + 1)) + x) != 1 ){ /* If not yet coalesced... */
gcount = 0;
for(j = 0; j < Ntot; j++){
if( (*((*(indvs + j)) + 2) != 2 ) ){
ridx = *((*(indvs + j)) + 0);
if( (*((*(GType + ridx)) + (x + 1)) != (-1))){
gcount++;
if( isfst == (-1) ){
isfst = ridx;
}
}
}
}
/* If only one individual exists which carries that tract, then it has coalesced */
/* Setting last ancestral piece to non-ancestral to reflect this */
if(gcount == 1){
*((*(breaks + 1)) + x) = 1;
*((*(GType + isfst)) + (x + 1)) = (-1);
achange = 1;
}
}
}
return(achange);
} /* End of 'ccheck' function */
/* Check if extra samples are removed, as all extant material coalesces */
void excoal(unsigned int **indvs, int **GType, unsigned int *par, unsigned int nbreaks, unsigned int npar, unsigned int Ntot, int *WCHex, int *BCHex, unsigned int deme){
unsigned int i, j;
unsigned int prow = 0;
unsigned int prent = 0;
for(i = 0; i < npar; i++){
if( isallI(*(GType + (*(par + i))), nbreaks + 1, (-1), 1) == 1 ) {
for(j = 0; j < Ntot; j++){
if( *((*(indvs + j)) + 0) == *(par + i) ){
prow = j;
break;
}
}
if(*((*(indvs + prow)) + 2) == 1){
*(BCHex + deme) -= 1;
}else if(*((*(indvs + prow)) + 2) == 0){
prent = *((*(indvs + prow)) + 1);
for(j = 0; j < Ntot; j++){
if( (*((*(indvs + j)) + 1) == prent) && (*((*(indvs + j)) + 0) != *(par + i) ) ){
*((*(indvs + j)) + 2) = 1;
break;
}
}
*(WCHex + deme) -= 1;
*(BCHex + deme) += 1;
}
*((*(indvs + prow)) + 1) = HUGEVAL;
*((*(indvs + prow)) + 2) = 2;
}
}
}
/* Routine to calculate length of coalesced tracts */
unsigned int coalcalc(unsigned int **breaks, unsigned int nsites, unsigned int nbreaks, unsigned int start){
/* Calculating length of coalesced samples:
deducting 1 to account for edge effects;
adding on breakpoints lying between two coalesced samples */
unsigned int x;
unsigned int val1, val2;
unsigned int lcoal = 0;
for(x = start; x < (nbreaks - 1); x++){
val1 = 0;
val2 = 0;
if(*((*(breaks + 1)) + x) == 1){
val1 = *((*(breaks + 0)) + x);
val2 = *((*(breaks + 0)) + x + 1);
lcoal += (val2 - val1 - 1);
if(*((*(breaks + 1)) + x + 1) == 1){
lcoal++;
}
}
}
val1 = 0;
val2 = 0;
if(*((*(breaks + 1)) + (nbreaks - 1)) == 1){
val1 = *((*(breaks + 0)) + (nbreaks - 1));
val2 = nsites;
lcoal += (val2 - val1 - 1);
}
return(lcoal);
} /* End of coalcalc function */
/* Function to choose which samples split by sex */
void sexsamp(unsigned int **indvs, unsigned int *rsex, unsigned int *nsex, unsigned int *Nwith, unsigned int Ntot, const gsl_rng *r){
unsigned int count = 0;
unsigned int x, a;
for(x = 0; x < d; x++){
if(*(Nwith + x) != 0 && *(nsex + x) != 0){ /* Avoiding errors if no WH in deme */
unsigned int *WHsamp = calloc(*(Nwith + x),sizeof(unsigned int));
unsigned int *WHchosen = calloc(*(nsex + x),sizeof(unsigned int));
/* Obtaining WH in that deme */
sselect_UI(indvs, WHsamp, Ntot, 2, 1, 0, 3, x);
/* Sampling those to be split */
gsl_ran_choose(r,WHchosen,(*(nsex + x)),WHsamp,(*(Nwith + x)),sizeof(unsigned int));
gsl_ran_shuffle(r, WHchosen, (*(nsex + x)), sizeof(unsigned int));
/* Assigning samples to 'rsex' */
for(a = 0; a < *(nsex + x); a++){
*(rsex + (count + a)) = *(WHchosen + a);
}
count += *(nsex + x);
free(WHchosen);
free(WHsamp);
}
}
}
/* Insertion-sort rows by individual no., to ensure paired samples are together after an action */
void indv_sort(unsigned int **indvs, unsigned int nrow){
unsigned int j, i; /* Sorting indices */
unsigned int temp0, temp1, temp2, temp3; /* For swapping */
unsigned int count = 0;
unsigned int icount = 0;
for(j = 1; j < nrow; j++){
i = j;
while( (i > 0) && ( *((*(indvs + (i - 1) )) + 1) > *((*(indvs + i)) + 1) )){
/* Swapping entries */
temp0 = *((*(indvs + (i - 1) )) + 0);
temp1 = *((*(indvs + (i - 1) )) + 1);
temp2 = *((*(indvs + (i - 1) )) + 2);
temp3 = *((*(indvs + (i - 1) )) + 3);
*((*(indvs + (i-1) )) + 0) = *((*(indvs + (i) )) + 0);
*((*(indvs + (i-1) )) + 1) = *((*(indvs + (i) )) + 1);
*((*(indvs + (i-1) )) + 2) = *((*(indvs + (i) )) + 2);
*((*(indvs + (i-1) )) + 3) = *((*(indvs + (i) )) + 3);
*((*(indvs + (i) )) + 0) = temp0;
*((*(indvs + (i) )) + 1) = temp1;
*((*(indvs + (i) )) + 2) = temp2;
*((*(indvs + (i) )) + 3) = temp3;
i--;
}
}
/* Then renumbering indvs */
while(count < nrow){
if(*((*(indvs + count)) + 2) == 1){
*((*(indvs + count)) + 1) = icount;
icount++;
count++;
}else if(*((*(indvs + count)) + 2) == 0){
*((*(indvs + count)) + 1) = icount;
*((*(indvs + count + 1)) + 1) = icount;
count++;
count++;
icount++;
}else if(*((*(indvs + count)) + 2) == 2){
count++;
}
}
}
/* Insertion-sort for double-type tables */
void indv_sortD(double **Tin, unsigned int nrow, unsigned int ncol, unsigned int tcol){
unsigned int j, i, k; /* Sorting indices */
double *tempcol = calloc(ncol,sizeof(double)); /* temp entries for swapping */
for(j = 1; j < nrow; j++){
i = j;
while( (i > 0) && ( *((*(Tin + (i - 1) )) + tcol) > *((*(Tin + i)) + tcol) )){
/* Swapping entries */
for(k = 0; k < ncol; k++){
*(tempcol + k) = *((*(Tin + (i - 1) )) + k);
*((*(Tin + (i - 1) )) + k) = *((*(Tin + (i) )) + k);
*((*(Tin + (i) )) + k) = *(tempcol + k);
}
i--;
}
}
free(tempcol);
}
void Wait(){
printf("Press Enter to Continue");
while( getchar() != '\n' );
printf("\n");
}
void TestTabs(unsigned int **indvs, int **GType, double **CTms, int **TAnc, unsigned int **breaks, unsigned int **nlri, unsigned int **nlrix, unsigned int NMax, unsigned int Itot, unsigned int Nbet, unsigned int Nwith, unsigned int nbreaks){
unsigned int j, x;
printf("INDV TABLE\n");
for(j = 0; j < NMax; j++){
for(x = 0; x < 4; x++){
printf("%d ",*((*(indvs + j)) + x));
}
printf("\n");
}
printf("\n");
printf("GTYPE TABLE\n");
for(j = 0; j < NMax; j++){
for(x = 0; x <= nbreaks; x++){
printf("%d ",*((*(GType + j)) + x));
}
printf("\n");
}
printf("\n");
/*
printf("CTMS TABLE\n");
for(j = 0; j < Itot; j++){
for(x = 0; x <= nbreaks; x++){
printf("%lf ",*((*(CTms + j)) + x));
}
printf("\n");
}
printf("\n");
printf("TANC TABLE\n");
for(j = 0; j < Itot; j++){
for(x = 0; x <= nbreaks; x++){
printf("%d ",*((*(TAnc + j)) + x));
}
printf("\n");
}
printf("\n");
printf("NLRI TABLE\n");
for(j = 0; j < Nbet; j++){
for(x = 0; x < 4; x++){
printf("%d ",*((*(nlri + j)) + x));
}
printf("\n");
}
printf("\n");
*/
printf("NLRIX TABLE\n");
for(j = 0; j < Nwith; j++){
for(x = 0; x < 4; x++){
printf("%d ",*((*(nlrix + j)) + x));
}
printf("\n");
}
printf("\n");
printf("BREAKS TABLE\n");
for(j = 0; j < 2; j++){
for(x = 0; x < nbreaks; x++){
printf("%d ",*((*(breaks + j)) + x));
}
printf("\n");
}
printf("\n");
Wait();
/* exit(1); */
}
/* Function to reconstruct genealogy and to add mutation to branches */
char * treemaker(double **TFin, double thetain, unsigned int mind2, unsigned int maxd2, double mind, double maxd, unsigned int Itot, unsigned int run, double gmi, double gme, unsigned int ismsp, unsigned int *nmutT, unsigned int prtrees, unsigned int ismut, double pburst, unsigned int mburst, double bdist, const gsl_rng *r){
unsigned int i, j, k, a;
unsigned int lct = Itot;
unsigned int lct2 = lct-1;
unsigned int nc = 0; /* {N}umber of {c}lades in current reconstruction */
double birthtime = 0; /* Coalescent time */
double cbst = 0; /* Centre of burst event */
unsigned int child1 = 0; /* Coalesced sample */
unsigned int parent1 = 0; /* Parental sample */
unsigned int csum = 0; /* How many of each have been sampled, to decide action*/
unsigned int ischild = 0; /* Is it a child sample? */
unsigned int rmut1 = 0; /* Mutations along first branch */
unsigned int rmut2 = 0; /* Mutations along second branch */
unsigned int cc = 0; /* Child clade */
unsigned int pc = 0; /* Parental clade */
unsigned int exsamps = 0; /* Extra samples */
unsigned int cs = 0; /* 'Clade' samps */
unsigned int minc = 0; /* Min, max clade (for resorting) */
unsigned int maxc = 0;
unsigned int ccM = 0;
unsigned int brk = 0; /* Breakpoint where tract starts */
unsigned int clen = 4096; /* Space allocated to clades array */
unsigned int nmut = 0; /* Number of mutants added */
unsigned int newr = 0; /* New rows in table if need to expand */
unsigned int isbst = 0; /* Are next mutants clustered ? */
unsigned int bsze = 0; /* Burst counter */
unsigned int isrb = 0; /* Checking if burst distance lies in actual distance */
static const char lbr[] = "(";
static const char rbr[] = ")";
static const char com[] = ",";
static const char cln[] = ":";
static const char scln[] = ";";
static const char lsq[] = "[";
static const char rsq[] = "]";
static const char spa[] = " ";
char p1char[10];
char c1char[10];
char btchar1[16];
char btchar2[16];
char brkchar[16];
char Mout[32]; /* String to hold filename in (Mutations) */
FILE *ofp_mut = NULL; /* Pointer for data output */
/* Defining necessary tables */
double *Cheight = calloc(lct,sizeof(double)); /* Current 'height' (time) of each clade */
char **clades = calloc(lct, sizeof(char *)); /* Vector of possible clades */
unsigned int **samps = calloc(lct,sizeof(unsigned int *)); /* Table of samples present in each clade (row = each clade) */
for(j = 0; j < lct; j++){
clades[j] = calloc((clen+1),sizeof(char));
samps[j] = calloc(lct,sizeof(unsigned int));
for(k = 0; k < lct; k++){
*((*(samps + j)) + k) = Itot;
}
}
/* Allocating space for mutation table */
unsigned int MTRows = 30;
double **MTab = calloc(MTRows,sizeof(double *)); /* Mutation table */
for(j = 0; j < MTRows; j++){
MTab[j] = calloc((Itot+1),sizeof(double));
}
for(i = 0; i < lct2; i++){
birthtime = *((*(TFin + i)) + 1);
child1 = *((*(TFin + i)) + 0);
parent1 = *((*(TFin + i)) + 2);
ischild = 0;
csum = 0;
if(i == 0){
*((*(samps + 0)) + 0) = parent1;
*((*(samps + 0)) + 1) = child1;
*(Cheight + 0) = birthtime;
/* Converting values to strings */
sprintf(p1char, "%d", parent1);
sprintf(c1char, "%d", child1);
sprintf(btchar1,"%0.5lf",birthtime);
strcpy(*(clades + 0),lbr);
strcat(*(clades + 0),p1char);
strcat(*(clades + 0),cln);
strcat(*(clades + 0),btchar1);
strcat(*(clades + 0),com);
strcat(*(clades + 0),c1char);
strcat(*(clades + 0),cln);
strcat(*(clades + 0),btchar1);
strcat(*(clades + 0),rbr);
/* Assigning mutations */
rmut1 = gsl_ran_poisson(r,(0.5*thetain*birthtime));
rmut2 = gsl_ran_poisson(r,(0.5*thetain*birthtime));
if(rmut1 != 0){
isbst = 0;
bsze = 0;
if((nmut + rmut1) > MTRows){
newr = MTRows;
while(newr < (nmut + rmut1)){
newr = 2*newr;
}
MTab = (double **)realloc(MTab, newr*sizeof(double *));
for(j = 0; j < MTRows; j++){
MTab[j] = (double *)realloc( *(MTab + j) ,(Itot+1)*sizeof(double));
}
for(j = MTRows; j < newr; j++){
MTab[j] = (double *)calloc((Itot + 1),sizeof(double));
}
MTRows = newr;
}
for(a = 0; a < rmut1; a++){
/* Indicating location of mutants */
if(bsze == 0){
*((*(MTab + (nmut+a))) + 0) = gsl_ran_flat(r, mind, maxd);
isbst = gsl_ran_bernoulli(r,pburst);
if(isbst == 1){
bsze = mburst;
cbst = *((*(MTab + (nmut+a))) + 0);
}
}else if(bsze > 0){
isrb = 0;
while(isrb == 0){
*((*(MTab + (nmut+a))) + 0) = gsl_ran_flat(r, cbst-bdist, cbst+bdist);
if( (mind < *((*(MTab + (nmut+a))) + 0)) && (*((*(MTab + (nmut+a))) + 0) < maxd) ){
isrb = 1;
}
}
bsze--;
}
*((*(MTab + (nmut+a))) + (parent1+1)) = 1;
}
nmut += rmut1;
}
if(rmut2 != 0){
isbst = 0;
bsze = 0;
if((nmut + rmut2) > MTRows){
newr = MTRows;
while(newr < (nmut + rmut2)){
newr = 2*newr;
}
MTab = (double **)realloc(MTab, newr*sizeof(double *));
for(j = 0; j < MTRows; j++){
MTab[j] = (double *)realloc( *(MTab + j) ,(Itot+1)*sizeof(double));
}
for(j = MTRows; j < newr; j++){
MTab[j] = (double *)calloc((Itot + 1),sizeof(double));
}
MTRows = newr;
}
for(a = 0; a < rmut2; a++){
/* Indicating location of mutants */
if(bsze == 0){
*((*(MTab + (nmut+a))) + 0) = gsl_ran_flat(r, mind, maxd);
isbst = gsl_ran_bernoulli(r,pburst);
if(isbst == 1){
bsze = mburst;
cbst = *((*(MTab + (nmut+a))) + 0);
}
}else if(bsze > 0){
isrb = 0;
while(isrb == 0){
*((*(MTab + (nmut+a))) + 0) = gsl_ran_flat(r, cbst-bdist, cbst+bdist);
if( (mind < *((*(MTab + (nmut+a))) + 0)) && (*((*(MTab + (nmut+a))) + 0) < maxd) ){
isrb = 1;
}
}
bsze--;
}
*((*(MTab + (nmut+a))) + (child1+1)) = 1;
}
nmut += rmut2;
}
}else if(i > 0){
/* There can be three cases: Merge clades if child already listed;
Add to clade if child new but parent already listed;
Create new clade otherwise.
Testing how many of the pair have already been sampled, to decide tree reconstruction */
cc = Itot;
pc = Itot;
csum = 0;
for(j = 0; j < lct; j++){
if( *((*(samps + j)) + 0) == Itot ){
break;
}
for(k = 0; k < lct; k++){
if( *((*(samps + j)) + k) == child1 ){
cc = j;
csum++;
}
if( *((*(samps + j)) + k) == parent1 ){
pc = j;
csum++;
}
if( *((*(samps + j)) + k) == Itot ){
break;
}
}
}
if(csum==0){ /* Create a new clade */
nc++;
*((*(samps + nc)) + 0) = parent1;
*((*(samps + nc)) + 1) = child1;
*(Cheight + nc) = birthtime;
/* Converting values to strings */
sprintf(p1char, "%d", parent1);
sprintf(c1char, "%d", child1);
sprintf(btchar1,"%0.5lf",birthtime);
strcpy(*(clades + nc),lbr);
strcat(*(clades + nc),p1char);
strcat(*(clades + nc),cln);
strcat(*(clades + nc),btchar1);
strcat(*(clades + nc),com);
strcat(*(clades + nc),c1char);
strcat(*(clades + nc),cln);
strcat(*(clades + nc),btchar1);
strcat(*(clades + nc),rbr);
/* Assigning mutations */
rmut1 = gsl_ran_poisson(r,(0.5*thetain*birthtime));
rmut2 = gsl_ran_poisson(r,(0.5*thetain*birthtime));
if(rmut1 != 0){
isbst = 0;
bsze = 0;
if((nmut + rmut1) > MTRows){
newr = MTRows;
while(newr < (nmut + rmut1)){
newr = 2*newr;
}
MTab = (double **)realloc(MTab, newr*sizeof(double *));
for(j = 0; j < MTRows; j++){
MTab[j] = (double *)realloc( *(MTab + j) ,(Itot+1)*sizeof(double));
}
for(j = MTRows; j < newr; j++){
MTab[j] = (double *)calloc((Itot + 1),sizeof(double));
}
MTRows = newr;
}
for(a = 0; a < rmut1; a++){
/* Indicating location of mutants */
if(bsze == 0){
*((*(MTab + (nmut+a))) + 0) = gsl_ran_flat(r, mind, maxd);
isbst = gsl_ran_bernoulli(r,pburst);
if(isbst == 1){
bsze = mburst;
cbst = *((*(MTab + (nmut+a))) + 0);
}
}else if(bsze > 0){
isrb = 0;
while(isrb == 0){
*((*(MTab + (nmut+a))) + 0) = gsl_ran_flat(r, cbst-bdist, cbst+bdist);
if( (mind < *((*(MTab + (nmut+a))) + 0)) && (*((*(MTab + (nmut+a))) + 0) < maxd) ){
isrb = 1;
}
}
bsze--;
}
*((*(MTab + (nmut+a))) + (parent1+1)) = 1;
}
nmut += rmut1;
}
if(rmut2 != 0){
isbst = 0;
bsze = 0;
if((nmut + rmut2) > MTRows){
newr = MTRows;
while(newr < (nmut + rmut2)){
newr = 2*newr;
}
MTab = (double **)realloc(MTab, newr*sizeof(double *));
for(j = 0; j < MTRows; j++){
MTab[j] = (double *)realloc( *(MTab + j) ,(Itot+1)*sizeof(double));
}
for(j = MTRows; j < newr; j++){
MTab[j] = (double *)calloc((Itot + 1),sizeof(double));
}
MTRows = newr;
}
for(a = 0; a < rmut2; a++){
/* Indicating location of mutants */
if(bsze == 0){
*((*(MTab + (nmut+a))) + 0) = gsl_ran_flat(r, mind, maxd);
isbst = gsl_ran_bernoulli(r,pburst);
if(isbst == 1){
bsze = mburst;
cbst = *((*(MTab + (nmut+a))) + 0);
}
}else if(bsze > 0){
isrb = 0;
while(isrb == 0){
*((*(MTab + (nmut+a))) + 0) = gsl_ran_flat(r, cbst-bdist, cbst+bdist);
if( (mind < *((*(MTab + (nmut+a))) + 0)) && (*((*(MTab + (nmut+a))) + 0) < maxd) ){
isrb = 1;
}
}
bsze--;
}
*((*(MTab + (nmut+a))) + (child1+1)) = 1;
}
nmut += rmut2;
}
}else if(csum == 1){ /* Add to existing clade */
/* Choosing row (and therefore clade) containing existing parent (or child) */
if(pc==Itot){
ischild = 1;
pc = cc;
}
/* Converting values to strings */
sprintf(c1char, "%d", child1);
sprintf(p1char, "%d", parent1);
sprintf(btchar1,"%0.5lf",birthtime);
sprintf(btchar2,"%0.5lf",(birthtime - (*(Cheight+pc))));
char *tc = malloc( (strlen((*(clades + pc))) + 40) * sizeof(char) );
if( tc == NULL ) {
fprintf(stderr, "Error - unable to allocate required memory\n");
}
if(ischild == 0){
/* Concatenating new clade */
strcpy(tc,lbr);
strcat(tc,c1char);
strcat(tc,cln);
strcat(tc,btchar1);
strcat(tc,com);
strcat(tc,(*(clades + pc)));
strcat(tc,cln);
strcat(tc,btchar2);
strcat(tc,rbr);
for(k = 0; k < lct; k++){
if( *((*(samps + pc)) + k) == Itot ){
*((*(samps + pc)) + k) = child1;
break;
}
}
exsamps = child1;
}else if(ischild==1){
strcpy(tc,lbr);
strcat(tc,p1char);
strcat(tc,cln);
strcat(tc,btchar1);
strcat(tc,com);
strcat(tc,(*(clades + pc)));
strcat(tc,cln);
strcat(tc,btchar2);
strcat(tc,rbr);
for(k = 0; k < lct; k++){
if( *((*(samps + pc)) + k) == Itot ){
*((*(samps + pc)) + k) = parent1;
break;
}
}
exsamps = parent1;
}
/* Assigning mutations */
rmut1 = gsl_ran_poisson(r,(0.5*thetain*(birthtime - (*(Cheight+pc)))));
rmut2 = gsl_ran_poisson(r,(0.5*thetain*birthtime));
if(rmut1 != 0){
isbst = 0;
bsze = 0;
if((nmut + rmut1) > MTRows){
newr = MTRows;
while(newr < (nmut + rmut1)){
newr = 2*newr;
}
MTab = (double **)realloc(MTab, newr*sizeof(double *));
for(j = 0; j < MTRows; j++){
MTab[j] = (double *)realloc( *(MTab + j) ,(Itot+1)*sizeof(double));
}
for(j = MTRows; j < newr; j++){
MTab[j] = (double *)calloc((Itot + 1),sizeof(double));
}
MTRows = newr;
}
for(a = 0; a < rmut1; a++){
/* Indicating location of mutants */
if(bsze == 0){
*((*(MTab + (nmut+a))) + 0) = gsl_ran_flat(r, mind, maxd);
isbst = gsl_ran_bernoulli(r,pburst);
if(isbst == 1){
bsze = mburst;
cbst = *((*(MTab + (nmut+a))) + 0);
}
}else if(bsze > 0){
isrb = 0;
while(isrb == 0){
*((*(MTab + (nmut+a))) + 0) = gsl_ran_flat(r, cbst-bdist, cbst+bdist);
if( (mind < *((*(MTab + (nmut+a))) + 0)) && (*((*(MTab + (nmut+a))) + 0) < maxd) ){
isrb = 1;
}
}
bsze--;
}
for(k = 0; k < lct; k++){
if( (*((*(samps + pc)) + k) != Itot) && (*((*(samps + pc)) + k) != exsamps) ){
cs = *((*(samps + pc)) + k);
*((*(MTab + (nmut+a))) + (cs + 1)) = 1;
}
}
}
nmut += rmut1;
}
if(rmut2 != 0){
isbst = 0;
bsze = 0;
if((nmut + rmut2) > MTRows){
newr = MTRows;
while(newr < (nmut + rmut2)){
newr = 2*newr;
}
MTab = (double **)realloc(MTab, newr*sizeof(double *));
for(j = 0; j < MTRows; j++){
MTab[j] = (double *)realloc( *(MTab + j) ,(Itot+1)*sizeof(double));
}
for(j = MTRows; j < newr; j++){
MTab[j] = (double *)calloc((Itot + 1),sizeof(double));
}
MTRows = newr;
}
for(a = 0; a < rmut2; a++){
/* Indicating location of mutants */
if(bsze == 0){
*((*(MTab + (nmut+a))) + 0) = gsl_ran_flat(r, mind, maxd);
isbst = gsl_ran_bernoulli(r,pburst);
if(isbst == 1){
bsze = mburst;
cbst = *((*(MTab + (nmut+a))) + 0);
}
}else if(bsze > 0){
isrb = 0;
while(isrb == 0){
*((*(MTab + (nmut+a))) + 0) = gsl_ran_flat(r, cbst-bdist, cbst+bdist);
if( (mind < *((*(MTab + (nmut+a))) + 0)) && (*((*(MTab + (nmut+a))) + 0) < maxd) ){
isrb = 1;
}
}
bsze--;
}
*((*(MTab + (nmut+a))) + (exsamps + 1)) = 1;
}
nmut += rmut2;
}
memset((*(clades + pc)),'\0',(clen+1));
if(strlen(tc) > clen){
while(strlen(tc) > clen){
clen = 2*clen;
}
for(j = 0; j < lct; j++){
clades[j] = realloc((*(clades + j)), (clen+1) * sizeof(char) );
}
}
strcpy((*(clades + pc)),tc);
*(Cheight + pc) = birthtime;
free(tc);
}else if((csum == 2) && (nc > 0)){ /* Add to existing clade */
/* Converting values to strings */
sprintf(c1char, "%d", child1);
sprintf(p1char, "%d", parent1);
sprintf(btchar1,"%0.5lf",(birthtime - (*(Cheight + pc))));
sprintf(btchar2,"%0.5lf",(birthtime - (*(Cheight + cc))));
/* memset(tc,'\0',sizeof(tc)); */
char *tc2 = malloc((strlen((*(clades + pc))) + strlen((*(clades + cc))) + 40) * sizeof(char));
if( tc2 == NULL ) {
fprintf(stderr, "Error - unable to allocate required memory\n");
}
strcpy(tc2,lbr);
strcat(tc2,(*(clades + pc)));
strcat(tc2,cln);
strcat(tc2,btchar1);
strcat(tc2,com);
strcat(tc2,(*(clades + cc)));
strcat(tc2,cln);
strcat(tc2,btchar2);
strcat(tc2,rbr);
/* Assigning mutations */
rmut1 = gsl_ran_poisson(r,(0.5*thetain*(birthtime - (*(Cheight+pc)))));
rmut2 = gsl_ran_poisson(r,(0.5*thetain*(birthtime - (*(Cheight+cc)))));
if(rmut1 != 0){
isbst = 0;
bsze = 0;
if((nmut + rmut1) > MTRows){
newr = MTRows;
while(newr < (nmut + rmut1)){
newr = 2*newr;
}
MTab = (double **)realloc(MTab, newr*sizeof(double *));
for(j = 0; j < MTRows; j++){
MTab[j] = (double *)realloc( *(MTab + j) ,(Itot+1)*sizeof(double));
}
for(j = MTRows; j < newr; j++){
MTab[j] = (double *)calloc((Itot + 1),sizeof(double));
}
MTRows = newr;
}
for(a = 0; a < rmut1; a++){
/* Indicating location of mutants */
if(bsze == 0){
*((*(MTab + (nmut+a))) + 0) = gsl_ran_flat(r, mind, maxd);
isbst = gsl_ran_bernoulli(r,pburst);
if(isbst == 1){
bsze = mburst;
cbst = *((*(MTab + (nmut+a))) + 0);
}
}else if(bsze > 0){
isrb = 0;
while(isrb == 0){
*((*(MTab + (nmut+a))) + 0) = gsl_ran_flat(r, cbst-bdist, cbst+bdist);
if( (mind < *((*(MTab + (nmut+a))) + 0)) && (*((*(MTab + (nmut+a))) + 0) < maxd) ){
isrb = 1;
}
}
bsze--;
}
for(k = 0; k < lct; k++){
if( *((*(samps + pc)) + k) != Itot ){
cs = *((*(samps + pc)) + k);
*((*(MTab + (nmut+a))) + (cs + 1)) = 1;
}
}
}
nmut += rmut1;
}
if(rmut2 != 0){
isbst = 0;
bsze = 0;
if((nmut + rmut2) > MTRows){
newr = MTRows;
while(newr < (nmut + rmut2)){
newr = 2*newr;
}
MTab = (double **)realloc(MTab, newr*sizeof(double *));
for(j = 0; j < MTRows; j++){
MTab[j] = (double *)realloc( *(MTab + j) ,(Itot+1)*sizeof(double));
}
for(j = MTRows; j < newr; j++){
MTab[j] = (double *)calloc((Itot + 1),sizeof(double));
}
MTRows = newr;
}
for(a = 0; a < rmut2; a++){
/* Indicating location of mutants */
if(bsze == 0){
*((*(MTab + (nmut+a))) + 0) = gsl_ran_flat(r, mind, maxd);
isbst = gsl_ran_bernoulli(r,pburst);
if(isbst == 1){
bsze = mburst;
cbst = *((*(MTab + (nmut+a))) + 0);
}
}else if(bsze > 0){
isrb = 0;
while(isrb == 0){
*((*(MTab + (nmut+a))) + 0) = gsl_ran_flat(r, cbst-bdist, cbst+bdist);
if( (mind < *((*(MTab + (nmut+a))) + 0)) && (*((*(MTab + (nmut+a))) + 0) < maxd) ){
isrb = 1;
}
}
bsze--;
}
for(k = 0; k < lct; k++){
if( *((*(samps + cc)) + k) != Itot ){
cs = *((*(samps + cc)) + k);
*((*(MTab + (nmut+a))) + (cs + 1)) = 1.0;
}
}
}
nmut += rmut2;
}
/* Deleting old clade data */
if(cc < pc){
minc = cc;
maxc = pc;
}else if (cc > pc){
minc = pc;
maxc = cc;
}
if(strlen(tc2) > clen){
while(strlen(tc2) > clen){
clen = 2*clen;
}
for(j = 0; j < lct; j++){
clades[j] = realloc((*(clades + j)), (clen+1) * sizeof(char) );
}
}
memset((*(clades + minc)),'\0',(clen+1));
memset((*(clades + maxc)),'\0',(clen+1));
strcpy((*(clades + minc)),tc2);
*(Cheight + minc) = birthtime;
*(Cheight + maxc) = 0;
free(tc2);
for(k = 0; k < lct; k++){
if(*((*(samps + minc)) + k) == Itot){
ccM = k;
break;
}
}
for(k = 0; k < lct; k++){
if(*((*(samps + maxc)) + k) == Itot){
break;
}
*((*(samps + minc)) + (k + ccM)) = *((*(samps + maxc)) + k);
/* *((*(samps + maxc)) + k) = Itot; */
}
/* Now to reorder (to prevent overflow/going out of array length) */
/* Then re-writing over original arrays */
for(j = maxc; j < nc; j++){
for(k = 0; k < lct; k++){
*((*(samps + j)) + k) = *((*(samps + j + 1)) + k);
}
memset((*(clades + j)),'\0',(clen+1));
strcpy((*(clades + j)),(*(clades + j + 1)));
*(Cheight + j) = *(Cheight + j + 1);
}
for(k = 0; k < lct; k++){
*((*(samps + nc)) + k) = Itot;
}
memset((*(clades + nc)),'\0',(clen+1));
*(Cheight + nc) = 0;
nc--;
}
}
}
/* Printing out Mutations to file */
indv_sortD(MTab,nmut,(Itot+1),0);
if(thetain > 0){
sprintf(Mout,"Mutations/Muts_%d.dat",run);
if(mind != 0){
ofp_mut = fopen(Mout,"a");
}else if(mind == 0){
ofp_mut = fopen(Mout,"w");
}
for(j = 0; j < nmut; j++){
fprintf(ofp_mut,"%lf ",*((*(MTab + j)) + 0));
for(a = 1; a < (Itot + 1); a++){
fprintf(ofp_mut,"%d ",(unsigned int)(*((*(MTab + j)) + a)));
}
fprintf(ofp_mut,"\n");
}
fclose(ofp_mut);
}
*nmutT += nmut;
strcat((*(clades + 0)),scln);
char *str = malloc(clen * sizeof(char));
if(str == NULL) {
fprintf(stderr, "Error - unable to allocate required memory (str1) \n");
}
char *str2 = malloc(clen * sizeof(char));
if(str2 == NULL) {
fprintf(stderr, "Error - unable to allocate required memory (str2) \n");
}
if( (rec == 0 && gmi == 0 && gme == 0) || nsites == 1){
strcpy(str,(*(clades + 0)));
strcpy(str2,(*(clades + 0)));
}else if((rec > 0 || gmi > 0 || gme > 0) && nsites > 1){
brk = (maxd2 - mind2);
sprintf(brkchar, "%d", brk);
strcpy(str,lsq);
strcpy(str2,lsq);
strcat(str,brkchar);
strcat(str2,brkchar);
strcat(str,rsq);
strcat(str2,rsq);
strcat(str,spa);
strcat(str,(*(clades + 0)));
strcat(str2,(*(clades + 0)));
}
if(ismsp == 1){
if(prtrees == 1){
printf("%s\n",str2);
}
/* If last tree, then print out mutation table */
if(maxd == 1 && ismut == 1){
/* If last tree and using MS-style printout, read in data and print to screen */
double **MTabF = calloc(*nmutT,sizeof(double *)); /* Mutation table */
for(j = 0; j < *nmutT; j++){
MTabF[j] = calloc((Itot+1),sizeof(double));
}
/* Reading in table */
sprintf(Mout,"Mutations/Muts_%d.dat",run);
ofp_mut = fopen(Mout,"r");
for(j = 0; j < *nmutT; j++){
for(a = 0; a < (Itot + 1); a++){
fscanf(ofp_mut,"%lf", &(MTabF[j][a]) );
}
}
fclose(ofp_mut);
/* Print off sites and positions */
printf("segsites: %d\n",*nmutT);
printf("positions: ");
for(j = 0; j < *nmutT; j++){
printf("%.4lf ",*((*(MTabF + j)) + 0));
}
printf("\n");
/* Now printing off mutation tables */
for(a = 1; a < (Itot + 1); a++){
for(j = 0; j < *nmutT; j++){
printf("%d",(unsigned int)(*((*(MTabF + j)) + a)));
}
printf("\n");
}
/* Then free tables */
for(j = 0; j < *nmutT; j++){
free(MTabF[j]);
}
free(MTabF);
}
}
free(str2);
for(j = 0; j < MTRows; j++){
free(MTab[j]);
}
for(j = 0; j < lct; j++){
free(samps[j]);
free(clades[j]);
}
free(MTab);
free(samps);
free(clades);
free(Cheight);
return(str);
free(str);
} /* End of treemaker routine */
/* Reccal: calculating effective recombination rate over potential sites */
void reccal(unsigned int **indvs, int **GType, unsigned int **breaks, unsigned int **nlri, unsigned int *Nbet, unsigned int *Nwith, unsigned int *rsex, unsigned int esex, unsigned int *lnrec, unsigned int nbreaks, unsigned int NMax, unsigned int sw, unsigned int run){
unsigned int j, i;
unsigned int count = 0;
unsigned int count2 = 0;
unsigned int vl = 0;
unsigned int mintr = 0;
unsigned int maxtr = 0;
unsigned int Ntot = sumUI(Nbet,d) + 2*sumUI(Nwith,d);
unsigned int is0l = 0;
unsigned int is0r = 0;
unsigned int ridx = 0;
unsigned int brec = 0; /* Accounted breakpoints */
unsigned int intot = 0;
unsigned int count3 = 0;
if(sw == 1){
count3 = sumUI(Nbet,d);
}
if(sw == 0){
vl = sumUI(Nbet,d);
}else if(sw == 1){
vl = 2*esex;
}
unsigned int *BHi = calloc(vl,sizeof(unsigned int));
unsigned int *BHid = calloc(vl,sizeof(unsigned int));
/* Vector of samples */
count = 0;
count2 = 0;
if(sw == 0){
while(count < vl){
for(j = 0; j < Ntot; j++){
if( *((*(indvs + j)) + 2) == 1){
*(BHi + count) = *((*(indvs + j)) + 0);
*(BHid + count) = *((*(indvs + j)) + 3);
count++;
}
}
}
}else if(sw == 1){
while(count < vl){
for(j = 0; j < Ntot; j++){
if( *((*(indvs + j)) + 1) == *(rsex + count2)){
*(BHi + count) = *((*(indvs + j)) + 0);
*(BHid + count) = *((*(indvs + j)) + 3);
*(BHi + count + 1) = *((*(indvs + j + 1)) + 0);
*(BHid + count + 1) = *((*(indvs + j + 1)) + 3);
count++;
count++;
count2++;
break;
}
}
}
}
for(i = 0; i < d; i++){
*(lnrec + i) = 0;
}
if(vl > 0){
for(i = 0; i < vl; i++){
mintr = 0;
maxtr = 0;
is0l = 0;
is0r = 0;
ridx = 0;
brec = 0;
intot = 0;
*((*(nlri + count3 + i)) + 0) = (*(BHi + i));
*((*(nlri + count3 + i)) + 1) = 0;
/* Determining case to run */
for(j = 0; j < NMax; j++){
if( *((*(GType + j)) + 0) == *(BHi + i) ){
ridx = j;
if( *((*(GType + j)) + 1) == -1 ){
is0l = 1;
}
if( *((*(GType + j)) + nbreaks) == -1 ){
is0r = 1;
}
break;
}
}
if( is0l == 1 ){
mintr = first_neI(*(GType + ridx), nbreaks + 1, (-1), 1);
mintr--; /* So concordant with 'breaks' table */
*((*(nlri + count3 + i)) + 1) = *((*(breaks + 0)) + mintr);
brec = *((*(breaks + 0)) + mintr);
*(lnrec + (*(BHid + i))) += brec;
intot = brec;
}
brec = 0;
if( is0r == 1 ){
maxtr = last_neI(*(GType + ridx), nbreaks+1, (-1), 1);
maxtr--; /* So concordant with 'breaks' table */
brec = nsites - *((*(breaks + 0)) + maxtr + 1);
*(lnrec + (*(BHid + i))) += brec;
intot += brec;
}
*((*(nlri + count3 + i)) + 2) = (nsites - 1 - intot);
*((*(nlri + count3 + i)) + 3) = (*(BHid + i));
}
}
free(BHid);
free(BHi);
}
/* ReccalX: calculating effective recombination rate over potential sites FOR PAIRED SAMPLES (for mitotic recombination) */
void reccalx(unsigned int **indvs, int **GType, unsigned int **breaks, unsigned int **nlrix, unsigned int *Nbet, unsigned int *Nwith, unsigned int *rsex, unsigned int esex, unsigned int *lnrec, unsigned int nbreaks, unsigned int NMax, unsigned int sw, unsigned int run){
unsigned int j, i;
unsigned int count = 0;
unsigned int vl = 0;
unsigned int mintr1 = 0;
unsigned int mintr2 = 0;
unsigned int mintr = 0;
unsigned int maxtr1 = 0;
unsigned int maxtr2 = 0;
unsigned int maxtr = 0;
unsigned int Ntot = sumUI(Nbet,d) + 2*sumUI(Nwith,d);
unsigned int is0l = 0;
unsigned int is0r = 0;
unsigned int ridx1 = 0;
unsigned int ridx2 = 0;
unsigned int brec = 0; /* Accounted breakpoints */
unsigned int intot = 0;
if(sw == 0){
vl = sumUI(Nwith,d);
}else if(sw == 1){
vl = (sumUI(Nwith,d) - esex);
}
unsigned int *WHi = calloc(vl,sizeof(unsigned int));
unsigned int *WHid = calloc(vl,sizeof(unsigned int));
for(j = 0; j < vl; j++){
*(WHi + j) = Ntot;
*(WHid + j) = Ntot;
}
/* Vector of samples */
if(sw == 0){
while(count < vl){
for(j = 0; j < Ntot; j++){
if( *((*(indvs + j)) + 2) == 0 && (isanyUI(WHi, vl, *((*(indvs + j)) + 1)) == 0) ){
*(WHi + count) = *((*(indvs + j)) + 1);
*(WHid + count) = *((*(indvs + j)) + 3);
count++;
}
}
}
}else if(sw == 1){
while(count < vl){
for(j = 0; j < Ntot; j++){
if( (*((*(indvs + j)) + 2) == 0) && (isanyUI(WHi, vl, *((*(indvs + j)) + 1)) == 0) && (isanyUI(rsex, esex, *((*(indvs + j)) + 1) ) == 0) ){
*(WHi + count) = *((*(indvs + j)) + 1);
*(WHid + count) = *((*(indvs + j)) + 3);
count++;
}
}
}
}
for(i = 0; i < d; i++){
*(lnrec + i) = 0;
}
if(vl > 0){
for(i = 0; i < vl; i++){
mintr = 0;
maxtr = 0;
is0l = 0;
is0r = 0;
ridx1 = 0;
ridx2 = 0;
brec = 0;
intot = 0;
*((*(nlrix + i)) + 0) = (*(WHi + i));
*((*(nlrix + i)) + 1) = 0;
/* Determining case to run */
for(j = 0; j < Ntot; j++){
if( *((*(indvs + j)) + 1) == *(WHi + i) ){
ridx1 = *((*(indvs + j)) + 0);
ridx2 = *((*(indvs + j + 1)) + 0);
if( (*((*(GType + ridx1)) + 1) == -1) && (*((*(GType + ridx2)) + 1) == -1) ){
is0l = 1;
}
if( (*((*(GType + ridx1)) + nbreaks) == -1) && (*((*(GType + ridx2)) + nbreaks) == -1) ){
is0r = 1;
}
break;
}
}
if( is0l == 1 ){
mintr1 = first_neI(*(GType + ridx1), nbreaks + 1, (-1), 1);
mintr2 = first_neI(*(GType + ridx2), nbreaks + 1, (-1), 1);
if(mintr1 < mintr2){
mintr = mintr1;
}else if(mintr1 >= mintr2){
mintr = mintr2;
}
mintr--; /* So concordant with 'breaks' table */
*((*(nlrix + i)) + 1) = *((*(breaks + 0)) + mintr);
brec = *((*(breaks + 0)) + mintr);
*(lnrec + (*(WHid + i))) += brec;
intot = brec;
}
brec = 0;
if( is0r == 1 ){
maxtr1 = last_neI(*(GType + ridx1), nbreaks + 1, (-1), 1);
maxtr2 = last_neI(*(GType + ridx2), nbreaks + 1, (-1), 1);
if(maxtr1 > maxtr2){
maxtr = maxtr1;
}else if(maxtr1 <= maxtr2){
maxtr = maxtr2;
}
maxtr--; /* So concordant with 'breaks' table */
brec = nsites - *((*(breaks + 0)) + maxtr + 1);
*(lnrec + (*(WHid + i))) += brec;
intot += brec;
}
*((*(nlrix + i)) + 2) = (nsites - 1 - intot);
*((*(nlrix + i)) + 3) = (*(WHid + i));
}
}
free(WHid);
free(WHi);
}
void proberr(unsigned int est, double **pr, unsigned int *NW, unsigned int *NB, unsigned int *esx){
unsigned int j, x;
fprintf(stderr,"A negative probability exists, you need to double-check your algebra (or probability inputs) - esex %d.\n",est);
fprintf(stderr,"This likely arises due to having excessively high recombination or gene conversion rates - please check.\n");
fprintf(stderr,"\n");
fprintf(stderr,"For error reporting, the number of paired and unpaired samples per deme are:\n");
if(est == 0){
for(x = 0; x < d; x++){
fprintf(stderr,"%d %d\n",*(NW + x), *(NB + x));
}
}else if(est == 1){
for(x = 0; x < d; x++){
fprintf(stderr,"%d %d (%d)\n",*(NW + x), *(NB + x), *(esx + x));
}
}
fprintf(stderr,"\n");
fprintf(stderr,"The final probability calculations per deme are:\n");
for(j = 0; j < 13; j++){
fprintf(stderr,"Event %d: ",j);
for(x = 0; x < d; x++){
fprintf(stderr,"%0.10lf ",(*((*(pr + j)) + x)));
}
fprintf(stderr,"\n");
}
fprintf(stderr,"\n");
exit(1);
}
void proberr2(double **pr, unsigned int *NW, unsigned int *NB){
unsigned int j, x;
fprintf(stderr,"Summed probabilities exceed one, you need to double-check your algebra (or probability inputs).\n");
fprintf(stderr,"This likely arises due to having excessively high recombination or gene conversion rates - please check.\n");
fprintf(stderr,"\n");
fprintf(stderr,"For error reporting, the number of paired and unpaired samples per deme are:\n");
for(x = 0; x < d; x++){
fprintf(stderr,"%d %d\n",*(NW + x), *(NB + x));
}
fprintf(stderr,"\n");
fprintf(stderr,"The final probability calculations per deme are:\n");
for(j = 0; j < 13; j++){
fprintf(stderr,"Event %d: ",j);
for(x = 0; x < d; x++){
fprintf(stderr,"%0.10lf ",(*((*(pr + j)) + x)));
}
fprintf(stderr,"\n");
}
fprintf(stderr,"\n");
exit(1);
}
void proberr3(double **pr, unsigned int *NW, unsigned int *NB){
unsigned int j, x;
fprintf(stderr,"Summed probabilites are zero or negative, you need to double-check your algebra (or probability inputs).\n");
fprintf(stderr,"\n");
fprintf(stderr,"For error reporting, the number of paired and unpaired samples per deme are:\n");
for(x = 0; x < d; x++){
fprintf(stderr,"%d %d\n",*(NW + x), *(NB + x));
}
fprintf(stderr,"\n");
fprintf(stderr,"The final probability calculations per deme are:\n");
for(j = 0; j < 13; j++){
fprintf(stderr,"Event %d: ",j);
for(x = 0; x < d; x++){
fprintf(stderr,"%0.10lf ",(*((*(pr + j)) + x)));
}
fprintf(stderr,"\n");
}
fprintf(stderr,"\n");
exit(1);
}
/* Function to print coalescent times of individual loci */
void printCT(double **CTms, unsigned int **breaks, unsigned int nbreaks, unsigned int nsites, unsigned int Itot, unsigned int run){
unsigned int j, x;
char Cout[32]; /* String to hold filename in */
FILE *ofp_ctm = NULL; /* Pointer for data output */
sprintf(Cout,"CoalTimes/CTimes_%d.dat",run);
ofp_ctm = fopen(Cout,"w");
for(x = 0; x < nbreaks; x++){
fprintf(ofp_ctm,"%d ",*((*(breaks + 0)) + x));
}
fprintf(ofp_ctm,"\n");
for(j = 0; j < Itot; j++){
for(x = 1; x <= nbreaks; x++){
fprintf(ofp_ctm,"%lf ",*((*(CTms + j)) + x));
}
fprintf(ofp_ctm,"\n");
}
fclose(ofp_ctm);
}
void manyr(){
fprintf(stderr,"Too many recombinants (exceeds HUGEVAL), exiting program.\n");
fprintf(stderr,"This is likely due to having excessively large recombination\n");
fprintf(stderr,"or gene conversion rates.\n");
exit(1);
}
void usage(){
fprintf(stderr,"\n");
fprintf(stderr,"Command: FacSexCoalescent <Population Size> <Paired Samples> <Single Samples> <Frequency of Sex> <Reps> <Other parameters>\n");
fprintf(stderr,"\n");
fprintf(stderr,"'Other parameters' include:\n");
fprintf(stderr," -t: [4N(mu)] defines neutral mutation rate\n");
fprintf(stderr," -T: prints out individuals trees to file\n");
fprintf(stderr," (Note that one of -t or -T MUST be used)\n");
fprintf(stderr," -P: prints out data to screen using MS-style format\n");
fprintf(stderr," -D: 'Debug mode'; prints table of coalescent times to file.\n");
fprintf(stderr," -r: [2Nc(L-1) L] to specify MEIOTIC crossover recombination (rate 2Nc(L-1) and number of sites L)\n");
fprintf(stderr," -x: [2N(cA)(L-1)] to specify MITOTIC crossover recombination\n");
fprintf(stderr," -c: [2N(gS)(L-1) lambda_S] specifies rate and mean length of MEIOTIC gene conversion\n");
fprintf(stderr," -m: [2Ng(L-1) lambda] specifies rate and mean length of MITOTIC gene conversion\n");
fprintf(stderr," (For -x, -c, -m: need to first use -r to specify number of sites L, even if 2Nc(L-1) = 0)\n");
fprintf(stderr," -I: d [Paired_j Single_j]...[2Nm] for defining island model.\n");
fprintf(stderr," d is number of demes: [Paired_j Single_j] are d pairs of samples per deme;\n");
fprintf(stderr," 2Nm is net migration rate between demes.\n");
fprintf(stderr," -H: [Type of heterogeneity] [pLH pHL] [SexL_j SexH_j] for heterogeneity in frequencies of sex.\n");
fprintf(stderr," Type of heterogeneity is 0 for constant switching; 1 for stepwise change; 2 for no temporal change (only spatial change).\n");
fprintf(stderr," If type = 0; pLH pHL is probability of switching from low-sex to high-sex state (and vice versa).\n");
fprintf(stderr," If type = 1; pLH is time (units of 2N generations) when switch occurs.\n");
fprintf(stderr," If type = 2; these are not used so should be set to zero.\n");
fprintf(stderr," [SexL_j SexH_j] are d pairs of low-sex, high-sex frequencies in deme j (if type = 0).\n");
fprintf(stderr," OR they are d pairs of initial-frequency, changed-frequency of sex (if type = 1).\n");
fprintf(stderr," Only SexL_j is defined if just spatial heterogeneity is present (if type = 2).\n");
fprintf(stderr," Note that with -H, one must first specify -I to specify subdivision (even if only one population).\n");
fprintf(stderr,"\n");
fprintf(stderr,"See documentation for further details.\n");
fprintf(stderr,"\n");
exit(1);
}
void inputtest(unsigned int argno, unsigned int argmax, char *args[]){
if( argno >= argmax || args[argno][0] == '-' ){
fprintf(stderr,"Incorrect command line setup.\n");
usage();
}
}
/* Main program */
int main(int argc, char *argv[]){
unsigned int x, i, j, z; /* Assignment counter, rep counter, indv counter, argument counter */
unsigned int pST = 0; /* State of reproduction heterogeneity */
unsigned int npST = 0; /* State of reproduction heterogeneity */
unsigned int Ntot = 0; /* Total number of samples at time */
unsigned int IwithT = 0; /* Total within individual samples */
unsigned int IbetT = 0; /* Total between individual samples */
unsigned int IwithT2 = 0; /* Sum for checking structured population case */
unsigned int IbetT2 = 0; /* Sum for checking structured population case */
unsigned int IwithC = 0; /* Cumulative Iwith sum */
unsigned int IbetC = 0; /* Cumulative Ibet sum */
unsigned int esex = 0; /* Total sex events (segregation of paired samples) */
unsigned int CsexS = 0; /* Switch once sex samples chosen */
unsigned int done = 0; /* Is simulation complete? */
unsigned int nbreaks = 0; /* Number of non-rec tracts */
unsigned int event = 0; /* What event happens? */
unsigned int deme = 0; /* Which deme does event happen in? */
unsigned int drec = 0; /* Receiving deme for migration event */
unsigned int e2 = 0; /* Outcome of mig sampling, type of deme that migrates */
unsigned int count = 0; /* For creating ancestry table */
unsigned int exr = INITBR; /* Extra rows */
unsigned int exc = INITBR; /* Extra columns */
unsigned int NMax = 0; /* Max samples present (for correct table searching!) */
unsigned int Itot = 0; /* Number of initial samples */
unsigned int Nreps = 0; /* Number of simulation replicates */
unsigned int pSTIN = 2; /* Determine type of heterogeneity (0 = fluctuating sex, 1 = stepwise change, 2 = constant sex) */
unsigned int N = 0; /* Population Size */
unsigned int gcalt = 0; /* How to alter number samples following GC event */
unsigned int argx = 6; /* Extra command line inputs, for parameter definitions */
unsigned int prtrees = 0; /* Print out trees to file */
unsigned int isrec = 0; /* Has rec been defined? */
unsigned int ismig = 0; /* Has population structure been defined? */
unsigned int isburst = 0; /* Has a burst of mutations been defined? */
unsigned int ismsp = 0; /* Use MS-style printout? */
unsigned int nmutT = 0; /* Total mutants (for printout) */
unsigned int mind2 = 0;
unsigned int maxd2 = 0;
unsigned int ismut = 0; /* Mutation defined? */
unsigned int mburst = 0; /* Max burst size */
unsigned int isexp = 0; /* Assume exponential growth/decay? */
unsigned int achange = 0; /* Has there been a coal event? If so then extra checks needed */
unsigned int iscmp = 0; /* Switch to denote whether to print off table of coalescent times */
double bsex = 0; /* Baseline rate of sex (for initial inputting) */
double pLH = 0; /* Prob of low-sex to high-sex transition, OR time of transition if stepwise change */
double pHL = 0; /* Prob of high-sex to low-sex transition */
double Ttot = 0; /* Time in past, initiate at zero */
double NextT = 0; /* Next time, after drawing event */
double tls = 0; /* 'Time since Last Switch' or tls */
double tts = 0; /* 'Time to switch' */
double nosex = 0; /* Probability of no sexual reproduction over all demes */
double psum = 0; /* Sum of transition probs (first go) */
double tjump = 0; /* Time until next event */
double mind = 0; /* Min tract dist */
double maxd = 0; /* Max tract dist */
double gmi = 0; /* MITOTIC gene conversion probability */
double gme = 0; /* MEIOTIC gene conversion probability */
double theta = 0; /* Scaled mutation rate, 4Nmu */
double mig = 0; /* Migration rate between demes */
double mrec = 0; /* MITOTIC recombination (crossover) rate 2N(cA) */
double lambdami = 0; /* Average length of MITOTIC GC event */
double lambdame = 0; /* Average length of MEIOTIC GC event */
double bigQmi = 1/(1.0*0); /* Relative length of lambdami (for GC prob calculations) */
double bigQme = 1/(1.0*0); /* Relative length of lambdame (for GC prob calculations) */
double pburst = 0; /* Probability that subsequent mutations will cluster */
double bdist = 0; /* Max distance if mutations cluster */
double alpha = 0; /* Population growth/shrink parameter */
char Tout[32]; /* String to hold filename in (Trees) */
FILE *ofp_tr = NULL; /* Pointer for tree output */
FILE *ofp_sd; /* Pointer for seed output */
/* GSL random number definitions */
const gsl_rng_type * T;
gsl_rng * r;
/* Reading in data from command line */
if(argc < 6){
fprintf(stderr,"At least 6 inputs are needed.\n");
usage();
}
N = atoi(argv[1]);
if(N <= 0){
fprintf(stderr,"Total Population size N is zero or negative, not allowed.\n");
usage();
}
IwithT = atoi(argv[2]);
IbetT = atoi(argv[3]);
Itot = 2*IwithT + IbetT;
if(Itot <= 1){
fprintf(stderr,"More than one sample must be initially present to execute the simulation.\n");
usage();
}
bsex = strtod(argv[4],NULL);
if( bsex <= 0 || bsex > 1){
fprintf(stderr,"Baseline rate of sexual reproduction has to lie between 0 and 1.\n");
usage();
}
/* Number of samples/reps to take */
Nreps = atoi(argv[5]);
if(Nreps <= 0){
fprintf(stderr,"Must set positive number of repetitions.\n");
usage();
}
/*
Initial state of two samples;
Iwith = No. of within host
Ibet = No. of between host
So total number of initial samples in a deme = 2*Iwith + Ibet
THEN sexL[i], sexH[i] = low-sex, high-sex rate in each deme
*/
unsigned int *Iwith = calloc(1,sizeof(unsigned int)); /* Within-individual samples */
unsigned int *Ibet = calloc(1,sizeof(unsigned int)); /* Between-individual samples */
unsigned int *Nwith = calloc(1,sizeof(unsigned int)); /* To be used in individual rep */
unsigned int *Nbet = calloc(1,sizeof(unsigned int)); /* To be used in individual rep */
unsigned int *zeros = calloc(1,sizeof(unsigned int)); /* Placeholder array of zeros */
unsigned int *demes = calloc(1,sizeof(unsigned int)); /* Indices of demes (for sampling) */
double *sexL = calloc(1,sizeof(double)); /* Low-sex rates */
double *sexH = calloc(1,sizeof(double)); /* High-sex rates */
*(Iwith + 0) = IwithT;
*(Ibet + 0) = IbetT;
*(sexL + 0) = bsex;
*(sexH + 0) = 0;
*(zeros + 0) = 0;
*(demes + 0) = 0;
/* Now moving onto case-by-case parameter setting */
/* Based on routine as used in ms (Hudson 2002, Bioinformatics) */
if(argc > 6){
while(argx < argc){
if(argv[argx][0] != '-'){
fprintf(stderr,"Further arguments should be of form -C, for C a defined character.\n");
usage();
}
switch ( argv[argx][1] ){
case 't': /* Defining Mutation Rate (theta) */
ismut = 1;
argx++;
inputtest(argx, argc, argv);
theta = strtod(argv[argx],NULL);
if(theta <= 0){
fprintf(stderr,"Mutation rate must be a positive value.\n");
usage();
}
argx++;
break;
case 'r': /* Defining recombination (cross over) */
isrec = 1;
argx++;
inputtest(argx, argc, argv);
rec = strtod(argv[argx],NULL);
if(rec < 0){
fprintf(stderr,"Must define a positive recombination rate.\n");
usage();
}
argx++;
inputtest(argx, argc, argv);
nsites = atoi(argv[argx]);
if(nsites < 2 && rec > 0){
fprintf(stderr,"Must define at least two sites with recombination.\n");
usage();
}
argx++;
break;
case 'x': /* Defining MITOTIC recombination (cross over) */
if(isrec == 0){
fprintf(stderr,"Have to define number of sites first (using -r) before defining mitotic crossover rates.\n");
usage();
}
argx++;
inputtest(argx, argc, argv);
mrec = strtod(argv[argx],NULL);
if(mrec < 0){
fprintf(stderr,"Must define a positive mitotic recombination rate.\n");
usage();
}
if(nsites < 2 && mrec > 0){
fprintf(stderr,"Must define at least two sites with mitotic recombination.\n");
usage();
}
argx++;
break;
case 'T': /* Print trees? */
prtrees = 1;
argx++;
break;
case 'c': /* MEIOTIC gene conversion */
if(isrec == 0){
fprintf(stderr,"Have to define number of sites first (using -r) before defining conversion rates.\n");
usage();
}
argx++;
inputtest(argx, argc, argv);
gme = strtod(argv[argx],NULL);
if(gme < 0){
fprintf(stderr,"Must define a positive meiotic gene conversion rate.\n");
usage();
}
if(nsites < 2 && gme > 0){
fprintf(stderr,"Must define at least two sites with meiotic gene conversion.\n");
usage();
}
argx++;
inputtest(argx, argc, argv);
lambdame = strtod(argv[argx],NULL);
if(lambdame < 1){
fprintf(stderr,"With meiotic gene conversion, average length (lambda) has to be at least 1.\n");
usage();
}
bigQme = (nsites-1)/(1.0*lambdame);
if((bigQme < WARNQ) && (nsites > 1)){
fprintf(stderr,"WARNING: Simulation assumes that lambda ~ nsites.\n");
fprintf(stderr,"Too large a lambda might produce inaccurate coalescent times.\n");
}
argx++;
break;
case 'm': /* MITOTIC gene conversion */
if(isrec == 0){
fprintf(stderr,"Have to define number of sites first (using -r) before defining conversion rates.\n");
usage();
}
argx++;
inputtest(argx, argc, argv);
gmi = strtod(argv[argx],NULL);
if(gmi < 0){
fprintf(stderr,"Must define a positive mitotic gene conversion rate.\n");
usage();
}
argx++;
inputtest(argx, argc, argv);
lambdami = strtod(argv[argx],NULL);
if(lambdami < 1 && nsites > 1){
fprintf(stderr,"With mitotic gene conversion, average length (lambda) has to be at least 1 with multiple sites.\n");
usage();
}
bigQmi = (nsites-1)/(1.0*lambdami);
if((bigQmi < WARNQ) && (nsites > 1)){
fprintf(stderr,"WARNING: Simulation assumes that lambda ~ nsites.\n");
fprintf(stderr,"Too large a lambda might produce inaccurate coalescent times.\n");
}
argx++;
break;
case 'I': /* Population subdivision (Island model) */
ismig = 1;
argx++;
inputtest(argx, argc, argv);
d = atoi(argv[argx]);
if(d <= 0){
fprintf(stderr,"Number of demes has to be a positive integer.\n");
usage();
}
if(N%d != 0){
fprintf(stderr,"Population size must be a multiple of deme number.\n");
usage();
}
N = (unsigned int)(N/(d*1.0)); /* Scaling NT to a demetic size, for more consistent use in calculations */
if(d > 1){ /* Assigning per-deme samples */
Iwith = (unsigned int *)realloc(Iwith,d*sizeof(unsigned int));
Ibet = (unsigned int *)realloc(Ibet,d*sizeof(unsigned int));
Nwith = (unsigned int *)realloc(Nwith,d*sizeof(unsigned int));
Nbet = (unsigned int *)realloc(Nbet,d*sizeof(unsigned int));
zeros = (unsigned int *)realloc(zeros,d*sizeof(unsigned int));
demes = (unsigned int *)realloc(demes,d*sizeof(unsigned int));
sexL = (double *)realloc(sexL,d*sizeof(double));
sexH = (double *)realloc(sexH,d*sizeof(double));
for(x = 0; x < d; x++){
argx++;
inputtest(argx, argc, argv);
*(Iwith + x) = atoi(argv[argx]);
argx++;
inputtest(argx, argc, argv);
*(Ibet + x) = atoi(argv[argx]);
*(sexL + x) = bsex;
*(sexH + x) = 0;
*(zeros + x) = 0;
*(demes + x) = x;
IwithT2 += (*(Iwith + x));
IbetT2 += (*(Ibet + x));
}
if( IwithT2 != IwithT ){
fprintf(stderr,"Sum of paired per-deme samples should equal total samples.\n");
usage();
}
if( IbetT2 != IbetT ){
fprintf(stderr,"Sum of unpaired per-deme samples should equal total samples.\n");
usage();
}
}else if(d == 1){
argx += 2;
}
argx++;
inputtest(argx, argc, argv);
mig = strtod(argv[argx],NULL);
mig = mig/(2.0*N*d);
if(mig < 0){
fprintf(stderr,"Migration rate must be a positive (or zero) value.\n");
usage();
}
if((d > 1) && (mig == 0)){
fprintf(stderr,"Migration rate cannot be zero with multiple demes.\n");
usage();
}
argx++;
break;
case 'H':
if(ismig == 0){
fprintf(stderr,"Have to define number of demes first (using -I) before defining heterogeneity.\n");
usage();
}
/* Defining type of heterogeneity */
argx++;
inputtest(argx, argc, argv);
pSTIN = atoi(argv[argx]);
argx++;
inputtest(argx, argc, argv);
pLH = strtod(argv[argx],NULL);
argx++;
inputtest(argx, argc, argv);
pHL = strtod(argv[argx],NULL);
if(pSTIN != 0 && pSTIN != 1 && pSTIN != 2){
fprintf(stderr,"pSTIN has to equal 0, 1 or 2.\n");
usage();
}
if(pSTIN != 1){
if(pHL < 0 || pHL > 1 || pLH < 0 || pLH > 1){
fprintf(stderr,"Sex transition probabilities have to lie between 0 and 1 (if there is no stepwise change in sex).\n");
usage();
}
}
if( (pHL == 0 || pLH == 0 ) && pSTIN == 0){
fprintf(stderr,"Sex transition probabilities have to lie between 0 and 1 with fluctuating sex.\n");
usage();
}
for(x = 0; x < d; x++){
argx++;
inputtest(argx, argc, argv);
*(sexL + x) = strtod(argv[argx],NULL);
argx++;
inputtest(argx, argc, argv);
*(sexH + x) = strtod(argv[argx],NULL);
if( *(sexL + x) < 0 || *(sexL + x) > 1 || *(sexH + x) < 0 || *(sexH + x) > 1){
fprintf(stderr,"Rate of sexual reproduction has to lie between 0 and 1.\n");
usage();
}
if( *(sexH + x) == 0 && pSTIN == 0){
fprintf(stderr,"With temporally heterogeneous sex, high rate cannot be zero.\n");
usage();
}
if((*(sexL + x) > *(sexH + x)) && pSTIN == 0){
fprintf(stderr,"All low-sex values must be less than or equal to high-sex values. Please re-check.\n");
usage();
}
}
argx++;
break;
case 'P':
ismsp = 1;
argx++;
break;
case 'D':
iscmp = 1;
argx++;
break;
case 'b':
if(isrec == 0){
fprintf(stderr,"Have to define number of breakpoints first (using -r) before defining burst of mutations.\n");
usage();
}
if(ismut == 0){
fprintf(stderr,"Need to define a mutation rate first.\n");
usage();
}
isburst = 1;
argx++;
inputtest(argx, argc, argv);
pburst = strtod(argv[argx],NULL);
argx++;
inputtest(argx, argc, argv);
mburst = atoi(argv[argx]);
argx++;
inputtest(argx, argc, argv);
bdist = strtod(argv[argx],NULL);
if( (pburst < 0) || (pburst > 1) ){
fprintf(stderr,"Burst probability has to lie between 0 and 1.\n");
usage();
}
if(mburst == 0){
fprintf(stderr,"Max burst size has to be greater than zero.\n");
usage();
}
if(bdist == 0){
fprintf(stderr,"Burst distance has to be greater than zero.\n");
usage();
}
argx++;
break;
case 'G':
isexp = 1;
argx++;
inputtest(argx, argc, argv);
alpha = strtod(argv[argx],NULL);
if(alpha <= 0){
fprintf(stderr,"Growth rate has to be a positive, non-zero value.\n");
usage();
}
argx++;
break;
default: /* If none of these cases chosen, exit with error message */
fprintf(stderr,"Error: Non-standard input given.\n");
usage();
break;
}
}
}
if(ismut == 0 && prtrees == 0){
fprintf(stderr,"Error: Have to define a mutation rate or print out trees.\n");
usage();
}
if(isrec == 1){
rec = rec/(2.0*(nsites-1)*N*d);
mrec = mrec/(2.0*(nsites-1)*N*d);
gme = ((gme)/(2.0*N*d));
gmi = ((gmi)/(2.0*N*d));
}
if(isburst == 1){
bdist = bdist/(1.0*nsites);
}
if(d == 1){
mig = 0; /* Set migration to zero if only one deme, as a precaution */
}
if(rec == 0 && mrec == 0 && gmi == 0 && gme == 0 && isburst == 0){
nsites = 1; /* Set number of sites to 1 if no recombination OR gc, as a precaution */
}
if(nsites == 1){
rec = 0;
mrec = 0;
}
/* Arrays definition and memory assignment */
unsigned int *nlrec = calloc(d,sizeof(unsigned int)); /* Non-recombinable samples 1 */
unsigned int *nlrec2 = calloc(d,sizeof(unsigned int)); /* Non-recombinable samples 2 */
unsigned int *nlrecx = calloc(d,sizeof(unsigned int)); /* Non-recombinable samples FOR PARIED SAMPLES */
unsigned int *evsex = calloc(d,sizeof(unsigned int)); /* Number of sex events per deme */
unsigned int *csex = calloc(2,sizeof(unsigned int)); /* Does sex occur or not? */
unsigned int *draw = calloc(13,sizeof(unsigned int)); /* Event that happens */
unsigned int *draw2 = calloc(d,sizeof(unsigned int)); /* Deme in which event happens */
unsigned int *draw3 = calloc(2,sizeof(unsigned int)); /* Which type of sample migrates */
double *Nsamps = calloc(2,sizeof(double)); /* Within and between-indv samples in deme */
int *WCH = calloc(d,sizeof(int)); /* How within-indv samples change */
int *BCH = calloc(d,sizeof(int)); /* How between-indv samples change */
int *WCHex = calloc(d,sizeof(int)); /* Extra calc if null values formed */
int *BCHex = calloc(d,sizeof(int)); /* Extra calc if null values formed */
double *sexC = calloc(d,sizeof(double)); /* Current rates of sex per deme */
double *sexCInv = calloc(d,sizeof(double)); /* Inverse of current rates of sex (1-sexC) */
double *psex = calloc(2,sizeof(double)); /* Individual probabilities if individuals undergo sex or not */
double *pr_rsums = calloc(13,sizeof(double)); /* Rowsums of probs (for event choosing) */
double **pr = calloc(13,sizeof(double *)); /* Probability matrix per deme */
for (j = 0; j < 13; j++){ /* Assigning space for each population within each deme */
pr[j] = calloc(d,sizeof(double));
}
/* create a generator chosen by the
environment variable GSL_RNG_TYPE */
gsl_rng_env_setup();
if (!getenv("GSL_RNG_SEED")) gsl_rng_default_seed = time(0);
T = gsl_rng_default;
r = gsl_rng_alloc(T);
ofp_sd = fopen("Seed.dat","w");
fprintf(ofp_sd,"%lu\n",gsl_rng_default_seed);
fclose(ofp_sd);
if(ismsp == 1){
for(z = 0; z < argc; z++){
printf("%s ",argv[z]);
}
printf("\n");
printf("%lu\n",gsl_rng_default_seed);
}
/* Creating necessary directories */
if((rec > 0 || mrec > 0 || gmi > 0 || gme > 0) && (nsites != 1) && (prtrees == 1)){
mkdir("Trees/", 0777);
}
if(ismut == 1){
mkdir("Mutations/", 0777);
}
if(iscmp == 1){
mkdir("CoalTimes/", 0777);
}
/* Running the simulation Nreps times */
for(i = 0; i < Nreps; i++){
/* printf("Starting Run %d\n",i); */
nmutT = 0;
/* Setting up type of sex heterogeneity */
if(pSTIN == 0){
pST = gsl_ran_bernoulli(r,pLH/(pLH+pHL)); /* Randomly assigning initial low-sex or high-sex state */
}else if(pSTIN == 1){
pST = 2;
}else if(pSTIN == 2){
pST = 3;
}
Ttot = 0;
Ntot = Itot;
NMax = Itot;
exr = INITBR;
exc = INITBR;
for(x = 0; x < d; x++){
*(Nwith + x) = *(Iwith + x); /* Resetting number of within-host samples */
*(Nbet + x) = *(Ibet + x); /* Resetting number of between-host samples */
*(nlrec + x) = 0; /* Genome not affected by recombination */
*(nlrec2 + x) = 0; /* Genome not affected by recombination */
*(nlrecx + x) = 0; /* Genome not affected by recombination (paired samples) */
}
/* Setting up temporal heterogeneity */
rate_change(N,pST,pLH,pHL,sexH,sexL,0,sexC,sexCInv,&tts,&npST,r);
pST = npST;
tls = 0;
/* Setting up summary table of individual samples */
/* ASSIGNING MEMORY FROM SCRATCH HERE, SINCE TABLES WILL BE MODIFIED FOR EACH SIM */
unsigned int **indvs = calloc(Itot+exr,sizeof(unsigned int *)); /* Table of individual samples */
int **GType = calloc(Itot+exr,sizeof(int *)); /* Table of sample genotypes */
double **CTms = calloc(Itot+exr,sizeof(double *)); /* Coalescent times per sample */
int **TAnc = calloc(Itot+exr,sizeof(int *)); /* Table of ancestors for each sample */
unsigned int **breaks = calloc(2,sizeof(unsigned int *)); /* Table of breakpoints created in the simulation */
double **TFin = calloc((Itot-1),sizeof(double *)); /* Final ancestry table, for tree reconstruction */
unsigned int **nlri = calloc(Itot+exr,sizeof(unsigned int *)); /* Per-unpaired-sample valid bp table (for weighted sampling) */
unsigned int **nlrix = calloc(Itot+exr,sizeof(unsigned int *)); /* Per-paired-sample valid bp table (for weighted sampling) */
for(j = 0; j < (Itot+exr); j++){ /* Assigning space for each genome sample */
indvs[j] = calloc(4,sizeof(unsigned int));
GType[j] = calloc(exc+1,sizeof(int));
nlri[j] = calloc(4,sizeof(unsigned int));
nlrix[j] = calloc(4,sizeof(unsigned int));
if(j < Itot){
CTms[j] = calloc(exc+1,sizeof(double));
TAnc[j] = calloc(exc+1,sizeof(int));
if(j < (Itot - 1)){
TFin[j] = calloc(3,sizeof(double));
}
}
}
breaks[0] = calloc(exc,sizeof(unsigned int));
breaks[1] = calloc(exc,sizeof(unsigned int));
nbreaks = 1;
IwithC = 0;
IbetC = 0;
for(j = 0; j < Itot; j++){
*((*(indvs + j)) + 0) = j;
*((*(GType + j)) + 0) = j;
*((*(GType + j)) + 1) = j;
*((*(CTms + j)) + 0) = j;
*((*(CTms + j)) + 1) = -1;
*((*(TAnc + j)) + 0) = j;
/* Entry of "-1" equivalent to NA in old code,
i.e. it is not ancestral, reflects extant tracts */
*((*(TAnc + j)) + 1) = (-1);
}
if(IwithT != 0){
for(j = 0; j < IwithT; j++){
*((*(indvs + 2*j)) + 1) = j;
*((*(indvs + (2*j+1))) + 1) = j;
*((*(indvs + 2*j)) + 2) = 0;
*((*(indvs + (2*j+1))) + 2) = 0;
*((*(nlrix + j)) + 0) = j;
*((*(nlrix + j)) + 1) = 0;
*((*(nlrix + j)) + 2) = (nsites-1);
}
for(x = 0; x < d; x++){
for(j = IwithC; j < (IwithC + *(Iwith + x)); j++){
*((*(indvs + 2*j)) + 3) = x;
*((*(indvs + (2*j+1))) + 3) = x;
*((*(nlrix + j)) + 3) = x;
}
IwithC += *(Iwith + x);
}
}
if(IbetT != 0){
for(j = 0; j < IbetT; j++){
*((*(indvs + (2*IwithT + j))) + 1) = IwithT + j;
*((*(indvs + (2*IwithT + j))) + 2) = 1;
*((*(nlri + j)) + 0) = j;
*((*(nlri + j)) + 1) = 0;
*((*(nlri + j)) + 2) = (nsites-1);
}
for(x = 0; x < d; x++){
for(j = IbetC; j < (IbetC + *(Ibet + x)); j++){
*((*(indvs + (2*IwithT + j))) + 3) = x;
*((*(nlri + j)) + 3) = x;
}
IbetC += *(Ibet + x);
}
}
done = 0;
while(done != 1){
/* Setting up vector of state-change probabilities *without sex* */
probset2(N, gmi, gme, sexC, rec, mrec, bigQmi, bigQme, nsites, nlrec, zeros, nlrecx, mig, Nwith, Nbet, zeros, 0, pr);
nosex = powDUI(sexCInv,Nwith,d); /* Probability of no segregation via sex, accounting for within-deme variation */
psum = (1-nosex) + nosex*(sumT_D(pr,13,d)); /* Sum of all event probabilities, for drawing random time */
/* Intermediate error checking */
if(psum > 1){
proberr2(pr,Nwith,Nbet);
}
if((psum <= 0) && (isallD(sexC,d,0) != 1)){
proberr3(pr,Nwith,Nbet);
}
if(isanylessD_2D(pr,13,d,0) == 1){
proberr(0,pr,Nwith,Nbet,evsex);
}
/* Drawing time to next event, SCALED TO 2NT GENERATIONS */
if(psum == 1){
tjump = 1.0/(2.0*N*d);
}else if(psum == 0){
tjump = (1.0/0.0);
}else{
tjump = (gsl_ran_geometric(r,psum))/(2.0*N*d);
}
NextT = (Ttot + tjump);
/* Outcomes depends on what's next: an event or change in rates of sex */
if(NextT > (tls + tts)){ /* If next event happens after a switch, change rates of sex */
tls = (tls + tts); /* 'Time since Last Switch' or tls */
Ttot = tls;
rate_change(N,pST,pLH,pHL,sexH,sexL,1,sexC,sexCInv,&tts,&npST,r);
pST = npST;
}else if (NextT <= (tls + tts)){ /* If next event happens before a switch, draw an action */
Ttot = NextT;
/* Determines if sex occurs; if so, which samples are chosen */
/* (deme-independent Binomial draws) */
esex = 0;
CsexS = 0;
vcopyUI(evsex,zeros,d);
*(psex + 0) = nosex*(sumT_D(pr,13,d));
*(psex + 1) = 1-nosex;
gsl_ran_multinomial(r,2,1,psex,csex);
if(*(csex + 1) == 1){ /* Working out number of sex events IF it does occur */
while(CsexS == 0){
for(x = 0; x < d; x++){
*(evsex + x) = gsl_ran_binomial(r,*(sexC + x),*(Nwith + x));
esex += *(evsex + x);
}
if(esex > 0){
CsexS = 1;
}
}
}
unsigned int *rsex = calloc(esex,sizeof(unsigned int));
/* Now redrawing probabilities with changed configuration */
if(esex >= 1){
/* New in ARG simulation:
already determining which samples have split
(so can calculate recombination prob accurately) */
/* First, choosing samples to split by sex */
sexsamp(indvs, rsex, evsex, Nwith, Ntot, r);
/* Then calculating relevant breakpoints in each new sample */
/* (And recalculate for paired samples) */
reccal(indvs, GType, breaks, nlri, Nbet, Nwith, rsex, esex, nlrec2, nbreaks, NMax, 1, i);
reccalx(indvs, GType, breaks, nlrix, Nbet, Nwith, rsex, esex, nlrecx, nbreaks, NMax, 1, i);
/* Then recalculating probability of events */
probset2(N, gmi, gme, sexC, rec, mrec, bigQmi, bigQme, nsites, nlrec, nlrec2, nlrecx, mig, Nwith, Nbet, evsex, 1, pr);
if(isanylessD_2D(pr,13,d,0) == 1){
proberr(1, pr, Nwith, Nbet, evsex);
}
}
/* Given event happens, what is that event?
Weighted average based on above probabilities.
Then drawing deme of event. */
rowsumD(pr,13,d,pr_rsums);
gsl_ran_multinomial(r,13,1,pr_rsums,draw);
event = matchUI(draw,13,1);
gsl_ran_multinomial(r,d,1,(*(pr + event)),draw2);
deme = matchUI(draw2,d,1);
/* printf("Event is %d\n",event);*/
if(event == 9){ /* Choosing demes to swap NOW if there is a migration */
stchange2(event,deme,evsex,WCH,BCH);
vsum_UI_I(Nwith, WCH, d);
vsum_UI_I(Nbet, BCH, d);
Ntot = 2*(sumUI(Nwith,d)) + sumUI(Nbet,d);
*(Nsamps + 0) = *(Nwith + deme);
*(Nsamps + 1) = *(Nbet + deme);
drec = deme;
while(drec == deme){
gsl_ran_choose(r,&drec,1,demes,d,sizeof(unsigned int));
}
gsl_ran_multinomial(r,2,1,Nsamps,draw3);
e2 = matchUI(draw3,2,1);
if(e2 == 0){ /* Paired sample migrates */
(*(Nwith + deme))--;
(*(Nwith + drec))++;
}else if(e2 == 1){ /* Single sample migrates */
(*(Nbet + deme))--;
(*(Nbet + drec))++;
}
}
/* Change ancestry accordingly */
gcalt = 0;
achange = coalesce(indvs, GType, CTms, TAnc, nlri, nlrix, Ttot, Nwith, Nbet, deme, rsex, evsex, event, drec, e2, breaks, nsites, &nbreaks, NMax, Itot, gmi, gme, bigQmi, bigQme, &gcalt, sexC, WCHex, BCHex, r, i);
/* Based on outcome, altering (non-mig) states accordingly */
if(event != 9){ /* Since already done for state = 9 above... */
stchange2(event,deme,evsex,WCH,BCH);
vsum_UI_I(Nwith, WCH, d);
vsum_UI_I(Nbet, BCH, d);
Ntot = 2*(sumUI(Nwith,d)) + sumUI(Nbet,d);
*(Nsamps + 0) = *(Nwith + deme);
*(Nsamps + 1) = *(Nbet + deme);
if(gcalt != 0){
if(gcalt == 1){ /* GC led to new BH sample being produced */
(*(Nwith + deme))++;
(*(Nsamps + 0))++;
(*(Nbet + deme))--;
(*(Nsamps + 1))--;
Ntot++;
NMax++;
if(NMax > HUGEVAL){
manyr();
}
}
if(gcalt == 2){ /* GC led to WH sample coalescing */
(*(Nbet + deme))++;
(*(Nsamps + 1))++;
(*(Nwith + deme))--;
(*(Nsamps + 0))--;
Ntot--;
}
}
if(achange == 1){
vsum_UI_I(Nwith, WCHex, d);
vsum_UI_I(Nbet, BCHex, d);
vcopyUI_I(WCHex, zeros, d);
vcopyUI_I(BCHex, zeros, d);
Ntot = 2*(sumUI(Nwith,d)) + sumUI(Nbet,d);
*(Nsamps + 0) = *(Nwith + deme);
*(Nsamps + 1) = *(Nbet + deme);
achange = 0;
}
}
if(event == 10){
NMax++;
if(NMax > HUGEVAL){
manyr();
}
}
/* Sorting table afterwards to ensure paired samples are together */
indv_sort(indvs, NMax);
/* Updating baseline recombinable material depending on number single samples */
if(isallUI(*(breaks+1),nbreaks,1,0) == 0){
reccal(indvs, GType, breaks, nlri, Nbet, Nwith, rsex, esex, nlrec, nbreaks, NMax, 0, i);
reccalx(indvs, GType, breaks, nlrix, Nbet, Nwith, rsex, esex, nlrecx, nbreaks, NMax, 0, i);
for(x = 0; x < d; x++){
*(nlrec2 + x) = 0;
}
}
free(rsex); /* Can be discarded once used to change ancestry */
/* Checking if need to expand tables */
if(NMax == (exr+Itot-1)){
exr += INITBR;
indvs = (unsigned int **)realloc(indvs,(Itot+exr)*sizeof(unsigned int *));
GType = (int **)realloc(GType, (Itot+exr)*sizeof(int *));
nlri = (unsigned int **)realloc(nlri,(Itot+exr)*sizeof(unsigned int *));
nlrix = (unsigned int **)realloc(nlrix,(Itot+exr)*sizeof(unsigned int *));
for(j = 0; j < (Itot+exr-INITBR); j++){
indvs[j] = (unsigned int *)realloc(*(indvs + j),4*sizeof(unsigned int));
GType[j] = (int *)realloc( *(GType + j) ,(exc + 1)*sizeof(int));
nlri[j] = (unsigned int *)realloc(*(nlri + j),4*sizeof(unsigned int));
nlrix[j] = (unsigned int *)realloc(*(nlrix + j),4*sizeof(unsigned int));
}
for(j = (Itot+exr-INITBR); j < (Itot+exr); j++){
indvs[j] = (unsigned int *)calloc(4,sizeof(unsigned int));
GType[j] = (int *)calloc((exc + 1),sizeof(int));
nlri[j] = (unsigned int *)calloc(4,sizeof(unsigned int));
nlrix[j] = (unsigned int *)calloc(4,sizeof(unsigned int));
}
}
if(nbreaks >= exc-1){
exc += INITBR;
for(j = 0; j < (Itot+exr); j++){
GType[j] = (int *)realloc( *(GType + j) ,(exc + 1)*sizeof(int));
if(j < Itot){
CTms[j] = (double *)realloc( *(CTms + j) ,(exc + 1)*sizeof(double));
TAnc[j] = (int *)realloc( *(TAnc + j) ,(exc + 1)*sizeof(int));
}
}
breaks[0] = (unsigned int *)realloc(*(breaks + 0),exc*sizeof(unsigned int));
breaks[1] = (unsigned int *)realloc(*(breaks + 1),exc*sizeof(unsigned int));
}
/* Testing if all sites coalesced or not */
done = isallUI(*(breaks + 1),nbreaks,1,0);
}
}
if(ismsp == 1){
printf("\n");
printf("// \n");
}
if(iscmp == 1){
/* Print off table of coalescent times if requested */
printCT(CTms, breaks, nbreaks, nsites, Itot, i);
}
for(x = 1; x <= nbreaks; x++){
/* Creating ancestry table */
count = 0;
for(j = 0; j < Itot; j++){
if((*((*(CTms + j)) + x)) != (-1.0)){
*((*(TFin + count)) + 0) = *((*(CTms + j)) + 0);
if(isexp == 0){
*((*(TFin + count)) + 1) = *((*(CTms + j)) + x);
}else if(isexp == 1){
*((*(TFin + count)) + 1) = (1/(1.0*alpha))*log(1 + alpha*(*((*(CTms + j)) + x)));
}
*((*(TFin + count)) + 2) = *((*(TAnc + j)) + x);
count++;
}
}
indv_sortD(TFin,(Itot-1),3,1);
/* Using ancestry table to build tree and mutation table */
if(x < nbreaks){
maxd2 = (*((*(breaks + 0)) + x));
maxd = maxd2/(1.0*nsites);
mind2 = (*((*(breaks + 0)) + (x-1)));
mind = mind2/(1.0*nsites);
}else if(x == nbreaks){
maxd2 = nsites;
maxd = 1;
mind2 = *((*(breaks + 0)) + (x-1));
mind = (mind2)/(1.0*nsites);
}
char *ret_tree = treemaker(TFin, theta*(maxd-mind), mind2, maxd2 ,mind, maxd, Itot, i, gmi, gme, ismsp, &nmutT, prtrees, ismut, pburst, mburst, bdist, r);
if(prtrees == 1){
if((rec == 0 && gmi == 0 && gme == 0) || (nsites == 1) ){
if(i == 0){
ofp_tr = fopen("Trees.dat","w");
}else if(i > 0){
ofp_tr = fopen("Trees.dat","a+");
}
fprintf(ofp_tr,"%s\n",ret_tree);
}else if((rec > 0 || gmi > 0 || gme > 0) && (nsites != 1)){
sprintf(Tout,"Trees/Trees_%d.dat",i);
if(x == 1){
ofp_tr = fopen(Tout,"w");
}else if(x > 1){
ofp_tr = fopen(Tout,"a+");
}
fprintf(ofp_tr,"%s\n",ret_tree);
}
fclose(ofp_tr);
}
free(ret_tree);
}
/* Freeing memory at end of particular run */
free(breaks[1]);
free(breaks[0]);
for(j = 0; j < (Itot + exr); j++){
if(j < Itot){
free(TAnc[j]);
free(CTms[j]);
if(j < (Itot - 1)){
free(TFin[j]);
}
}
free(nlrix[j]);
free(nlri[j]);
free(GType[j]);
free(indvs[j]);
}
free(nlrix);
free(nlri);
free(TFin);
free(breaks);
free(TAnc);
free(CTms);
free(GType);
free(indvs);
}
/* Freeing memory and wrapping up */
gsl_rng_free(r);
for(x = 0; x < 13; x++){
free(pr[x]);
}
free(pr);
free(pr_rsums);
free(psex);
free(sexCInv);
free(sexC);
free(nlrecx);
free(nlrec2);
free(nlrec);
free(sexH);
free(sexL);
free(BCHex);
free(WCHex);
free(BCH);
free(WCH);
free(Nsamps);
free(draw3);
free(draw2);
free(draw);
free(csex);
free(evsex);
free(demes);
free(zeros);
free(Nbet);
free(Nwith);
free(Ibet);
free(Iwith);
return 0;
} /* End of main program */
/* End of File */
Computing file changes ...