예제 #1
0
def test_plot_schechter():

    phiStar = 1.8e-3
    MStar = -20.04
    alpha = -1.71

    LStar = magnitudes.L_nu_from_magAB(MStar)

    mags = numpy.arange(-22, -11.0, 0.5)
    lums = magnitudes.L_nu_from_magAB(mags)

    phi_L = schechterL(lums, phiStar, alpha, LStar)
    phi_M = schechterM(mags, phiStar, alpha, MStar)

    L_L = schechterCumuLL(lums, phiStar, alpha, LStar)
    L_M = schechterCumuLM(mags, phiStar, alpha, MStar)

    phi_L_func = lambda l: l * schechterL(l, phiStar, alpha, LStar)
    L_L_num = utils.logquad(phi_L_func, lums, 1e35)[0]
    L_L_num2 = utils.vecquad(phi_L_func, lums, 1e29)[0]

    phi_M_func = lambda m: (magnitudes.L_nu_from_magAB(m) * schechterM(
        m, phiStar, alpha, MStar))
    L_M_num2 = utils.vecquad(phi_M_func, -25, mags)[0]

    Ltot_L = schechterTotLL(phiStar, alpha, LStar)
    Ltot_M = schechterTotLM(phiStar, alpha, MStar)

    pylab.figure()
    pylab.subplot(221)
    pylab.plot(lums, lums * lums * phi_L)
    pylab.xscale('log')
    pylab.yscale('log')
    pylab.ylabel(r'$ L^2 \Phi_L$')

    pylab.subplot(222)
    pylab.plot(mags, -mags * lums * phi_M)
    pylab.yscale('log')
    pylab.ylabel(r'$ -M L \Phi_M$')

    pylab.subplot(223)
    pylab.plot(lums, Ltot_L - L_L)
    pylab.plot(lums, L_M)
    pylab.plot(lums, L_L_num, '--')
    pylab.plot(lums, L_L_num2, ':')
    pylab.plot(lums, L_M_num2, 'x')
    pylab.axhline(y=Ltot_L)
    pylab.axhline(y=Ltot_M)
    pylab.xscale('log')
    pylab.yscale('log')

    pylab.subplot(224)
    pylab.plot(mags, Ltot_M - L_M)
    pylab.plot(mags, L_L)
    pylab.plot(mags, L_L_num, '--')
    pylab.plot(mags, L_L_num2, ':')
    pylab.plot(mags, L_M_num2, 'x')
    pylab.axhline(y=Ltot_L)
    pylab.axhline(y=Ltot_M)
    pylab.yscale('log')
예제 #2
0
def schechterCumuLM(magnitudeAB, phiStar, alpha, MStar):
    """Integrate luminosity in galaxies brighter than magnitudeAB.

    Uses an analytical formula.
    """
    LStar = magnitudes.L_nu_from_magAB(MStar)
    lum = magnitudes.L_nu_from_magAB(magnitudeAB)
    return schechterCumuLL(lum, phiStar, alpha, LStar)
예제 #3
0
def schechterTotLM(phiStar, alpha, MStar):
    """Integrate total luminosity in galaxies.

    Uses an analytical formula.
    """
    LStar = magnitudes.L_nu_from_magAB(MStar)
    return schechterTotLL(phiStar, alpha, LStar)
예제 #4
0
def test_sfr():
    """Check that M = -18 -> SFR ~ 1 Msun/yr.

    From Oesch et al (2009 ApJ 690 1350).
    """

    mag = -18
    lum = magnitudes.L_nu_from_magAB(mag)
    sfr = luminosityfunction.sfr_from_L_nu(lum)

    print("M = %.3g -> L_nu = %.3g erg/s/Hz -> SFR = %.3g Msun/yr" %
          (mag, lum, sfr))
    assert numpy.round(sfr) == 1
def test_sfrd():
    """ Check conversion of Lmin -> SFRD.

    At z=7:
    Lmin = 0.2 L*z=6 -> Mmin=-18.5 -> log(rho/erg/s/Hz/Mpc^3)=25.5 ->
    SFRD = 10^-2.32 Msun/yr^-1/Mpc^-3.

    From Oesch et al (2009 ApJ 690 1350).
    """

    cosmo = cparam.WMAP7_BAO_H0_mean(flat=True)


