示例#1
0
def calcDiskMass(data,samples,
                 locations,effsel,distmods,
                 type='tribrokenexpflare'):
    """
    NAME:
       calcDiskMass
    PURPOSE:
       calculate the local surface density for a set of density profiles
    INPUT:
       data - the data array
       samples - an array [nparam,ndens] of density-profile parameters
       locations - locations of the APOGEE effective selection function
       effsel - array (nloc,nD) of the effective selection function, includes area of the field
       distmods - grid of distance moduli on which the effective selection function is pre-computed
       type= ('exp') type of density profile to use
    OUTPUT:
       local surface density in Msol/pc^2
    HISTORY:
       2015-04-29 - Written - Bovy (IAS)
    """
    # Setup the density function and its initial parameters
    densfunc= fitDens._setup_densfunc(type)
    # Setup the integration of the effective volume
    effsel, Rgrid, phigrid, zgrid= \
        fitDens._setup_effvol(locations,effsel,distmods)
    out= []
    for sample in samples.T:
        # Setup the density function, fix the normalization for Rb < R0
        if 'tribroken' in type and numpy.exp(sample[3]) < densprofiles._R0:
            norm= numpy.exp(-(sample[0]+sample[2])\
                                 *(numpy.exp(sample[3])-densprofiles._R0))
        else:
            norm= 1.
        tdensfunc= lambda x,y,z: densfunc(x,y,z,params=sample)*norm
        out.append(calcDiskMass_single(data,tdensfunc,
                                       effsel,Rgrid,phigrid,zgrid))
    return numpy.array(out)*12500.
def predict_spacedist(params,
                      locations,effsel,distmods,
                      type='exp',
                      coord='Z'):
    """
    NAME:
       predict_spacedist
    PURPOSE:
       predict the spatial distribution
    INPUT:
       params - parameters of the density profile
       locations - locations of the APOGEE effective selection function to consider
       effsel - array (nloc,nD) of the effective selection function, includes area of the field
       distmods - grid of distance moduli on which the effective selection function is pre-computed
       type= ('exp') type of density profile to fit      
       coord= ('dm', 'X', or 'Z')
    OUTPUT:
       (R,model(R))
    HISTORY:
       2015-03-26 - Written - Bovy (IAS)
    """
    if coord.lower() == 'x':
        # Grid in X
        Xs= numpy.linspace(0.,20.,301)
    elif coord.lower() == 'z':
        # Grid in X
        Xs= numpy.linspace(0.,20.,301)
    elif coord.lower() == 'dm':
        # Grid in X
        Xs= numpy.linspace(7.,15.5,301)
    # Setup the density function
    rdensfunc= _setup_densfunc(type)
    densfunc= lambda x,y,z: rdensfunc(x,y,z,params=params)
    # Restore the APOGEE selection function (assumed pre-computed)
    selectFile= '../savs/selfunc-nospdata.sav'
    if os.path.exists(selectFile):
        with open(selectFile,'rb') as savefile:
            apo= pickle.load(savefile)
    # Now compute the necessary coordinate transformations
    ds= 10.**(distmods/5-2.)
    Rgrid, phigrid, zgrid, Xgrid= [], [], [], []
    for loc in locations:
        lcen, bcen= apo.glonGlat(loc)
        XYZ= bovy_coords.lbd_to_XYZ(lcen*numpy.ones_like(ds),
                                    bcen*numpy.ones_like(ds),
                                    ds,
                                    degree=True)
        Rphiz= bovy_coords.XYZ_to_galcencyl(XYZ[:,0],XYZ[:,1],XYZ[:,2],
                                            Xsun=define_rcsample._R0,
                                            Ysun=0.,
                                            Zsun=define_rcsample._Z0)
        Rgrid.append(Rphiz[0])
        phigrid.append(Rphiz[1])
        zgrid.append(Rphiz[2])
        Xgrid.append(Rphiz[0]*numpy.cos(Rphiz[1]))
    Rgrid= numpy.array(Rgrid)
    phigrid= numpy.array(phigrid)
    zgrid= numpy.array(zgrid)
    Xgrid= numpy.array(Xgrid)
    # Now compute rate(R) for each location and combine
    effsel*= numpy.tile(ds**3.*(distmods[1]-distmods[0]),(effsel.shape[0],1))
    tdens= densfunc(Rgrid,phigrid,zgrid)
    rate= tdens*effsel
    out= numpy.zeros((len(locations),len(Xs)))
    for ii in range(len(locations)):
        if coord.lower() == 'x':
            # Jacobian
            tjac= numpy.fabs((numpy.roll(distmods,-1)-distmods)/\
                                 (numpy.roll(Xgrid[ii],-1)-Xgrid[ii]))
            tjac[-1]= tjac[-2]
            tXs= Xgrid[ii,rate[ii] > 0.]
        elif coord.lower() == 'z':
            # Jacobian
            tjac= numpy.fabs((numpy.roll(distmods,-1)-distmods)/\
                                 (numpy.roll(zgrid[ii],-1)-zgrid[ii]))
            tjac[-1]= tjac[-2]
            tXs= zgrid[ii,rate[ii] > 0.]
        elif coord.lower() == 'dm':
            # Jacobian
            tjac= numpy.ones_like(Xs)
            tXs= distmods[rate[ii] > 0.]
        sindx= numpy.argsort(tXs)
        tXs= tXs[sindx]
        trate= rate[ii,rate[ii] > 0.][sindx]
        tjac= tjac[rate[ii] > 0.][sindx]
        ipthis= numpy.log(trate*tjac+10.**-8.)
        baseline= numpy.polynomial.Polynomial.fit(tXs,ipthis,4)
        ipthis= ipthis/baseline(tXs)
        sp= interpolate.InterpolatedUnivariateSpline(tXs,ipthis,k=3)
        tindx= (Xs >= numpy.amin(tXs))\
            *(Xs <= numpy.amax(tXs))
        out[ii,tindx]= (numpy.exp(sp(Xs[tindx])*baseline(Xs[tindx]))-10.**-8.)
    out[numpy.isinf(out)]= 0.
    return (Xs,out.sum(axis=0))
