Ejemplo n.º 1
0
def disc_mock(gp):
    global K,C,D,F, zth, zp_kz, zmin, zmax, z0, z02
    # Set up simple population here using analytic formulae:
    zmin = 100.                               # [pc], first bin center
    zmax = 1300.                              # [pc], last bin center
    # get Stuetzpunkte for theoretical profiles (not yet stars, finer spacing in real space)
    nth = 3*gp.nipol
    zth = 1.* np.arange(nth) * (zmax-zmin)/(nth-1.) + zmin
    z0  = 240.                                # [pc], scaleheight of first population
    z02 = 200.                                # [pc], scaleheight of second population
    D   = 250.                                # [pc], scaleheight of all stellar tracers
    K   = 1.65
    F   = 1.65e-4
    C   = 17.**2.                             # [km/s] integration constant in sig

    # Draw mock data:
    nu_zth = np.exp(-zth/z0)                                 # [1]
    Kz_zth = -(K*zth/np.sqrt(zth**2.+D**2.) + 2.0 * F * zth)

    if gp.adddarkdisc:
        DD = 600                                         # [pc]
        KD = 0.15 * 1.650
        Kz_zth = Kz_zth - KD*zth/np.sqrt(zth**2. + DD**2.)

    # calculate sig_z^2
    inti = np.zeros(nth)
    for i in range(1, nth):
        inti[i] = simps(Kz_zth[:i]*nu_zth[:i], zth[:i])

    sigzth = np.sqrt((inti + C) / nu_zth)

    # project back to positions of stars
    ran = npr.uniform(size=int(gp.ntracer[1-1]))                 # [1]
    zstar = -z0 * np.log(1.0 - ran)           # [pc] stellar positions
    sigzstar = gh.ipol(zth, sigzth, zstar)
    # > 0 ((IDL, Justin)) stellar velocity dispersion

    # assign [0,1] * maxsig
    ran2 = npr.normal(size=int(gp.ntracer[1-1]))  # [1]
    vzstar = ran2 * sigzstar                      # [km/s]

    # Add second population [thick-disc like]:
    if gp.pops == 2:
        nu_zth2 = gp.ntracer[2-1]/gp.ntracer[1-1]*np.exp(-zth/z02)
        # no normalization to 1
        inti    = np.zeros(nth)
        for i in range(1, nth):
            inti[i] = simps(Kz_zth[:i]*nu_zth2[:i], zth[:i])
        sigzth2 = np.sqrt((inti + C) / nu_zth2) # same integration constant
        ran = npr.uniform(-1., 1., gp.ntracer[2-1])            # [1]
        zstar2 = -z02 * np.log(1.0 - ran)                      # [pc]
        zstarobs = np.hstack([zstar, zstar2]) # concat pop1, pop2 for all stars
        sigzstar2 = gh.ipol(zth, sigzth2, zstar2)
        ran2 = npr.normal(-1., 1, gp.ntracer[2-1])        # [1]
        vzstar2 = ran2 * sigzstar2                        # [(km/2)^2]

    # enforce observational cut on zmax:
    sel = (zstar < zmax)
    print('fraction of z<zmax selected elements: ', 1.*sum(sel)/(1.*len(sel)))
    z_dat  = zstar[sel]
    vz_dat = vzstar[sel]

    # throw away velocities of value zero (unstable?):
    sel = (abs(vz_dat) > 0)
    print('fraction of vz_dat>0 selected elements: ', 1.*sum(sel)/(1.*len(sel)))
    z_dat  = z_dat[sel]
    vz_dat = vz_dat[sel]

    # Calulate binned data (for plots/binned anal.). old way, linear spacings, no const #particles/bin
    binmin, binmax, z_dat_bin, sig_dat_bin, count_bin = gh.binsmooth(z_dat, vz_dat, \
                                                                     zmin, zmax, gp.nipol, 0.)
    sig_dat_err_bin = sig_dat_bin / np.sqrt(count_bin)

    nu_dat_bin, count_bin = gh.bincount(z_dat, binmax)
    nu_dat_err_bin = nu_dat_bin / np.sqrt(count_bin)
    renorm = max(nu_dat_bin)
    nu_dat_bin = nu_dat_bin / renorm
    nu_dat_err_bin = nu_dat_err_bin / renorm

    # if only 1 pop, use 0 for all components
    binmin0 = binmin; binmax0 = binmax; z_dat_bin0 = z_dat_bin
    sig_dat_bin0 = sig_dat_bin; sig_dat_err_bin0 = sig_dat_err_bin
    nu_dat_bin0  = nu_dat_bin;  nu_dat_err_bin0  = nu_dat_err_bin

    if gp.pops == 2:
        # enforce observational constraint on z<z_max
        sel = (zstar2 < zmax)
        z_dat2  = zstar2[sel]
        vz_dat2 = vzstar2[sel]

        # cut zero velocities:
        sel = (abs(vz_dat2) > 0)
        z_dat2  = z_dat2[sel]
        vz_dat2 = vz_dat2[sel]

        # Calulate binned data (for plots/binned analysis):
        binmin2, binmax2, z_dat_bin2, sig_dat_bin2, count_bin2 = gh.binsmooth(z_dat2, vz_dat2, \
                                                                              zmin, zmax, gp.nipol, 0.)
        sig_dat_err_bin2 = sig_dat_bin2 / np.sqrt(count_bin2)

        nu_dat_bin2, count_bin2 = gh.bincount(z_dat2, binmax2)
        nu_dat_err_bin2 = nu_dat_bin2 / np.sqrt(count_bin2)
        renorm2 = max(nu_dat_bin2) # normalize by max density of first bin, rather
        nu_dat_bin2 = nu_dat_bin2 / renorm2
        nu_dat_err_bin2 = nu_dat_err_bin2 / renorm2

        # CALCULATE PROPERTIES FOR ALL POP TOGETHER
        z_dat0 = np.hstack([z_dat, z_dat2])
        vz_dat0 = np.hstack([vz_dat, vz_dat2])

        # Calulate binned data (for plots/binned anal.). old way, linear spacings, no const #particles/bin
        binmin0, binmax0, z_dat_bin0, sig_dat_bin0, count_bin0 = gh.binsmooth(z_dat0, vz_dat0, \
                                                                              zmin, zmax, gp.nipol, 0.)
        sig_dat_err_bin0 = sig_dat_bin0 / np.sqrt(count_bin0)
        # binmin, binmax, z_dat_bin = gh.bin_r_const_tracers(z_dat, gp.nipol)
        nu_dat_bin0, count_bin0 = gh.bincount(z_dat0, binmax0)
        nu_dat_err_bin0 = nu_dat_bin0 / np.sqrt(count_bin0)
        renorm0 = max(nu_dat_bin0)
        nu_dat_bin0 = nu_dat_bin0 / renorm0
        nu_dat_err_bin0 = nu_dat_err_bin0 / renorm0


    xip = np.copy(z_dat_bin0)                        # [pc]
    gp.dat.binmin = binmin0
    gp.dat.rbin   = xip
    gp.xipol      = gp.dat.rbin
    gp.Rscale.append(D)  # [pc]
    gp.Rscale.append(z0) # [pc]
    maxr          = max(gp.dat.rbin)
    gp.xepol      = np.hstack([gp.dat.rbin, 2*maxr, 4*maxr, 8*maxr])
    gp.dat.binmax = binmax0
    gp.dat.Mrdat   = K*xip/np.sqrt(xip**2.+D**2.) / (2.0*np.pi*gu.G1__pcMsun_1km2s_2)
    gp.dat.Mrerr   = gp.dat.Mrdat*nu_dat_err_bin/nu_dat_bin

    gp.dat.nu.append(nu_dat_bin0)        # [Msun/pc^3], normalized to 1 at center
    gp.dat.nuerr.append(nu_dat_err_bin0) # [Msun/pc^3], normalized

    gp.dat.sig.append(sig_dat_bin0)       # [km/s]
    gp.dat.sigerr.append(sig_dat_err_bin0)# [km/s]

    gp.dat.nu.append(nu_dat_bin)         # [Msun/pc^3], normalized to 1
    gp.dat.nuerr.append(nu_dat_err_bin)  # [Msun/pc^3], normalized

    gp.dat.sig.append(sig_dat_bin)        # [km/s]
    gp.dat.sigerr.append(sig_dat_err_bin) # [km/s]

    if gp.pops == 2:
        gp.Rscale.append(z02)                 # [pc]
        gp.dat.nu.append(nu_dat_bin2)        # [Msun/pc^3], normalized to 1
        gp.dat.nuerr.append(nu_dat_err_bin2) # [Msun/pc^3], normalized

        gp.dat.sig.append(sig_dat_bin2)       # [km/s]
        gp.dat.sigerr.append(sig_dat_err_bin2)# [km/s]
    return gp.dat