#     # From Bouwens 2008ApJ...686..230B
#     lfhist = luminosityfunction.LFHistory(params=luminosityfunction.B2008,
#                                           **cosmo)
    
#     mStarz6 = lfhist.params_z(6.0)['MStar']

    alpha = -1.74
    mStarz6 = -20.24
    mStarz7 = -19.7
    phiStar = 1.4e-3
    
    lStarz6 = magnitudes.L_nu_from_magAB(mStarz6)
    lmin = 0.2 * lStarz6
    magmin = magnitudes.magnitude_AB_from_L_nu(lmin)
    ltot = luminosityfunction.schechterCumuLM(magnitudeAB=magmin,
                                              MStar=mStarz7,
                                              phiStar=phiStar,
                                              alpha=alpha)
    sfrd = luminosityfunction.sfr_from_L_nu(ltot)

    print """Lmin = 0.2 L*z=6 -> Lmin/erg/s/Hz = %.3g -> Mmin = %.3g ->
    log(rho/(erg/s/Hz/Mpc^3)) = %.3g -> log(SFRD/(MSun/yr)) = %.3g"""\
    % (lmin, magmin, numpy.log10(ltot), numpy.log10(sfrd))

    ltotz6 = luminosityfunction.schechterCumuLM(magnitudeAB=magmin,
                                                MStar=mStarz6,
                                                phiStar=phiStar,
                                                alpha=alpha)

    print "luminosity density increase from z=7 to z=6 is %.2g percent." \
          % (100 * (1. - ltot/ltotz6))


    assert numpy.abs(numpy.round(1. - ltot/ltotz6, 1) - 0.5) < 0.1
    assert numpy.round(magmin, 1) == -18.5
    assert numpy.abs(numpy.round(numpy.log10(ltot), 1) - 25.5) < 0.2
    assert numpy.abs(numpy.round(numpy.log10(sfrd), 1) - -2.32) < 0.05
