def phi_2D_admix_2_into_1(phi, f, xx,yy): """ Admix population 2 into population 1. Alters phi in place and returns the new version. phi: phi corresponding to original 2 populations f: Fraction of updated population 1 to be derived from population 2. (A fraction 1-f will be derived from the original population 1.) xx,yy: Mapping of points in phi to frequencies in populations 1 and 2. """ # Note that it's 1-f here since f now denotes the fraction coming from # population 2. lower_z_index, upper_z_index, frac_lower, frac_upper, norm \ = _two_pop_admixture_intermediates(phi, 1-f, xx,yy,xx) idx_i = numpy.arange(phi.shape[0]) lower_cont = frac_lower*norm upper_cont = frac_upper*norm for jj in xrange(len(yy)): phi_int = numpy.zeros((len(xx), len(xx))) phi_int[idx_i, lower_z_index[:,jj]] = lower_cont[:,jj] phi_int[idx_i, upper_z_index[:,jj]] = upper_cont[:,jj] phi[:,jj] = Numerics.trapz(phi_int, xx, axis=0) return phi
def phi_3D_admix_2_and_3_into_1(phi, f2,f3, xx,yy,zz): """ Admix populations 2 and 3 into population 1. Alters phi in place and returns the new version. phi: phi corresponding to original 3 populations. f2: Fraction of updated population 1 to be derived from population 2. f3: Fraction of updated population 1 to be derived from population 3. A fraction (1-f2-f3) will be derived from the original pop 1. xx,yy,zz: Mapping of points in phi to frequencies in populations 1,2 and 3. """ lower_w_index, upper_w_index, frac_lower, frac_upper, norm \ = _three_pop_admixture_intermediates(phi, 1-f2-f3,f2, xx,yy,zz, xx) lower_cont = frac_lower * norm upper_cont = frac_upper * norm # Basically, we're splitting into a fourth ww population, then integrating # over yy to be left with the two populations we care about. idx_i = numpy.arange(phi.shape[0]) for jj in xrange(phi.shape[1]): for kk in xrange(phi.shape[2]): phi_int = numpy.zeros((phi.shape[0], phi.shape[0])) phi_int[idx_i, lower_w_index[:,jj,kk]] = lower_cont[:,jj,kk] phi_int[idx_i, upper_w_index[:,jj,kk]] = upper_cont[:,jj,kk] phi[:,jj,kk] = Numerics.trapz(phi_int, xx, axis=0) return phi
def phi_3D_admix_1_and_2_into_3(phi, f1,f2, xx,yy,zz): """ Admix populations 1 and 2 into population 3. Alters phi in place and returns the new version. phi: phi corresponding to original 3 populations. f1: Fraction of updated population 3 to be derived from population 1. f2: Fraction of updated population 3 to be derived from population 2. A fraction (1-f1-f2) will be derived from the original pop 3. xx,yy,zz: Mapping of points in phi to frequencies in populations 1,2 and 3. """ lower_w_index, upper_w_index, frac_lower, frac_upper, norm \ = _three_pop_admixture_intermediates(phi, f1,f2, xx,yy,zz, zz) lower_cont = frac_lower * norm upper_cont = frac_upper * norm # Basically, we're splitting into a fourth ww population, then integrating # over zz to be left with the two populations we care about. idx_k = numpy.arange(phi.shape[2]) for ii in xrange(phi.shape[0]): for jj in xrange(phi.shape[1]): phi_int = numpy.zeros((phi.shape[2], phi.shape[2])) phi_int[idx_k, lower_w_index[ii,jj]] = lower_cont[ii,jj] phi_int[idx_k, upper_w_index[ii,jj]] = upper_cont[ii,jj] phi[ii,jj] = Numerics.trapz(phi_int, zz, axis=0) return phi
def split_mig(params, ns, pts): """ params = (nu1,nu2,T,m) ns = (n1,n2) Split into two populations of specifed size, with migration. nu1: Size of population 1 after split. nu2: Size of population 2 after split. T: Time in the past of split (in units of 2*Na generations) m: Migration rate between populations (2*Na*m) n1,n2: Sample sizes of resulting Spectrum pts: Number of grid points to use in integration. """ nu1,nu2,T,m = params xx = Numerics.default_grid(pts) phi = PhiManip.phi_1D(xx) phi = PhiManip.phi_1D_to_2D(xx, phi) phi = Integration.two_pops(phi, xx, T, nu1, nu2, m12=m, m21=m) fs = Spectrum.from_phi(phi, ns, (xx,xx)) return fs
def bottlegrowth(params, ns, pts): """ Instantanous size change followed by exponential growth. params = (nuB,nuF,T) ns = (n1,) nuB: Ratio of population size after instantanous change to ancient population size nuF: Ratio of contemporary to ancient population size T: Time in the past at which instantaneous change happened and growth began (in units of 2*Na generations) n1: Number of samples in resulting Spectrum pts: Number of grid points to use in integration. """ nuB,nuF,T = params xx = Numerics.default_grid(pts) phi = PhiManip.phi_1D(xx) nu_func = lambda t: nuB*numpy.exp(numpy.log(nuF/nuB) * t/T) phi = Integration.one_pop(phi, xx, T, nu_func) fs = Spectrum.from_phi(phi, ns, (xx,)) return fs
def bottlegrowth_split_mig(params, ns, pts): """ params = (nuB,nuF,m,T,Ts) ns = (n1,n2) Instantanous size change followed by exponential growth then split with migration. nuB: Ratio of population size after instantanous change to ancient population size nuF: Ratio of contempoary to ancient population size m: Migration rate between the two populations (2*Na*m). T: Time in the past at which instantaneous change happened and growth began (in units of 2*Na generations) Ts: Time in the past at which the two populations split. n1,n2: Sample sizes of resulting Spectrum pts: Number of grid points to use in integration. """ nuB,nuF,m,T,Ts = params xx = Numerics.default_grid(pts) phi = PhiManip.phi_1D(xx) nu_func = lambda t: nuB*numpy.exp(numpy.log(nuF/nuB) * t/T) phi = Integration.one_pop(phi, xx, T-Ts, nu_func) phi = PhiManip.phi_1D_to_2D(xx, phi) nu0 = nu_func(T-Ts) nu_func = lambda t: nu0*numpy.exp(numpy.log(nuF/nu0) * t/Ts) phi = Integration.two_pops(phi, xx, Ts, nu_func, nu_func, m12=m, m21=m) fs = Spectrum.from_phi(phi, ns, (xx,xx)) return fs
def phi_2D_admix_1_into_2(phi, f, xx,yy): """ Admix population 1 into population 2. Alters phi in place and returns the new version. phi: phi corresponding to original 2 populations f: Fraction of updated population 2 to be derived from population 1. (A fraction 1-f will be derived from the original population 2.) xx,yy: Mapping of points in phi to frequencies in populations 1 and 2. """ # This is just like the the split_admix situation, but we're splitting into # a population with zz=yy. We could do this by creating a xx by yy by yy # array, then integrating out the second population. That's a big waste of # memory, however. lower_z_index, upper_z_index, frac_lower, frac_upper, norm \ = _two_pop_admixture_intermediates(phi, f, xx,yy,yy) # Basically, we're splitting into a third zz population, then integrating # over yy to be left with the two populations we care about. lower_cont = frac_lower*norm upper_cont = frac_upper*norm idx_j = numpy.arange(phi.shape[1]) for ii in range(phi.shape[0]): phi_int = numpy.zeros((phi.shape[1], phi.shape[1])) # Use fancy indexing to avoid the commented out loop. #for jj in xrange(len(yy)): # phi_int[jj, upper_z_index[ii,jj]] += frac_upper[ii,jj]*norm[ii,jj] # phi_int[jj, lower_z_index[ii,jj]] += frac_lower[ii,jj]*norm[ii,jj] phi_int[idx_j, lower_z_index[ii]] = lower_cont[ii] phi_int[idx_j, upper_z_index[ii]] += upper_cont[ii] phi[ii] = Numerics.trapz(phi_int, yy, axis=0) return phi
def IM(params, ns, pts): """ ns = (n1,n2) params = (s,nu1,nu2,T,m12,m21) Isolation-with-migration model with exponential pop growth. s: Size of pop 1 after split. (Pop 2 has size 1-s.) nu1: Final size of pop 1. nu2: Final size of pop 2. T: Time in the past of split (in units of 2*Na generations) m12: Migration from pop 2 to pop 1 (2*Na*m12) m21: Migration from pop 1 to pop 2 n1,n2: Sample sizes of resulting Spectrum pts: Number of grid points to use in integration. """ s,nu1,nu2,T,m12,m21 = params xx = Numerics.default_grid(pts) phi = PhiManip.phi_1D(xx) phi = PhiManip.phi_1D_to_2D(xx, phi) nu1_func = lambda t: s * (nu1/s)**(t/T) nu2_func = lambda t: (1-s) * (nu2/(1-s))**(t/T) phi = Integration.two_pops(phi, xx, T, nu1_func, nu2_func, m12=m12, m21=m21) fs = Spectrum.from_phi(phi, ns, (xx,xx)) return fs
def bottleneck_1d(params, n1, pts): nuC, T = params xx = Numerics.default_grid(pts) phi = PhiManip.phi_1D(xx) phi = Integration.one_pop(phi, xx, T, nuC) model_sfs = Spectrum.from_phi(phi, n1, (xx,)) return model_sfs
def snm2(notused, ns, pts): """ ns = (n1,n2) Standard neutral model, populations never diverge. """ xx = Numerics.default_grid(pts) phi = PhiManip.phi_1D(xx) phi = PhiManip.phi_1D_to_2D(xx, phi) fs = Spectrum.from_phi(phi, ns, (xx,xx)) return fs
def remove_pop(phi, xx, popnum): """ Remove a population from phi. Returns new phi with one fewer population. phi: phi corresponding to original populations xx: Mapping of points in phi to frequencies in population to be removed popnum: Population number to remove, numbering from 1. """ return Numerics.trapz(phi, xx, axis=popnum-1)
def optimal_sfs_scaling(model, data): """ Optimal multiplicative scaling factor between model and data. This scaling is based on only those entries that are masked in neither model nor data. """ if data.folded and not model.folded: model = model.fold() model, data = Numerics.intersect_masks(model, data) return data.sum()/model.sum()
def snm(notused, ns, pts): """ Standard neutral model. ns = (n1,) n1: Number of samples in resulting Spectrum pts: Number of grid points to use in integration. """ xx = Numerics.default_grid(pts) phi = PhiManip.phi_1D(xx) fs = Spectrum.from_phi(phi, ns, (xx,)) return fs
def plot_1d_comp_Poisson(model, data, fig_num=None, residual='Anscombe', plot_masked=False): """ Poisson comparison between 1d model and data. model: 1-dimensional model SFS data: 1-dimensional data SFS fig_num: Clear and use figure fig_num for display. If None, an new figure window is created. residual: 'Anscombe' for Anscombe residuals, which are more normally distributed for Poisson sampling. 'linear' for the linear residuals, which can be less biased. plot_masked: Additionally plots (in open circles) results for points in the model or data that were masked. """ if fig_num is None: f = pylab.gcf() else: f = pylab.figure(fig_num, figsize=(7,7)) pylab.clf() if data.folded and not model.folded: model = model.fold() masked_model, masked_data = Numerics.intersect_masks(model, data) ax = pylab.subplot(2,1,1) pylab.semilogy(masked_data, '-ob') pylab.semilogy(masked_model, '-or') if plot_masked: pylab.semilogy(masked_data.data, '--ob', mfc='w', zorder=-100) pylab.semilogy(masked_model.data, '--or', mfc='w', zorder=-100) pylab.subplot(2,1,2, sharex = ax) if residual == 'Anscombe': resid = Inference.Anscombe_Poisson_residual(masked_model, masked_data) elif residual == 'linear': resid = Inference.linear_Poisson_residual(masked_model, masked_data) else: raise ValueError("Unknown class of residual '%s'." % residual) pylab.plot(resid, '-og') if plot_masked: pylab.plot(resid.data, '--og', mfc='w', zorder=-100) ax.set_xlim(0, data.shape[0]-1) pylab.show()
def two_epoch(params, ns, pts): """ Instantaneous size change some time ago. params = (nu,T) ns = (n1,) nu: Ratio of contemporary to ancient population size T: Time in the past at which size change happened (in units of 2*Na generations) n1: Number of samples in resulting Spectrum pts: Number of grid points to use in integration. """ nu,T = params xx = Numerics.default_grid(pts) phi = PhiManip.phi_1D(xx) phi = Integration.one_pop(phi, xx, T, nu) fs = Spectrum.from_phi(phi, ns, (xx,)) return fs
def three_epoch(params, ns, pts): """ params = (nuB,nuF,TB,TF) ns = (n1,) nuB: Ratio of bottleneck population size to ancient pop size nuF: Ratio of contemporary to ancient pop size TB: Length of bottleneck (in units of 2*Na generations) TF: Time since bottleneck recovery (in units of 2*Na generations) n1: Number of samples in resulting Spectrum pts: Number of grid points to use in integration. """ nuB,nuF,TB,TF = params xx = Numerics.default_grid(pts) phi = PhiManip.phi_1D(xx) phi = Integration.one_pop(phi, xx, TB, nuB) phi = Integration.one_pop(phi, xx, TF, nuF) fs = Spectrum.from_phi(phi, ns, (xx,)) return fs
def growth(params, ns, pts): """ Exponential growth beginning some time ago. params = (nu,T) ns = (n1,) nu: Ratio of contemporary to ancient population size T: Time in the past at which growth began (in units of 2*Na generations) n1: Number of samples in resulting Spectrum pts: Number of grid points to use in integration. """ nu,T = params xx = Numerics.default_grid(pts) phi = PhiManip.phi_1D(xx) nu_func = lambda t: numpy.exp(numpy.log(nu) * t/T) phi = Integration.one_pop(phi, xx, T, nu_func) fs = Spectrum.from_phi(phi, ns, (xx,)) return fs
def IM_pre(params, ns, pts): """ params = (nuPre,TPre,s,nu1,nu2,T,m12,m21) ns = (n1,n2) Isolation-with-migration model with exponential pop growth and a size change prior to split. nuPre: Size after first size change TPre: Time before split of first size change. s: Fraction of nuPre that goes to pop1. (Pop 2 has size nuPre*(1-s).) nu1: Final size of pop 1. nu2: Final size of pop 2. T: Time in the past of split (in units of 2*Na generations) m12: Migration from pop 2 to pop 1 (2*Na*m12) m21: Migration from pop 1 to pop 2 n1,n2: Sample sizes of resulting Spectrum pts: Number of grid points to use in integration. """ nuPre,TPre,s,nu1,nu2,T,m12,m21 = params xx = Numerics.default_grid(pts) phi = PhiManip.phi_1D(xx) phi = Integration.one_pop(phi, xx, TPre, nu=nuPre) phi = PhiManip.phi_1D_to_2D(xx, phi) nu1_0 = nuPre*s nu2_0 = nuPre*(1-s) nu1_func = lambda t: nu1_0 * (nu1/nu1_0)**(t/T) nu2_func = lambda t: nu2_0 * (nu2/nu2_0)**(t/T) phi = Integration.two_pops(phi, xx, T, nu1_func, nu2_func, m12=m12, m21=m21) fs = Spectrum.from_phi(phi, ns, (xx,xx)) return fs
def __init__(self, params, ns, demo_sel_func, pts=500, pts_l=None, Npts=500, n=20170., int_breaks=None, int_bounds=(1e-4, 1000.), mp=False, echo=False, cpus=None): """ params: optimized demographic parameters, don't include gamma here demo_sel_func: dadi demographic function with selection. gamma must be the last argument. ns: sample sizes Npts: number of grid points over which to integrate steps: use this to set break points for spacing out the intervals mp: True if you want to use multiple cores (utilizes multiprocessing) if using the mp option you must also specify # of cpus, otherwise this will just use nthreads-1 on your machine """ self.ns = ns self.spectra = [] #create a vector of gammas that are log-spaced over sequential #intervals or log-spaced over a single interval. if not (int_breaks is None): numbreaks = len(int_breaks) stepint = Npts / (numbreaks - 1) self.gammas = [] for i in reversed(range(0, numbreaks - 1)): self.gammas = numpy.append( self.gammas, -numpy.logspace(numpy.log10(int_breaks[i + 1]), numpy.log10(int_breaks[i]), stepint)) else: self.gammas = -numpy.logspace(numpy.log10(int_bounds[1]), numpy.log10(int_bounds[0]), Npts) if pts_l == None: self.pts = pts self.pts_l = [self.pts,self.pts+(self.pts/5), \ self.pts+(self.pts/5)*2] else: self.pts_l = pts_l func_ex = Numerics.make_extrap_func(demo_sel_func) self.params = tuple(params) if not mp: #for running with a single thread for ii, gamma in enumerate(self.gammas): self.spectra.append( func_ex(tuple(params) + (gamma, ), self.ns, self.pts_l)) if echo: print '{0}: {1}'.format(ii, gamma) else: #for running with with multiple cores import multiprocessing if cpus is None: cpus = multiprocessing.cpu_count() - 1 def worker_sfs(in_queue, outlist, popn_func_ex, params, ns, pts_l): """ Worker function -- used to generate SFSes for single values of gamma. """ while True: item = in_queue.get() if item == None: return ii, gamma = item sfs = popn_func_ex(tuple(params) + (gamma, ), ns, pts_l) print '{0}: {1}'.format(ii, gamma) result = (gamma, sfs) outlist.append(result) manager = multiprocessing.Manager() results = manager.list() work = manager.Queue(cpus) pool = [] for i in xrange(cpus): p = multiprocessing.Process(target=worker_sfs, args=(work, results, func_ex, params, self.ns, self.pts_l)) p.start() pool.append(p) for ii, gamma in enumerate(self.gammas): work.put((ii, gamma)) for jj in xrange(cpus): work.put(None) for p in pool: p.join() reslist = [] for line in results: reslist.append(line) reslist.sort(key=operator.itemgetter(0)) for gamma, sfs in reslist: self.spectra.append(sfs) #self.neu_spec = demo_sel_func(params+(0,), self.ns, self.pts) self.neu_spec = func_ex(tuple(params) + (0, ), self.ns, self.pts_l) self.extrap_x = self.spectra[0].extrap_x self.spectra = numpy.array(self.spectra)
0.000904436801400043, 0.00095928867779992, 0.00102119052600009, 0.00109169024399996, 0.00117274381199999, 0.00126646200000007, 0.00137692562999991, 0.00150807480600003, 0.00166722686399998, 0.00186366919200004, 0.00211288077000004, 0.00243920581199994, 0.00288500043600006, 0.00353089605600002, 0.00455208658199998, 0.00641589649199996, 0.0109679830740001) def sso_model_trim_39( (nu38, nu37, nu36, nu35, nu34, nu33, nu32, nu31, nu30, nu29, nu28, nu27, nu26, nu25, nu24, nu23, nu22, nu21, nu20, nu19, nu18, nu17, nu16, nu15, nu14, nu13, nu12, nu11, nu10, nu9, nu8, nu7, nu6, nu5, nu4, nu3, nu2, nu1, nu0, T38, T37, T36, T35, T34, T33, T32, T31, T30, T29, T28, T27, T26, T25, T24, T23, T22, T21, T20, T19, T18, T17, T16, T15, T14, T13, T12, T11, T10, T9, T8, T7, T6, T5, T4, T3, T2, T1, T0), ns, pts): xx = Numerics.default_grid(pts) # intialize phi with ancestral pop: (nu0 = 1) phi = PhiManip.phi_1D(xx, nu=nu0) # stays at nu0 for T0 duration of time: phi = Integration.one_pop(phi, xx, T0, nu0) # followed by a number of time steps, with associated pop changes: phi = Integration.one_pop(phi, xx, T0, nu0) phi = Integration.one_pop(phi, xx, T1, nu1) phi = Integration.one_pop(phi, xx, T2, nu2) phi = Integration.one_pop(phi, xx, T3, nu3) phi = Integration.one_pop(phi, xx, T4, nu4) phi = Integration.one_pop(phi, xx, T5, nu5) phi = Integration.one_pop(phi, xx, T6, nu6) phi = Integration.one_pop(phi, xx, T7, nu7) phi = Integration.one_pop(phi, xx, T8, nu8) phi = Integration.one_pop(phi, xx, T9, nu9)
if fs.folded==False: fs=fs.fold() else: fs=fs ############### Set up General Dadi Parameters ######################## ns = fs.sample_sizes # get sample size from SFS (in haploids) pts_l = [ns[0]+5,ns[0]+15,ns[0]+25] # this should be slightly larger (+5) than sample size and increase by 10 Nanc = 22759 # params in dadi units (nu = Nx/Nanc; T = gen/(2*Nanc)) in same order that they should go into function (all nus from nu32 --> nu0 followed by Ts from T32 --> T0) -- note that order is from recent --> old because that is how it comes out of msmc. But then dadi function starts with oldest (nu0) first. params = (0.0881030544009925, 0.0339730033926217, 0.0929355795355233, 0.146484994149822, 0.185969764821238, 0.218631178707224, 0.244857652102702, 0.262357053342665, 0.270286941253667, 0.269710116013023, 0.257097104104347, 0.257097104104347, 0.232676303911964, 0.232676303911964, 0.208900140554491, 0.208900140554491, 0.191032772098617, 0.191032772098617, 0.18040432146964, 0.18040432146964, 0.177336636081359, 0.177336636081359, 0.182994441404337, 0.182994441404337, 0.200959926621754, 0.200959926621754, 0.240224202954715, 0.240224202954715, 0.323417652253806, 0.323417652253806, 0.512531459731541, 0.512531459731541, 1, 0.00723549801, 0.00742344193499999, 0.00762142478500003, 0.00783031066999984, 0.00805070955000007, 0.00828427340000002, 0.00853156135000007, 0.00879409829999996, 0.00907340914999987, 0.00937101879999997, 0.00968845215000001, 0.0100287589999999, 0.0103932101, 0.0107858718499999, 0.0112085233, 0.0116665016000001, 0.0121628565499998, 0.0127036877500001, 0.01329484065, 0.0139436855999999, 0.0146588637000001, 0.0154518116999998, 0.0163349829500007, 0.0173256596499985, 0.0184436655000015, 0.0197169569999992, 0.0211808609999998, 0.0228735000000012, 0.0248685774999983, 0.0272372555000004, 0.0301116919999995, 0.0336596260000006, 0.0381606225000007) ################### copy/paste MSMC information from def sso_model_trim_33((nu32, nu31, nu30, nu29, nu28, nu27, nu26, nu25, nu24, nu23, nu22, nu21, nu20, nu19, nu18, nu17, nu16, nu15, nu14, nu13, nu12, nu11, nu10, nu9, nu8, nu7, nu6, nu5, nu4, nu3, nu2, nu1, nu0, T32, T31, T30, T29, T28, T27, T26, T25, T24, T23, T22, T21, T20, T19, T18, T17, T16, T15, T14, T13, T12, T11, T10, T9, T8, T7, T6, T5, T4, T3, T2, T1, T0),ns,pts): xx = Numerics.default_grid(pts) # intialize phi with ancestral pop: (nu0 = 1) phi = PhiManip.phi_1D(xx,nu=nu0) # stays at nu0 for T0 duration of time: # followed by a number of time steps, with associated pop changes: phi = Integration.one_pop(phi, xx, T0, nu0) phi = Integration.one_pop(phi, xx, T1, nu1) phi = Integration.one_pop(phi, xx, T2, nu2) phi = Integration.one_pop(phi, xx, T3, nu3) phi = Integration.one_pop(phi, xx, T4, nu4) phi = Integration.one_pop(phi, xx, T5, nu5) phi = Integration.one_pop(phi, xx, T6, nu6) phi = Integration.one_pop(phi, xx, T7, nu7) phi = Integration.one_pop(phi, xx, T8, nu8) phi = Integration.one_pop(phi, xx, T9, nu9) phi = Integration.one_pop(phi, xx, T10, nu10)
def plot_2d_comp_Poisson(model, data, vmin=None, vmax=None, resid_range=None, fig_num=None, pop_ids=None, residual='Anscombe', adjust=True): """ Poisson comparison between 2d model and data. model: 2-dimensional model SFS data: 2-dimensional data SFS vmin, vmax: Minimum and maximum values plotted for sfs are vmin and vmax respectively. resid_range: Residual plot saturates at +- resid_range. fig_num: Clear and use figure fig_num for display. If None, an new figure window is created. pop_ids: If not None, override pop_ids stored in Spectrum. residual: 'Anscombe' for Anscombe residuals, which are more normally distributed for Poisson sampling. 'linear' for the linear residuals, which can be less biased. adjust: Should method use automatic 'subplots_adjust'? For advanced manipulation of plots, it may be useful to make this False. """ if data.folded and not model.folded: model = model.fold() masked_model, masked_data = Numerics.intersect_masks(model, data) if fig_num is None: f = pylab.gcf() else: f = pylab.figure(fig_num, figsize=(7,7)) pylab.clf() if adjust: pylab.subplots_adjust(bottom=0.07, left=0.07, top=0.94, right=0.95, hspace=0.26, wspace=0.26) max_toplot = max(masked_model.max(), masked_data.max()) min_toplot = min(masked_model.min(), masked_data.min()) if vmax is None: vmax = max_toplot if vmin is None: vmin = min_toplot extend = _extend_mapping[vmin <= min_toplot, vmax >= max_toplot] if pop_ids is not None: data_pop_ids = model_pop_ids = resid_pop_ids = pop_ids if len(pop_ids) != 2: raise ValueError('pop_ids must be of length 2.') else: data_pop_ids = masked_data.pop_ids model_pop_ids = masked_model.pop_ids if masked_model.pop_ids is None: model_pop_ids = data_pop_ids if model_pop_ids == data_pop_ids: resid_pop_ids = model_pop_ids else: resid_pop_ids = None ax = pylab.subplot(2,2,1) plot_single_2d_sfs(masked_data, vmin=vmin, vmax=vmax, pop_ids=data_pop_ids, colorbar=False) ax.set_title('data') ax2 = pylab.subplot(2,2,2, sharex=ax, sharey=ax) plot_single_2d_sfs(masked_model, vmin=vmin, vmax=vmax, pop_ids=model_pop_ids, extend=extend ) ax2.set_title('model') if residual == 'Anscombe': resid = Inference.Anscombe_Poisson_residual(masked_model, masked_data, mask=vmin) elif residual == 'linear': resid = Inference.linear_Poisson_residual(masked_model, masked_data, mask=vmin) else: raise ValueError("Unknown class of residual '%s'." % residual) if resid_range is None: resid_range = max((abs(resid.max()), abs(resid.min()))) resid_extend = _extend_mapping[-resid_range <= resid.min(), resid_range >= resid.max()] ax3 = pylab.subplot(2,2,3, sharex=ax, sharey=ax) plot_2d_resid(resid, resid_range, pop_ids=resid_pop_ids, extend=resid_extend) ax3.set_title('residuals') ax = pylab.subplot(2,2,4) flatresid = numpy.compress(numpy.logical_not(resid.mask.ravel()), resid.ravel()) ax.hist(flatresid, bins=20, normed=True) ax.set_title('residuals') ax.set_yticks([]) pylab.show()
import numpy from dadi import Numerics, PhiManip, Integration, Spectrum def OutOfAfrica((nuAf, nuB, nuEu0, nuEu, nuAs0, nuAs, mAfB, mAfEu, mAfAs, mEuAs, TAf, TB, TEuAs), (n1,n2,n3), pts): xx = Numerics.default_grid(pts) phi = PhiManip.phi_1D(xx) phi = Integration.one_pop(phi, xx, TAf, nu=nuAf) phi = PhiManip.phi_1D_to_2D(xx, phi) phi = Integration.two_pops(phi, xx, TB, nu1=nuAf, nu2=nuB, m12=mAfB, m21=mAfB) phi = PhiManip.phi_2D_to_3D_split_2(xx, phi) nuEu_func = lambda t: nuEu0*(nuEu/nuEu0)**(t/TEuAs) nuAs_func = lambda t: nuAs0*(nuAs/nuAs0)**(t/TEuAs) phi = Integration.three_pops(phi, xx, TEuAs, nu1=nuAf, nu2=nuEu_func, nu3=nuAs_func, m12=mAfEu, m13=mAfAs, m21=mAfEu, m23=mEuAs, m31=mAfAs, m32=mEuAs) fs = Spectrum.from_phi(phi, (n1,n2,n3), (xx,xx,xx)) return fs def OutOfAfrica_mscore((nuAf, nuB, nuEu0, nuEu, nuAs0, nuAs, mAfB, mAfEu, mAfAs, mEuAs, TAf, TB, TEuAs)): alphaEu = numpy.log(nuEu/nuEu0)/TEuAs alphaAs = numpy.log(nuAs/nuAs0)/TEuAs
def plot_3d_comp_Poisson(model, data, vmin=None, vmax=None, resid_range=None, fig_num=None, pop_ids=None, residual='Anscombe', adjust=True): """ Poisson comparison between 3d model and data. model: 3-dimensional model SFS data: 3-dimensional data SFS vmin, vmax: Minimum and maximum values plotted for sfs are vmin and vmax respectively. resid_range: Residual plot saturates at +- resid_range. fig_num: Clear and use figure fig_num for display. If None, an new figure window is created. pop_ids: If not None, override pop_ids stored in Spectrum. residual: 'Anscombe' for Anscombe residuals, which are more normally distributed for Poisson sampling. 'linear' for the linear residuals, which can be less biased. adjust: Should method use automatic 'subplots_adjust'? For advanced manipulation of plots, it may be useful to make this False. """ if data.folded and not model.folded: model = model.fold() masked_model, masked_data = Numerics.intersect_masks(model, data) if fig_num is None: f = pylab.gcf() else: f = pylab.figure(fig_num, figsize=(8,10)) pylab.clf() if adjust: pylab.subplots_adjust(bottom=0.07, left=0.07, top=0.95, right=0.95) modelmax = max(masked_model.sum(axis=sax).max() for sax in range(3)) datamax = max(masked_data.sum(axis=sax).max() for sax in range(3)) modelmin = min(masked_model.sum(axis=sax).min() for sax in range(3)) datamin = min(masked_data.sum(axis=sax).min() for sax in range(3)) max_toplot = max(modelmax, datamax) min_toplot = min(modelmin, datamin) if vmax is None: vmax = max_toplot if vmin is None: vmin = min_toplot extend = _extend_mapping[vmin <= min_toplot, vmax >= max_toplot] # Calculate the residuals if residual == 'Anscombe': resids = [Inference.\ Anscombe_Poisson_residual(masked_model.sum(axis=2-sax), masked_data.sum(axis=2-sax), mask=vmin) for sax in range(3)] elif residual == 'linear': resids =[Inference.\ linear_Poisson_residual(masked_model.sum(axis=2-sax), masked_data.sum(axis=2-sax), mask=vmin) for sax in range(3)] else: raise ValueError("Unknown class of residual '%s'." % residual) min_resid = min([r.min() for r in resids]) max_resid = max([r.max() for r in resids]) if resid_range is None: resid_range = max((abs(max_resid), abs(min_resid))) resid_extend = _extend_mapping[-resid_range <= min_resid, resid_range >= max_resid] if pop_ids is not None: if len(pop_ids) != 3: raise ValueError('pop_ids must be of length 3.') data_ids = model_ids = resid_ids = pop_ids else: data_ids = masked_data.pop_ids model_ids = masked_model.pop_ids if model_ids is None: model_ids = data_ids if model_ids == data_ids: resid_ids = model_ids else: resid_ids = None for sax in range(3): marg_data = masked_data.sum(axis=2-sax) marg_model = masked_model.sum(axis=2-sax) curr_ids = [] for ids in [data_ids, model_ids, resid_ids]: if ids is None: ids = ['pop0', 'pop1', 'pop2'] if ids is not None: ids = list(ids) del ids[2-sax] curr_ids.append(ids) ax = pylab.subplot(4,3,sax+1) plot_colorbar = (sax == 2) plot_single_2d_sfs(marg_data, vmin=vmin, vmax=vmax, pop_ids=curr_ids[0], extend=extend, colorbar=plot_colorbar) pylab.subplot(4,3,sax+4, sharex=ax, sharey=ax) plot_single_2d_sfs(marg_model, vmin=vmin, vmax=vmax, pop_ids=curr_ids[1], extend=extend, colorbar=False) resid = resids[sax] pylab.subplot(4,3,sax+7, sharex=ax, sharey=ax) plot_2d_resid(resid, resid_range, pop_ids=curr_ids[2], extend=resid_extend, colorbar=plot_colorbar) ax = pylab.subplot(4,3,sax+10) flatresid = numpy.compress(numpy.logical_not(resid.mask.ravel()), resid.ravel()) ax.hist(flatresid, bins=20, normed=True) ax.set_yticks([]) pylab.show()
def plot_2d_comp_Poisson(model, data, vmin=None, vmax=None, resid_range=None, fig_num=None, pop_ids=None, residual='Anscombe', adjust=True, saveplot=False, nomplot="plot_2d_comp_Poisson", showplot=True): """ Poisson comparison between 2d model and data. model: 2-dimensional model SFS data: 2-dimensional data SFS vmin, vmax: Minimum and maximum values plotted for sfs are vmin and vmax respectively. resid_range: Residual plot saturates at +- resid_range. fig_num: Clear and use figure fig_num for display. If None, an new figure window is created. pop_ids: If not None, override pop_ids stored in Spectrum. residual: 'Anscombe' for Anscombe residuals, which are more normally distributed for Poisson sampling. 'linear' for the linear residuals, which can be less biased. adjust: Should method use automatic 'subplots_adjust'? For advanced manipulation of plots, it may be useful to make this False. """ if data.folded and not model.folded: model = model.fold() masked_model, masked_data = Numerics.intersect_masks(model, data) if fig_num is None: f = pylab.gcf() else: f = pylab.figure(fig_num, figsize=(7,7)) pylab.clf() if adjust: pylab.subplots_adjust(bottom=0.07, left=0.07, top=0.94, right=0.95, hspace=0.26, wspace=0.26) max_toplot = max(masked_model.max(), masked_data.max()) min_toplot = min(masked_model.min(), masked_data.min()) if vmax is None: vmax = max_toplot if vmin is None: vmin = min_toplot extend = _extend_mapping[vmin <= min_toplot, vmax >= max_toplot] if pop_ids is not None: data_pop_ids = model_pop_ids = resid_pop_ids = pop_ids if len(pop_ids) != 2: raise ValueError('pop_ids must be of length 2.') else: data_pop_ids = masked_data.pop_ids model_pop_ids = masked_model.pop_ids if masked_model.pop_ids is None: model_pop_ids = data_pop_ids if model_pop_ids == data_pop_ids: resid_pop_ids = model_pop_ids else: resid_pop_ids = None ax = pylab.subplot(2,2,1) plot_single_2d_sfs(masked_data, vmin=vmin, vmax=vmax, pop_ids=data_pop_ids, colorbar=False) ax.set_title('data') ax2 = pylab.subplot(2,2,2, sharex=ax, sharey=ax) plot_single_2d_sfs(masked_model, vmin=vmin, vmax=vmax, pop_ids=model_pop_ids, extend=extend ) ax2.set_title('model') if residual == 'Anscombe': resid = Inference.Anscombe_Poisson_residual(masked_model, masked_data, mask=vmin) elif residual == 'linear': resid = Inference.linear_Poisson_residual(masked_model, masked_data, mask=vmin) else: raise ValueError("Unknown class of residual '%s'." % residual) if resid_range is None: resid_range = max((abs(resid.max()), abs(resid.min()))) resid_extend = _extend_mapping[-resid_range <= resid.min(), resid_range >= resid.max()] ax3 = pylab.subplot(2,2,3, sharex=ax, sharey=ax) plot_2d_resid(resid, resid_range, pop_ids=resid_pop_ids, extend=resid_extend) ax3.set_title('residuals') ax = pylab.subplot(2,2,4) flatresid = numpy.compress(numpy.logical_not(resid.mask.ravel()), resid.ravel()) ax.hist(flatresid, bins=20, normed=True) ax.set_title('residuals') ax.set_yticks([]) if saveplot: nomplot=nomplot + ".png" pylab.savefig(nomplot) if showplot: pylab.show()
1.31334850354829, 1.16537332842806, 1.16537332842806, 1.05963716704008, 1.05963716704008, 1, 1, 0.04439683224, 0.0455501223099999, 0.0467642982499995, 0.0480467154000004, 0.0494006428000006, 0.0508308478, 0.052349589299999, 0.0539609536000003, 0.0556744753999996, 0.0574996894000009, 0.0594488544999996, 0.0615355917000003, 0.0637735219999999, 0.0661803527000002, 0.0687765152999997, 0.0715851654999999, 0.0746321831999993, 0.0779488967000003, 0.0815775310999996, 0.0855562252000041) def nso_model_trim_20( (nu19, nu18, nu17, nu16, nu15, nu14, nu13, nu12, nu11, nu10, nu9, nu8, nu7, nu6, nu5, nu4, nu3, nu2, nu1, nu0, T19, T18, T17, T16, T15, T14, T13, T12, T11, T10, T9, T8, T7, T6, T5, T4, T3, T2, T1, T0), ns, pts): xx = Numerics.default_grid(pts) # intialize phi with ancestral pop: (nu0 = 1) phi = PhiManip.phi_1D(xx, nu=nu0) # stays at nu0 for T0 duration of time: phi = Integration.one_pop(phi, xx, T0, nu0) # followed by a number of time steps, with associated pop changes: phi = Integration.one_pop(phi, xx, T0, nu0) phi = Integration.one_pop(phi, xx, T1, nu1) phi = Integration.one_pop(phi, xx, T2, nu2) phi = Integration.one_pop(phi, xx, T3, nu3) phi = Integration.one_pop(phi, xx, T4, nu4) phi = Integration.one_pop(phi, xx, T5, nu5) phi = Integration.one_pop(phi, xx, T6, nu6) phi = Integration.one_pop(phi, xx, T7, nu7) phi = Integration.one_pop(phi, xx, T8, nu8) phi = Integration.one_pop(phi, xx, T9, nu9)
nu1_func = lambda t: nu01 * (nu1 / nu01)**(t / T) nu2_func = lambda t: nu02 * (nu2 / nu02)**(t / T) phi = Integration.two_pops(phi, xx, T, nu1_func, nu2_func, m12=m12, m21=m21) fs = Spectrum.from_phi(phi, ns, (xx, xx)) return fs im2 = Numerics.make_extrap_log_func(IM2) params = array([0.078, 2.136, 2.174, 2.063, 1.174, 0.514, 0.379]) upper_bound = [100, 100, 100, 100, 100, 200, 200] lower_bound = [1e-3, 1e-3, 1e-3, 1e-3, 1e-3, 0, 0] poptg = dadi.Inference.optimize_log(params, data, im2, pts, lower_bound=lower_bound, upper_bound=upper_bound, verbose=len(params), maxiter=20) model = im2(poptg, ns, pts) ll_model = dadi.Inference.ll_multinom(model, data)
def psmc_100steps(params, ns, pts_1): nu99, nu98, nu97, nu96, nu95, nu94, nu93, nu92, nu91, nu90, nu89, nu88, nu87, nu86, nu85, nu84, nu83, nu82, nu81, nu80, nu79, nu78, nu77, nu76, nu75, nu74, nu73, nu72, nu71, nu70, nu69, nu68, nu67, nu66, nu65, nu64, nu63, nu62, nu61, nu60, nu59, nu58, nu57, nu56, nu55, nu54, nu53, nu52, nu51, nu50, nu49, nu48, nu47, nu46, nu45, nu44, nu43, nu42, nu41, nu40, nu39, nu38, nu37, nu36, nu35, nu34, nu33, nu32, nu31, nu30, nu29, nu28, nu27, nu26, nu25, nu24, nu23, nu22, nu21, nu20, nu19, nu18, nu17, nu16, nu15, nu14, nu13, nu12, nu11, nu10, nu9, nu8, nu7, nu6, nu5, nu4, nu3, nu2, nu1, nuA, T99, T98, T97, T96, T95, T94, T93, T92, T91, T90, T89, T88, T87, T86, T85, T84, T83, T82, T81, T80, T79, T78, T77, T76, T75, T74, T73, T72, T71, T70, T69, T68, T67, T66, T65, T64, T63, T62, T61, T60, T59, T58, T57, T56, T55, T54, T53, T52, T51, T50, T49, T48, T47, T46, T45, T44, T43, T42, T41, T40, T39, T38, T37, T36, T35, T34, T33, T32, T31, T30, T29, T28, T27, T26, T25, T24, T23, T22, T21, T20, T19, T18, T17, T16, T15, T14, T13, T12, T11, T10, T9, T8, T7, T6, T5, T4, T3, T2, T1, T0 = params xx = Numerics.default_grid(pts_1) # initial phi with ancestral pop: (nuA = 1) phi = PhiManip.phi_1D(xx,nu=nuA) # stays at nuA for T0 duration of time: phi = Integration.one_pop(phi,xx,T0,nuA) # followed by a number of time steps, with associated pop changes: phi = Integration.one_pop(phi, xx, T1, nu1) phi = Integration.one_pop(phi, xx, T2, nu2) phi = Integration.one_pop(phi, xx, T3, nu3) phi = Integration.one_pop(phi, xx, T4, nu4) phi = Integration.one_pop(phi, xx, T5, nu5) phi = Integration.one_pop(phi, xx, T6, nu6) phi = Integration.one_pop(phi, xx, T7, nu7) phi = Integration.one_pop(phi, xx, T8, nu8) phi = Integration.one_pop(phi, xx, T9, nu9) phi = Integration.one_pop(phi, xx, T10, nu10) phi = Integration.one_pop(phi, xx, T11, nu11) phi = Integration.one_pop(phi, xx, T12, nu12) phi = Integration.one_pop(phi, xx, T13, nu13) phi = Integration.one_pop(phi, xx, T14, nu14) phi = Integration.one_pop(phi, xx, T15, nu15) phi = Integration.one_pop(phi, xx, T16, nu16) phi = Integration.one_pop(phi, xx, T17, nu17) phi = Integration.one_pop(phi, xx, T18, nu18) phi = Integration.one_pop(phi, xx, T19, nu19) phi = Integration.one_pop(phi, xx, T20, nu20) phi = Integration.one_pop(phi, xx, T21, nu21) phi = Integration.one_pop(phi, xx, T22, nu22) phi = Integration.one_pop(phi, xx, T23, nu23) phi = Integration.one_pop(phi, xx, T24, nu24) phi = Integration.one_pop(phi, xx, T25, nu25) phi = Integration.one_pop(phi, xx, T26, nu26) phi = Integration.one_pop(phi, xx, T27, nu27) phi = Integration.one_pop(phi, xx, T28, nu28) phi = Integration.one_pop(phi, xx, T29, nu29) phi = Integration.one_pop(phi, xx, T30, nu30) phi = Integration.one_pop(phi, xx, T31, nu31) phi = Integration.one_pop(phi, xx, T32, nu32) phi = Integration.one_pop(phi, xx, T33, nu33) phi = Integration.one_pop(phi, xx, T34, nu34) phi = Integration.one_pop(phi, xx, T35, nu35) phi = Integration.one_pop(phi, xx, T36, nu36) phi = Integration.one_pop(phi, xx, T37, nu37) phi = Integration.one_pop(phi, xx, T38, nu38) phi = Integration.one_pop(phi, xx, T39, nu39) phi = Integration.one_pop(phi, xx, T40, nu40) phi = Integration.one_pop(phi, xx, T41, nu41) phi = Integration.one_pop(phi, xx, T42, nu42) phi = Integration.one_pop(phi, xx, T43, nu43) phi = Integration.one_pop(phi, xx, T44, nu44) phi = Integration.one_pop(phi, xx, T45, nu45) phi = Integration.one_pop(phi, xx, T46, nu46) phi = Integration.one_pop(phi, xx, T47, nu47) phi = Integration.one_pop(phi, xx, T48, nu48) phi = Integration.one_pop(phi, xx, T49, nu49) phi = Integration.one_pop(phi, xx, T50, nu50) phi = Integration.one_pop(phi, xx, T51, nu51) phi = Integration.one_pop(phi, xx, T52, nu52) phi = Integration.one_pop(phi, xx, T53, nu53) phi = Integration.one_pop(phi, xx, T54, nu54) phi = Integration.one_pop(phi, xx, T55, nu55) phi = Integration.one_pop(phi, xx, T56, nu56) phi = Integration.one_pop(phi, xx, T57, nu57) phi = Integration.one_pop(phi, xx, T58, nu58) phi = Integration.one_pop(phi, xx, T59, nu59) phi = Integration.one_pop(phi, xx, T60, nu60) phi = Integration.one_pop(phi, xx, T61, nu61) phi = Integration.one_pop(phi, xx, T62, nu62) phi = Integration.one_pop(phi, xx, T63, nu63) phi = Integration.one_pop(phi, xx, T64, nu64) phi = Integration.one_pop(phi, xx, T65, nu65) phi = Integration.one_pop(phi, xx, T66, nu66) phi = Integration.one_pop(phi, xx, T67, nu67) phi = Integration.one_pop(phi, xx, T68, nu68) phi = Integration.one_pop(phi, xx, T69, nu69) phi = Integration.one_pop(phi, xx, T70, nu70) phi = Integration.one_pop(phi, xx, T71, nu71) phi = Integration.one_pop(phi, xx, T72, nu72) phi = Integration.one_pop(phi, xx, T73, nu73) phi = Integration.one_pop(phi, xx, T74, nu74) phi = Integration.one_pop(phi, xx, T75, nu75) phi = Integration.one_pop(phi, xx, T76, nu76) phi = Integration.one_pop(phi, xx, T77, nu77) phi = Integration.one_pop(phi, xx, T78, nu78) phi = Integration.one_pop(phi, xx, T79, nu79) phi = Integration.one_pop(phi, xx, T80, nu80) phi = Integration.one_pop(phi, xx, T81, nu81) phi = Integration.one_pop(phi, xx, T82, nu82) phi = Integration.one_pop(phi, xx, T83, nu83) phi = Integration.one_pop(phi, xx, T84, nu84) phi = Integration.one_pop(phi, xx, T85, nu85) phi = Integration.one_pop(phi, xx, T86, nu86) phi = Integration.one_pop(phi, xx, T87, nu87) phi = Integration.one_pop(phi, xx, T88, nu88) phi = Integration.one_pop(phi, xx, T89, nu89) phi = Integration.one_pop(phi, xx, T90, nu90) phi = Integration.one_pop(phi, xx, T91, nu91) phi = Integration.one_pop(phi, xx, T92, nu92) phi = Integration.one_pop(phi, xx, T93, nu93) phi = Integration.one_pop(phi, xx, T94, nu94) phi = Integration.one_pop(phi, xx, T95, nu95) phi = Integration.one_pop(phi, xx, T96, nu96) phi = Integration.one_pop(phi, xx, T97, nu97) phi = Integration.one_pop(phi, xx, T98, nu98) phi = Integration.one_pop(phi, xx, T99, nu99) # get sfs: fs = Spectrum.from_phi(phi,ns,(xx,)) return fs
############### Input data #################################### fs = dadi.Spectrum.from_file(sfs) # this is folded if from easy SFS # check if it's folded, if not folded, fold it if fs.folded == False: fs = fs.fold() else: fs = fs ############ set up grid for specific model ########## ######## set up model ####### def sso_model_trim_22_plusContraction_forOptimization_SIMPLIFIED( (T, nu), ns, pts): xx = Numerics.default_grid(pts) # intialize phi with ancestral pop: (nu0 = 1) phi = PhiManip.phi_1D(xx, nu=1) # stays at nu0=1 for T0 duration of time: # followed by a number of time steps, with associated pop changes: phi = Integration.one_pop(phi, xx, 0.125, 0.5) ### add contraction: phi = Integration.one_pop(phi, xx, T, nu) # get expected SFS: fs = Spectrum.from_phi(phi, ns, (xx, )) return fs func = sso_model_trim_22_plusContraction_forOptimization_SIMPLIFIED # param_names = ("nu", "T")
# split with migration, with recent change in migration def s2mRM(params, ns, pts): nu1, nu2, T, M12, M21, M12r, M21r = params Tr = 0.01 xx = Numerics.default_grid(pts) phi = PhiManip.phi_1D(xx) phi = PhiManip.phi_1D_to_2D(xx, phi) phi = Integration.two_pops(phi, xx, T, nu1, nu2, m12=M12, m21=M21) phi = Integration.two_pops(phi, xx, Tr, nu1, nu2, m12=M12r, m21=M21r) fs = Spectrum.from_phi(phi, ns, (xx, xx)) return fs S2MRM = Numerics.make_extrap_log_func(s2mRM) params = array([1, 1, 1, 30, 30, 30, 30]) upper_bound = [10, 10, 10, 300, 300, 300, 300] lower_bound = [0.01, 0.01, 0.01, 0.1, 0.1, 0.1, 0.1] poptg = dadi.Inference.optimize_log(params, data, S2MRM, pts, lower_bound=lower_bound, upper_bound=upper_bound, verbose=len(params), maxiter=15) model = S2MRM(poptg, ns, pts) print 's2mRM ', sys.argv[1], sys.argv[2], sys.argv[3], ' params : ', poptg