props = map(numpy.mean, bypopfrac) Ls = pop.Ls nind = pop.nind cutoff = 2 def randomize(arr, scale=2): # takes an array and multiplies every element by a factor between 0 and # 2, uniformly. caps at 1. return map(lambda i: min(i, 1), scale * numpy.random.random(arr.shape) * arr) xopt = tracts.optimize_brute_fracs2( bins, Ls, data, nind, func, props, slices, outofbounds_fun=bound, cutoff=cutoff) print xopt optmod = tracts.demographic_model(func(xopt[0], props)) optpars = xopt[0] liks = xopt[1] maxlik = optmod.loglik(bins, Ls, data, pop.nind, cutoff=cutoff) expects = [] for popnum in range(len(data)): expects.append(optmod.expectperbin(Ls, popnum, bins)) expects = nind * numpy.array(expects) outf = outdir + "boot%d_%2.2f" % (bootnum, maxlik,) fbins = open(outf + "_bins", 'w') fbins.write("\t".join(map(str, bins))) fbins.close()
Ls=pop.Ls nind=pop.nind #we compare two models; single pulse versus two European pulses. func=pp.pp bound=pp.outofbounds_pp func2=pp_px.pp_px bound2=pp_px.outofbounds_pp_px #(init_Eu,tstart,t2,nuEu_prop) #give two different starting conditions, with one starting near the single-pulse model startparams2=numpy.array([ 0.125102 , 0.107152 , 0.0438957 , 0.051725 ]) startparams2p=numpy.array([ 0.155102 , 0.07152 , 0.03 , 1e-8 ]) optmod=tracts.demographic_model(func(startparams)) def randomize(arr,scale=2): #takes an array and multiplies every element by a factor between 0 and 2, uniformly. caps at 1. return map(lambda i: min(i,1),scale*numpy.random.random(arr.shape)*arr) liks_orig_pp=[] maxlik=-1e18 startrand=startparams for i in range(rep_pp): xopt=tracts.optimize_cob(startrand,bins,Ls,data,nind,func,outofbounds_fun=bound,cutoff=cutoff,epsilon=1e-2) try: optmodlocal=tracts.demographic_model(func(xopt))
def dual_analysis(labels, pop, migration_fun, migration_outofbounds_fun, startparams, migration_fun_name): """ Analyse a population using a given migration function, with both the composite and classical models. """ ## 1a. the composite demographic model. # Get the information about the tracts out of the population object, and # split the population into 2 groups, in order to perform an analysis as a # composite demographic model. bins, group_data = pop.get_global_tractlengths(npts=50, split_count=2) # The actual groups that we're splitting the population into. groups = pop.split_by_props(2) # Compute the counts of individuals in each group and the average ancestry # proportions across individuals. The counts of individuals in each groups # should differ by no more than one. ninds, group_ancestry_averages = zip(*map( lambda p: ( len(p.indivs), p.get_mean_ancestry_proportions(ancestry_labels)), groups)) # Rearrange the data for each group into a list ordered in the same way as # the population labels. group_data = [ [g[ancestry_label] for ancestry_label in ancestry_labels] for g in group_data] ## Optimize the model parameters using COBYLA #composite_model_parameters = tracts.optimize_cob_multifracs( # startparams, bins, pop.Ls, group_data, ninds, migration_fun, # group_ancestry_averages, outofbounds_fun=migration_outofbounds_fun, # cutoff=cutoff, epsilon=1e-12) # Optimize the model parameters using brute composite_model_parameters, _ = tracts.optimize_brute_multifracs( bins, pop.Ls, group_data, ninds, migration_fun, group_ancestry_averages, startparams, outofbounds_fun=migration_outofbounds_fun, cutoff=cutoff) # Construct the composite demographic model composite_model = tracts.composite_demographic_model( migration_fun, composite_model_parameters, group_ancestry_averages) ## 1b. the fracs2 model. nind = len(pop.indivs) _, data = pop.get_global_tractlengths(npts=50, split_count=1) data = [data[ancestry_label] for ancestry_label in ancestry_labels] ancestry_averages = pop.get_mean_ancestry_proportions(ancestry_labels) fracs2_model_parameters, _ = tracts.optimize_brute_fracs2( bins, pop.Ls, data, nind, migration_fun, ancestry_averages, startparams, outofbounds_fun=migration_outofbounds_fun, cutoff=cutoff) fracs2_model = tracts.demographic_model( migration_fun(fracs2_model_parameters, ancestry_averages)) return { 'classical': { 'params': fracs2_model_parameters, 'model': fracs2_model, 'averages': ancestry_averages, 'theories': dict( ( name, fp.Theory( bins, nind * np.array( fracs2_model.expectperbin( pop.Ls, i, bins)), migration_fun_name + ' classical', name) ) for i, name in enumerate(labels)), }, 'composite': { 'params': composite_model_parameters, 'model': composite_model, 'ninds': ninds, 'averages': group_ancestry_averages, 'groups': group_data, 'theories': dict( ( name, fp.Theory( bins, composite_model.expectperbin( pop.Ls, i, bins, ninds), migration_fun_name + ' composite', name) ) for i, name in enumerate(labels)), }, 'misc': { 'startparams': startparams, 'bins': bins, 'data': data, 'fun': migration_fun, }, }
func2 = pp_px.pp_px_fix bound2 = pp_px.outofbounds_pp_px_fix # ((tstart,t2,nuEu_prop)) # tstart: start time, # t2: time of second migration, # nuEu_prop : proportion at second migration (proportion at first migration is # fixed by total ancestry proportion) # # Note: times are measured in units of 100 generations (see above) # give two different starting conditions, with one starting near the # single-pulse model startparams2 = numpy.array([0.107152, 0.0438957, 0.051725]) startparams2p = numpy.array([0.07152, 0.03, 1e-8]) optmod = tracts.demographic_model(func(startparams, props)) def randomize(arr, scale=2): """ Scale each element of an array by some random factor between zero and a limit (default: 2), capping the result at 1. """ return [min(i, 1) for i in scale * numpy.random.random(arr.shape) * arr] liks_orig_pp = [] maxlik = -1e18 startrand = startparams for i in range(rep_pp): xopt = tracts.optimize_cob_fracs2(startrand, bins,