示例#3
0
def calc_normalisation(params,
                       nbin,
                       iso_grid,
                       fehbin=[-0.1, 0.0],
                       agebin=[1., 3.],
                       loggcut=[1.8, 3.0],
                       teffcut=[4000, 5000],
                       type='brokenexpflare',
                       verbose=True,
                       fitIndx=None,
                       weights='padova',
                       distance_cut=False,
                       lowermass=None):
    #first get the values necessary from the isochrone grid
    #make a mask for giant stars (+ J-K cut)
    if teffcut == None:
        giants = (iso_grid[:, 3] >= loggcut[0]) & (
            iso_grid[:, 3] < loggcut[1]) & (iso_grid[:, 5] > 0.5)
    else:
        giants = (iso_grid[:, 3] >= loggcut[0]) & (
            iso_grid[:, 3] < loggcut[1]) & (iso_grid[:, 5] > 0.5) & (
                10**iso_grid[:, 7] >= teffcut[0]) & (10**iso_grid[:, 7] <
                                                     teffcut[1])
    #make a mask for the age and feh bin
    if agebin == None:
        bin = (10**iso_grid[:,0] >= 0.)&(10**iso_grid[:,0] < 13.)&\
             (Z2FEH(iso_grid[:,1]) >= fehbin[0])&(Z2FEH(iso_grid[:,1]) < fehbin[1])
    else:
        bin = (10**iso_grid[:,0] >= agebin[0])&(10**iso_grid[:,0] < agebin[1])&\
             (Z2FEH(iso_grid[:,1]) >= fehbin[0])&(Z2FEH(iso_grid[:,1]) < fehbin[1])

    if lowermass != None:
        giants *= iso_grid[:, 2] >= lowermass
        bin *= iso_grid[:, 2] >= lowermass
    if len(iso_grid[:, 0][bin]) < 1:
        fehs = np.unique(Z2FEH(iso_grid[:, 1]))
        cfehbin = fehbin[0] + ((fehbin[1] - fehbin[0]) / 2)
        feh_offsets = np.fabs(fehs - cfehbin)
        ind = np.argmin(feh_offsets)
        cfeh = fehs[ind]
        bin = (10**iso_grid[:,0] >= agebin[0])&(10**iso_grid[:,0] < agebin[1])&\
          (Z2FEH(iso_grid[:,1]) == cfeh)
    #find the average giant mass
    mass = iso_grid[:, 2]
    if weights == 'padova':
        weight = iso_grid[:, 6] * (10**iso_grid[:, 0] / iso_grid[:, 1])
    if weights == 'basti':
        weight = iso_grid[:, 6]
    av_mass = np.sum(mass[giants & bin] * weight[giants & bin]) / np.sum(
        weight[giants & bin])
    #find the ratio between giants and the total stellar pop. for this bin
    mass_total = mass[bin]
    weight_total = weight[bin]
    mass_bin = mass[giants & bin]
    weight_bin = weight[giants & bin]
    m_ratio = np.sum(mass_bin * weight_bin) / np.sum(mass_total * weight_total)
    #now compute and sum the rate for this density function
    #load the raw selection function
    selectFile = '../savs/selfunc-nospdata.sav'
    if os.path.exists(selectFile):
        with open(selectFile, 'rb') as savefile:
            apo = pickle.load(savefile)
    #load the effective selection function
        if agebin == None:
            with open(
                    '../essf/maps/essf_rgb_green15_modelmh_feh' +
                    str(round(fehbin[0], 1)) + '.sav', 'rb') as savefile:
                locations = pickle.load(savefile)
                effsel = pickle.load(savefile)
                distmods = pickle.load(savefile)
            with open(
                    '../essf/maps/essf_rgb_marshall06_modelmh_feh' +
                    str(round(fehbin[0], 1)) + '.sav', 'rb') as savefile:
                mlocations = pickle.load(savefile)
                meffsel = pickle.load(savefile)
                mdistmods = pickle.load(savefile)
    if agebin != None:
        if agebin[0] < 1.:
            with open(
                    '../essf/maps/essf_rgb_green15_modelmh_feh' +
                    str(round(fehbin[0], 1)) + '_age' + str(round(1.0, 1)) +
                    '.sav', 'rb') as savefile:
                locations = pickle.load(savefile)
                effsel = pickle.load(savefile)
                distmods = pickle.load(savefile)
            with open(
                    '../essf/maps/essf_rgb_marshall06_modelmh_feh' +
                    str(round(fehbin[0], 1)) + '_age' + str(round(1.0, 1)) +
                    '.sav', 'rb') as savefile:
                mlocations = pickle.load(savefile)
                meffsel = pickle.load(savefile)
                mdistmods = pickle.load(savefile)
        if agebin[0] > 0.9:
            with open(
                    '../essf/maps/essf_rgb_green15_modelmh_feh' +
                    str(round(fehbin[0], 1)) + '_age' +
                    str(round(agebin[0], 1)) + '.sav', 'rb') as savefile:
                locations = pickle.load(savefile)
                effsel = pickle.load(savefile)
                distmods = pickle.load(savefile)
            with open(
                    '../essf/maps/essf_rgb_marshall06_modelmh_feh' +
                    str(round(fehbin[0], 1)) + '_age' +
                    str(round(agebin[0], 1)) + '.sav', 'rb') as savefile:
                mlocations = pickle.load(savefile)
                meffsel = pickle.load(savefile)
                mdistmods = pickle.load(savefile)

    # Fill in regions not covered by Marshall map
    meffsel[meffsel < -0.5] = effsel[meffsel < -0.5]
    if fitIndx is None:
        fitIndx = numpy.ones(len(mlocations), dtype='bool')  #True-betwDiskIndx
    locations, effsel, distmods = np.array(mlocations)[fitIndx], np.array(
        meffsel)[fitIndx], mdistmods
    #get the density function and set it up to find the normalisation (surfdens=True)
    rdensfunc = _setup_densfunc(type)
    densfunc = lambda x: rdensfunc(x, None, None, params=params, surfdens=True)
    #evaluate surface density at R0 for the density normalisation (always 1. if R_b > R0)
    R0 = densprofiles._R0
    Rb = np.exp(params[3])
    dens_norm = densfunc(densprofiles._R0)
    #set up the density function again with surfdens=False for the rate calculation
    rdensfunc = _setup_densfunc(type)
    densfunc = lambda x, y, z: rdensfunc(
        x, y, z, params=params, surfdens=False)
    ds = 10.**(distmods / 5. - 2.)
    #imply the distance cut if distance_cut == True
    if distance_cut == True:
        distmods = distmods[ds <= 3.]
        ds = ds[ds <= 3.]
        effsel = effsel[:, :len(ds)]
    #Compute the grid of R, phi and Z for each location
    Rgrid, phigrid, zgrid = [], [], []
    for loc in locations:
        lcen, bcen = apo.glonGlat(loc)
        XYZ = bovy_coords.lbd_to_XYZ(lcen * numpy.ones_like(ds),
                                     bcen * numpy.ones_like(ds),
                                     ds,
                                     degree=True)
        Rphiz = bovy_coords.XYZ_to_galcencyl(XYZ[:, 0],
                                             XYZ[:, 1],
                                             XYZ[:, 2],
                                             Xsun=define_rgbsample._R0,
                                             Zsun=define_rgbsample._Z0)
        Rgrid.append(Rphiz[:, 0])
        phigrid.append(Rphiz[:, 1])
        zgrid.append(Rphiz[:, 2])
    Rgrid = numpy.array(Rgrid)
    phigrid = numpy.array(phigrid)
    zgrid = numpy.array(zgrid)
    # Now compute rate(R) for each location and combine
    effsel *= numpy.tile(
        ds**2. * (distmods[1] - distmods[0]) * (ds * np.log(10) / 5.),
        (effsel.shape[0], 1))
    tdens = densfunc(Rgrid, phigrid, zgrid) / dens_norm
    rate = tdens * effsel
    sumrate = np.sum(rate)
    #calculate normalisation N(R0)
    norm = (nbin / sumrate)
    #convert units (Kpc^2 > pc^2, deg > rad etc)
    norm *= 1e-6 * (180 / np.pi)**2
    #compute mass in bin using values from isochrones
    bin_mass = (norm * av_mass) / m_ratio
    if verbose == True:
        print bin_mass
    return bin_mass, norm, m_ratio, (av_mass * 1e-6 *
                                     (180 / np.pi)**2) / (sumrate * m_ratio)