예제 #6
0
def find_galaxy_list(map_path,
                     airmass_threshold=airmass_thresholdp,
                     completeness=completenessp,
                     credzone=0.99):
    #loading the map:
    try:
        skymap = hp.read_map(map_path, field=None, verbose=False)
    except Exception as e:
        from smtplib import SMTP
        msg = '''Subject: Failed to Read LVC Sky Map
From: Super N. Ova <*****@*****.**>
To: [email protected]

FITS file: {}
Exception: {}'''.format(map_path, e)
        s = SMTP('localhost')
        s.sendmail('*****@*****.**', ['*****@*****.**'], msg)
        s.quit()
        print 'Failed to read sky map. Sending email.'
        return

    if isinstance(skymap, tuple) and len(skymap) == 4:
        prob, distmu, distsigma, distnorm = skymap
    else:
        print 'No distance information available. Cannot produce galaxy list.'
        return

    #loading the galaxy catalog. this one contains only RA, DEC, distance, Bmag
    galax = np.load("glade_RA_DEC.npy")

    #map parameters:
    npix = len(prob)
    nside = hp.npix2nside(npix)

    #galaxy parameters(RA, DEC to theta, phi):
    galax = (galax[np.where(galax[:, 2] > 0), :])[0]  #no distance<0

    theta = 0.5 * np.pi - np.pi * (galax[:, 1]) / 180
    phi = np.deg2rad(galax[:, 0])
    d = np.array(galax[:, 2])

    #converting galaxy coordinates to map pixels:
    ipix = hp.ang2pix(nside, theta, phi)

    maxprobcoord_tup = hp.pix2ang(nside, np.argmax(prob))
    maxprobcoord = [0, 0]
    maxprobcoord[0] = np.rad2deg(0.5 * np.pi - maxprobcoord_tup[0])
    maxprobcoord[1] = np.rad2deg(maxprobcoord_tup[1])

    #finding given percent probability zone(default is 99%):

    probcutoff = 1
    probsum = 0
    npix99 = 0

    sortedprob = np.sort(prob)
    while probsum < credzone:
        probsum = probsum + sortedprob[-1]
        probcutoff = sortedprob[-1]
        sortedprob = sortedprob[:-1]
        npix99 = npix99 + 1

    area = npix99 * hp.nside2pixarea(nside, degrees=True)

    ####################################################

    #calculating probability for galaxies by the localization map:
    p = prob[ipix]
    distp = (
        norm(distmu[ipix], distsigma[ipix]).pdf(d) * distnorm[ipix]
    )  # * d**2)#/(norm(distmu[ipix], distsigma[ipix]).pdf(distmu[ipix]) * distnorm[ipix] * distmu[ipix]**2)

    #cuttoffs- 99% of probability by angles and 3sigma by distance:
    inddistance = np.where(
        np.abs(d - distmu[ipix]) < nsigmas_in_d * distsigma[ipix])
    indcredzone = np.where(p >= probcutoff)

    doMassCuttoff = True

    #if no galaxies
    if (galax[np.intersect1d(indcredzone, inddistance)]).size == 0:
        while probsum < 0.99995:
            if sortedprob.size == 0:
                break
            probsum = probsum + sortedprob[-1]
            probcutoff = sortedprob[-1]
            sortedprob = sortedprob[:-1]
            npix99 = npix99 + 1
        inddistance = np.where(np.abs(d - distmu[ipix]) < 5 * distsigma[ipix])
        indcredzone = np.where(p >= probcutoff)
        doMassCuttoff = False

    ipix = ipix[np.intersect1d(indcredzone, inddistance)]
    p = p[np.intersect1d(indcredzone, inddistance)]
    p = (p * (distp[np.intersect1d(indcredzone, inddistance)]))  ##d**2?

    galax = galax[np.intersect1d(indcredzone, inddistance)]
    if galax.size == 0:
        print "no galaxies in field"
        print "99.995% of probability is ", npix99 * hp.nside2pixarea(
            nside, degrees=True), "deg^2"
        print "peaking at [RA,DEC](deg) = ", maxprobcoord
        return

    # normalized luminosity to account for mass:
    luminosity = mag.L_nu_from_magAB(galax[:, 3] - 5 * np.log10(galax[:, 2] *
                                                                (10**5)))
    luminosityNorm = luminosity / np.sum(luminosity)
    luminositynormalization = np.sum(luminosity)
    normalization = np.sum(p * luminosityNorm)

    #taking 50% of mass (missingpiece is the area under the schecter function between l=inf and the brightest galaxy in the field.
    #if the brightest galaxy in the field is fainter than the schecter function cutoff- no cutoff is made.
    #while the number of galaxies in the field is smaller than minGalaxies- we allow for fainter galaxies, until we take all of them.

    missingpiece = gammaincc(
        alpha + 2,
        10**(-(min(galax[:, 3] - 5 * np.log10(galax[:, 2] *
                                              (10**5))) - MB_star) / 2.5)
    )  ##no galaxies brighter than this in the field- so don't count that part of the Schechter function

    while doMassCuttoff:
        MB_max = MB_star + 2.5 * np.log10(
            gammaincinv(alpha + 2, completeness + missingpiece))

        if (
                min(galax[:, 3] - 5 * np.log10(galax[:, 2] *
                                               (10**5))) - MB_star
        ) > 0:  #if the brightest galaxy in the field is fainter then cutoff brightness- don't cut by brightness
            MB_max = 100

        brightest = np.where(galax[:, 3] - 5 * np.log10(galax[:, 2] *
                                                        (10**5)) < MB_max)
        # print MB_max
        if len(brightest[0]) < minGalaxies:
            if completeness >= 0.9:  #tried hard enough. just take all of them
                completeness = 1  # just to be consistent.
                doMassCuttoff = False
            else:
                completeness = (completeness + (1. - completeness) / 2)
        else:  #got enough galaxies
            galax = galax[brightest]
            p = p[brightest]
            luminosityNorm = luminosityNorm[brightest]
            doMassCuttoff = False

