Beispiel #1
0
/*-----------------*
 * Function getsam |
 *-----------------*
 | Generates a gene genealogy for a locus.
*/
int gensam(struct params *pparam, char **list, int **pnbvariant, int *pS) 
{
  int nsegs=0, k=0, seg=0, ns=0, start=0, end=0, len=0, segsit=0, nsites=0, nsam=0;
  /* The function returns ns, the number of sgregating sites.
   * nsegs is the gametes were broken into in tracing back the history of the gametes.
   * The histories of these segments are  passed back to the calling function in the array of structures seglst[]
   */
  struct segl *seglst=NULL;
  double nsinv=0.0, tseg=0.0, tt=0.0, theta=0.0;
  void make_gametes(int, struct node*, double, int, int, char**, int, int*, int**, int*, int*);

  void inititable(int, int, int*);
  void initimatrix(int, int, int, int**);
  void biggerimatrix(int, int**);
  void biggerlist(int, char**);
  void locate(int, double, double, double*);
  //// From make_gametes ////
  void prtree(struct node*, int);
  double ttime(struct node*, int);
  int poisso(double);
  //// From streec.c ////
  struct segl*segtre_mig(struct c_params*, int*);

  nsites=pparam->cp.nsites;                 // Locus lenght available for recombination
  nsinv=1./nsites;
  seglst=segtre_mig(&(pparam->cp), &nsegs); // Generate Xove and ARGr, record # segments
  nsam=pparam->cp.nsam;                     // # chromo in the sample
  theta=pparam->mp.theta;                   // mutation rate given by user
  ns=0;                                     // # seg sites
  if(pparam->mp.treeflag)                   // Case output tree.
    {
      theta=pparam->mp.theta;
      ns=0;
      for(seg=0, k=0;k<nsegs;seg=seglst[seg].next, k++)
        {
          if((pparam->cp.r>0.0)||(pparam->cp.f>0.0))
            {
              end=(k<nsegs-1 ? seglst[seglst[seg].next].beg-1:nsites-1);
              start=seglst[seg].beg;
              len=end-start+1;
              fprintf(stdout, "[%d]", len);
            }
          prtree(seglst[seg].ptree, nsam);
          if((theta==0.0)) 
            free(seglst[seg].ptree);
        }
    }
  //--- Loop along all segments ---//
  for(seg=0, k=0;k<nsegs; seg=seglst[seg].next, k++)
    {
      end=(k<nsegs-1 ? seglst[seglst[seg].next].beg-1:nsites-1); // End of segment
      start=seglst[seg].beg;                                     // beginning of segment
      len=end-start+1;                                           // Lengh of segment
      tseg=len*(theta/nsites);                                   // Mutation rate along the segment
      tt=ttime(seglst[seg].ptree, nsam);                         // Total time in the tree for this segment
      segsit=poisso(tseg*tt);                                    // get # segsites along genealogy for the segment

      //--- Realloc memory if # segsite bigger than max previously define ---//
      if((segsit+ns)>=maxsites)
        {
          maxsites=segsit+ns+SITESINC;                          // Bigger Max sites 
          biggerlist(nsam, list);                               // Increase list of haplotype
          typeseg=(int*)realloc(typeseg, maxsites*sizeof(int)); // Increase # seg sites in typeseg
          biggerimatrix(pparam->cp.npop+1, pnbvariant);         // Increase matrix of variant
        }

      //--- Initialize table of variant and segType ---//
      initimatrix(ns, ns+segsit, pparam->cp.npop+1, pnbvariant);
      inititable(ns, segsit+ns, typeseg);
      make_gametes(nsam, seglst[seg].ptree, tt, segsit, ns, list, pparam->cp.npop, pparam->cp.config, pnbvariant, typeseg, pS); // Make gametes (Put segsites on gene genealogy)
      free(seglst[seg].ptree);                                   // Free memory
      ns+=segsit;                                                // Total # seg sites
    }
  for(k=0;k<nsam;k++) list[k][ns]='\0';                          // End of haplotype strings
  return(ns);                                                    // Total # segsites
}// End Gensam
Beispiel #2
0
int
gensam( char **list, double *pprobss, double *ptmrca, double *pttot )
{
    int nsegs, h, i, k, j, seg, ns, start, end, len, segsit ;
    struct segl *seglst, *segtre_mig(struct c_params *p, int *nsegs ) ; /* used to be: [MAXSEG];  */
    double nsinv,  tseg, tt, ttime(struct node *, int nsam), ttimemf(struct node *, int nsam, int mfreq) ;
    double *pk;
    int *ss;
    int segsitesin,nsites;
    double theta, es ;
    int nsam, mfreq ;
    void prtree( struct node *ptree, int nsam);
    void make_gametes(int nsam, int mfreq,  struct node *ptree, double tt, int newsites, int ns, char **list );
    void ndes_setup( struct node *, int nsam );


    nsites = pars.cp.nsites ;
    nsinv = 1./nsites;
    seglst = segtre_mig(&(pars.cp),  &nsegs ) ;

    nsam = pars.cp.nsam;
    segsitesin = pars.mp.segsitesin ;
    theta = pars.mp.theta ;
    mfreq = pars.mp.mfreq ;

    if( pars.mp.treeflag ) {
        ns = 0 ;
        for( seg=0, k=0; k<nsegs; seg=seglst[seg].next, k++) {
            if( (pars.cp.r > 0.0 ) || (pars.cp.f > 0.0) ) {
                end = ( k<nsegs-1 ? seglst[seglst[seg].next].beg -1 : nsites-1 );
                start = seglst[seg].beg ;
                len = end - start + 1 ;
                fprintf(stdout,"[%d]", len);
            }
            prtree( seglst[seg].ptree, nsam ) ;
            if( (segsitesin == 0) && ( theta == 0.0 ) && ( pars.mp.timeflag == 0 ) )
                free(seglst[seg].ptree) ;
        }
    }

    if( pars.mp.timeflag ) {
        tt = 0.0 ;
        for( seg=0, k=0; k<nsegs; seg=seglst[seg].next, k++) {
            if( mfreq > 1 ) ndes_setup( seglst[seg].ptree, nsam );
            end = ( k<nsegs-1 ? seglst[seglst[seg].next].beg -1 : nsites-1 );
            start = seglst[seg].beg ;
            if( (nsegs==1) || ( ( start <= nsites/2) && ( end >= nsites/2 ) ) )
                *ptmrca = (seglst[seg].ptree + 2*nsam-2) -> time ;
            len = end - start + 1 ;
            tseg = len/(double)nsites ;
            if( mfreq == 1 ) tt += ttime(seglst[seg].ptree,nsam)*tseg ;
            else tt += ttimemf(seglst[seg].ptree,nsam, mfreq)*tseg ;
            if( (segsitesin == 0) && ( theta == 0.0 )  )
                free(seglst[seg].ptree) ;
        }
        *pttot = tt ;
    }

    if( (segsitesin == 0) && ( theta > 0.0)   ) {
        ns = 0 ;
        for( seg=0, k=0; k<nsegs; seg=seglst[seg].next, k++) {
            if( mfreq > 1 ) ndes_setup( seglst[seg].ptree, nsam );
            end = ( k<nsegs-1 ? seglst[seglst[seg].next].beg -1 : nsites-1 );
            start = seglst[seg].beg ;
            len = end - start + 1 ;
            tseg = len*(theta/nsites) ;
            if( mfreq == 1) tt = ttime(seglst[seg].ptree, nsam);
            else tt = ttimemf(seglst[seg].ptree, nsam, mfreq );
            segsit = poisso( tseg*tt );
            if( (segsit + ns) >= maxsites ) {
                maxsites = segsit + ns + SITESINC ;
                posit = (double *)realloc(posit, maxsites*sizeof(double) ) ;
                biggerlist(nsam, list) ;
            }
            make_gametes(nsam,mfreq,seglst[seg].ptree,tt, segsit, ns, list );
            free(seglst[seg].ptree) ;
            locate(segsit,start*nsinv, len*nsinv,posit+ns);
            ns += segsit;
        }
    }
    else if( segsitesin > 0 ) {

        pk = (double *)malloc((unsigned)(nsegs*sizeof(double)));
        ss = (int *)malloc((unsigned)(nsegs*sizeof(int)));
        if( (pk==NULL) || (ss==NULL) ) perror("malloc error. gensam.2");


        tt = 0.0 ;
        for( seg=0, k=0; k<nsegs; seg=seglst[seg].next, k++) {
            if( mfreq > 1 ) ndes_setup( seglst[seg].ptree, nsam );
            end = ( k<nsegs-1 ? seglst[seglst[seg].next].beg -1 : nsites-1 );
            start = seglst[seg].beg ;
            len = end - start + 1 ;
            tseg = len/(double)nsites ;
            if( mfreq == 1 ) pk[k] = ttime(seglst[seg].ptree,nsam)*tseg ;
            else pk[k] = ttimemf(seglst[seg].ptree,nsam, mfreq)*tseg ;
            tt += pk[k] ;
        }
        if( theta > 0.0 ) {
            es = theta * tt ;
            *pprobss = exp( -es )*pow( es, (double) segsitesin) / segfac ;
        }
        if( tt > 0.0 ) {
            for (k=0; k<nsegs; k++) pk[k] /= tt ;
            mnmial(segsitesin,nsegs,pk,ss);
        }
        else
            for( k=0; k<nsegs; k++) ss[k] = 0 ;
        ns = 0 ;
        for( seg=0, k=0; k<nsegs; seg=seglst[seg].next, k++) {
            end = ( k<nsegs-1 ? seglst[seglst[seg].next].beg -1 : nsites-1 );
            start = seglst[seg].beg ;
            len = end - start + 1 ;
            tseg = len/(double)nsites;
            make_gametes(nsam,mfreq,seglst[seg].ptree,tt*pk[k]/tseg, ss[k], ns, list);

            free(seglst[seg].ptree) ;
            locate(ss[k],start*nsinv, len*nsinv,posit+ns);
            ns += ss[k] ;
        }
        free(pk);
        free(ss);

    }
    for(i=0; i<nsam; i++) list[i][ns] = '\0' ;
    return( ns ) ;
}