示例#4
0
def generate(locations,
             type='exp',
             sample='lowlow',
             extmap='green15',
             nls=101,
             nmock=1000,
             H0=-1.49,
             _dmapg15=None,             
             ncpu=1):
    """
    NAME:
       generate
    PURPOSE:
       generate mock data following a given density
    INPUT:
       locations - locations to be included in the sample
       type= ('exp') type of density profile to sample from
       sample= ('lowlow') for selecting mock parameters
       extmap= ('green15') extinction map to use ('marshall06' and others use Green15 to fill in unobserved regions)
       nls= (101) number of longitude bins to use for each field
       nmock= (1000) number of mock data points to generate
       H0= (-1.49) absolute magnitude (can be array w/ sampling spread)
       ncpu= (1) number of cpus to use to compute the probability
    OUTPUT:
       mockdata recarray with tags 'RC_GALR_H', 'RC_GALPHI_H', 'RC_GALZ_H'
    HISTORY:
       2015-04-03 - Written - Bovy (IAS)
    """
    if isinstance(H0,float): H0= [H0]
    # Setup the density function and its initial parameters
    rdensfunc= fitDens._setup_densfunc(type)
    mockparams= _setup_mockparams_densfunc(type,sample)
    densfunc= lambda x,y,z: rdensfunc(x,y,z,params=mockparams)   
    # Setup the extinction map
    global dmap
    global dmapg15
    if _dmapg15 is None: dmapg15= mwdust.Green15(filter='2MASS H')
    else: dmapg15= _dmapg15
    if isinstance(extmap,mwdust.DustMap3D.DustMap3D):
        dmap= extmap
    elif extmap.lower() == 'green15':
        dmap= dmapg15
    elif extmap.lower() == 'marshall06':
        dmap= mwdust.Marshall06(filter='2MASS H')
    elif extmap.lower() == 'sale14':
        dmap= mwdust.Sale14(filter='2MASS H')
    elif extmap.lower() == 'drimmel03':
        dmap= mwdust.Drimmel03(filter='2MASS H')
    # Use brute-force rejection sampling to make no approximations
    # First need to estimate the max probability to use in rejection;
    # Loop through all locations and compute sampling probability on grid in 
    # (l,b,D)
    # First restore the APOGEE selection function (assumed pre-computed)
    global apo
    selectFile= '../savs/selfunc-nospdata.sav'
    if os.path.exists(selectFile):
        with open(selectFile,'rb') as savefile:
            apo= pickle.load(savefile)
    # Now compute the necessary coordinate transformations and evaluate the 
    # maximum probability
    distmods= numpy.linspace(7.,15.5,301)
    ds= 10.**(distmods/5-2.)
    nbs= nls
    lnprobs= numpy.empty((len(locations),len(distmods),nbs,nls))
    radii= []
    lcens, bcens= [], []
    lnprobs= multi.parallel_map(lambda x: _calc_lnprob(locations[x],nls,nbs,
                                                       ds,distmods,
                                                       H0,
                                                       densfunc),
                                range(len(locations)),
                                numcores=numpy.amin([len(locations),
                                                     multiprocessing.cpu_count(),ncpu]))
    lnprobs= numpy.array(lnprobs)
    for ll, loc in enumerate(locations):
        lcen, bcen= apo.glonGlat(loc)
        rad= apo.radius(loc)
        radii.append(rad) # save for later
        lcens.append(lcen[0])
        bcens.append(bcen[0])
    maxp= (numpy.exp(numpy.nanmax(lnprobs))-10.**-8.)*1.1 # Just to be sure
    # Now generate mock data using rejection sampling
    nout= 0
    arlocations= numpy.array(locations)
    arradii= numpy.array(radii)
    arlcens= numpy.array(lcens)
    arbcens= numpy.array(bcens)
    out= numpy.recarray((nmock,),
                        dtype=[('RC_DIST_H','f8'),
                               ('RC_DM_H','f8'),
                               ('RC_GALR_H','f8'),
                               ('RC_GALPHI_H','f8'),
                               ('RC_GALZ_H','f8')])
    while nout < nmock:
        nnew= 2*(nmock-nout)
        # nnew new locations
        locIndx= numpy.floor(numpy.random.uniform(size=nnew)*len(locations)).astype('int')
        newlocations= arlocations[locIndx]
        # Point within these locations
        newds_coord= numpy.random.uniform(size=nnew)
        newds= 10.**((newds_coord*(numpy.amax(distmods)-numpy.amin(distmods))\
            +numpy.amin(distmods))/5.-2.)
        newdls_coord= numpy.random.uniform(size=nnew)
        newdls= newdls_coord*2.*arradii[locIndx]\
            -arradii[locIndx]
        newdbs_coord= numpy.random.uniform(size=nnew)
        newdbs= newdbs_coord*2.*arradii[locIndx]\
            -arradii[locIndx]
        newr2s= newdls**2.+newdbs**2.
        keepIndx= newr2s < arradii[locIndx]**2.
        newlocations= newlocations[keepIndx]
        newds_coord= newds_coord[keepIndx]
        newdls_coord= newdls_coord[keepIndx]
        newdbs_coord= newdbs_coord[keepIndx]
        newds= newds[keepIndx]
        newdls= newdls[keepIndx]
        newdbs= newdbs[keepIndx]
        newls= newdls+arlcens[locIndx][keepIndx]
        newbs= newdbs+arbcens[locIndx][keepIndx]
        # Reject?
        tps= numpy.zeros_like(newds)
        for nloc in list(set(newlocations)):
            lindx= newlocations == nloc
            pindx= arlocations == nloc
            coord= numpy.array([newds_coord[lindx]*(len(distmods)-1.),
                                newdbs_coord[lindx]*(nbs-1.),
                                newdls_coord[lindx]*(nls-1.)])
            tps[lindx]= \
                numpy.exp(ndimage.interpolation.map_coordinates(\
                    lnprobs[pindx][0],
                    coord,cval=-10.,
                    order=1))-10.**-8.
        XYZ= bovy_coords.lbd_to_XYZ(newls,newbs,newds,degree=True)
        Rphiz= bovy_coords.XYZ_to_galcencyl(XYZ[:,0],XYZ[:,1],XYZ[:,2],
                                            Xsun=define_rcsample._R0,
                                            Ysun=0.,
                                            Zsun=define_rcsample._Z0)
        testp= numpy.random.uniform(size=len(newds))*maxp
        keepIndx= tps > testp 
        if numpy.sum(keepIndx) > nmock-nout:
            rangeIndx= numpy.zeros(len(keepIndx),dtype='int')
            rangeIndx[keepIndx]= numpy.arange(numpy.sum(keepIndx))
            keepIndx*= (rangeIndx < nmock-nout)
        out['RC_DIST_H'][nout:nout+numpy.sum(keepIndx)]= newds[keepIndx]
        out['RC_DM_H'][nout:nout+numpy.sum(keepIndx)]= newds_coord[keepIndx]*(numpy.amax(distmods)-numpy.amin(distmods))\
            +numpy.amin(distmods)
        out['RC_GALR_H'][nout:nout+numpy.sum(keepIndx)]= Rphiz[0][keepIndx]
        out['RC_GALPHI_H'][nout:nout+numpy.sum(keepIndx)]= Rphiz[1][keepIndx]
        out['RC_GALZ_H'][nout:nout+numpy.sum(keepIndx)]= Rphiz[2][keepIndx]
        nout= nout+numpy.sum(keepIndx)
    return (out,lnprobs)