#accounting for distance
    absolute_sensitivity = sensitivity - 5 * np.log10(galax[:, 2] * (10**5))

    absolute_sensitivity_lum = mag.f_nu_from_magAB(absolute_sensitivity)
    distanceFactor = np.zeros(galax.shape[0])

    distanceFactor[:] = ((maxL - absolute_sensitivity_lum) / (maxL - minL))
    distanceFactor[mindistFactor > (maxL - absolute_sensitivity_lum) /
                   (maxL - minL)] = mindistFactor
    distanceFactor[absolute_sensitivity_lum < minL] = 1
    distanceFactor[absolute_sensitivity > maxL] = mindistFactor

    #sorting glaxies by probability
    ii = np.argsort(p * luminosityNorm * distanceFactor)[::-1]

    ####counting galaxies that constitute 50% of the probability(~0.5*0.98)
    sum = 0
    galaxies50per = 0
    observable50per = 0  #how many of the galaxies in the top 50% of probability are observable.
    sum_seen = 0
    enough = True
    while sum < 0.5:
        if galaxies50per >= len(ii):
            enough = False
            break
        sum = sum + (p[ii[galaxies50per]] *
                     luminosityNorm[ii[galaxies50per]]) / float(normalization)
        sum_seen = sum_seen + (
            p[ii[galaxies50per]] * luminosityNorm[ii[galaxies50per]] *
            distanceFactor[ii[galaxies50per]]) / float(normalization)
        galaxies50per = galaxies50per + 1

    #event stats:
    #
    # Ngalaxies_50percent = number of galaxies consisting 50% of probability (including luminosity but not distance factor)
    # actual_percentage = usually arround 50
    # seen_percentage = if we include the distance factor- how much are the same galaxies worth
    # 99percent_area = area of map in [deg^2] consisting 99% (using only the map from LIGO)
    stats = {
        "Ngalaxies_50percent": galaxies50per,
        "actual_percentage": sum * 100,
        "seen_percentage": sum_seen,
        "99percent_area": area
    }

    #creating sorted galaxy list, containing info. each entry is (RA, DEC, distance(Mpc), Bmag, score, distance factor(between 0-1))
    #score is normalized so that all the galaxies in the field sum to 1 (before luminosity cutoff)
    galaxylist = np.ndarray((galax.shape[0], 6))

    ngalaxtoshow = 500  # SET NO. OF BEST GALAXIES TO USE
    if len(ii) > ngalaxtoshow:
        n = ngalaxtoshow
    else:
        n = len(ii)

    #adding to galaxy table database
    for i in range(ii.shape[0])[:n]:
        ind = ii[i]
        galaxylist[i, :] = [
            galax[ind, 0], galax[ind, 1], galax[ind, 2], galax[ind, 3],
            (p * luminosityNorm / normalization)[ind], distanceFactor[ind]
        ]
        lvc_galaxy_dict = {
            'voeventid':
            '(SELECT MAX(id) from voevent_lvc)',
            'score': (p * luminosityNorm / normalization)[ind],
            'gladeid':
            '(SELECT id from glade WHERE ra0={:f} AND dec0={:f})'.format(
                galax[ind, 0], galax[ind, 1])
        }
        insert_values('lvc_galaxies', lvc_galaxy_dict)

    return galaxylist  #, stats