Ejemplo n.º 2
0
def run(gp):
    global K, C, D, F, zth, zp_kz, zmin, zmax, z0, z02
    # Set up simple population here using analytic formulae:
    zmin = 100.0  # [pc], first bin center
    zmax = 1300.0  # [pc], last bin center
    # get Stuetzpunkte for theoretical profiles (not yet stars, finer spacing in real space)
    nth = gp.nipol  # [1] number of bins

    zth = 1.0 * np.arange(nth) * (zmax - zmin) / (nth - 1.0) + zmin  # [pc] bin centers

    z0 = 240.0  # [pc], scaleheight of first population
    z02 = 200.0  # [pc], scaleheight of second population
    D = 250.0  # [pc], scaleheight of all stellar tracers
    K = 1.65
    F = 1.65e-4
    C = 17.0 ** 2.0  # [km/s] integration constant in sig

    # Draw mock data from exponential disk:
    nu_zth = np.exp(-zth / z0)  # [nu0] = [Msun/A/pc] 3D tracer density
    Kz_zth = -(K * zth / np.sqrt(zth ** 2.0 + D ** 2.0) + 2.0 * F * zth)

    if gp.adddarkdisc:
        DD = 600  # [pc] scaleheight of dark disc
        KD = 0.15 * 1.650
        Kz_zth = Kz_zth - KD * zth / np.sqrt(zth ** 2.0 + DD ** 2.0)

    # calculate sig_z^2
    inti = np.zeros(nth)
    for i in range(1, nth):
        inti[i] = simps(Kz_zth[:i] * nu_zth[:i], zth[:i])

    sigzth = np.sqrt((inti + C) / nu_zth)

    # project back to positions of stars
    ran = npr.uniform(size=int(gp.ntracer[1 - 1]))  # [1]
    zstar = -z0 * np.log(1.0 - ran)  # [pc] stellar positions, exponential falloff

    sigzstar = gh.ipol(zth, sigzth, zstar)
    # > 0 ((IDL, Justin)) stellar velocity dispersion

    # assign [0,1] * maxsig
    ran2 = npr.normal(size=int(gp.ntracer[1 - 1]))  # [1]
    vzstar = ran2 * sigzstar  # [km/s]

    # Add second population [thick-disc like]:
    if gp.pops == 2:
        nu_zth2 = gp.ntracer[2 - 1] / gp.ntracer[1 - 1] * np.exp(-zth / z02)
        # [nu0,2] = [Msun/A/pc], 3D tracer density, exponentially falling
        # no normalization to 1 done here
        inti = np.zeros(nth)
        for i in range(1, nth):
            inti[i] = simps(Kz_zth[:i] * nu_zth2[:i], zth[:i])
        sigzth2 = np.sqrt((inti + C) / nu_zth2)  # same integration constant
        ran = npr.uniform(-1.0, 1.0, gp.ntracer[2 - 1])  # [1]
        zstar2 = -z02 * np.log(1.0 - ran)  # [pc]
        # zstarobs = np.hstack([zstar, zstar2]) # concat pop1, pop2 for all stars
        sigzstar2 = gh.ipol(zth, sigzth2, zstar2)
        ran2 = npr.normal(-1.0, 1, gp.ntracer[2 - 1])  # [1]
        vzstar2 = ran2 * sigzstar2  # [(km/2)^2]

    # enforce observational cut on zmax:
    sel = zstar < zmax
    print("fraction of z<zmax selected elements: ", 1.0 * sum(sel) / (1.0 * len(sel)))
    z_dat1 = zstar[sel]
    vz_dat1 = vzstar[sel]

    # throw away velocities of value zero (unstable?):
    sel = abs(vz_dat1) > 0
    print("fraction of vz_dat>0 selected elements: ", 1.0 * sum(sel) / (1.0 * len(sel)))
    z_dat1 = z_dat1[sel]
    vz_dat1 = vz_dat1[sel]

    # Calulate binned data (for plots/binned anal.). old way, linear spacings, no const #particles/bin
    binmin1, binmax1, z_dat_bin1, sig_dat_bin1, count_bin1 = gh.binsmooth(z_dat1, vz_dat1, zmin, zmax, gp.nipol, 0.0)
    sig_dat_err_bin1 = np.sqrt(sig_dat_bin1)  # Poisson errors

    nu_dat_bin1, nu_dat_err_bin1 = gh.bincount(z_dat1, binmax1)
    nu_dat_bin1 /= binmax1 - binmin1
    nu_dat_err_bin1 /= binmax1 - binmin1

    import gr_params

    gpr = gr_params.grParams(gp)
    if gpr.showplots:
        nuscaleb = nu_zth[np.argmin(np.abs(zth - z0))]
        plt.loglog(zth, nu_zth / nuscaleb, "b.-")
        nuscaler = nu_dat_bin1[np.argmin(np.abs(zth - z0))]
        plt.loglog(zth, nu_dat_bin1 / nuscaler, "r.-")
        # pdb.set_trace()

    Sig_dat_bin1 = np.cumsum(nu_dat_bin1)
    Sig_dat_err_bin1 = np.sqrt(Sig_dat_bin1)
    Mrdat1 = np.cumsum(Sig_dat_bin1)
    Mrerr1 = Mrdat1 * Sig_dat_err_bin1 / Sig_dat_bin1

    scales = [[], [], []]
    scales[1].append(z0)  # [pc]
    scales[1].append(Sig_dat_bin1[0])
    scales[1].append(Mrdat1[-1])
    scales[1].append(nu_dat_bin1[0])
    scales[1].append(max(sig_dat_bin1))

    # start analysis of "all stars" with only component 1,
    # append to it later if more populations required
    z_dat0 = z_dat1  # [pc]
    vz_dat0 = vz_dat1  # [km/s]

    if gp.pops == 2:
        # enforce observational constraints on z<z_max
        sel = zstar2 < zmax
        z_dat2 = zstar2[sel]
        vz_dat2 = vzstar2[sel]

        # cut zero velocities:
        sel = abs(vz_dat2) > 0
        z_dat2 = z_dat2[sel]
        vz_dat2 = vz_dat2[sel]

        # Calulate binned data (for plots/binned analysis):
        binmin2, binmax2, z_dat_bin2, sig_dat_bin2, count_bin2 = gh.binsmooth(
            z_dat2, vz_dat2, zmin, zmax, gp.nipol, 0.0
        )
        sig_dat_err_bin2 = np.sqrt(sig_dat_bin2)  # Poissonian errors

        nu_dat_bin2, nu_dat_err_bin2 = gh.bincount(z_dat2, binmax2)
        nu_dat_bin2 /= binmax2 - binmin2
        nu_dat_err_bin2 /= binmax2 - binmin2

        Sig_dat_bin2 = np.cumsum(nu_dat_bin2)
        Sig_dat_err_bin2 = np.sqrt(Sig_dat_bin2)
        Mrdat2 = np.cumsum(nu_dat_bin2)
        Mrerr2 = np.sqrt(Mrdat2)

        scales[2].append(z02)  # [pc]
        scales[2].append(Sig_dat_bin2[0])
        scales[2].append(Mrdat2[-1])
        scales[2].append(nu_dat_bin2[0])  # normalize by max density of first bin, rather
        scales[2].append(max(sig_dat_bin2))

        # calculate properties for all pop together with stacked values
        z_dat0 = np.hstack([z_dat1, z_dat2])
        vz_dat0 = np.hstack([vz_dat1, vz_dat2])

    # Calulate binned data (for plots/binned anal.). old way, linear spacings, no const #particles/bin
    binmin0, binmax0, z_dat_bin0, sig_dat_bin0, count_bin0 = gh.binsmooth(z_dat0, vz_dat0, zmin, zmax, gp.nipol, 0.0)
    sig_dat_err_bin0 = np.sqrt(sig_dat_bin0)
    # binmin, binmax, z_dat_bin = gh.bin_r_const_tracers(z_dat, gp.nipol)

    nu_dat_bin0, nu_dat_err_bin0 = gh.bincount(z_dat0, binmax0)
    nu_dat_bin0 /= binmax0 - binmin0
    nu_dat_err_bin0 /= binmax0 - binmin0

    Sig_dat_bin0 = np.cumsum(nu_dat_bin0)
    Sig_dat_err_bin0 = np.sqrt(Sig_dat_bin0)
    # renorm0 = max(nu_dat_bin0)

    xip = np.copy(z_dat_bin0)  # [pc]
    Mrdat0 = K * xip / np.sqrt(xip ** 2.0 + D ** 2.0) / (2.0 * np.pi * gu.G1__pcMsun_1km2s_2)
    Mrerr0 = Mrdat0 * nu_dat_err_bin0 / nu_dat_bin0

    scales[0].append(D)  # [pc]
    scales[0].append(Sig_dat_bin0[0])
    scales[0].append(Mrdat0[-1])
    scales[0].append(nu_dat_bin0[0])
    scales[0].append(max(sig_dat_bin0))

    rmin = binmin0 / scales[0][0]  # [pc]
    rbin = xip / scales[0][0]  # [pc]
    rmax = binmax0 / scales[0][0]  # [pc]

    # store parameters for output
    # normalized by scale values
    nudat = []
    nudat.append(nu_dat_bin0 / scales[0][3])  # [Msun/pc^3]
    nudat.append(nu_dat_bin1 / scales[1][3])
    if gp.pops == 2:
        nudat.append(nu_dat_bin2 / scales[2][3])

    nuerr = []
    nuerr.append(nu_dat_err_bin0 / scales[0][3])  # [Msun/pc^3]
    nuerr.append(nu_dat_err_bin1 / scales[1][3])
    if gp.pops == 2:
        nuerr.append(nu_dat_err_bin2 / scales[2][3])

    Mrdat = []
    Mrdat.append(Mrdat0 / scales[0][2])  # [Msun]
    Mrdat.append(Mrdat1 / scales[1][2])
    if gp.pops == 2:
        Mrdat.append(Mrdat2 / scales[2][2])

    Mrerr = []
    Mrerr.append(Mrerr0 / scales[0][2])  # [Msun]
    Mrerr.append(Mrerr1 / scales[1][2])
    if gp.pops == 2:
        Mrerr.append(Mrerr2 / scales[2][2])

    Sigdat = []
    Sigdat.append(Sig_dat_bin0 / scales[0][1])
    Sigdat.append(Sig_dat_bin1 / scales[1][1])
    if gp.pops == 2:
        Sigdat.append(Sig_dat_bin2 / scales[2][1])

    Sigerr = []
    Sigerr.append(Sig_dat_err_bin0 / scales[0][1])
    Sigerr.append(Sig_dat_err_bin1 / scales[1][1])
    if gp.pops == 2:
        Sigerr.append(Sig_dat_err_bin2 / scales[2][1])

    sigdat = []
    sigdat.append(sig_dat_bin0 / scales[0][4])  # [km/s]
    sigdat.append(sig_dat_bin1 / scales[1][4])
    if gp.pops == 2:
        sigdat.append(sig_dat_bin2 / scales[2][4])

    sigerr = []
    sigerr.append(sig_dat_err_bin0 / scales[0][4])  # [km/s]
    sigerr.append(sig_dat_err_bin1 / scales[1][4])
    if gp.pops == 2:
        sigerr.append(sig_dat_err_bin2 / scales[2][4])
    write_disc_output_files(rbin, rmin, rmax, nudat, nuerr, Sigdat, Sigerr, Mrdat, Mrerr, sigdat, sigerr, scales, gp)

    return gp.dat