示例#5
0
def generate(locations,
             type='exp',
             sample='lowlow',
             extmap='green15',
             nls=101,
             nmock=1000,
             H0=-1.49,
             _dmapg15=None,
             ncpu=1):
    """
    NAME:
       generate
    PURPOSE:
       generate mock data following a given density
    INPUT:
       locations - locations to be included in the sample
       type= ('exp') type of density profile to sample from
       sample= ('lowlow') for selecting mock parameters
       extmap= ('green15') extinction map to use ('marshall06' and others use Green15 to fill in unobserved regions)
       nls= (101) number of longitude bins to use for each field
       nmock= (1000) number of mock data points to generate
       H0= (-1.49) absolute magnitude (can be array w/ sampling spread)
       ncpu= (1) number of cpus to use to compute the probability
    OUTPUT:
       mockdata recarray with tags 'RC_GALR_H', 'RC_GALPHI_H', 'RC_GALZ_H'
    HISTORY:
       2015-04-03 - Written - Bovy (IAS)
    """
    if isinstance(H0, float): H0 = [H0]
    # Setup the density function and its initial parameters
    rdensfunc = fitDens._setup_densfunc(type)
    mockparams = _setup_mockparams_densfunc(type, sample)
    densfunc = lambda x, y, z: rdensfunc(x, y, z, params=mockparams)
    # Setup the extinction map
    global dmap
    global dmapg15
    if _dmapg15 is None: dmapg15 = mwdust.Green15(filter='2MASS H')
    else: dmapg15 = _dmapg15
    if isinstance(extmap, mwdust.DustMap3D.DustMap3D):
        dmap = extmap
    elif extmap.lower() == 'green15':
        dmap = dmapg15
    elif extmap.lower() == 'marshall06':
        dmap = mwdust.Marshall06(filter='2MASS H')
    elif extmap.lower() == 'sale14':
        dmap = mwdust.Sale14(filter='2MASS H')
    elif extmap.lower() == 'drimmel03':
        dmap = mwdust.Drimmel03(filter='2MASS H')
    # Use brute-force rejection sampling to make no approximations
    # First need to estimate the max probability to use in rejection;
    # Loop through all locations and compute sampling probability on grid in
    # (l,b,D)
    # First restore the APOGEE selection function (assumed pre-computed)
    global apo
    selectFile = '../savs/selfunc-nospdata.sav'
    if os.path.exists(selectFile):
        with open(selectFile, 'rb') as savefile:
            apo = pickle.load(savefile)
    # Now compute the necessary coordinate transformations and evaluate the
    # maximum probability
    distmods = numpy.linspace(7., 15.5, 301)
    ds = 10.**(distmods / 5 - 2.)
    nbs = nls
    lnprobs = numpy.empty((len(locations), len(distmods), nbs, nls))
    radii = []
    lcens, bcens = [], []
    lnprobs = multi.parallel_map(lambda x: _calc_lnprob(
        locations[x], nls, nbs, ds, distmods, H0, densfunc),
                                 range(len(locations)),
                                 numcores=numpy.amin([
                                     len(locations),
                                     multiprocessing.cpu_count(), ncpu
                                 ]))
    lnprobs = numpy.array(lnprobs)
    for ll, loc in enumerate(locations):
        lcen, bcen = apo.glonGlat(loc)
        rad = apo.radius(loc)
        radii.append(rad)  # save for later
        lcens.append(lcen[0])
        bcens.append(bcen[0])
    maxp = (numpy.exp(numpy.nanmax(lnprobs)) -
            10.**-8.) * 1.1  # Just to be sure
    # Now generate mock data using rejection sampling
    nout = 0
    arlocations = numpy.array(locations)
    arradii = numpy.array(radii)
    arlcens = numpy.array(lcens)
    arbcens = numpy.array(bcens)
    out = numpy.recarray((nmock, ),
                         dtype=[('RC_DIST_H', 'f8'), ('RC_DM_H', 'f8'),
                                ('RC_GALR_H', 'f8'), ('RC_GALPHI_H', 'f8'),
                                ('RC_GALZ_H', 'f8')])
    while nout < nmock:
        nnew = 2 * (nmock - nout)
        # nnew new locations
        locIndx = numpy.floor(
            numpy.random.uniform(size=nnew) * len(locations)).astype('int')
        newlocations = arlocations[locIndx]
        # Point within these locations
        newds_coord = numpy.random.uniform(size=nnew)
        newds= 10.**((newds_coord*(numpy.amax(distmods)-numpy.amin(distmods))\
            +numpy.amin(distmods))/5.-2.)
        newdls_coord = numpy.random.uniform(size=nnew)
        newdls= newdls_coord*2.*arradii[locIndx]\
            -arradii[locIndx]
        newdbs_coord = numpy.random.uniform(size=nnew)
        newdbs= newdbs_coord*2.*arradii[locIndx]\
            -arradii[locIndx]
        newr2s = newdls**2. + newdbs**2.
        keepIndx = newr2s < arradii[locIndx]**2.
        newlocations = newlocations[keepIndx]
        newds_coord = newds_coord[keepIndx]
        newdls_coord = newdls_coord[keepIndx]
        newdbs_coord = newdbs_coord[keepIndx]
        newds = newds[keepIndx]
        newdls = newdls[keepIndx]
        newdbs = newdbs[keepIndx]
        newls = newdls + arlcens[locIndx][keepIndx]
        newbs = newdbs + arbcens[locIndx][keepIndx]
        # Reject?
        tps = numpy.zeros_like(newds)
        for nloc in list(set(newlocations)):
            lindx = newlocations == nloc
            pindx = arlocations == nloc
            coord = numpy.array([
                newds_coord[lindx] * (len(distmods) - 1.),
                newdbs_coord[lindx] * (nbs - 1.),
                newdls_coord[lindx] * (nls - 1.)
            ])
            tps[lindx]= \
                numpy.exp(ndimage.interpolation.map_coordinates(\
                    lnprobs[pindx][0],
                    coord,cval=-10.,
                    order=1))-10.**-8.
        XYZ = bovy_coords.lbd_to_XYZ(newls, newbs, newds, degree=True)
        Rphiz = bovy_coords.XYZ_to_galcencyl(XYZ[:, 0],
                                             XYZ[:, 1],
                                             XYZ[:, 2],
                                             Xsun=define_rcsample._R0,
                                             Ysun=0.,
                                             Zsun=define_rcsample._Z0)
        testp = numpy.random.uniform(size=len(newds)) * maxp
        keepIndx = tps > testp
        if numpy.sum(keepIndx) > nmock - nout:
            rangeIndx = numpy.zeros(len(keepIndx), dtype='int')
            rangeIndx[keepIndx] = numpy.arange(numpy.sum(keepIndx))
            keepIndx *= (rangeIndx < nmock - nout)
        out['RC_DIST_H'][nout:nout + numpy.sum(keepIndx)] = newds[keepIndx]
        out['RC_DM_H'][nout:nout+numpy.sum(keepIndx)]= newds_coord[keepIndx]*(numpy.amax(distmods)-numpy.amin(distmods))\
            +numpy.amin(distmods)
        out['RC_GALR_H'][nout:nout + numpy.sum(keepIndx)] = Rphiz[0][keepIndx]
        out['RC_GALPHI_H'][nout:nout +
                           numpy.sum(keepIndx)] = Rphiz[1][keepIndx]
        out['RC_GALZ_H'][nout:nout + numpy.sum(keepIndx)] = Rphiz[2][keepIndx]
        nout = nout + numpy.sum(keepIndx)
    return (out, lnprobs)