예제 #7
0
def select_gladegalaxy_accordingto_luminosity(galaxytable,
                                              doMassCuttoff=True,
                                              completeness=0.5,
                                              minGalaxies=100):

    ##if galaxy number less than 500, don't do mass cut
    if len(galaxytable) < 500:
        doMassCuttoff = False

    # schecter function parameters:
    alpha = -1.07
    MB_star = -20.7  # random slide from https://www.astro.umd.edu/~richard/ASTRO620/LumFunction-pp.pdf but not really...?

    from scipy.special import gammaincc
    from scipy.special import gammaincinv
    # normalized luminosity to account for mass:
    luminosity = mag.L_nu_from_magAB(galaxytable['Bmag'] -
                                     5 * np.log10(galaxytable['disMpc'] *
                                                  (10**5)))
    Slum = luminosity / np.sum(luminosity)
    galaxytable.add_column(Column(Slum, name='S_lum'))

    # taking 50% of mass (missingpiece is the area under the schecter function between l=inf and the brightest galaxy in the field.
    # if the brightest galaxy in the field is fainter than the schecter function cutoff- no cutoff is made.
    # while the number of galaxies in the field is smaller than minGalaxies- we allow for fainter galaxies, until we take all of them.

    # no galaxies brighter than this in the field- so don't count that part of the Schechter function
    missingpiece = gammaincc(
        alpha + 2,
        10**(-(min(galaxytable['Bmag'] - 5 * np.log10(galaxytable['disMpc'] *
                                                      (10**5))) - MB_star) /
             2.5))

    while doMassCuttoff:
        MB_max = MB_star + 2.5 * np.log10(
            gammaincinv(alpha + 2, completeness + missingpiece))

        if (min(galaxytable['Bmag'] - 5 * np.log10(galaxytable['disMpc'] *
                                                   (10**5))) - MB_star) > 0:
            # if the brightest galaxy in the field is fainter then cutoff brightness- don't cut by brightness
            MB_max = 100

        brightest = np.where(
            galaxytable['Bmag'] - 5 * np.log10(galaxytable['disMpc'] *
                                               (10**5)) < MB_max)
        print('MB_max: ', MB_max)
        if len(brightest[0]) < minGalaxies:
            if completeness >= 0.9:  # tried hard enough. just take all of them
                completeness = 1  # just to be consistent.
                doMassCuttoff = False
            else:
                completeness = (completeness + (1. - completeness) / 2)
        else:  # got enough galaxies
            galaxytable = galaxytable[brightest]
            doMassCuttoff = False

    print(len(galaxytable), ' galaxies are selected!')
    ##great, we can now return the new result, need redo the normalization if any galaxy was cut
    galaxytable['S_lum'] = galaxytable['S_lum'] / np.sum(galaxytable['S_lum'])
    galaxytable['S_total'] = (
        galaxytable['S_total'] * galaxytable['S_lum']) / np.sum(
            galaxytable['S_total'] * galaxytable['S_lum'])
    indextmp = np.argsort(galaxytable['S_total'])[::-1]
    galaxytable = galaxytable[indextmp]
    return galaxytable
예제 #8
0
def find_galaxy_list(map_path,
                     airmass_threshold=airmass_thresholdp,
                     completeness=completenessp,
                     credzone=0.99):

    #loading the map:
    prob, distmu, distsigma, distnorm = hp.read_map(map_path,
                                                    field=[0, 1, 2, 3],
                                                    verbose=False)

    #loading the galaxy catalog. this one contains only RA, DEC, distance, Bmag
    galax = np.load("glade_RA_DEC.npy")

    #map parameters:
    npix = len(prob)
    nside = hp.npix2nside(npix)

    #galaxy parameters(RA, DEC to theta, phi):
    galax = (galax[np.where(galax[:, 2] > 0), :])[0]  #no distance<0

    theta = 0.5 * np.pi - np.pi * (galax[:, 1]) / 180
    phi = np.deg2rad(galax[:, 0])
    d = np.array(galax[:, 2])

    #converting galaxy coordinates to map pixels:
    ipix = hp.ang2pix(nside, theta, phi)

    #finding given percent probability zone(default is 99%):
    ####################################################

    probcutoff = 1
    probsum = 0

    sortedprob = np.sort(prob)
    while probsum < credzone:
        probsum = probsum + sortedprob[-1]
        probcutoff = sortedprob[-1]
        sortedprob = sortedprob[:-1]

    ####################################################

    #calculating probability for galaxies by the localization map:
    p = prob[ipix]
    distp = (
        norm(distmu[ipix], distsigma[ipix]).pdf(d) * distnorm[ipix]
    )  # * d**2)#/(norm(distmu[ipix], distsigma[ipix]).pdf(distmu[ipix]) * distnorm[ipix] * distmu[ipix]**2)

    #cuttoffs- 99% of probability by angles and 3sigma by distance:
    inddistance = np.where(
        np.abs(d - distmu[ipix]) < nsigmas_in_d * distsigma[ipix])
    indcredzone = np.where(p >= probcutoff)

    galax = galax[np.intersect1d(indcredzone, inddistance)]
    ipix = ipix[np.intersect1d(indcredzone, inddistance)]
    p = p[np.intersect1d(indcredzone, inddistance)]
    p = (p * (distp[np.intersect1d(indcredzone, inddistance)]))  ##d**2?

    # normalized luminosity to account for mass:
    luminosity = mag.L_nu_from_magAB(galax[:, 3] - 5 * np.log10(galax[:, 2] *
                                                                (10**5)))
    luminosityNorm = luminosity / np.sum(luminosity)
    normalization = np.sum(p * luminosityNorm)

    #taking 50% of mass (missingpiece is the area under the schecter function between l=inf and the brightest galaxy in the field.
    #if the brightest galaxy in the field is fainter than the schecter function cutoff- no cutoff is made.
    #while the number of galaxies in the field is smaller than minGalaxies- we allow for fainter galaxies, until we take all of them.

    missingpiece = gammaincc(
        alpha + 2,
        10**(-(min(galax[:, 3] - 5 * np.log10(galax[:, 2] *
                                              (10**5))) - MB_star) / 2.5)
    )  ##no galaxies brighter than this in the field- so don't count that part of the Schechter function

    doMassCuttoff = True
    while doMassCuttoff:
        MB_max = MB_star + 2.5 * np.log10(
            gammaincinv(alpha + 2, completeness + missingpiece))

        if (
                min(galax[:, 3] - 5 * np.log10(galax[:, 2] *
                                               (10**5))) - MB_star
        ) > 0:  #if the brightest galaxy in the field is fainter then cutoff brightness- don't cut by brightness
            MB_max = 100

        brightest = np.where(galax[:, 3] - 5 * np.log10(galax[:, 2] *
                                                        (10**5)) < MB_max)
        # print MB_max
        if len(brightest[0]) < minGalaxies:
            if completeness >= 0.9:  #tried hard enough. just take all of them
                completeness = 1  # just to be consistent.
                doMassCuttoff = False
            else:
                completeness = (completeness + (1. - completeness) / 2)
        else:  #got enough galaxies
            galax = galax[brightest]
            p = p[brightest]
            luminosityNorm = luminosityNorm[brightest]
            doMassCuttoff = False

    #including observation constraints. (uses code in observational_const.py)
    indices = get_observables(galax, airmass_threshold)
    haleakalaObservable = indices['indHal']
    sidingSpringObservable = indices['indSS']

    #sorting glaxies by probability
    ii = np.argsort(p * luminosityNorm)[::-1]

    ####counting galaxies that constitute 50% of the probability(~0.5*0.98)
    sum = 0
    galaxies50per = 0
    observable50per = 0  #how many of the galaxies in the top 50% of probability are observable.
    enough = True
    while sum < 0.5:
        if galaxies50per >= len(ii):
            enough = False
            break
        sum = sum + (p[ii[galaxies50per]] *
                     luminosityNorm[ii[galaxies50per]]) / float(normalization)
        if ii[galaxies50per] in haleakalaObservable or ii[
                galaxies50per] in sidingSpringObservable:
            observable50per = observable50per + 1
        galaxies50per = galaxies50per + 1
    ####

    #creating sorted galaxy list, containing info on #ngalaxtoshow. each entry is (RA, DEC, distance(Mpc), Bmag, score)
    #score is normalized so that all the galaxies in the field sum to 1 (before luminosity cutoff)
    galaxylist = np.ndarray((ngalaxtoshow, 5))

    ###uncomment to include only observable galaxies.
    # i=0
    # n=0
    # while i<ngalaxtoshow and n<galax.shape[0]:
    #     ind = ii[n]
    #     if ind in haleakalaObservable or ind in sidingSpringObservable:
    #         galaxylist[i,:] = [galax[ind, 0], galax[ind, 1], galax[ind,2], galax[ind,3], (p*luminosityNorm/normalization)[ind]]
    #         i = i+1
    #     n = n+1

    for i in range(ngalaxtoshow):
        ind = ii[i]
        galaxylist[i, :] = [
            galax[ind, 0], galax[ind, 1], galax[ind, 2], galax[ind, 3],
            (p * luminosityNorm / normalization)[ind]
        ]

    return galaxylist  #[:i,:]#uncomment to include only observable galaxies.

    ##########################################################################################################


#to call function with commandline:
# print find_galaxy_list(sys.argv[1])