Example #1
0
def test_age():
    """Test integrated age against analytical age."""
    z = numpy.arange(0, 10.0, 0.05)

    cosmo = {}
    cosmo['omega_M_0'] = numpy.array([[0.99],[0.01],[0.3]])
    cosmo['omega_lambda_0'] = 1. - cosmo['omega_M_0']
    cosmo['h'] = 0.7
    cd.set_omega_k_0(cosmo)

    linestyle = ['-', ':', '--']

    gyr = 1e9 * cc.yr_s

    tl = cd.lookback_time(z, **cosmo)
    age = cd.age(z, **cosmo)
    age_ana = cd.age_flat(z, **cosmo)

    pylab.figure(figsize=(6,6))
    for i in range(len(linestyle)):
        pylab.plot(z, (tl/gyr)[i], ls=linestyle[i], color='0.5')
        pylab.plot(z, (age/gyr)[i], ls=linestyle[i], color='r')
        pylab.plot(z, (age_ana/gyr)[i], ls=linestyle[i], color='k')
    pylab.xlabel("redshift z")
    pylab.ylabel(r"age $t_L/$Gyr")

    pylab.figure(figsize=(6,6))
    for i in range(len(linestyle)):
        pylab.plot(z, ((age - age_ana)/age_ana)[i], ls=linestyle[i], 
                   color='k')
        # Make sure errors are small:
        ntest.assert_array_less((numpy.abs((age - age_ana)/age_ana)[i]),
                                3e-13)
    pylab.xlabel("redshift z")
    pylab.ylabel(r"age: (integral - analytical)/analytical")
 def params_z(self, z):
     """Return interp/extrapolated Schechter function parameters."""
     if self.extrap_var == 'z':
         return {'MStar':self._MStarfunc(z),
                 'phiStar':self._phiStarfunc(z),
                 'alpha':self._alphafunc(z)}
     elif self.extrap_var == 't':
         z = numpy.atleast_1d(z)
         t = cd.age(z, **self.cosmo)[0]
         return self.params_t(t)
Example #3
0
 def params_z(self, z):
     """Return interp/extrapolated Schechter function parameters."""
     if self.extrap_var == 'z':
         return {
             'MStar': self._MStarfunc(z),
             'phiStar': self._phiStarfunc(z),
             'alpha': self._alphafunc(z)
         }
     elif self.extrap_var == 't':
         z = numpy.atleast_1d(z)
         t = cd.age(z, **self.cosmo)[0]
         return self.params_t(t)
Example #4
0
def age_t(z, **cosmo):
    z = np.atleast_1d(z)
    if cosmo == {}:
        cosmo_in = {
            'omega_M_0': 0.3,
            'omega_lambda_0': 0.7,
            'omega_k_0': 0.0,
            'h': 0.70
        }
    else:
        cosmo_in = cosmo

    results = cd.age(z, **cosmo_in) / cc.Gyr_s
    return results
Example #5
0
    def get_lookback_time(self, z):
        """Calculates the lookback time to redshift z.

        Uses :func:`cosmolopy.distance.age` and 
        :func:`cosmolopy.distance.lookback_time`, 
        which are based on equation 30 of David Hogg's `Distance 
        measures in cosmology. <https://arxiv.org/abs/astro-ph/9905116>`_
           
        Args:
            z (float): Redshift for which to calculate the lookback time

        Returns:
            (float): Lookback time in years

        """
        sec = cd.age(z, **self.cosmo)
        return sec / cc.yr_s 
Example #6
0
def calculate_age_stars(ro_in=None,
                        dset_in=None,
                        converted=False,
                        time_proper=True):
    """

    Parameters
    ----------
    converted: bool
        if the epoch field is in code unit or converted to some physical unit

    Return
    ------
    starsFormedatUniverseAge:
        age of the universe when the star particle was created in Myr

    """

    if converted:
        raise ValueError(
            "Epoch field should be in code unit for this function to work properly.."
        )

    if (time_proper):
        # switch depends on ramses run setup
        import cosmolopy.distance as cd
        import cosmolopy.constants as cc

        cosmo = {
            'omega_M_0': ro_in.info["omega_m"],
            'omega_lambda_0': ro_in.info["omega_l"],
            'h': ro_in.info["H0"] / 100.
        }
        cosmo = cd.set_omega_k_0(cosmo)

        t_z0 = cd.age(0., **cosmo) / (cc.Gyr_s / 1.e+3)  # Myr
        ram2myr = ro_in.info["unit_time"].express(
            C.Myr) / ro_in.info["aexp"]**2

        starsFormedatUniverseAge = t_z0 + dset_in["epoch"][:] * ram2myr
    else:
        Myr_unit_time = ro_in.info["unit_time"].express(C.Myr)
        starsFormedatUniverseAge = (ro_in.info["time"] -
                                    dset_in["epoch"][:]) * Myr_unit_time

    return starsFormedatUniverseAge
Example #7
0
def test_t_0():
    """Check the age of the universe we get using WMAP cosmologies.

    We only find agreement to 3 sig figs, not the 4 specified in the
    WMAP paper.

    The results of test_age.py show that we're doing the integral
    correctly, so I think the problem is that we're not taking into
    account some of the higher-order effects included in the WMAP
    numbers.

    """

    dz = 0.1
    z = numpy.arange(80., 0. - 1.5 * dz, -1. * dz)

    flat = True
    cosmos = [
        cparam.WMAP7_BAO_H0_mean(flat=True),
        cparam.WMAP7_ML(flat=True),
        cparam.WMAP5_BAO_SN_mean(flat=True),
        cparam.WMAP5_ML(flat=True),
        cparam.WMAP5_mean(flat=True)
    ]

    for cosmo in cosmos:
        age = cd.age(0.0, **cosmo)
        age_flat = cd.age_flat(0.0, **cosmo)
        gyr = 1e9 * cc.yr_s
        age /= gyr
        age_flat /= gyr

        print "integrated age: ",
        print tu.fractional_diff_string(age, cosmo['t_0'], 4)
        ntest.assert_approx_equal(age,
                                  cosmo['t_0'],
                                  significant=3,
                                  err_msg="Integrated age doesn't match WMAP")

        print "analytical age: ",
        print tu.fractional_diff_string(age_flat, cosmo['t_0'], 4)
        ntest.assert_approx_equal(age_flat,
                                  cosmo['t_0'],
                                  significant=3,
                                  err_msg="Analytical age doesn't match WMAP")
Example #8
0
def test_figure6():
    """Plot Hogg fig. 6: The dimensionless lookback time t_L/t_H and age t/t_H.

    The three curves are for the three world models, 

    - Einstein-de Sitter (omega_M, omega_lambda) = (1, 0) [solid]
    
    : Low-density (0.05, 0) [dotted]

    -- High lambda, (0.2, 0.8) [dashed]

    Hubble distance DH = c / H0

    z from 0--5
    t/th from 0--1.2

    """

    z = numpy.arange(0, 5.05, 0.05)

    cosmo = {}
    cosmo['omega_M_0'] = numpy.array([[1.0], [0.05], [0.2]])
    cosmo['omega_lambda_0'] = numpy.array([[0.0], [0.0], [0.8]])
    cosmo['h'] = 0.5
    cd.set_omega_k_0(cosmo)

    linestyle = ['-', ':', '--']

    th = 1 / cd.hubble_z(0, **cosmo)

    tl = cd.lookback_time(z, **cosmo)
    age = cd.age(z, **cosmo)

    pylab.figure(figsize=(6, 6))
    for i in range(len(linestyle)):
        pylab.plot(z, (tl / th)[i], ls=linestyle[i])
        pylab.plot(z, (age / th)[i], ls=linestyle[i])
    pylab.xlim(0, 5)
    pylab.ylim(0, 1.2)
    pylab.xlabel("redshift z")
    pylab.ylabel(r"lookback timne $t_L/t_H$")
    pylab.title("compare to " + inspect.stack()[0][3].replace('test_', '') +
                " (astro-ph/9905116v4)")
def test_figure6():
    """Plot Hogg fig. 6: The dimensionless lookback time t_L/t_H and age t/t_H.

    The three curves are for the three world models, 

    - Einstein-de Sitter (omega_M, omega_lambda) = (1, 0) [solid]
    
    : Low-density (0.05, 0) [dotted]

    -- High lambda, (0.2, 0.8) [dashed]

    Hubble distance DH = c / H0

    z from 0--5
    t/th from 0--1.2

    """

    z = numpy.arange(0, 5.05, 0.05)

    cosmo = {}
    cosmo['omega_M_0'] = numpy.array([[1.0],[0.05],[0.2]])
    cosmo['omega_lambda_0'] = numpy.array([[0.0],[0.0],[0.8]])
    cosmo['h'] = 0.5
    cd.set_omega_k_0(cosmo)
    
    linestyle = ['-', ':', '--']

    th = 1/ cd.hubble_z(0, **cosmo)

    tl = cd.lookback_time(z, **cosmo)
    age = cd.age(z, **cosmo)

    pylab.figure(figsize=(6,6))
    for i in range(len(linestyle)):
        pylab.plot(z, (tl/th)[i], ls=linestyle[i])
        pylab.plot(z, (age/th)[i], ls=linestyle[i])
    pylab.xlim(0,5)
    pylab.ylim(0,1.2)
    pylab.xlabel("redshift z")
    pylab.ylabel(r"lookback timne $t_L/t_H$")
    pylab.title("compare to " + inspect.stack()[0][3].replace('test_', '') + 
                " (astro-ph/9905116v4)")
Example #10
0
def test_t_0():
    """Check the age of the universe we get using WMAP cosmologies.

    We only find agreement to 3 sig figs, not the 4 specified in the
    WMAP paper.

    The results of test_age.py show that we're doing the integral
    correctly, so I think the problem is that we're not taking into
    account some of the higher-order effects included in the WMAP
    numbers.

    """

    dz = 0.1
    z = numpy.arange(80., 0. - 1.5 * dz, -1. * dz)

    flat = True
    cosmos = [cparam.WMAP7_BAO_H0_mean(flat=True),
              cparam.WMAP7_ML(flat=True),
              cparam.WMAP5_BAO_SN_mean(flat=True),
              cparam.WMAP5_ML(flat=True),
              cparam.WMAP5_mean(flat=True)]

    for cosmo in cosmos:
        age = cd.age(0.0, **cosmo)
        age_flat = cd.age_flat(0.0, **cosmo)
        gyr = 1e9 * cc.yr_s
        age /= gyr
        age_flat /= gyr

        print "integrated age: ",
        print tu.fractional_diff_string(age, cosmo['t_0'], 4)
        ntest.assert_approx_equal(age, cosmo['t_0'], significant=3, 
                                  err_msg="Integrated age doesn't match WMAP")

        print "analytical age: ",
        print tu.fractional_diff_string(age_flat, cosmo['t_0'], 4)
        ntest.assert_approx_equal(age_flat, cosmo['t_0'], significant=3, 
                                  err_msg="Analytical age doesn't match WMAP")
Example #11
0
def test_age():
    """Test integrated age against analytical age."""
    z = numpy.arange(0, 10.0, 0.05)

    cosmo = {}
    cosmo['omega_M_0'] = numpy.array([[0.99], [0.01], [0.3]])
    cosmo['omega_lambda_0'] = 1. - cosmo['omega_M_0']
    cosmo['h'] = 0.7
    cd.set_omega_k_0(cosmo)

    linestyle = ['-', ':', '--']

    gyr = 1e9 * cc.yr_s

    tl = cd.lookback_time(z, **cosmo)
    age = cd.age(z, **cosmo)
    age_ana = cd.age_flat(z, **cosmo)

    pylab.figure(figsize=(6, 6))
    for i in range(len(linestyle)):
        pylab.plot(z, (tl / gyr)[i], ls=linestyle[i], color='0.5')
        pylab.plot(z, (age / gyr)[i], ls=linestyle[i], color='r')
        pylab.plot(z, (age_ana / gyr)[i], ls=linestyle[i], color='k')
    pylab.xlabel("redshift z")
    pylab.ylabel(r"age $t_L/$Gyr")

    pylab.figure(figsize=(6, 6))
    for i in range(len(linestyle)):
        pylab.plot(z, ((age - age_ana) / age_ana)[i],
                   ls=linestyle[i],
                   color='k')
        # Make sure errors are small:
        ntest.assert_array_less((numpy.abs((age - age_ana) / age_ana)[i]),
                                3e-13)
    pylab.xlabel("redshift z")
    pylab.ylabel(r"age: (integral - analytical)/analytical")
Example #12
0
def get_evolv(ID0, PA, Z=np.arange(-1.2,0.4249,0.05), age=[0.01, 0.1, 0.3, 0.7, 1.0, 3.0], f_comp = 0, fil_path = './FILT/', inputs=None, dust_model=0, DIR_TMP='./templates/', delt_sfh = 0.01):
    #
    # delt_sfh (float): delta t of input SFH in Gyr.
    #
    # Returns: SED as function of age, based on SF and Z histories;
    #
    print('This function may take a while.')
    flim = 0.01
    lsfrl = -1 # log SFR low limit
    mmax  = 1000
    Txmax = 4 # Max x value
    lmmin = 10.3

    nage = np.arange(0,len(age),1)
    fnc  = Func(Z, nage, dust_model=dust_model) # Set up the number of Age/ZZ
    bfnc = Basic(Z)
    age = np.asarray(age)

    ################
    # RF colors.
    import os.path
    home = os.path.expanduser('~')
    c      = 3.e18 # A/s
    chimax = 1.
    mag0   = 25.0
    d      = 10**(73.6/2.5) * 1e-18 # From [ergs/s/cm2/A] to [ergs/s/cm2/Hz]

    ###########################
    # Open result file
    ###########################
    file = 'summary_' + ID0 + '_PA' + PA + '.fits'
    hdul = fits.open(file) # open a FITS file
    zbes = hdul[0].header['z']
    chinu= hdul[1].data['chi']

    uv= hdul[1].data['uv']
    vj= hdul[1].data['vj']

    RA   = 0
    DEC  = 0
    rek  = 0
    erekl= 0
    ereku= 0
    mu = 1.0
    nn = 0
    qq = 0
    enn = 0
    eqq = 0
    try:
        RA   = hdul[0].header['RA']
        DEC  = hdul[0].header['DEC']
    except:
        RA  = 0
        DEC = 0

    try:
        SN = hdul[0].header['SN']
    except:
        ###########################
        # Get SN of Spectra
        ###########################
        file = 'templates/spec_obs_' + ID0 + '_PA' + PA + '.cat'
        fds  = np.loadtxt(file, comments='#')
        nrs  = fds[:,0]
        lams = fds[:,1]
        fsp  = fds[:,2]
        esp  = fds[:,3]

        consp = (nrs<10000) & (lams/(1.+zbes)>3600) & (lams/(1.+zbes)<4200)
        if len((fsp/esp)[consp]>10):
            SN = np.median((fsp/esp)[consp])
        else:
            SN = 1


    Asum = 0
    A50 = np.arange(len(age), dtype='float32')
    for aa in range(len(A50)):
        A50[aa] = hdul[1].data['A'+str(aa)][1]
        Asum += A50[aa]

    ####################
    # For cosmology
    ####################
    DL = cd.luminosity_distance(zbes, **cosmo) * Mpc_cm # Luminositydistance in cm
    Cons = (4.*np.pi*DL**2/(1.+zbes))

    Tuni = cd.age(zbes, use_flat=True, **cosmo)
    Tuni0 = (Tuni/cc.Gyr_s - age[:])

    delT  = np.zeros(len(age),dtype='float32')
    delTl = np.zeros(len(age),dtype='float32')
    delTu = np.zeros(len(age),dtype='float32')
    for aa in range(len(age)):
        if aa == 0:
            delTl[aa] = age[aa]
            delTu[aa] = (age[aa+1]-age[aa])/2.
            delT[aa]  = delTu[aa] + delTl[aa]
        elif Tuni/cc.Gyr_s < age[aa]:
            delTl[aa] = (age[aa]-age[aa-1])/2.
            delTu[aa] = delTl[aa] #10.
            delT[aa]  = delTu[aa] + delTl[aa]
        elif aa == len(age)-1:
            delTl[aa] = (age[aa]-age[aa-1])/2.
            delTu[aa] = Tuni/cc.Gyr_s - age[aa]
            delT[aa]  = delTu[aa] + delTl[aa]
        else:
            delTl[aa] = (age[aa]-age[aa-1])/2.
            delTu[aa] = (age[aa+1]-age[aa])/2.
            delT[aa]  = delTu[aa] + delTl[aa]

    delT[:]  *= 1e9 # Gyr to yr
    delTl[:] *= 1e9 # Gyr to yr
    delTu[:] *= 1e9 # Gyr to yr
    ##############################
    # Load Pickle
    ##############################
    samplepath = './'
    pfile = 'chain_' + ID0 + '_PA' + PA + '_corner.cpkl'

    niter = 0
    data = loadcpkl(os.path.join(samplepath+'/'+pfile))
    try:
        ndim   = data['ndim']     # By default, use ndim and burnin values contained in the cpkl file, if present.
        burnin = data['burnin']
        nmc    = data['niter']
        nwalk  = data['nwalkers']
        Nburn  = burnin #* nwalk/10/2 # I think this takes 3/4 of samples
        #if nmc>1000:
        #    Nburn  = 500
        samples = data['chain'][:]
    except:
        print(' =   >   NO keys of ndim and burnin found in cpkl, use input keyword values')
        return -1

    ######################
    # Mass-to-Light ratio.
    ######################
    AM = np.zeros((len(age), mmax), dtype='float32') # Mass in each bin.
    AC = np.zeros((len(age), mmax), dtype='float32') # Cumulative mass in each bin.
    AL = np.zeros((len(age), mmax), dtype='float32') # Cumulative light in each bin.
    ZM = np.zeros((len(age), mmax), dtype='float32') # Z.
    ZC = np.zeros((len(age), mmax), dtype='float32') # Cumulative Z.
    ZL = np.zeros((len(age), mmax), dtype='float32') # Light weighted cumulative Z.
    TC = np.zeros((len(age), mmax), dtype='float32') # Mass weighted T.
    TL = np.zeros((len(age), mmax), dtype='float32') # Light weighted T.
    ZMM= np.zeros((len(age), mmax), dtype='float32') # Mass weighted Z.
    ZML= np.zeros((len(age), mmax), dtype='float32') # Light weighted Z.
    SF = np.zeros((len(age), mmax), dtype='float32') # SFR
    Av = np.zeros(mmax, dtype='float32') # SFR

    # ##############################
    # Add simulated scatter in quad
    # if files are available.
    # ##############################
    if inputs:
        f_zev = int(inputs['ZEVOL'])
    else:
        f_zev = 1

    eZ_mean = 0
    try:
        meanfile = './sim_SFH_mean.cat'
        dfile    = np.loadtxt(meanfile, comments='#')
        eA = dfile[:,2]
        eZ = dfile[:,4]
        eAv= np.mean(dfile[:,6])
        if f_zev == 0:
            eZ_mean = np.mean(eZ[:])
            eZ[:]   = age * 0 #+ eZ_mean
        else:
            try:
                f_zev = int(prihdr['ZEVOL'])
                if f_zev == 0:
                    eZ_mean = np.mean(eZ[:])
                    eZ = age * 0
            except:
                pass
    except:
        print('No simulation file (%s).\nError may be underestimated.' % meanfile)
        eA = age * 0
        eZ = age * 0
        eAv= 0

    mm = 0
    #mmax = 10
    #print('mmax is set to 10')
    for mm in range(mmax):
        mtmp  = np.random.randint(len(samples))# + Nburn
        AAtmp = np.zeros(len(age), dtype='float32')
        ZZtmp = np.zeros(len(age), dtype='float32')
        mslist= np.zeros(len(age), dtype='float32')

        Av_tmp = samples['Av'][mtmp]

        f0     = fits.open(DIR_TMP + 'ms_' + ID0 + '_PA' + PA + '.fits')
        sedpar = f0[1]
        f1     = fits.open(DIR_TMP + 'ms.fits')
        mloss  = f1[1].data

        Avrand = np.random.uniform(-eAv, eAv)
        if Av_tmp + Avrand<0:
            Av[mm] = 0
        else:
            Av[mm] = Av_tmp + Avrand

        for aa in range(len(age)):
            AAtmp[aa] = samples['A'+str(aa)][mtmp]/mu
            try:
                ZZtmp[aa] = samples['Z'+str(aa)][mtmp]
            except:
                ZZtmp[aa] = samples['Z0'][mtmp]

            nZtmp      = bfnc.Z2NZ(ZZtmp[aa])
            mslist[aa] = sedpar.data['ML_'+str(nZtmp)][aa]

            ml = mloss['ms_'+str(nZtmp)][aa]

            Arand = np.random.uniform(-eA[aa],eA[aa])
            Zrand = np.random.uniform(-eZ[aa],eZ[aa])
            AM[aa, mm] = AAtmp[aa] * mslist[aa] * 10**Arand
            AL[aa, mm] = AM[aa, mm] / mslist[aa]
            SF[aa, mm] = AAtmp[aa] * mslist[aa] / delT[aa] / ml * 10**Arand
            ZM[aa, mm] = ZZtmp[aa] + Zrand
            ZMM[aa, mm]= (10 ** ZZtmp[aa]) * AAtmp[aa] * mslist[aa] * 10**Zrand
            ZML[aa, mm]= ZMM[aa, mm] / mslist[aa]

        for aa in range(len(age)):
            AC[aa, mm] = np.sum(AM[aa:, mm])
            ZC[aa, mm] = np.log10(np.sum(ZMM[aa:, mm])/AC[aa, mm])
            ZL[aa, mm] = np.log10(np.sum(ZML[aa:, mm])/np.sum(AL[aa:, mm]))
            if f_zev == 0: # To avoid random fluctuation in A.
                ZC[aa, mm] = ZM[aa, mm]

            ACs = 0
            ALs = 0
            for bb in range(aa, len(age), 1):
                tmpAA       = 10**np.random.uniform(-eA[bb],eA[bb])
                tmpTT       = np.random.uniform(-delT[bb]/1e9,delT[bb]/1e9)
                TC[aa, mm] += (age[bb]+tmpTT) * AAtmp[bb] * mslist[bb] * tmpAA
                TL[aa, mm] += (age[bb]+tmpTT) * AAtmp[bb] * tmpAA
                ACs        += AAtmp[bb] * mslist[bb] * tmpAA
                ALs        += AAtmp[bb] * tmpAA

            TC[aa, mm] /= ACs
            TL[aa, mm] /= ALs

    Avtmp  = np.percentile(Av[:],[16,50,84])

    #############
    # Plot
    #############
    AMp = np.zeros((len(age),3), dtype='float32')
    ACp = np.zeros((len(age),3), dtype='float32')
    ZMp = np.zeros((len(age),3), dtype='float32')
    ZCp = np.zeros((len(age),3), dtype='float32')
    SFp = np.zeros((len(age),3), dtype='float32')
    for aa in range(len(age)):
       AMp[aa,:] = np.percentile(AM[aa,:], [16,50,84])
       ACp[aa,:] = np.percentile(AC[aa,:], [16,50,84])
       ZMp[aa,:] = np.percentile(ZM[aa,:], [16,50,84])
       ZCp[aa,:] = np.percentile(ZC[aa,:], [16,50,84])
       SFp[aa,:] = np.percentile(SF[aa,:], [16,50,84])

    ###################
    msize = np.zeros(len(age), dtype='float32')
    for aa in range(len(age)):
        if A50[aa]/Asum>flim: # if >1%
            msize[aa] = 150 * A50[aa]/Asum

    conA = (msize>=0)
    # Make template;
    tbegin = np.min(Tuni/cc.Gyr_s-age)
    tuniv_hr = np.arange(tbegin,Tuni/cc.Gyr_s,delt_sfh) # in Gyr
    sfh_hr_in= np.interp(tuniv_hr,(Tuni/cc.Gyr_s-age)[::-1],SFp[:,1][::-1])
    zh_hr_in = np.interp(tuniv_hr,(Tuni/cc.Gyr_s-age)[::-1],ZCp[:,1][::-1])

    # FSPS
    con_sfh = (tuniv_hr>0)
    import fsps
    nimf = int(inputs['NIMF'])
    try:
        fneb = int(inputs['ADD_NEBULAE'])
    except:
        fneb = 0

    if fneb == 1:
        print('Metallicity is set to logZ/Zsun=%.2f'%(np.max(zh_hr_in)))
        sp = fsps.StellarPopulation(compute_vega_mags=False, zcontinuous=1, imf_type=nimf, logzsol=np.max(zh_hr_in), sfh=3, dust_type=2, dust2=0.0, add_neb_emission=True)
        sp.set_tabular_sfh(tuniv_hr[con_sfh], sfh_hr_in[con_sfh])
    else:
        sp = fsps.StellarPopulation(compute_vega_mags=False, zcontinuous=3, imf_type=nimf, sfh=3, dust_type=2, dust2=0.0, add_neb_emission=False)
        sp.set_tabular_sfh(tuniv_hr[con_sfh], sfh_hr_in[con_sfh], Z=10**zh_hr_in[con_sfh])

    col01 = []
    t_get = tuniv_hr[con_sfh]
    #con_tget = ((Tuni/cc.Gyr_s-age)>0)
    #t_get = (Tuni/cc.Gyr_s-age)[con_tget][::-1]
    for ss in range(len(t_get)):
        wave0, flux0 = sp.get_spectrum(tage=t_get[ss], peraa=True) # if peraa=True, in unit of L/AA
        if ss == 0:
            spec_mul_nu_conv = np.zeros((len(t_get),len(wave0)),dtype='float32')
        #ax2.plot(wave0, flux0, linestyle='-', color='b')
        #plt.show()
        print('Template %d is done.'%(ss))
        wavetmp  = wave0*(1.+zbes)
        spec_mul_nu = flamtonu(wavetmp, flux0) # Conversion from Flambda to Fnu.
        Lsun = 3.839 * 1e33 #erg s-1
        stmp_common = 1e10 # 1 tmp is in 1e10Lsun

        spec_mul_nu_conv[ss,:] = spec_mul_nu[:]
        spec_mul_nu_conv[ss,:] *= Lsun/(4.*np.pi*DL**2/(1.+zbes))
        Ls = 10**sp.log_lbol
        spec_mul_nu_conv[ss,:] *= (1./Ls)*stmp_common # in unit of erg/s/Hz/cm2/ms[ss].

        consave = (wavetmp/(1.+zbes)<20000) # AA
        if ss == 0:
            nd_ap  = np.arange(0,len(wave0),1)
            col1   = fits.Column(name='wavelength', format='E', unit='AA', disp='obs', array=wavetmp[consave])
            col2   = fits.Column(name='colnum', format='K', unit='', array=nd_ap[consave])
            col00  = [col1, col2]
            col3   = fits.Column(name='age', format='E', unit='Gyr', array=t_get)
            col4   = fits.Column(name='sfh', format='E', unit='Msun/yr', array=sfh_hr_in[con_sfh])
            col5   = fits.Column(name='zh', format='E', unit='Zsun', array=zh_hr_in[con_sfh])
            col01  = [col3,col4,col5]

        colspec_all = fits.Column(name='fspec_'+str(ss), format='E', unit='Fnu', disp='%s'%(t_get[ss]), array=spec_mul_nu_conv[ss,:][consave])
        col00.append(colspec_all)

    coldefs_spec = fits.ColDefs(col00)
    hdu = fits.BinTableHDU.from_columns(coldefs_spec)
    hdu.writeto(DIR_TMP + 'obsspec_' + ID0 + '_PA' + PA + '.fits', overwrite=True)

    coldefs_spec = fits.ColDefs(col01)
    hdu = fits.BinTableHDU.from_columns(coldefs_spec)
    hdu.writeto(DIR_TMP + 'obshist_' + ID0 + '_PA' + PA + '.fits', overwrite=True)
Example #13
0
def plot_sfh(ID0, PA, Z=np.arange(-1.2,0.4249,0.05), age=[0.01, 0.1, 0.3, 0.7, 1.0, 3.0], f_comp = 0, fil_path = './FILT/', inputs=None, dust_model=0, DIR_TMP='./templates/',f_SFMS=False):
    #
    #
    #
    flim = 0.01
    lsfrl = -1 # log SFR low limit
    mmax  = 1000
    Txmax = 4 # Max x value
    lmmin = 9.5 #10.3

    nage = np.arange(0,len(age),1)
    fnc  = Func(Z, nage, dust_model=dust_model) # Set up the number of Age/ZZ
    bfnc = Basic(Z)

    age = np.asarray(age)

    ################
    # RF colors.
    import os.path
    home = os.path.expanduser('~')
    c      = 3.e18 # A/s
    chimax = 1.
    mag0   = 25.0
    d      = 10**(73.6/2.5) * 1e-18 # From [ergs/s/cm2/A] to [ergs/s/cm2/Hz]
    #d = 10**(-73.6/2.5) # From [ergs/s/cm2/Hz] to [ergs/s/cm2/A]

    #############
    # Plot.
    #############
    fig = plt.figure(figsize=(8,2.8))
    fig.subplots_adjust(top=0.88, bottom=0.18, left=0.07, right=0.99, hspace=0.15, wspace=0.3)
    ax1 = fig.add_subplot(131)
    ax2 = fig.add_subplot(132)
    #ax3 = fig.add_subplot(223)
    ax4 = fig.add_subplot(133)

    ax1t = ax1.twiny()
    ax2t = ax2.twiny()
    #ax3t = ax3.twiny()
    ax4t = ax4.twiny()

    ##################
    # Fitting Results
    ##################
    #DIR_TMP = './templates/'
    SNlim = 3 # avobe which SN line is shown.

    ###########################
    # Open result file
    ###########################
    file = 'summary_' + ID0 + '_PA' + PA + '.fits'
    hdul = fits.open(file) # open a FITS file
    zbes = hdul[0].header['z']
    chinu= hdul[1].data['chi']

    uv= hdul[1].data['uv']
    vj= hdul[1].data['vj']

    RA   = 0
    DEC  = 0
    rek  = 0
    erekl= 0
    ereku= 0
    mu = 1.0
    nn = 0
    qq = 0
    enn = 0
    eqq = 0
    try:
        RA   = hdul[0].header['RA']
        DEC  = hdul[0].header['DEC']
    except:
        RA  = 0
        DEC = 0

    try:
        SN = hdul[0].header['SN']
    except:
        ###########################
        # Get SN of Spectra
        ###########################
        file = 'templates/spec_obs_' + ID0 + '_PA' + PA + '.cat'
        fds  = np.loadtxt(file, comments='#')
        nrs  = fds[:,0]
        lams = fds[:,1]
        fsp  = fds[:,2]
        esp  = fds[:,3]

        consp = (nrs<10000) & (lams/(1.+zbes)>3600) & (lams/(1.+zbes)<4200)
        if len((fsp/esp)[consp]>10):
            SN = np.median((fsp/esp)[consp])
        else:
            SN = 1


    Asum = 0
    A50 = np.arange(len(age), dtype='float32')
    for aa in range(len(A50)):
        A50[aa] = hdul[1].data['A'+str(aa)][1]
        Asum += A50[aa]

    ####################
    # For cosmology
    ####################
    DL = cd.luminosity_distance(zbes, **cosmo) * Mpc_cm # Luminositydistance in cm
    Cons = (4.*np.pi*DL**2/(1.+zbes))

    Tuni = cd.age(zbes, use_flat=True, **cosmo)
    Tuni0 = (Tuni/cc.Gyr_s - age[:])

    delT  = np.zeros(len(age),dtype='float32')
    delTl = np.zeros(len(age),dtype='float32')
    delTu = np.zeros(len(age),dtype='float32')
    for aa in range(len(age)):
        if aa == 0:
            delTl[aa] = age[aa]
            delTu[aa] = (age[aa+1]-age[aa])/2.
            delT[aa]  = delTu[aa] + delTl[aa]
        elif Tuni/cc.Gyr_s < age[aa]:
            delTl[aa] = (age[aa]-age[aa-1])/2.
            delTu[aa] = delTl[aa] #10.
            delT[aa]  = delTu[aa] + delTl[aa]
        elif aa == len(age)-1:
            delTl[aa] = (age[aa]-age[aa-1])/2.
            delTu[aa] = Tuni/cc.Gyr_s - age[aa]
            delT[aa]  = delTu[aa] + delTl[aa]
        else:
            delTl[aa] = (age[aa]-age[aa-1])/2.
            delTu[aa] = (age[aa+1]-age[aa])/2.
            delT[aa]  = delTu[aa] + delTl[aa]


    delT[:]  *= 1e9 # Gyr to yr
    delTl[:] *= 1e9 # Gyr to yr
    delTu[:] *= 1e9 # Gyr to yr
    #print(age, delT, delTu, delTl)
    ##############################
    # Load Pickle
    ##############################
    samplepath = './'
    pfile = 'chain_' + ID0 + '_PA' + PA + '_corner.cpkl'

    niter = 0
    data = loadcpkl(os.path.join(samplepath+'/'+pfile))
    try:
    #if 1>0:
        ndim   = data['ndim']     # By default, use ndim and burnin values contained in the cpkl file, if present.
        burnin = data['burnin']
        nmc    = data['niter']
        nwalk  = data['nwalkers']
        Nburn  = burnin #* nwalk/10/2 # I think this takes 3/4 of samples
        #if nmc>1000:
        #    Nburn  = 500
        samples = data['chain'][:]
    except:
        print(' =   >   NO keys of ndim and burnin found in cpkl, use input keyword values')
        return -1

    ######################
    # Mass-to-Light ratio.
    ######################
    #ms     = np.zeros(len(age), dtype='float32')
    # Wht do you want from MCMC sampler?
    AM = np.zeros((len(age), mmax), dtype='float32') # Mass in each bin.
    AC = np.zeros((len(age), mmax), dtype='float32') # Cumulative mass in each bin.
    AL = np.zeros((len(age), mmax), dtype='float32') # Cumulative light in each bin.
    ZM = np.zeros((len(age), mmax), dtype='float32') # Z.
    ZC = np.zeros((len(age), mmax), dtype='float32') # Cumulative Z.
    ZL = np.zeros((len(age), mmax), dtype='float32') # Light weighted cumulative Z.
    TC = np.zeros((len(age), mmax), dtype='float32') # Mass weighted T.
    TL = np.zeros((len(age), mmax), dtype='float32') # Light weighted T.
    ZMM= np.zeros((len(age), mmax), dtype='float32') # Mass weighted Z.
    ZML= np.zeros((len(age), mmax), dtype='float32') # Light weighted Z.
    SF = np.zeros((len(age), mmax), dtype='float32') # SFR
    Av = np.zeros(mmax, dtype='float32') # SFR


    # ##############################
    # Add simulated scatter in quad
    # if files are available.
    # ##############################
    if inputs:
        f_zev = int(inputs['ZEVOL'])
    else:
        f_zev = 1

    eZ_mean = 0
    try:
        #meanfile = '/Users/tmorishita/Documents/Astronomy/sim_tran/sim_SFH_mean.cat'
        meanfile = './sim_SFH_mean.cat'
        dfile    = np.loadtxt(meanfile, comments='#')
        eA = dfile[:,2]
        eZ = dfile[:,4]
        eAv= np.mean(dfile[:,6])
        if f_zev == 0:
            eZ_mean = np.mean(eZ[:])
            eZ[:]   = age * 0 #+ eZ_mean
        else:
            try:
                f_zev = int(prihdr['ZEVOL'])
                if f_zev == 0:
                    eZ_mean = np.mean(eZ[:])
                    eZ = age * 0
            except:
                pass
    except:
        print('No simulation file (%s).\nError may be underestimated.' % meanfile)
        eA = age * 0
        eZ = age * 0
        eAv= 0

    mm = 0
    #while mm<mmax:
    for mm in range(mmax):
        mtmp  = np.random.randint(len(samples))# + Nburn

        AAtmp = np.zeros(len(age), dtype='float32')
        ZZtmp = np.zeros(len(age), dtype='float32')
        mslist= np.zeros(len(age), dtype='float32')

        Av_tmp = samples['Av'][mtmp]

        f0     = fits.open(DIR_TMP + 'ms_' + ID0 + '_PA' + PA + '.fits')
        sedpar = f0[1]
        f1     = fits.open(DIR_TMP + 'ms.fits')
        mloss  = f1[1].data

        Avrand = np.random.uniform(-eAv, eAv)
        if Av_tmp + Avrand<0:
            Av[mm] = 0
        else:
            Av[mm] = Av_tmp + Avrand

        for aa in range(len(age)):
            AAtmp[aa] = samples['A'+str(aa)][mtmp]/mu
            try:
                ZZtmp[aa] = samples['Z'+str(aa)][mtmp]
            except:
                ZZtmp[aa] = samples['Z0'][mtmp]

            nZtmp      = bfnc.Z2NZ(ZZtmp[aa])
            mslist[aa] = sedpar.data['ML_'+str(nZtmp)][aa]

            ml = mloss['ms_'+str(nZtmp)][aa]

            Arand = np.random.uniform(-eA[aa],eA[aa])
            Zrand = np.random.uniform(-eZ[aa],eZ[aa])
            AM[aa, mm] = AAtmp[aa] * mslist[aa] * 10**Arand
            AL[aa, mm] = AM[aa, mm] / mslist[aa]
            SF[aa, mm] = AAtmp[aa] * mslist[aa] / delT[aa] / ml * 10**Arand
            ZM[aa, mm] = ZZtmp[aa] + Zrand
            ZMM[aa, mm]= (10 ** ZZtmp[aa]) * AAtmp[aa] * mslist[aa] * 10**Zrand
            ZML[aa, mm]= ZMM[aa, mm] / mslist[aa]

        for aa in range(len(age)):
            AC[aa, mm] = np.sum(AM[aa:, mm])
            ZC[aa, mm] = np.log10(np.sum(ZMM[aa:, mm])/AC[aa, mm])
            ZL[aa, mm] = np.log10(np.sum(ZML[aa:, mm])/np.sum(AL[aa:, mm]))
            if f_zev == 0: # To avoid random fluctuation in A.
                ZC[aa, mm] = ZM[aa, mm]

            ACs = 0
            ALs = 0
            for bb in range(aa, len(age), 1):
                tmpAA       = 10**np.random.uniform(-eA[bb],eA[bb])
                tmpTT       = np.random.uniform(-delT[bb]/1e9,delT[bb]/1e9)
                TC[aa, mm] += (age[bb]+tmpTT) * AAtmp[bb] * mslist[bb] * tmpAA
                TL[aa, mm] += (age[bb]+tmpTT) * AAtmp[bb] * tmpAA
                ACs        += AAtmp[bb] * mslist[bb] * tmpAA
                ALs        += AAtmp[bb] * tmpAA

            TC[aa, mm] /= ACs
            TL[aa, mm] /= ALs

    #Avtmp  = np.percentile(samples['Av'][:],[16,50,84])
    Avtmp  = np.percentile(Av[:],[16,50,84])

    #############
    # Plot
    #############
    AMp = np.zeros((len(age),3), dtype='float32')
    ACp = np.zeros((len(age),3), dtype='float32')
    ZMp = np.zeros((len(age),3), dtype='float32')
    ZCp = np.zeros((len(age),3), dtype='float32')
    SFp = np.zeros((len(age),3), dtype='float32')
    for aa in range(len(age)):
       AMp[aa,:] = np.percentile(AM[aa,:], [16,50,84])
       ACp[aa,:] = np.percentile(AC[aa,:], [16,50,84])
       ZMp[aa,:] = np.percentile(ZM[aa,:], [16,50,84])
       ZCp[aa,:] = np.percentile(ZC[aa,:], [16,50,84])
       SFp[aa,:] = np.percentile(SF[aa,:], [16,50,84])

    ###################
    msize = np.zeros(len(age), dtype='float32')
    for aa in range(len(age)):
        if A50[aa]/Asum>flim: # if >1%
            msize[aa] = 150 * A50[aa]/Asum

    conA = (msize>=0)

    ax1.fill_between(age[conA], np.log10(SFp[:,0])[conA], np.log10(SFp[:,2])[conA], linestyle='-', color='k', alpha=0.3)
    #ax1.fill_between(age, np.log10(SFp[:,0]), np.log10(SFp[:,2]), linestyle='-', color='k', alpha=0.3)
    ax1.scatter(age[conA], np.log10(SFp[:,1])[conA], marker='.', c='k', s=msize[conA])
    ax1.errorbar(age[conA], np.log10(SFp[:,1])[conA], xerr=[delTl[:][conA]/1e9,delTu[:][conA]/1e9], yerr=[np.log10(SFp[:,1])[conA]-np.log10(SFp[:,0])[conA], np.log10(SFp[:,2])[conA]-np.log10(SFp[:,1])[conA]], linestyle='-', color='k', lw=0.5, marker='')

    # Get SFMS;
    IMF = int(inputs['NIMF'])
    SFMS_16 = get_SFMS(zbes,age,ACp[:,0],IMF=IMF)
    SFMS_50 = get_SFMS(zbes,age,ACp[:,1],IMF=IMF)
    SFMS_84 = get_SFMS(zbes,age,ACp[:,2],IMF=IMF)

    f_rejuv,t_quench,t_rejuv = check_rejuv(age,np.log10(SFp[:,:]),np.log10(ACp[:,:]),np.log10(SFMS_50))
    #print(f_rejuv,t_quench,t_rejuv)

    # Plot MS?
    if f_SFMS:
        #ax1.fill_between(age[conA], np.log10(SFMS_16)[conA], np.log10(SFMS_84)[conA], linestyle='-', color='b', alpha=0.3)
        ax1.fill_between(age[conA], np.log10(SFMS_50)[conA]-0.2, np.log10(SFMS_50)[conA]+0.2, linestyle='-', color='b', alpha=0.3)
        ax1.plot(age[conA], np.log10(SFMS_50)[conA], linestyle='--', color='b', alpha=0.5)

    #
    # Fit with delayed exponential??
    #
    minsfr = 1e-10
    if f_comp == 1:
        #
        # Plot exp model?
        #
        DIR_exp = '/Users/tmorishita/Documents/Astronomy/sedfitter_exp/'
        file = DIR_exp + 'summary_' + ID0 + '_PA' + PA + '.fits'
        hdul = fits.open(file) # open a FITS file

        t0  = 10**float(hdul[1].data['age'][1])
        tau = 10**float(hdul[1].data['tau'][1])
        A   = float(hdul[1].data['A'][1])
        Zexp= hdul[1].data['Z']
        Mexp= float(hdul[1].data['ms'][1])

        deltt0 = 0.01 # in Gyr
        tt0 = np.arange(0.01,10,deltt0)
        sfr = SFH_dec(np.max(age)-t0, tau, A, tt=tt0)
        mtmp = np.sum(sfr * deltt0 * 1e9)
        C_exp = Mexp/mtmp
        ax1.plot(np.max(age) - tt0, np.log10(sfr*C_exp), marker='', linestyle='--', color='r', lw=1.5, alpha=0.7, zorder=-4, label='')
        mctmp = tt0 * 0
        for ii in range(len(tt0)):
            mctmp[ii] = np.sum(sfr[:ii] * deltt0 * 1e9)
        ax2.plot(np.max(age) - tt0, np.log10(mctmp*C_exp), marker='', linestyle='--', color='r', lw=1.5, alpha=0.7, zorder=-4)
        ax4.errorbar(t0, Zexp[1], yerr=[[Zexp[1]-Zexp[0]], [Zexp[2]-Zexp[1]]], marker='s', color='r', alpha=0.7, zorder=-4, capsize=0)
        sfr_exp = sfr
        mc_exp = mctmp*C_exp
        '''
        #
        # Plot delay model?
        #
        DIR_exp = '/Users/tmorishita//Documents/Astronomy/sedfitter_del/'
        file = DIR_exp + 'summary_' + ID0 + '_PA' + PA + '.fits'
        hdul = fits.open(file) # open a FITS file

        t0  = 10**float(hdul[1].data['age'][0])
        tau = 10**float(hdul[1].data['tau'][0])
        A   = float(hdul[1].data['A'][0])
        Mdel= float(hdul[1].data['ms'][1])

        tt0 = np.arange(0.01,10,0.01)
        sfr = SFH_del(np.max(age)-t0, tau, A, tt=tt0)
        mtmp = np.sum(sfr * deltt0 * 1e9)
        C_del = Mdel/mtmp
        '''

    #
    # Mass in each bin
    #
    ax2label = ''
    ax2.fill_between(age[conA], np.log10(ACp[:,0])[conA], np.log10(ACp[:,2])[conA], linestyle='-', color='k', alpha=0.3)
    ax2.errorbar(age[conA], np.log10(ACp[:,1])[conA], xerr=[delTl[:][conA]/1e9,delTu[:][conA]/1e9], yerr=[np.log10(ACp[:,1])[conA]-np.log10(ACp[:,0])[conA],np.log10(ACp[:,2])[conA]-np.log10(ACp[:,1])[conA]], linestyle='-', color='k', lw=0.5, label=ax2label)
    ax2.scatter(age[conA], np.log10(ACp[:,1])[conA], marker='.', c='k', s=msize)

    y2min = np.max([lmmin,np.min(np.log10(ACp[:,0])[conA])])
    y2max = np.max(np.log10(ACp[:,2])[conA])+0.05

    if f_comp == 1:
        y2max = np.max([y2max, np.log10(np.max(mc_exp))+0.05])
        y2min = np.min([y2min, np.log10(np.max(mc_exp))-0.05])

    if (y2max-y2min)<0.2:
        y2min -= 0.2


    #
    # Total Metal
    #
    ax4.fill_between(age[conA], ZCp[:,0][conA], ZCp[:,2][conA], linestyle='-', color='k', alpha=0.3)
    ax4.scatter(age[conA], ZCp[:,1][conA], marker='.', c='k', s=msize[conA])
    ax4.errorbar(age[conA], ZCp[:,1][conA], yerr=[ZCp[:,1][conA]-ZCp[:,0][conA],ZCp[:,2][conA]-ZCp[:,1][conA]], linestyle='-', color='k', lw=0.5)


    fw_sfr = open('SFH_' + ID0 + '_PA' + PA + '.txt', 'w')
    fw_sfr.write('# time_l time_u SFR SFR16 SFR84\n')
    fw_sfr.write('# (Gyr)  (Gyr)  (M/yr) (M/yr) (M/yr)\n')

    fw_met = open('ZH_' + ID0 + '_PA' + PA + '.txt', 'w')
    fw_met.write('# time_l time_u logZ logZ16 logZ84\n')
    fw_met.write('# (Gyr)  (Gyr)  (logZsun) (logZsun) (logZsun)\n')

    for ii in range(len(age)-1,0-1,-1):
        t0 = Tuni/cc.Gyr_s - age[ii]
        fw_sfr.write('%.2f %.2f %.2f %.2f %.2f\n'%(t0-delTl[ii]/1e9, t0+delTl[ii]/1e9, SFp[ii,1], SFp[ii,0], SFp[ii,2]))
        fw_met.write('%.2f %.2f %.2f %.2f %.2f\n'%(t0-delTl[ii]/1e9, t0+delTl[ii]/1e9, ZCp[ii,1], ZCp[ii,0], ZCp[ii,2]))
    fw_sfr.close()
    fw_met.close()

    #########################
    # Title
    #########################
    #ax1.set_title('Each $t$-bin', fontsize=12)
    #ax2.set_title('Net system', fontsize=12)
    #ax3.set_title('Each $t$-bin', fontsize=12)
    #ax4.set_title('Net system', fontsize=12)


    #############
    # Axis
    #############
    #ax1.set_xlabel('$t$ (Gyr)', fontsize=12)
    ax1.set_ylabel('$\log \dot{M}_*/M_\odot$yr$^{-1}$', fontsize=12)
    #ax1.set_ylabel('$\log M_*/M_\odot$', fontsize=12)

    lsfru = 2.8
    if np.max(np.log10(SFp[:,2]))>2.8:
        lsfru = np.max(np.log10(SFp[:,2]))+0.1

    if f_comp == 1:
        lsfru = np.max([lsfru, np.log10(np.max(sfr_exp*C_exp))])


    ax1.set_xlim(0.008, Txmax)
    ax1.set_ylim(lsfrl, lsfru)
    ax1.set_xscale('log')

    #ax2.set_xlabel('$t$ (Gyr)', fontsize=12)
    ax2.set_ylabel('$\log M_*/M_\odot$', fontsize=12)

    ax2.set_xlim(0.008, Txmax)
    ax2.set_ylim(y2min, y2max)
    ax2.set_xscale('log')

    ax2.text(0.01, y2min + 0.07*(y2max-y2min), 'ID: %s\n$z_\mathrm{obs.}:%.2f$\n$\log M_\mathrm{*}/M_\odot:%.2f$\n$\log Z_\mathrm{*}/Z_\odot:%.2f$\n$\log T_\mathrm{*}$/Gyr$:%.2f$\n$A_V$/mag$:%.2f$'%(ID0, zbes, np.log10(ACp[0,1]), ZCp[0,1], np.log10(np.percentile(TC[0,:],50)), Avtmp[1]), fontsize=9)

    #
    # Brief Summary
    #
    # Writing SED param in a fits file;
    # Header
    prihdr = fits.Header()
    prihdr['ID']     = ID0
    prihdr['PA']     = PA
    prihdr['z']      = zbes
    prihdr['RA']     = RA
    prihdr['DEC']    = DEC
    prihdr['Re_kpc'] = rek
    prihdr['Ser_n']  = nn
    prihdr['Axis_q'] = qq
    prihdr['e_Re']   = (erekl+ereku)/2.
    prihdr['e_n']    = enn
    prihdr['e_q']    = eqq
    # Add rejuv properties;
    prihdr['f_rejuv']= f_rejuv
    prihdr['t_quen'] = t_quench
    prihdr['t_rejuv']= t_rejuv
    prihdu = fits.PrimaryHDU(header=prihdr)

    col01 = []
    # Redshift
    zmc = hdul[1].data['zmc']
    col50 = fits.Column(name='zmc', format='E', unit='', array=zmc[:])
    col01.append(col50)

    # Stellar mass
    ACP = [np.log10(ACp[0,0]), np.log10(ACp[0,1]), np.log10(ACp[0,2])]
    col50 = fits.Column(name='Mstel', format='E', unit='logMsun', array=ACP[:])
    col01.append(col50)

    # Metallicity_MW
    ZCP = [ZCp[0,0], ZCp[0,1], ZCp[0,2]]
    col50 = fits.Column(name='Z_MW', format='E', unit='logZsun', array=ZCP[:])
    col01.append(col50)

    # Age_mw
    para = [np.log10(np.percentile(TC[0,:],16)), np.log10(np.percentile(TC[0,:],50)), np.log10(np.percentile(TC[0,:],84))]
    col50 = fits.Column(name='T_MW', format='E', unit='logGyr', array=para[:])
    col01.append(col50)

    # Metallicity_LW
    ZCP = [ZL[0,0], ZL[0,1], ZL[0,2]]
    col50 = fits.Column(name='Z_LW', format='E', unit='logZsun', array=ZCP[:])
    col01.append(col50)

    # Age_lw
    para = [np.log10(np.percentile(TL[0,:],16)), np.log10(np.percentile(TL[0,:],50)), np.log10(np.percentile(TL[0,:],84))]
    col50 = fits.Column(name='T_LW', format='E', unit='logGyr', array=para[:])
    col01.append(col50)

    # Dust
    para = [Avtmp[0], Avtmp[1], Avtmp[2]]
    col50 = fits.Column(name='AV', format='E', unit='mag', array=para[:])
    col01.append(col50)

    # U-V
    para = [uv[0], uv[1], uv[2]]
    col50 = fits.Column(name='U-V', format='E', unit='mag', array=para[:])
    col01.append(col50)

    # V-J
    para = [vj[0], vj[1], vj[2]]
    col50 = fits.Column(name='V-J', format='E', unit='mag', array=para[:])
    col01.append(col50)

    colms  = fits.ColDefs(col01)
    dathdu = fits.BinTableHDU.from_columns(colms)
    hdu    = fits.HDUList([prihdu, dathdu])
    hdu.writeto('SFH_' + ID0 + '_PA' + PA + '_param.fits', overwrite=True)


    #
    # SFH
    #
    zzall = np.arange(1.,12,0.01)
    Tall  = cd.age(zzall, use_flat=True, **cosmo)/cc.Gyr_s

    fw = open('SFH_' + ID0 + '_PA' + PA + '_sfh.cat', 'w')
    fw.write('%s'%(ID0))
    for mm in range(len(age)):
        mmtmp = np.argmin(np.abs(Tall - Tuni0[mm]))
        zztmp = zzall[mmtmp]
        fw.write(' %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f'%(zztmp, Tuni0[mm], np.log10(ACp[mm,1]), (np.log10(ACp[mm,1])-np.log10(ACp[mm,0])), (np.log10(ACp[mm,2])-np.log10(ACp[mm,1])), ZCp[mm,1], ZCp[mm,1]-ZCp[mm,0], ZCp[mm,2]-ZCp[mm,1], SFp[mm,1], SFp[mm,1]-SFp[mm,0], SFp[mm,2]-SFp[mm,1]))
    fw.write('\n')
    fw.close()
    #print('%s & $%.5e$ & $%.5e$ & $%.3f$ & $%.2f_{-%.2f}^{+%.2f}$ & $%.2f_{-%.2f}^{+%.2f}$ & $%.2f_{-%.2f}^{+%.2f}$ & $%.2f_{-%.2f}^{+%.2f}$ & $%.2f_{-%.2f}^{+%.2f}$ & $%.2f_{-%.2f}^{+%.2f}$ & $%.2f_{-%.2f}^{+%.2f}$ & $%.1f$ & $%.1f$ & $%.2f$\\\\'%(ID0, RA, DEC, zbes, np.log10(ACp[0,1]), (np.log10(ACp[0,1])-np.log10(ACp[0,0])), (np.log10(ACp[0,2])-np.log10(ACp[0,1])), ACp[7,1]/ACp[0,1], ACp[7,1]/ACp[0,1]-ACp[7,0]/ACp[0,1], ACp[7,2]/ACp[0,1]-ACp[7,1]/ACp[0,1], ZCp[0,1], ZCp[0,1]-ZCp[0,0], ZCp[0,2]-ZCp[0,1], np.percentile(TC[0,:],50), np.percentile(TC[0,:],50)-np.percentile(TC[0,:],16), np.percentile(TC[0,:],84)-np.percentile(TC[0,:],50), Avtmp[1], Avtmp[1]-Avtmp[0], Avtmp[2]-Avtmp[1], uv[1], uv[1]-uv[0], uv[2]-uv[1], vj[1], vj[1]-vj[0], vj[2]-vj[1], chinu[1], SN, rek))

    dely2 = 0.1
    while (y2max-y2min)/dely2>7:
        dely2 *= 2.

    y2ticks = np.arange(y2min, y2max, dely2)
    ax2.set_yticks(y2ticks)
    ax2.set_yticklabels(np.arange(y2min, y2max, 0.1), minor=False)

    ax2.yaxis.set_major_formatter(FormatStrFormatter('%.1f'))
    #ax2.yaxis.set_major_locator(plt.MaxNLocator(4))
    #ax3.set_xlabel('$t$ (Gyr)', fontsize=12)
    #ax3.set_ylabel('$\log Z_*/Z_\odot$', fontsize=12)
    y3min, y3max = np.min(Z), np.max(Z)
    #ax3.set_xlim(0.008, Txmax)
    #ax3.set_ylim(y3min, y3max)
    #ax3.set_xscale('log')
    #ax3.yaxis.set_major_formatter(FormatStrFormatter('%.2f'))

    fwt = open('T_' + ID0 + '_PA' + PA + '_sfh.cat', 'w')
    fwt.write('%s %.3f %.3f %.3f'%(ID0, np.percentile(TC[0,:],50), np.percentile(TC[0,:],16), np.percentile(TC[0,:],84)))
    fwt.close()

    # For redshift
    if zbes<4:
        if zbes<2:
            zred  = [zbes, 2, 3, 6]
            #zredl = ['$z_\mathrm{obs.}$', 2, 3, 6]
            zredl = ['$z_\mathrm{obs.}$', 2, 3, 6]
        elif zbes<2.5:
            zred  = [zbes, 2.5, 3, 6]
            zredl = ['$z_\mathrm{obs.}$', 2.5, 3, 6]
        elif zbes<3.:
            zred  = [zbes, 3, 6]
            zredl = ['$z_\mathrm{obs.}$', 3, 6]
        else:
            zred  = [zbes, 6]
            zredl = ['$z_\mathrm{obs.}$', 6]
    else:
        zred  = [zbes, 6, 7, 9]
        zredl = ['$z_\mathrm{obs.}$', 6, 7, 9]

    Tzz   = np.zeros(len(zred), dtype='float32')
    for zz in range(len(zred)):
        Tzz[zz] = (Tuni - cd.age(zred[zz], use_flat=True, **cosmo))/cc.Gyr_s
        if Tzz[zz] < 0.01:
            Tzz[zz] = 0.01

    #print(zred, Tzz)
    #ax3t.set_xscale('log')
    #ax3t.set_xlim(0.008, Txmax)

    ax1.set_xlabel('$t_\mathrm{lookback}$/Gyr', fontsize=12)
    ax2.set_xlabel('$t_\mathrm{lookback}$/Gyr', fontsize=12)
    ax4.set_xlabel('$t_\mathrm{lookback}$/Gyr', fontsize=12)
    ax4.set_ylabel('$\log Z_*/Z_\odot$', fontsize=12)

    ax1t.set_xscale('log')
    ax1t.set_xlim(0.008, Txmax)
    ax2t.set_xscale('log')
    ax2t.set_xlim(0.008, Txmax)
    ax4t.set_xscale('log')
    ax4t.set_xlim(0.008, Txmax)

    ax4.set_xlim(0.008, Txmax)
    ax4.set_ylim(y3min-0.05, y3max)
    ax4.set_xscale('log')

    ax4.set_yticks([-0.8, -0.4, 0., 0.4])
    ax4.set_yticklabels(['-0.8', '-0.4', '0', '0.4'])
    #ax4.yaxis.set_major_formatter(FormatStrFormatter('%.2f'))

    #ax3.yaxis.labelpad = -2
    ax4.yaxis.labelpad = -2


    ax1t.set_xticklabels(zredl[:])
    ax1t.set_xticks(Tzz[:])
    ax1t.tick_params(axis='x', labelcolor='k')
    ax1t.xaxis.set_ticks_position('none')
    #ax1t.plot(Tzz, Tzz*0+y3max+(y3max-y3min)*.00, marker='|', color='k', ms=3, linestyle='None')

    ax2t.set_xticklabels(zredl[:])
    ax2t.set_xticks(Tzz[:])
    ax2t.tick_params(axis='x', labelcolor='k')
    ax2t.xaxis.set_ticks_position('none')
    #ax2t.plot(Tzz, Tzz*0+y3max+(y3max-y3min)*.00, marker='|', color='k', ms=3, linestyle='None')

    ax4t.set_xticklabels(zredl[:])
    ax4t.set_xticks(Tzz[:])
    ax4t.tick_params(axis='x', labelcolor='k')
    ax4t.xaxis.set_ticks_position('none')
    ax4t.plot(Tzz, Tzz*0+y3max+(y3max-y3min)*.00, marker='|', color='k', ms=3, linestyle='None')

    ax1.plot(Tzz, Tzz*0+lsfru+(lsfru-lsfrl)*.00, marker='|', color='k', ms=3, linestyle='None')
    ax2.plot(Tzz, Tzz*0+y2max+(y2max-y2min)*.00, marker='|', color='k', ms=3, linestyle='None')

    ####################
    ## Save
    ####################
    #plt.show()
    #ax1.legend(loc=2, fontsize=8)
    #ax2.legend(loc=3, fontsize=8)
    plt.savefig('SFH_' + ID0 + '_PA' + PA + '_pcl.png')
Example #14
0
def plot_evolv(ID0, PA, Z=np.arange(-1.2,0.4249,0.05), age=[0.01, 0.1, 0.3, 0.7, 1.0, 3.0], f_comp = 0, fil_path = './FILT/', inputs=None, dust_model=0, DIR_TMP='./templates/', delt_sfh = 0.01, nmc=300):
    #
    # delt_sfh (float): delta t of input SFH in Gyr.
    #
    # Returns: SED as function of age, based on SF and Z histories;
    #
    ################
    flim = 0.01
    lsfrl = -1 # log SFR low limit
    mmax  = 1000
    Txmax = 4 # Max x value
    lmmin = 10.3

    nage = np.arange(0,len(age),1)
    fnc  = Func(Z, nage, dust_model=dust_model) # Set up the number of Age/ZZ
    bfnc = Basic(Z)
    age = np.asarray(age)

    ################
    # RF colors.
    import os.path
    home = os.path.expanduser('~')
    c      = 3.e18 # A/s
    chimax = 1.
    mag0   = 25.0
    d      = 10**(73.6/2.5) * 1e-18 # From [ergs/s/cm2/A] to [ergs/s/cm2/Hz]

    #############
    # Plot.
    #############
    fig = plt.figure(figsize=(5,2.6))
    fig.subplots_adjust(top=0.96, bottom=0.16, left=0.12, right=0.99, hspace=0.15, wspace=0.15)
    #ax1 = fig.add_subplot(131)
    #ax2 = fig.add_subplot(132)
    #ax3 = fig.add_subplot(133)
    ax2 = fig.add_subplot(121)
    ax3 = fig.add_subplot(122)

    ###########################
    # Open result file
    ###########################
    file = 'summary_' + ID0 + '_PA' + PA + '.fits'
    hdul = fits.open(file) # open a FITS file
    zbes = hdul[0].header['z']
    chinu= hdul[1].data['chi']
    uv= hdul[1].data['uv']
    vj= hdul[1].data['vj']

    try:
        RA   = hdul[0].header['RA']
        DEC  = hdul[0].header['DEC']
    except:
        RA  = 0
        DEC = 0

    try:
        SN = hdul[0].header['SN']
    except:
        ###########################
        # Get SN of Spectra
        ###########################
        file = 'templates/spec_obs_' + ID0 + '_PA' + PA + '.cat'
        fds  = np.loadtxt(file, comments='#')
        nrs  = fds[:,0]
        lams = fds[:,1]
        fsp  = fds[:,2]
        esp  = fds[:,3]

        consp = (nrs<10000) & (lams/(1.+zbes)>3600) & (lams/(1.+zbes)<4200)
        if len((fsp/esp)[consp]>10):
            SN = np.median((fsp/esp)[consp])
        else:
            SN = 1

    Asum = 0
    A50 = np.arange(len(age), dtype='float32')
    for aa in range(len(A50)):
        A50[aa] = hdul[1].data['A'+str(aa)][1]
        Asum += A50[aa]

    # Cosmo;
    DL = cd.luminosity_distance(zbes, **cosmo) * Mpc_cm # Luminositydistance in cm
    Cons = (4.*np.pi*DL**2/(1.+zbes))
    Tuni = cd.age(zbes, use_flat=True, **cosmo)
    Tuni0 = (Tuni/cc.Gyr_s - age[:])

    # Open summary;
    file = 'summary_' + ID0 + '_PA' + PA + '.fits'
    fd   = fits.open(file)[1].data
    #print(fits.open(file)[1].header)
    Avtmp = fd['Av0']
    uvtmp = fd['uv']
    vjtmp = fd['vj']
    #ax2.plot(vj[1],uv[1],color='gray',marker='s',ms=3)

    # SFH
    file = DIR_TMP + 'obshist_' + ID0 + '_PA' + PA + '.fits'
    fd   = fits.open(file)[1].data
    age  = fd['age']
    sfh  = fd['sfh']
    zh   = fd['zh']

    # Open FSPS temp;
    file = DIR_TMP + 'obsspec_' + ID0 + '_PA' + PA + '.fits'
    fd   = fits.open(file)[1].data
    wave = fd['wavelength']
    nr   = fd['colnum']
    uvall= age * 0 - 99
    vjall= age * 0 - 99

    delp = -10
    flag = False
    flag2= False
    #for ii in range(1,len(age),10):
    for ii in range(len(age)-1,-1,delp):
        flux = fd['fspec_%d'%(ii)]
        flux_att = madau_igm_abs(wave/(1.+zbes), flux, zbes)
        flux_d, xxd, nrd = dust_calz(wave/(1.+zbes), flux_att, 0.0, nr)
        #ax1.plot(xxd,flux_d,linestyle='-',lw=0.3+0.1*ii/len(age))
        band0  = ['u','v','j']
        lmconv,fconv = filconv(band0, xxd, flux_d, fil_path) # flux in fnu
        uv = -2.5*np.log10(fconv[0]/fconv[1])
        vj = -2.5*np.log10(fconv[1]/fconv[2])
        uvall[ii] = uv
        vjall[ii] = vj
        #ax2.plot(vjall[ii],uvall[ii],marker='s',ms=5,linestyle='-',zorder=5)

        if flag and not flag2:
            flux_d, xxd, nrd = dust_calz(wave/(1.+zbes), flux_att, Avtmp[1], nr)
            lmconv,fconv = filconv(band0, xxd, flux_d, fil_path) # flux in fnu
            uv_av = -2.5*np.log10(fconv[0]/fconv[1])
            vj_av = -2.5*np.log10(fconv[1]/fconv[2])
            delvj, deluv = vj_av-vj, uv_av-uv
            flag2 = True
        flag = True

    #import matplotlib.colormaps as cm
    conuvj = (vjall>-90)&(uvall>-90)
    ax2.plot(vjall[conuvj],uvall[conuvj],marker='s',markeredgecolor='k',color='none',ms=5,zorder=4)
    ax2.scatter(vjall[conuvj],uvall[conuvj],marker='s',c=age[conuvj],cmap='jet',s=8,zorder=5)
    ax2.plot(vjall[conuvj],uvall[conuvj],marker='',color='k',ms=3,linestyle='-',zorder=3)
    ax3.plot(age,np.log10(sfh),color='b', linewidth=1, linestyle='-',label=r'$\log$SFR$/M_\odot$yr$^{-1}$')
    ax3.plot(age,zh,color='r', linewidth=1, linestyle='-',label=r'$\log Z_*/Z_\odot$')

    '''
    ax1.set_xlim(1000,40000)
    ax1.set_xscale('log')
    ax1.set_ylim(1e-2,1e2)
    ax1.set_yscale('log')
    ax1.set_xlabel('Wavelength')
    '''

    ax2.set_xlim(-0.3,2.3)
    ax2.set_ylim(-0.3,2.3)

    ax2.set_xlabel('$V-J\,$/ mag')
    ax2.set_ylabel('$U-V\,$/ mag')
    ax3.set_xlabel('age / Gyr')
    #ax3.set_ylabel('$\log$SFR$/M_\odot$yr$^{-1}$ or $\log Z_*/Z_\odot$')

    ##
    prog_path = '/Users/tmorishita/GitHub/gsf/gsf/example/misc/'
    data_uvj = np.loadtxt(prog_path+'f2.cat',comments='#')
    x=data_uvj[:,0]
    y=data_uvj[:,1]
    ax2.plot(x,y,color="gray",lw=1,ls="-")

    data_uvj = np.loadtxt(prog_path+'g2.cat',comments='#')
    x=data_uvj[:,0]
    y=data_uvj[:,1]
    ax2.plot(x,y,color="gray",lw=1,ls="-")

    data_uvj = np.loadtxt(prog_path+'h2.cat',comments='#')
    x=data_uvj[:,0]
    y=data_uvj[:,1]
    ax2.plot(x,y,color="gray",lw=1,ls="-")

    try:
        av=np.array([1.2,0.,delvj,deluv])
        X,Y,U,V=zip(av)
        ax2.quiver(X,Y,U,V,angles='xy',scale_units='xy',scale=1,linewidth=1,color="k")
    except:
        pass

    ax2.text(-0.1,2.1,'Quiescent',fontsize=11,color='orangered')
    ax2.text(1.3,-0.2,'Starforming',fontsize=11,color='royalblue')

    ax3.legend(loc=3)
    #plt.show()
    plt.savefig('hist_' + ID0 + '_PA' + PA + '.pdf')
Example #15
0
def plotLFevo(
        hist=None,
        params=B2008,
        extrap_var='t',
        #maglim = -21.07 - 2.5 * numpy.log10(0.2)):
        maglim=-21. - 2.5 * numpy.log10(0.2),
        z_max=20.0,
        skipIon=True):
    """Plot evolution of luminosity function params and total luminsity.

    Schechter function at each redshift is integrated up to maglim to
    find total luminsity.
    """

    for (k, v) in params.iteritems():
        params[k] = numpy.asarray(v)

    if hist is None:
        cosmo = cp.WMAP7_BAO_H0_mean(flat=True)
        hist = LFHistory(params, extrap_var=extrap_var, **cosmo)
    else:
        params = hist.params
        extrap_var = hist.extrap_var
        cosmo = hist.cosmo

    z = params['z']
    t = cd.age(z, **cosmo)[0] / cc.yr_s
    MStar = params['MStar']
    phiStar = params['phiStar']
    alpha = params['alpha']

    if maglim is None:
        ltot = schechterTotLM(MStar=MStar, phiStar=phiStar, alpha=alpha)
    else:
        ltot = schechterCumuLM(magnitudeAB=maglim,
                               MStar=MStar,
                               phiStar=phiStar,
                               alpha=alpha)

    print(hist._MStarfunc.extrap_string())

    zPlot = numpy.arange(z.min() - 0.1, z_max, 0.1)
    tPlot = cd.age(zPlot, **cosmo)[0] / cc.yr_s
    newparams = hist.params_z(zPlot)
    MPlot = newparams['MStar']
    phiPlot = newparams['phiStar']
    alphaPlot = newparams['alpha']

    if maglim is None:
        ltotPlot = hist.schechterTotLM(zPlot)
    else:
        ltotPlot = hist.schechterCumuLM(zPlot, magnitudeAB=maglim)
    # From Table 6 of 2008ApJ...686..230B
    lB2008 = 10.**numpy.array([26.18, 25.85, 25.72, 25.32, 25.14])

    iPhot = hist.iPhotonRateDensity_z(zPlot, maglim=maglim)
    #    iPhotFunc = lambda t1: cc.yr_s * hist.iPhotonRateDensity_t(t1,
    #                                                               maglim=maglim)

    if not skipIon:
        xH = hist.ionization(zPlot, maglim)
    import pylab
    pylab.figure(1)
    pylab.gcf().set_label('LFion_vs_z')
    if skipIon:
        pylab.subplot(111)
    else:
        pylab.subplot(211)
    pylab.plot(zPlot, iPhot)
    if not skipIon:
        pylab.subplot(212)
        pylab.plot(zPlot, xH)
        pylab.ylim(0.0, 1.5)

    pylab.figure(2)
    pylab.gcf().set_label('LFparams_vs_z')
    pylab.subplot(311)
    pylab.plot(z, MStar, '-')
    pylab.plot(z, MStar, 'o')
    pylab.plot(zPlot, MPlot, ':')

    pylab.subplot(312)
    pylab.plot(z, phiStar, '-')
    pylab.plot(z, phiStar, 'o')
    pylab.plot(zPlot, phiPlot, ':')

    pylab.subplot(313)
    pylab.plot(z, alpha, '-')
    pylab.plot(z, alpha, 'o')
    pylab.plot(zPlot, alphaPlot, ':')

    pylab.figure(3)
    pylab.gcf().set_label('LFparams_vs_t')
    pylab.subplot(311)
    pylab.plot(t, MStar, '-')
    pylab.plot(t, MStar, 'o')
    pylab.plot(tPlot, MPlot, ':')

    pylab.subplot(312)
    pylab.plot(t, phiStar, '-')
    pylab.plot(t, phiStar, '.')
    pylab.plot(tPlot, phiPlot, ':')

    pylab.subplot(313)
    pylab.plot(t, alpha, '-')
    pylab.plot(t, alpha, 'o')
    pylab.plot(tPlot, alphaPlot, ':')

    pylab.figure(4)
    pylab.gcf().set_label('LFlum_vs_z')
    pylab.subplot(121)
    pylab.plot(z, ltot, 'o')
    pylab.plot(z, lB2008, 'x')
    pylab.plot(zPlot, ltotPlot)

    pylab.subplot(122)
    pylab.plot(t, ltot, 'o')
    pylab.plot(t, lB2008, 'x')
    pylab.plot(tPlot, ltotPlot)
Example #16
0
    def main(self,
             ID0,
             PA0,
             zgal,
             flag_m,
             zprev,
             Cz0,
             Cz1,
             mcmcplot=True,
             fzvis=1,
             specplot=1,
             fneld=0,
             ntemp=5,
             sigz=1.0,
             ezmin=0.01,
             f_move=False,
             f_disp=False
             ):  # flag_m related to redshift error in redshift check func.
        #
        # sigz (float): confidence interval for redshift fit.
        # ezmin (float): minimum error in redshift.
        #
        print('########################')
        print('### Fitting Function ###')
        print('########################')
        start = timeit.default_timer()

        inputs = self.inputs
        DIR_TMP = inputs['DIR_TEMP']

        if os.path.exists(DIR_TMP) == False:
            os.mkdir(DIR_TMP)

        # For error parameter
        ferr = 0

        #
        # Age
        #
        age = inputs['AGE']
        age = [float(x.strip()) for x in age.split(',')]
        nage = np.arange(0, len(age), 1)

        #
        # Metallicity
        #
        Zmax, Zmin = float(inputs['ZMAX']), float(inputs['ZMIN'])
        delZ = float(inputs['DELZ'])
        Zall = np.arange(Zmin, Zmax, delZ)  # in logZsun

        # For minimizer.
        delZtmp = delZ
        #delZtmp = 0.4 # to increase speed.

        # For z prior.
        delzz = 0.001
        zlimu = 6.
        snlim = 1
        zliml = zgal - 0.5
        agemax = cd.age(zgal, use_flat=True, **cosmo) / cc.Gyr_s

        # N of param:
        try:
            ndim = int(inputs['NDIM'])
            print('No of params are : %d' % (ndim))
        except:
            if int(inputs['ZEVOL']) == 1:
                ndim = int(len(nage) * 2 + 1)
                print('Metallicity evolution is on.')
                if int(inputs['ZMC']) == 1:
                    ndim += 1
                print('No of params are : %d' % (ndim))
            else:
                ndim = int(len(nage) + 1 + 1)
                print('Metallicity evolution is off.')
                if int(inputs['ZMC']) == 1:
                    ndim += 1
                print('No of params are : %d' % (ndim))
            pass

        #
        # Line
        #
        LW0 = inputs['LINE']
        LW0 = [float(x.strip()) for x in LW0.split(',')]

        #
        # Params for MCMC
        #
        nmc = int(inputs['NMC'])
        nwalk = int(inputs['NWALK'])
        nmc_cz = int(inputs['NMCZ'])
        nwalk_cz = int(inputs['NWALKZ'])
        f_Zevol = int(inputs['ZEVOL'])
        #f_zvis   = int(inputs['ZVIS'])
        try:
            fzmc = int(inputs['ZMC'])
        except:
            fzmc = 0

        #
        # If FIR data;
        #
        try:
            DT0 = float(inputs['TDUST_LOW'])
            DT1 = float(inputs['TDUST_HIG'])
            dDT = float(inputs['TDUST_DEL'])
            Temp = np.arange(DT0, DT1, dDT)
            f_dust = True
            print('FIR fit is on.')
        except:
            f_dust = False
            pass

        #
        # Tau for MCMC parameter; not as fitting parameters.
        #
        tau0 = inputs['TAU0']
        tau0 = [float(x.strip()) for x in tau0.split(',')]

        #
        # Dust model specification;
        #
        try:
            dust_model = int(inputs['DUST_MODEL'])
        except:
            dust_model = 0

        from .function_class import Func
        from .basic_func import Basic
        fnc = Func(Zall, nage, dust_model=dust_model,
                   DIR_TMP=DIR_TMP)  # Set up the number of Age/ZZ
        bfnc = Basic(Zall)

        # Open ascii file and stock to array.
        #lib = open_spec(ID0, PA0)
        lib = fnc.open_spec_fits(ID0, PA0, fall=0, tau0=tau0)
        lib_all = fnc.open_spec_fits(ID0, PA0, fall=1, tau0=tau0)

        if f_dust:
            lib_dust = fnc.open_spec_dust_fits(ID0,
                                               PA0,
                                               Temp,
                                               fall=0,
                                               tau0=tau0)
            lib_dust_all = fnc.open_spec_dust_fits(ID0,
                                                   PA0,
                                                   Temp,
                                                   fall=1,
                                                   tau0=tau0)

        #################
        # Observed Data
        #################
        ##############
        # Spectrum
        ##############
        dat = np.loadtxt(DIR_TMP + 'spec_obs_' + ID0 + '_PA' + PA0 + '.cat',
                         comments='#')
        NR = dat[:, 0]
        x = dat[:, 1]
        fy00 = dat[:, 2]
        ey00 = dat[:, 3]

        con0 = (NR < 1000)
        fy0 = fy00[con0] * Cz0
        ey0 = ey00[con0] * Cz0
        con1 = (NR >= 1000) & (NR < 10000)
        fy1 = fy00[con1] * Cz1
        ey1 = ey00[con1] * Cz1

        # BB data in spec_obs are not in use.
        #con2 = (NR>=10000) # BB
        #fy2  = fy00[con2]
        #ey2  = ey00[con2]

        ##############
        # Broadband
        ##############
        dat = np.loadtxt(DIR_TMP + 'bb_obs_' + ID0 + '_PA' + PA0 + '.cat',
                         comments='#')
        NRbb = dat[:, 0]
        xbb = dat[:, 1]
        fybb = dat[:, 2]
        eybb = dat[:, 3]
        exbb = dat[:, 4]
        fy2 = fybb
        ey2 = eybb

        fy01 = np.append(fy0, fy1)
        fy = np.append(fy01, fy2)
        ey01 = np.append(ey0, ey1)
        ey = np.append(ey01, ey2)

        wht = 1. / np.square(ey)
        wht2 = check_line_man(fy, x, wht, fy, zprev, LW0)
        sn = fy / ey

        #####################
        # Function fo MCMC
        #####################
        def residual(
                pars,
                fy,
                wht2,
                f_fir,
                out=False):  # x, y, wht are taken from out of the definition.
            #
            # Returns: residual of model and data.
            # out: model as second output. For lnprob func.
            # f_fir: syntax. If dust component is on or off.
            vals = pars.valuesdict()
            model, x1 = fnc.tmp04(ID0, PA0, vals, zprev, lib, tau0=tau0)
            if f_fir:
                model_dust, x1_dust = fnc.tmp04_dust(ID0,
                                                     PA0,
                                                     vals,
                                                     zprev,
                                                     lib_dust,
                                                     tau0=tau0)
                n_optir = len(model)
                # Add dust flux to opt/IR grid.
                model[:] += model_dust[:n_optir]
                #print(model_dust)
                # then append only FIR flux grid.
                model = np.append(model, model_dust[n_optir:])
                x1 = np.append(x1, x1_dust[n_optir:])
                #plt.plot(x1,model,'r.')
                #plt.show()

            if ferr == 1:
                f = vals['f']
            else:
                f = 0  # temporary... (if f is param, then take from vals dictionary.)
            con_res = (model > 0) & (wht2 > 0)  #& (fy>0)
            sig = np.sqrt(1. / wht2 + f**2 * model**2)
            '''
            contmp = x1>1e6 & (wht2>0)
            try:
                print(x1[contmp],model[contmp],fy[contmp],np.log10(vals['MDUST']))
            except:
                pass
            '''

            if not out:
                if fy is None:
                    print('Data is none')
                    return model[con_res]
                else:
                    return (model - fy)[con_res] / sig[
                        con_res]  # i.e. residual/sigma. Because is_weighted = True.
            if out:
                if fy is None:
                    print('Data is none')
                    return model[con_res], model
                else:
                    return (model - fy)[con_res] / sig[
                        con_res], model  # i.e. residual/sigma. Because is_weighted = True.

        def lnprob(pars, fy, wht2, f_fir):
            #
            # Returns: posterior.
            #
            vals = pars.valuesdict()
            if ferr == 1:
                f = vals['f']
            else:
                f = 0  # temporary... (if f is param, then take from vals dictionary.)
            resid, model = residual(pars, fy, wht2, f_fir, out=True)
            con_res = (model > 0) & (wht2 > 0)
            sig = np.sqrt(1. / wht2 + f**2 * model**2)
            lnlike = -0.5 * np.sum(resid**2 +
                                   np.log(2 * 3.14 * sig[con_res]**2))
            #print(np.log(2 * 3.14 * 1) * len(sig[con_res]), np.sum(np.log(2 * 3.14 * sig[con_res]**2)))
            #Av   = vals['Av']
            #if Av<0:
            #     return -np.inf
            #else:
            #    respr = 0 #np.log(1)
            respr = 0  # Flat prior...
            return lnlike + respr

        ###############################
        # Add parameters
        ###############################
        fit_params = Parameters()
        for aa in range(len(age)):
            if age[aa] == 99 or age[aa] > agemax:
                fit_params.add('A' + str(aa), value=0, min=0, max=1e-10)
            else:
                fit_params.add('A' + str(aa), value=1, min=0, max=1e3)

        #####################
        # Dust attenuation
        #####################
        try:
            Avmin = float(inputs['AVMIN'])
            Avmax = float(inputs['AVMAX'])
            fit_params.add('Av', value=Avmin, min=Avmin, max=Avmax)
        except:
            fit_params.add('Av', value=0.2, min=0, max=4.0)

        #####################
        # Metallicity
        #####################
        if int(inputs['ZEVOL']) == 1:
            for aa in range(len(age)):
                if age[aa] == 99 or age[aa] > agemax:
                    fit_params.add('Z' + str(aa), value=0, min=0, max=1e-10)
                else:
                    fit_params.add('Z' + str(aa),
                                   value=0,
                                   min=np.min(Zall),
                                   max=np.max(Zall))
        elif inputs['ZFIX']:
            #print('Z is fixed')
            ZFIX = float(inputs['ZFIX'])
            aa = 0
            fit_params.add('Z' + str(aa), value=0, min=ZFIX, max=ZFIX + 0.01)
        else:
            aa = 0
            fit_params.add('Z' + str(aa),
                           value=0,
                           min=np.min(Zall),
                           max=np.max(Zall))

        ####################################
        # Initial Metallicity Determination
        ####################################
        chidef = 1e5
        Zbest = 0

        fwz = open('Z_' + ID0 + '_PA' + PA0 + '.cat', 'w')
        fwz.write('# ID Zini chi/nu AA Av Zbest\n')
        fwz.write('# FNELD = %d\n' % fneld)

        nZtmp = int((Zmax - Zmin) / delZtmp)
        ZZtmp = np.arange(Zmin, Zmax, delZtmp)

        # How to get initial parameters?
        # Nelder;
        if fneld == 1:
            fit_name = 'nelder'
            for zz in range(len(ZZtmp)):
                ZZ = ZZtmp[zz]
                if int(inputs['ZEVOL']) == 1:
                    for aa in range(len(age)):
                        fit_params['Z' + str(aa)].value = ZZ
                else:
                    aa = 0
                    fit_params['Z' + str(aa)].value = ZZ

                out_tmp = minimize(
                    residual,
                    fit_params,
                    args=(fy, wht2, False),
                    method=fit_name)  # nelder is the most efficient.
                keys = fit_report(out_tmp).split('\n')
                csq = 99999
                rcsq = 99999
                for key in keys:
                    if key[4:7] == 'chi':
                        skey = key.split(' ')
                        csq = float(skey[14])
                    if key[4:7] == 'red':
                        skey = key.split(' ')
                        rcsq = float(skey[7])

                fitc = [csq, rcsq]  # Chi2, Reduced-chi2

                fwz.write('%s %.2f %.5f' % (ID0, ZZ, fitc[1]))

                AA_tmp = np.zeros(len(age), dtype='float32')
                ZZ_tmp = np.zeros(len(age), dtype='float32')
                for aa in range(len(age)):
                    AA_tmp[aa] = out_tmp.params['A' + str(aa)].value
                    fwz.write(' %.5f' % (AA_tmp[aa]))

                Av_tmp = out_tmp.params['Av'].value
                fwz.write(' %.5f' % (Av_tmp))
                if int(inputs['ZEVOL']) == 1:
                    for aa in range(len(age)):
                        ZZ_tmp[aa] = out_tmp.params['Z' + str(aa)].value
                        fwz.write(' %.5f' % (ZZ_tmp[aa]))
                else:
                    aa = 0
                    ZZ_tmp[aa] = out_tmp.params['Z' + str(aa)].value
                    fwz.write(' %.5f' % (ZZ_tmp[aa]))

                fwz.write('\n')
                if fitc[1] < chidef:
                    chidef = fitc[1]
                    out = out_tmp
        # Or
        # Powell;
        else:
            fit_name = 'powell'
            for zz in range(0, nZtmp, 2):
                ZZ = zz * delZtmp + np.min(Zall)
                if int(inputs['ZEVOL']) == 1:
                    for aa in range(len(age)):
                        fit_params['Z' + str(aa)].value = ZZ
                else:
                    aa = 0
                    fit_params['Z' + str(aa)].value = ZZ

                out_tmp = minimize(
                    residual,
                    fit_params,
                    args=(fy, wht2, False),
                    method=fit_name)  # powel is the more accurate.
                keys = fit_report(out_tmp).split('\n')
                csq = 99999
                rcsq = 99999
                for key in keys:
                    if key[4:7] == 'chi':
                        skey = key.split(' ')
                        csq = float(skey[14])
                    if key[4:7] == 'red':
                        skey = key.split(' ')
                        rcsq = float(skey[7])

                fitc = [csq, rcsq]  # Chi2, Reduced-chi2
                fwz.write('%s %.2f %.5f' % (ID0, ZZ, fitc[1]))

                AA_tmp = np.zeros(len(age), dtype='float32')
                ZZ_tmp = np.zeros(len(age), dtype='float32')
                for aa in range(len(age)):
                    AA_tmp[aa] = out_tmp.params['A' + str(aa)].value
                    fwz.write(' %.5f' % (AA_tmp[aa]))

                Av_tmp = out_tmp.params['Av'].value
                fwz.write(' %.5f' % (Av_tmp))
                if int(inputs['ZEVOL']) == 1:
                    for aa in range(len(age)):
                        ZZ_tmp[aa] = out_tmp.params['Z' + str(aa)].value
                        fwz.write(' %.5f' % (ZZ_tmp[aa]))
                else:
                    aa = 0
                    fwz.write(' %.5f' % (ZZ_tmp[aa]))

                fwz.write('\n')
                if fitc[1] < chidef:
                    chidef = fitc[1]
                    out = out_tmp

        #
        # Best fit
        #
        keys = fit_report(out).split('\n')
        for key in keys:
            if key[4:7] == 'chi':
                skey = key.split(' ')
                csq = float(skey[14])
            if key[4:7] == 'red':
                skey = key.split(' ')
                rcsq = float(skey[7])

        fitc = [csq, rcsq]  # Chi2, Reduced-chi2
        #fitc = fit_report_chi(out) # Chi2, Reduced-chi2
        ZZ = Zbest  # This is really important/does affect lnprob/residual.

        print('\n\n')
        print('#####################################')
        print('Zbest, chi are;', Zbest, chidef)
        print('Params are;', fit_report(out))
        print('#####################################')
        print('\n\n')
        fwz.close()

        Av_tmp = out.params['Av'].value
        AA_tmp = np.zeros(len(age), dtype='float32')
        ZZ_tmp = np.zeros(len(age), dtype='float32')
        fm_tmp, xm_tmp = fnc.tmp04_val(ID0, PA0, out, zprev, lib, tau0=tau0)

        ########################
        # Check redshift
        ########################
        zrecom = zprev

        # Observed data.
        con_cz = (NR < 10000)  #& (sn>snlim)
        fy_cz = fy[con_cz]
        ey_cz = ey[con_cz]
        x_cz = x[con_cz]  # Observed range
        NR_cz = NR[con_cz]

        xm_s = xm_tmp / (1 + zprev) * (1 + zrecom)
        fm_s = np.interp(x_cz, xm_s, fm_tmp)

        if fzvis == 1:
            plt.plot(x_cz / (1 + zprev) * (1. + zrecom),
                     fm_s,
                     'gray',
                     linestyle='--',
                     linewidth=0.5,
                     label='Default ($z=%.5f$)' %
                     (zprev))  # Model based on input z.
            plt.plot(x_cz,
                     fy_cz,
                     'b',
                     linestyle='-',
                     linewidth=0.5,
                     label='Obs.')  # Observation
            plt.errorbar(x_cz,
                         fy_cz,
                         yerr=ey_cz,
                         color='b',
                         capsize=0,
                         linewidth=0.5)  # Observation

        if flag_m == 0:
            dez = 0.5
        else:
            dez = 0.2

        #
        # For Eazy
        #
        '''
        dprob = np.loadtxt(eaz_path + 'photz_' + str(int(ID0)) + '.pz', comments='#')
        zprob = dprob[:,0]
        cprob = dprob[:,1]

        zz_prob = np.arange(0,13,delzz)
        cprob_s = np.interp(zz_prob, zprob, cprob)
        prior_s = 1/cprob_s
        prior_s /= np.sum(prior_s)
        '''

        zz_prob = np.arange(0, 13, delzz)
        prior_s = zz_prob * 0 + 1.
        prior_s /= np.sum(prior_s)

        try:
            print('############################')
            print('Start MCMC for redshift fit')
            print('############################')
            res_cz, fitc_cz = check_redshift(fy_cz, ey_cz, x_cz, fm_tmp,
                                             xm_tmp / (1 + zprev), zprev, dez,
                                             prior_s, NR_cz, zliml, zlimu,
                                             delzz, nmc_cz, nwalk_cz)
            z_cz = np.percentile(res_cz.flatchain['z'], [16, 50, 84])
            scl_cz0 = np.percentile(res_cz.flatchain['Cz0'], [16, 50, 84])
            scl_cz1 = np.percentile(res_cz.flatchain['Cz1'], [16, 50, 84])

            zrecom = z_cz[1]
            Czrec0 = scl_cz0[1]
            Czrec1 = scl_cz1[1]

            # Switch to peak redshift:
            from scipy import stats
            from scipy.stats import norm
            # find minimum and maximum of xticks, so we know
            # where we should compute theoretical distribution
            ser = res_cz.flatchain['z']
            xmin, xmax = zprev - 0.2, zprev + 0.2
            lnspc = np.linspace(xmin, xmax, len(ser))
            print('\n\n')
            print(
                'Recommended redshift, Cz0 and Cz1, %.5f %.5f %.5f, with chi2/nu=%.3f'
                % (zrecom, Cz0 * Czrec0, Cz1 * Czrec1, fitc_cz[1]))
            print('\n\n')

        except:
            print('z fit failed. No spectral data set?')
            try:
                ezl = float(inputs['EZL'])
                ezu = float(inputs['EZU'])
                print('Redshift error is taken from input file.')
                if ezl < ezmin:
                    ezl = ezmin  #0.03
                if ezu < ezmin:
                    ezu = ezmin  #0.03
            except:
                ezl = ezmin
                ezu = ezmin
                print('Redshift error is assumed to %.1f.' % (ezl))
            z_cz = [zprev - ezl, zprev, zprev + ezu]
            zrecom = z_cz[1]
            scl_cz0 = [1., 1., 1.]
            scl_cz1 = [1., 1., 1.]
            Czrec0 = scl_cz0[1]
            Czrec1 = scl_cz1[1]
        '''
        try:
            # lets try the normal distribution first
            m, s  = stats.norm.fit(ser) # get mean and standard deviation
            pdf_g = stats.norm.pdf(lnspc, m, s) # now get theoretical values in our interval
            z_cz[:]    = [m-s, m, m+s]
            zrecom     = z_cz[1]
            f_fitgauss = 1
        except:
            print('Guassian fitting to z distribution failed.')
            f_fitgauss=0
        '''
        f_fitgauss = 0

        xm_s = xm_tmp / (1 + zprev) * (1 + zrecom)
        fm_s = np.interp(x_cz, xm_s, fm_tmp)
        whtl = 1 / np.square(ey_cz)
        try:
            wht3, ypoly = check_line_cz_man(fy_cz, x_cz, whtl, fm_s, zrecom,
                                            LW0)
        except:
            wht3, ypoly = whtl, fy_cz
        con_line = (wht3 == 0)

        if fzvis == 1:
            plt.plot(x_cz,
                     fm_s,
                     'r',
                     linestyle='-',
                     linewidth=0.5,
                     label='Updated model ($z=%.5f$)' %
                     (zrecom))  # Model based on recomended z.
            plt.plot(x_cz[con_line],
                     fm_s[con_line],
                     color='orange',
                     marker='o',
                     linestyle='',
                     linewidth=3.)
            # Plot lines for reference
            for ll in range(len(LW)):
                try:
                    conpoly = (x_cz /
                               (1. + zrecom) > 3000) & (x_cz /
                                                        (1. + zrecom) < 8000)
                    yline = np.max(ypoly[conpoly])
                    yy = np.arange(yline / 1.02, yline * 1.1)
                    xxpre = yy * 0 + LW[ll] * (1. + zprev)
                    xx = yy * 0 + LW[ll] * (1. + zrecom)
                    plt.plot(xxpre,
                             yy / 1.02,
                             linewidth=0.5,
                             linestyle='--',
                             color='gray')
                    plt.text(LW[ll] * (1. + zprev),
                             yline / 1.05,
                             '%s' % (LN[ll]),
                             fontsize=8,
                             color='gray')
                    plt.plot(xx,
                             yy,
                             linewidth=0.5,
                             linestyle='-',
                             color='orangered')
                    plt.text(LW[ll] * (1. + zrecom),
                             yline,
                             '%s' % (LN[ll]),
                             fontsize=8,
                             color='orangered')
                except:
                    pass

            plt.plot(xbb,
                     fybb,
                     '.r',
                     linestyle='',
                     linewidth=0,
                     zorder=4,
                     label='Obs.(BB)')
            plt.plot(xm_tmp,
                     fm_tmp,
                     color='gray',
                     marker='.',
                     ms=0.5,
                     linestyle='',
                     linewidth=0.5,
                     zorder=4,
                     label='Model')
            try:
                xmin, xmax = np.min(x_cz) / 1.1, np.max(x_cz) * 1.1
            except:
                xmin, xmax = 2000, 10000
            plt.xlim(xmin, xmax)
            try:
                plt.ylim(0, yline * 1.1)
            except:
                pass
            plt.xlabel('Wavelength ($\mathrm{\AA}$)')
            plt.ylabel('$F_\\nu$ (arb.)')
            plt.legend(loc=0)

            zzsigma = ((z_cz[2] - z_cz[0]) / 2.) / zprev
            zsigma = np.abs(zprev - zrecom) / (zprev)
            C0sigma = np.abs(Czrec0 - Cz0) / Cz0
            eC0sigma = ((scl_cz0[2] - scl_cz0[0]) / 2.) / Cz0
            C1sigma = np.abs(Czrec1 - Cz1) / Cz1
            eC1sigma = ((scl_cz1[2] - scl_cz1[0]) / 2.) / Cz1

            print('Input redshift is %.3f per cent agreement.' %
                  ((1. - zsigma) * 100))
            print('Error is %.3f per cent.' % (zzsigma * 100))
            print('Input Cz0 is %.3f per cent agreement.' %
                  ((1. - C0sigma) * 100))
            print('Error is %.3f per cent.' % (eC0sigma * 100))
            print('Input Cz1 is %.3f per cent agreement.' %
                  ((1. - C1sigma) * 100))
            print('Error is %.3f per cent.' % (eC1sigma * 100))
            plt.show()

            #
            # Ask interactively;
            #
            flag_z = raw_input(
                'Do you want to continue with original redshift, Cz0 and Cz1, %.5f %.5f %.5f? ([y]/n/m) '
                % (zprev, Cz0, Cz1))
        else:
            flag_z = 'y'

        #################################################
        # Gor for mcmc phase
        #################################################
        if flag_z == 'y' or flag_z == '':
            zrecom = zprev
            Czrec0 = Cz0
            Czrec1 = Cz1

            #######################
            # Added
            #######################
            if fzmc == 1:
                out_keep = out
                #sigz = 1.0 #3.0
                fit_params.add('zmc',
                               value=zrecom,
                               min=zrecom - (z_cz[1] - z_cz[0]) * sigz,
                               max=zrecom + (z_cz[2] - z_cz[1]) * sigz)
                #print(zrecom,zrecom-(z_cz[1]-z_cz[0])*sigz,zrecom+(z_cz[2]-z_cz[1])*sigz)
                #####################
                # Error parameter
                #####################
                try:
                    ferr = int(inputs['F_ERR'])
                    if ferr == 1:
                        fit_params.add('f', value=1e-2, min=0, max=1e2)
                        ndim += 1
                except:
                    ferr = 0
                    pass

                #####################
                # Dust;
                #####################
                if f_dust:
                    Tdust = np.arange(DT0, DT1, dDT)
                    fit_params.add('TDUST',
                                   value=len(Tdust) / 2.,
                                   min=0,
                                   max=len(Tdust) - 1)
                    #fit_params.add('TDUST', value=1, min=0, max=len(Tdust)-1)
                    fit_params.add('MDUST', value=1e6, min=0, max=1e10)
                    ndim += 2

                    # Append data;
                    dat_d = np.loadtxt(DIR_TMP + 'spec_dust_obs_' + ID0 +
                                       '_PA' + PA0 + '.cat',
                                       comments='#')
                    x_d = dat_d[:, 1]
                    fy_d = dat_d[:, 2]
                    ey_d = dat_d[:, 3]

                    fy = np.append(fy, fy_d)
                    x = np.append(x, x_d)
                    wht = np.append(wht, 1. / np.square(ey_d))
                    wht2 = check_line_man(fy, x, wht, fy, zprev, LW0)

                # Then, minimize again.
                out = minimize(
                    residual,
                    fit_params,
                    args=(fy, wht2, f_dust),
                    method=fit_name
                )  # It needs to define out with redshift constrain.
                print(fit_report(out))

                # Fix params to what we had before.
                out.params['zmc'].value = zrecom
                out.params['Av'].value = out_keep.params['Av'].value
                for aa in range(len(age)):
                    out.params['A' +
                               str(aa)].value = out_keep.params['A' +
                                                                str(aa)].value
                    try:
                        out.params['Z' + str(aa)].value = out_keep.params[
                            'Z' + str(aa)].value
                    except:
                        out.params['Z0'].value = out_keep.params['Z0'].value

            ##############################
            # Save fig of z-distribution.
            ##############################
            try:  # if spectrum;
                fig = plt.figure(figsize=(6.5, 2.5))
                fig.subplots_adjust(top=0.96,
                                    bottom=0.16,
                                    left=0.09,
                                    right=0.99,
                                    hspace=0.15,
                                    wspace=0.25)
                ax1 = fig.add_subplot(111)
                #n, nbins, patches = ax1.hist(res_cz.flatchain['z'], bins=200, normed=False, color='gray',label='')
                n, nbins, patches = ax1.hist(res_cz.flatchain['z'],
                                             bins=200,
                                             normed=True,
                                             color='gray',
                                             label='')
                if f_fitgauss == 1:
                    ax1.plot(lnspc,
                             pdf_g,
                             label='Gaussian fit',
                             color='g',
                             linestyle='-')  # plot it

                ax1.set_xlim(m - s * 3, m + s * 3)
                yy = np.arange(0, np.max(n), 1)
                xx = yy * 0 + z_cz[1]
                ax1.plot(
                    xx,
                    yy,
                    linestyle='-',
                    linewidth=1,
                    color='orangered',
                    label='$z=%.5f_{-%.5f}^{+%.5f}$\n$C_z0=%.3f$\n$C_z1=%.3f$'
                    % (z_cz[1], z_cz[1] - z_cz[0], z_cz[2] - z_cz[1], Czrec0,
                       Czrec1))
                xx = yy * 0 + z_cz[0]
                ax1.plot(xx,
                         yy,
                         linestyle='--',
                         linewidth=1,
                         color='orangered')
                xx = yy * 0 + z_cz[2]
                ax1.plot(xx,
                         yy,
                         linestyle='--',
                         linewidth=1,
                         color='orangered')
                xx = yy * 0 + zprev
                ax1.plot(xx, yy, linestyle='-', linewidth=1, color='royalblue')
                ax1.set_xlabel('Redshift')
                ax1.set_ylabel('$dn/dz$')
                ax1.legend(loc=0)
                plt.savefig('zprob_' + ID0 + '_PA' + PA0 + '.pdf', dpi=300)
                plt.close()
            except:
                print('z-distribution figure is not generated.')
                pass

            ##############################
            print('\n\n')
            print('###############################')
            print('Input redshift is adopted.')
            print('Starting long journey in MCMC.')
            print('###############################')
            print('\n\n')
            #################
            # Initialize mm.
            #################
            mm = 0
            # add a noise parameter
            # out.params.add('f', value=1, min=0.001, max=20)
            wht2 = wht

            ################################
            print('\nMinimizer Defined\n')
            mini = Minimizer(lnprob,
                             out.params,
                             fcn_args=[fy, wht2, f_dust],
                             f_disp=f_disp,
                             f_move=f_move)
            print('######################')
            print('### Starting emcee ###')
            print('######################')
            import multiprocess
            ncpu0 = int(multiprocess.cpu_count() / 2)
            try:
                ncpu = int(inputs['NCPU'])
                if ncpu > ncpu0:
                    print('!!! NCPU is larger than No. of CPU. !!!')
                    #print('Now set to %d'%(ncpu0))
                    #ncpu = ncpu0
            except:
                ncpu = ncpu0
                pass

            print('No. of CPU is set to %d' % (ncpu))
            start_mc = timeit.default_timer()
            res = mini.emcee(burn=int(nmc / 2),
                             steps=nmc,
                             thin=10,
                             nwalkers=nwalk,
                             params=out.params,
                             is_weighted=True,
                             ntemps=ntemp,
                             workers=ncpu)
            stop_mc = timeit.default_timer()
            tcalc_mc = stop_mc - start_mc
            print('###############################')
            print('### MCMC part took %.1f sec ###' % (tcalc_mc))
            print('###############################')

            #----------- Save pckl file
            #-------- store chain into a cpkl file
            start_mc = timeit.default_timer()
            import corner
            burnin = int(nmc / 2)
            savepath = './'
            cpklname = 'chain_' + ID0 + '_PA' + PA0 + '_corner.cpkl'
            savecpkl(
                {
                    'chain': res.flatchain,
                    'burnin': burnin,
                    'nwalkers': nwalk,
                    'niter': nmc,
                    'ndim': ndim
                }, savepath + cpklname)  # Already burn in
            stop_mc = timeit.default_timer()
            tcalc_mc = stop_mc - start_mc
            print('#################################')
            print('### Saving chain took %.1f sec' % (tcalc_mc))
            print('#################################')

            Avmc = np.percentile(res.flatchain['Av'], [16, 50, 84])
            #Zmc  = np.percentile(res.flatchain['Z'], [16,50,84])
            Avpar = np.zeros((1, 3), dtype='float32')
            Avpar[0, :] = Avmc

            out = res
            ####################
            # Best parameters
            ####################
            Amc = np.zeros((len(age), 3), dtype='float32')
            Ab = np.zeros(len(age), dtype='float32')
            Zmc = np.zeros((len(age), 3), dtype='float32')
            Zb = np.zeros(len(age), dtype='float32')
            NZbest = np.zeros(len(age), dtype='int')
            f0 = fits.open(DIR_TMP + 'ms_' + ID0 + '_PA' + PA0 + '.fits')
            sedpar = f0[1]
            ms = np.zeros(len(age), dtype='float32')
            for aa in range(len(age)):
                Ab[aa] = out.params['A' + str(aa)].value
                Amc[aa, :] = np.percentile(res.flatchain['A' + str(aa)],
                                           [16, 50, 84])
                try:
                    Zb[aa] = out.params['Z' + str(aa)].value
                    Zmc[aa, :] = np.percentile(res.flatchain['Z' + str(aa)],
                                               [16, 50, 84])
                except:
                    Zb[aa] = out.params['Z0'].value
                    Zmc[aa, :] = np.percentile(res.flatchain['Z0'],
                                               [16, 50, 84])
                NZbest[aa] = bfnc.Z2NZ(Zb[aa])
                ms[aa] = sedpar.data['ML_' + str(NZbest[aa])][aa]

            Avb = out.params['Av'].value

            if f_dust:
                Mdust_mc = np.zeros(3, dtype='float32')
                Tdust_mc = np.zeros(3, dtype='float32')
                Mdust_mc[:] = np.percentile(res.flatchain['MDUST'],
                                            [16, 50, 84])
                Tdust_mc[:] = np.percentile(res.flatchain['TDUST'],
                                            [16, 50, 84])
                print(Mdust_mc)
                print(Tdust_mc)

            ####################
            # MCMC corner plot.
            ####################
            if mcmcplot:
                fig1 = corner.corner(res.flatchain, labels=res.var_names, \
                label_kwargs={'fontsize':16}, quantiles=[0.16, 0.84], show_titles=False, \
                title_kwargs={"fontsize": 14}, truths=list(res.params.valuesdict().values()), \
                plot_datapoints=False, plot_contours=True, no_fill_contours=True, \
                plot_density=False, levels=[0.68, 0.95, 0.997], truth_color='gray', color='#4682b4')
                fig1.savefig('SPEC_' + ID0 + '_PA' + PA0 + '_corner.pdf')
                plt.close()

            #########################
            msmc0 = 0
            for aa in range(len(age)):
                msmc0 += res.flatchain['A' + str(aa)] * ms[aa]
            msmc = np.percentile(msmc0, [16, 50, 84])

            # Do analysis on MCMC results.
            # Write to file.
            stop = timeit.default_timer()
            tcalc = stop - start

            # Load writing package;
            from .writing import Analyze
            wrt = Analyze(inputs)  # Set up for input

            start_mc = timeit.default_timer()
            wrt.get_param(res,
                          lib_all,
                          zrecom,
                          Czrec0,
                          Czrec1,
                          z_cz[:],
                          scl_cz0[:],
                          scl_cz1[:],
                          fitc[:],
                          tau0=tau0,
                          tcalc=tcalc)
            stop_mc = timeit.default_timer()
            tcalc_mc = stop_mc - start_mc
            print('##############################################')
            print('### Writing params tp file took %.1f sec ###' % (tcalc_mc))
            print('##############################################')

            return 0, zrecom, Czrec0, Czrec1

        ###################################################################
        elif flag_z == 'm':
            zrecom = float(
                raw_input('What is your manual input for redshift? '))
            Czrec0 = float(raw_input('What is your manual input for Cz0? '))
            Czrec1 = float(raw_input('What is your manual input for Cz1? '))
            print('\n\n')
            print('Generate model templates with input redshift and Scale.')
            print('\n\n')
            return 1, zrecom, Czrec0, Czrec1

        else:
            print('\n\n')
            print('Terminated because of redshift estimate.')
            print('Generate model templates with recommended redshift.')
            print('\n\n')

            flag_gen = raw_input(
                'Do you want to make templates with recommended redshift, Cz0, and Cz1 , %.5f %.5f %.5f? ([y]/n) '
                % (zrecom, Czrec0, Czrec1))
            if flag_gen == 'y' or flag_gen == '':
                #return 1, zrecom, Cz0 * Czrec0, Cz1 * Czrec1
                return 1, zrecom, Czrec0, Czrec1
            else:
                print('\n\n')
                print('There is nothing to do.')
                print('\n\n')
                return 0, zprev, Czrec0, Czrec1
Example #17
0
    def __init__(self,
                 params=B2008,
                 MStar_bounds=['extrapolate', float('NaN')],
                 phiStar_bounds=['constant', float('NaN')],
                 alpha_bounds=['constant', float('NaN')],
                 extrap_args={},
                 extrap_var='z',
                 sedParams={},
                 wavelength=1500.,
                 **cosmo):

        for (k, v) in params.iteritems():
            params[k] = numpy.asarray(v)

        self.params = params
        self.MStar_bounds = MStar_bounds
        self.phiStar_bounds = phiStar_bounds
        self.alpha_bounds = alpha_bounds
        self.extrap_args = extrap_args
        self.extrap_var = extrap_var
        self.sedParams = sedParams
        self.wavelength = wavelength
        self.cosmo = cosmo

        self.zobs = params['z']
        self.tobs = cd.age(self.zobs, **cosmo)[0]
        self.MStar = params['MStar']
        self.phiStar = params['phiStar']
        self.alpha = params['alpha']

        if extrap_var == 't':
            self.xobs = self.tobs
            self._iPhotFunc = \
                       lambda t1, mag: (self.iPhotonRateDensity_t(t1,
                                                                  maglim=mag))

        elif extrap_var == 'z':
            self.xobs = self.zobs
            MStar_bounds = MStar_bounds[::-1]
            phiStar_bounds = phiStar_bounds[::-1]
            alpha_bounds = alpha_bounds[::-1]
            self._iPhotFunc = \
                        lambda z1, mag: (self.iPhotonRateDensity_z(z1,
                                                                   maglim=mag))

        self._MStarfunc = utils.Extrapolate1d(self.xobs,
                                              self.MStar,
                                              bounds_behavior=MStar_bounds,
                                              **extrap_args)
        print("M*:", )
        print(self._MStarfunc.extrap_string())

        self._phiStarfunc = utils.Extrapolate1d(self.xobs,
                                                self.phiStar,
                                                bounds_behavior=phiStar_bounds,
                                                **extrap_args)
        print("phi*:", )
        print(self._phiStarfunc.extrap_string())
        self._alphafunc = utils.Extrapolate1d(self.xobs,
                                              self.alpha,
                                              bounds_behavior=alpha_bounds,
                                              **extrap_args)
        print("alpha:", )
        print(self._alphafunc.extrap_string())

        self._SED = BrokenPowerlawSED(**sedParams)
        self._rQL = self._SED.iPhotonRateRatio(wavelength)

        for name, func in globals().items():
            if not name.startswith('schechter'):
                continue

            def newfunc(z, _name=name, _func=func, **kwargs):
                params = self.params_z(z)
                M = params['MStar']
                phi = params['phiStar']
                alpha = params['alpha']
                return _func(MStar=M, phiStar=phi, alpha=alpha, **kwargs)

            newfunc.__name__ = func.__name__
            newfunc.__doc__ = func.__doc__
            self.__dict__[name] = newfunc
Example #18
0
import matplotlib.pyplot as plt
from scipy.integrate import quad
from scipy.stats import truncnorm
import cosmolopy.distance as cd
import cosmolopy.constants as cc

nObj = 1000000

intercept = -8.
slope = 1.
scatter = 0.3

cosmo = {'omega_M_0' : 0.3, 'omega_lambda_0' : 0.7, 'h' : 0.7}
cosmo = cd.set_omega_k_0(cosmo)
zObs=2.0
ageUniv = cd.age(zObs, **cosmo)/cc.yr_s
ageUniv5 = cd.age(5.0, **cosmo)/cc.yr_s

msa = 10**np.random.uniform(low=6, high=np.log10(ageUniv), size=nObj)                      # yrs
tau = 10**np.random.uniform(low=7, high=10.5, size=nObj)                      # yrs
tau_exp = 10**np.random.uniform(low=7, high=10.5, size=nObj)                      # yrs
mass = 10**np.random.uniform(low=7, high=12, size=nObj)                         # solar masses



A = np.zeros(nObj)

for i in range(nObj):
    integrand = lambda T: T*np.heaviside(tau[i]-T, 0) + tau[i]*np.exp((tau[i]-T)/tau_exp[i])*np.heaviside(T-tau[i], 1)
    integral  = quad(integrand, 0, msa[i])
Example #19
0
def ionization_from_luminosity(z,
                               ratedensityfunc,
                               xHe=1.0,
                               rate_is_tfunc=False,
                               ratedensityfunc_args=(),
                               method='romberg',
                               **cosmo):
    """Integrate the ionization history given an ionizing luminosity
    function, ignoring recombinations.

    Parameters
    ----------
    
    ratedensityfunc: callable
        function giving comoving ionizing photon emission rate
        density, or ionizing emissivity (photons s^-1 Mpc^-3) as a
        function of redshift (or time).

    rate_is_tfunc: boolean
        Set to true if ratedensityfunc is a function of time rather than z.

    Notes
    -----

    Ignores recombinations.

    The ionization rate is computed as ratedensity / nn, where nn = nH
    + xHe * nHe. So if xHe is 1.0, we are assuming that helium becomes
    singly ionized at proportionally the same rate as hydrogen. If xHe
    is 2.0, we are assuming helium becomes fully ionizing at
    proportionally the same rate as hydrogen.

    The returened x is therefore the ionized fraction of hydrogen, and
    the ionized fraction of helium is xHe * x.

    """

    cosmo = cd.set_omega_k_0(cosmo)
    rhoc, rho0, nHe, nH = cden.baryon_densities(**cosmo)
    nn = (nH + xHe * nHe)
    if rate_is_tfunc:
        t = cd.age(z, **cosmo)[0]

        def dx_dt(t1):
            return numpy.nan_to_num(
                ratedensityfunc(t1, *ratedensityfunc_args) / nn)

        sorti = numpy.argsort(t)
        x = numpy.empty(t.shape)
        x[sorti] = cu.integrate_piecewise(dx_dt, t[sorti], method=method)
        return x
    else:
        dt_dz = lambda z1: cd.lookback_integrand(z1, **cosmo)

        def dx_dz(z1):
            z1 = numpy.abs(z1)
            return numpy.nan_to_num(
                dt_dz(z1) * ratedensityfunc(z1, *ratedensityfunc_args) / nn)

        sorti = numpy.argsort(-z)
        x = numpy.empty(z.shape)
        x[sorti] = cu.integrate_piecewise(dx_dz, -z[sorti], method=method)
        return x
Example #20
0
def plot_mz(ID0,
            PA,
            Z=np.arange(-1.2, 0.4249, 0.05),
            age=[0.01, 0.1, 0.3, 0.7, 1.0, 3.0]):

    #col = ['darkred', 'r', 'coral','orange','g','lightgreen', 'lightblue', 'b','indigo','violet','k']
    import matplotlib.cm as cm

    flim = 0.01

    lsfrl = -1  # log SFR low limit
    mmax = 500

    Txmax = 4  # Max x value

    lmmin = 10.3

    nage = np.arange(0, len(age), 1)
    fnc = Func(Z, nage)  # Set up the number of Age/ZZ
    bfnc = Basic(Z)

    age = np.asarray(age)

    ################
    # RF colors.
    import os.path
    home = os.path.expanduser('~')
    #fil_path = '/Users/tmorishita/eazy-v1.01/PROG/FILT/'
    fil_path = home + '/Dropbox/FILT/'
    fil_u = fil_path + 'u.fil'
    fil_b = fil_path + 'b.fil'
    fil_v = fil_path + "v.fil"
    fil_j = fil_path + "j.fil"
    fil_k = fil_path + "k.fil"
    fil_f125w = fil_path + "f125w.fil"
    fil_f160w = fil_path + "f160w.fil"
    fil_36 = fil_path + "3.6.fil"
    fil_45 = fil_path + "4.5.fil"

    du = np.loadtxt(fil_u, comments="#")
    lu = du[:, 1]
    fu = du[:, 2]

    db = np.loadtxt(fil_b, comments="#")
    lb = db[:, 1]
    fb = db[:, 2]

    dv = np.loadtxt(fil_v, comments="#")
    lv = dv[:, 1]
    fv = dv[:, 2]

    dj = np.loadtxt(fil_j, comments="#")
    lj = dj[:, 1]
    fj = dj[:, 2]

    c = 3.e18  # A/s
    chimax = 1.
    mag0 = 25.0
    d = 10**(73.6 / 2.5) * 1e-18  # From [ergs/s/cm2/A] to [ergs/s/cm2/Hz]
    #d = 10**(-73.6/2.5) # From [ergs/s/cm2/Hz] to [ergs/s/cm2/A]

    #############
    # Plot.
    #############
    fig = plt.figure(figsize=(6, 6))
    fig.subplots_adjust(top=0.98,
                        bottom=0.08,
                        left=0.1,
                        right=0.99,
                        hspace=0.18,
                        wspace=0.25)
    ax1 = fig.add_subplot(221)
    ax2 = fig.add_subplot(222)
    ax3 = fig.add_subplot(223)
    ax4 = fig.add_subplot(224)

    #ax3t = ax3.twiny()
    #ax4t = ax4.twiny()

    ##################
    # Fitting Results
    ##################
    DIR_TMP = './templates/'
    SNlim = 3  # avobe which SN line is shown.

    ###########################
    # Open result file
    ###########################
    file = 'summary_' + ID0 + '_PA' + PA + '.fits'
    hdul = fits.open(file)  # open a FITS file
    zbes = hdul[0].header['z']

    Asum = 0
    A50 = np.arange(len(age), dtype='float32')
    for aa in range(len(A50)):
        A50[aa] = hdul[1].data['A' + str(aa)][1]
        Asum += A50[aa]

    # Cosmo;
    DL = cd.luminosity_distance(zbes, **
                                cosmo) * Mpc_cm  # Luminositydistance in cm
    Cons = (4. * np.pi * DL**2 / (1. + zbes))

    Tuni = cd.age(zbes, use_flat=True, **cosmo)  # age at zobs.
    Tuni0 = (Tuni / cc.Gyr_s - age[:])

    delT = np.zeros(len(age), dtype='float32')
    delTl = np.zeros(len(age), dtype='float32')
    delTu = np.zeros(len(age), dtype='float32')

    col = np.zeros((len(age), 4), dtype='float32')
    for aa in range(len(age)):
        col[aa, :] = cm.nipy_spectral_r((aa + 0.1) / (len(age)))

    for aa in range(len(age)):
        if aa == 0:
            delTl[aa] = age[aa]
            delTu[aa] = (age[aa + 1] - age[aa]) / 2.
            delT[aa] = delTu[aa] + delTl[aa]
        elif Tuni / cc.Gyr_s < age[aa]:
            delTl[aa] = (age[aa] - age[aa - 1]) / 2.
            delTu[aa] = 10.
            delT[aa] = delTu[aa] + delTl[aa]
        elif aa == len(age) - 1:
            delTl[aa] = (age[aa] - age[aa - 1]) / 2.
            delTu[aa] = Tuni / cc.Gyr_s - age[aa]
            delT[aa] = delTu[aa] + delTl[aa]
        else:
            delTl[aa] = (age[aa] - age[aa - 1]) / 2.
            delTu[aa] = (age[aa + 1] - age[aa]) / 2.
            delT[aa] = delTu[aa] + delTl[aa]

    delT[:] *= 1e9  # Gyr to yr
    delTl[:] *= 1e9  # Gyr to yr
    delTu[:] *= 1e9  # Gyr to yr
    #print(age, delT, delTu, delTl)
    ##############################
    # Load Pickle
    ##############################
    samplepath = './'
    pfile = 'chain_' + ID0 + '_PA' + PA + '_corner.cpkl'

    niter = 0
    data = loadcpkl(os.path.join(samplepath + '/' + pfile))
    try:
        #if 1>0:
        ndim = data[
            'ndim']  # By default, use ndim and burnin values contained in the cpkl file, if present.
        burnin = data['burnin']
        nmc = data['niter']
        nwalk = data['nwalkers']
        Nburn = burnin  #* nwalk/10/2 # I think this takes 3/4 of samples
        #if nmc>1000:
        #    Nburn  = 500
        samples = data['chain'][:]
    except:
        print(
            ' =   >   NO keys of ndim and burnin found in cpkl, use input keyword values'
        )
        return -1

    ######################
    # Mass-to-Light ratio.
    ######################
    # Wht do you want from MCMC sampler?
    AM = np.zeros((len(age), mmax), dtype='float32')  # Mass in each bin.
    AC = np.zeros((len(age), mmax),
                  dtype='float32')  # Cumulative mass in each bin.
    ZM = np.zeros((len(age), mmax), dtype='float32')  # Z.
    ZC = np.zeros((len(age), mmax), dtype='float32')  # Cumulative Z.
    TC = np.zeros((len(age), mmax), dtype='float32')  # Mass weighted T.
    ZMM = np.zeros((len(age), mmax), dtype='float32')  # Mass weighted Z.

    SF = np.zeros((len(age), mmax), dtype='float32')  # SFR

    mm = 0
    while mm < mmax:
        mtmp = np.random.randint(len(samples))  # + Nburn

        AAtmp = np.zeros(len(age), dtype='float32')
        ZZtmp = np.zeros(len(age), dtype='float32')
        mslist = np.zeros(len(age), dtype='float32')

        Av_tmp = samples['Av'][mtmp]

        f0 = fits.open(DIR_TMP + 'ms_' + ID0 + '_PA' + PA + '.fits')
        sedpar = f0[1]

        for aa in range(len(age)):
            AAtmp[aa] = samples['A' + str(aa)][mtmp]
            ZZtmp[aa] = samples['Z' + str(aa)][mtmp]

            nZtmp = bfnc.Z2NZ(ZZtmp[aa])
            mslist[aa] = sedpar.data['ML_' + str(nZtmp)][aa]

            AM[aa, mm] = AAtmp[aa] * mslist[aa]
            SF[aa, mm] = AAtmp[aa] * mslist[aa] / delT[aa]
            ZM[aa, mm] = ZZtmp[aa]  # AAtmp[aa] * mslist[aa]
            ZMM[aa, mm] = (10**ZZtmp[aa]) * AAtmp[aa] * mslist[aa]

        for aa in range(len(age)):
            AC[aa, mm] = np.sum(AM[aa:, mm])
            ZC[aa, mm] = np.log10(np.sum((ZMM)[aa:, mm]) / AC[aa, mm])

            ACs = 0
            for bb in range(aa, len(age), 1):
                TC[aa, mm] += age[bb] * AAtmp[bb] * mslist[bb]
                ACs += AAtmp[bb] * mslist[bb]

            TC[aa, mm] /= ACs

        mm += 1

    #############
    # Plot
    #############
    AMp = np.zeros((len(age), 3), dtype='float32')
    ACp = np.zeros((len(age), 3), dtype='float32')
    ZMp = np.zeros((len(age), 3), dtype='float32')
    ZCp = np.zeros((len(age), 3), dtype='float32')
    SFp = np.zeros((len(age), 3), dtype='float32')
    for aa in range(len(age)):
        AMp[aa, :] = np.percentile(AM[aa, :], [16, 50, 84])
        ACp[aa, :] = np.percentile(AC[aa, :], [16, 50, 84])
        ZMp[aa, :] = np.percentile(ZM[aa, :], [16, 50, 84])
        ZCp[aa, :] = np.percentile(ZC[aa, :], [16, 50, 84])
        SFp[aa, :] = np.percentile(SF[aa, :], [16, 50, 84])

    ###################
    msize = np.zeros(len(age), dtype='float32')
    for aa in range(len(age)):
        if A50[aa] / Asum > flim:  # if >1%
            msize[aa] = 10 + 150 * A50[aa] / Asum

    conA = (msize >= 0)

    #
    # M-SFR
    #
    #ax1.fill_between(age[conA], np.log10(SFp[:,0])[conA], np.log10(SFp[:,2])[conA], linestyle='-', color='k', alpha=0.3)
    ax1.scatter(np.log10(ACp[:, 1])[conA],
                np.log10(SFp[:, 1])[conA],
                marker='o',
                c=col[:],
                s=msize[conA],
                edgecolors='k',
                zorder=2)
    ax1.errorbar(np.log10(ACp[:, 1])[conA],
                 np.log10(SFp[:, 1])[conA],
                 linestyle='--',
                 color='k',
                 lw=1.,
                 marker='',
                 zorder=0,
                 alpha=1.)

    lM = np.arange(9, 13, 0.1)
    delSFR = np.zeros(len(age), dtype='float32')
    delSFRl = np.zeros(len(age), dtype='float32')
    delSFRu = np.zeros(len(age), dtype='float32')
    for ii in range(len(Tuni0)):
        lSFR = (0.84 - 0.026 * Tuni0[ii]) * (lM - 0.19) - (6.51 -
                                                           0.11 * Tuni0[ii])
        ax1.fill_between(lM,
                         lSFR - 0.1,
                         lSFR + 0.1,
                         linestyle='None',
                         lw=0.5,
                         zorder=-5,
                         alpha=0.5,
                         color=col[ii])  # 0.19 is for Kroupa to Salpeter.

        lSFRtmp = (0.84 - 0.026 * Tuni0[ii]) * np.log10(ACp[ii, 1]) - (
            6.51 - 0.11 * Tuni0[ii])
        delSFR[ii] = np.log10(SFp[ii, 1]) - lSFRtmp
        delSFRl[ii] = np.log10(SFp[ii, 0]) - lSFRtmp
        delSFRu[ii] = np.log10(SFp[ii, 2]) - lSFRtmp

    #
    # t - delta SRF relation (right top)
    #
    #ax2.plot(age[:][conA], delSFR[conA], marker='', c='k',zorder=1, lw=1, linestyle='-')
    ax2.scatter(age[:][conA],
                delSFR[conA],
                marker='o',
                c=col[:],
                s=msize[conA],
                edgecolors='k',
                zorder=2)
    ax2.errorbar(age[:][conA],
                 delSFR[:][conA],
                 linestyle='--',
                 fmt='--',
                 color='k',
                 lw=1.,
                 marker='',
                 zorder=0,
                 alpha=1.)

    #
    # Mass - Z relation (left bottom)
    #
    ax2label = ''
    #ax2.fill_between(age[conA], np.log10(ACp[:,0])[conA], np.log10(ACp[:,2])[conA], linestyle='-', color='k', alpha=0.3)
    ax3.errorbar(
        np.log10(ACp[:, 1])[conA],
        ZCp[:, 1][conA],
        linestyle='--',
        zorder=0,
        color='k',
        lw=1.,
        label=ax2label,
        alpha=1.
    )  #, xerr=[np.log10(ACp[:,1])[conA]-np.log10(ACp[:,0])[conA],np.log10(ACp[:,2])[conA]-np.log10(ACp[:,1])[conA]], yerr=[ZCp[:,1][conA]-ZCp[:,0][conA],ZCp[:,2][conA]-ZCp[:,1][conA]]
    ax3.scatter(np.log10(ACp[:, 1])[conA],
                ZCp[:, 1][conA],
                marker='o',
                c=col[:],
                s=msize,
                edgecolors='k',
                zorder=2)

    #
    # Mass-Z from Gallazzi+05
    #
    lM = [
        8.91, 9.11, 9.31, 9.51, 9.72, 9.91, 10.11, 10.31, 10.51, 10.72, 10.91,
        11.11, 11.31, 11.51, 11.72, 11.91
    ]
    lZ50 = [
        -0.6, -0.61, -0.65, -0.61, -.52, -.41, -.23, -.11, -.01, .04, .07, .10,
        .12, .13, .14, .15
    ]
    lZ16 = [
        -1.11, -1.07, -1.1, -1.03, -.97, -.90, -.8, -.65, -.41, -.24, -.14,
        -.09, -.06, -.04, -.03, -.03
    ]
    lZ84 = [
        -0., -0., -0.05, -0.01, .05, .09, .14, .17, .20, .22, .24, .25, .26,
        .28, .29, .30
    ]

    lM = np.asarray(lM)
    lZ50 = np.asarray(lZ50)
    lZ16 = np.asarray(lZ16)
    lZ84 = np.asarray(lZ84)

    ax3.errorbar(lM,
                 lZ50,
                 marker='',
                 color='gray',
                 ms=15,
                 linestyle='-',
                 lw=1,
                 zorder=-2)  #, yerr=[lZ50-lZ16, lZ84-lZ50]
    ax3.fill_between(lM,
                     lZ16,
                     lZ84,
                     color='gray',
                     linestyle='None',
                     lw=1,
                     alpha=0.4,
                     zorder=-2)

    #
    # Fundamental Metal
    #
    bsfr = -0.32  # From Mannucci+10
    #ax4.fill_between(age[conA], ZCp[:,0][conA], ZCp[:,2][conA], linestyle='-', color='k', alpha=0.3)
    ax4.scatter((np.log10(ACp[:, 1]) + bsfr * np.log10(SFp[:, 1]))[conA],
                ZCp[:, 1][conA],
                marker='o',
                c=col[:],
                s=msize[conA],
                edgecolors='k',
                zorder=2)
    ax4.errorbar((np.log10(ACp[:, 1]) + bsfr * np.log10(SFp[:, 1]))[conA],
                 ZCp[:, 1][conA],
                 linestyle='--',
                 color='k',
                 lw=1.,
                 zorder=0,
                 alpha=1.)

    for iic in range(len(A50)):
        if msize[iic] > 10:
            lwe = 1.5
            ax1.errorbar(np.log10(ACp[iic, 1]),
                         np.log10(SFp[iic, 1]),
                         xerr=[[np.log10(ACp[iic, 1]) - np.log10(ACp[iic, 0])],
                               [np.log10(ACp[iic, 2]) - np.log10(ACp[iic, 1])]
                               ],
                         yerr=[[np.log10(SFp[iic, 1]) - np.log10(SFp[iic, 0])],
                               [np.log10(SFp[iic, 2]) - np.log10(SFp[iic, 1])]
                               ],
                         linestyle='-',
                         color=col[iic],
                         lw=lwe,
                         marker='',
                         zorder=1)
            ax2.errorbar(age[iic],
                         delSFR[iic],
                         xerr=[[delTl[iic] / 1e9], [delTu[iic] / 1e9]],
                         yerr=[[delSFR[iic] - delSFRl[iic]],
                               [delSFRu[iic] - delSFR[iic]]],
                         linestyle='-',
                         fmt='-',
                         color=col[iic],
                         lw=lwe,
                         marker='',
                         zorder=1)
            ax3.errorbar(np.log10(ACp[iic, 1]),
                         ZCp[iic, 1],
                         xerr=[[np.log10(ACp[iic, 1]) - np.log10(ACp[iic, 0])],
                               [np.log10(ACp[iic, 2]) - np.log10(ACp[iic, 1])]
                               ],
                         yerr=[[ZCp[iic, 1] - ZCp[iic, 0]],
                               [ZCp[iic, 2] - ZCp[iic, 1]]],
                         linestyle='-',
                         color=col[iic],
                         lw=lwe,
                         label=ax2label,
                         zorder=1)

            xerl_ax4 = np.sqrt(
                (np.log10(ACp[iic, 1]) - np.log10(ACp[iic, 0]))**2 + bsfr**2 *
                (np.log10(SFp[iic, 1]) - np.log10(SFp[iic, 0]))**2)
            xeru_ax4 = np.sqrt(
                (np.log10(ACp[iic, 2]) - np.log10(ACp[iic, 1]))**2 + bsfr**2 *
                (np.log10(SFp[iic, 2]) - np.log10(SFp[iic, 1]))**2)

            ax4.errorbar(
                (np.log10(ACp[iic, 1]) + bsfr * np.log10(SFp[iic, 1])),
                ZCp[iic, 1],
                xerr=[[xerl_ax4], [xeru_ax4]],
                yerr=[[ZCp[iic, 1] - ZCp[iic, 0]],
                      [ZCp[iic, 2] - ZCp[iic, 1]]],
                linestyle='-',
                color=col[iic],
                lw=lwe,
                label=ax2label,
                zorder=1)

    #########################
    # Title
    #########################
    #ax1.set_title('Each $t$-bin', fontsize=12)
    #ax2.set_title('Net system', fontsize=12)
    #ax3.set_title('Each $t$-bin', fontsize=12)
    #ax4.set_title('Net system', fontsize=12)

    #############
    # Axis
    #############
    #ax1.set_xlabel('$t$ (Gyr)', fontsize=12)
    ax1.set_ylabel('$\log \dot{M_*}/M_\odot$yr$^{-1}$', fontsize=12)
    #ax1.set_ylabel('$\log M_*/M_\odot$', fontsize=12)

    y3min, y3max = np.min(Z), np.max(Z)

    lsfru = 2.8
    if np.max(np.log10(SFp[:, 2])) > 2.8:
        lsfru = np.max(np.log10(SFp[:, 2])) + 0.1

    y2min, y2max = 9.5, 12.5
    ax1.set_xlim(y2min, y2max)
    ax1.set_ylim(lsfrl, lsfru)
    #ax1.set_xscale('log')
    ax1.set_xlabel('$\log M_*/M_\odot$', fontsize=12)

    #ax1.xaxis.labelpad = -3
    #ax1.yaxis.labelpad = -2
    #ax2t.set_yticklabels(())

    #ax2.set_xlabel('$t$ (Gyr)', fontsize=12)
    #ax2.set_ylabel('$\log M_*/M_\odot$', fontsize=12)
    ax2.set_xlabel('$t-t_\mathrm{obs.}$/Gyr', fontsize=12)
    ax2.set_ylabel('$\Delta_\mathrm{SFR}$', fontsize=12)

    #ax2.set_ylim(lsfrl, lsfru)
    ax2.set_ylim(-4, 2.5)
    ax2.set_xlim(0.008, 3.2)
    ax2.set_xscale('log')

    dely2 = 0.1
    while (y2max - y2min) / dely2 > 7:
        dely2 *= 2.

    #y2ticks = np.arange(y2min, y2max, dely2)
    #ax2.set_yticks(y2ticks)
    #ax2.set_yticklabels(np.arange(y2min, y2max, 0.1), minor=False)
    #ax2.yaxis.set_major_formatter(FormatStrFormatter('%.1f'))

    ax3.set_xlim(y2min, y2max)
    ax3.set_ylim(y3min, y3max)

    ax3.set_xlabel('$\log M_*/M_\odot$', fontsize=12)
    ax3.set_ylabel('$\log Z_*/Z_\odot$', fontsize=12)

    #ax3.set_xscale('log')
    #ax2.yaxis.set_major_formatter(FormatStrFormatter('%.2f'))

    # For redshift
    if zbes < 2:
        zred = [zbes, 2, 3, 6]
        #zredl = ['$z_\mathrm{obs.}$', 2, 3, 6]
        zredl = ['$z_\mathrm{obs.}$', 2, 3, 6]
    elif zbes < 2.5:
        zred = [zbes, 2.5, 3, 6]
        zredl = ['$z_\mathrm{obs.}$', 2.5, 3, 6]
    elif zbes < 3.:
        zred = [zbes, 3, 6]
        zredl = ['$z_\mathrm{obs.}$', 3, 6]
    elif zbes < 6:
        zred = [zbes, 6]
        zredl = ['$z_\mathrm{obs.}$', 6]

    Tzz = np.zeros(len(zred), dtype='float32')
    for zz in range(len(zred)):
        Tzz[zz] = (Tuni - cd.age(zred[zz], use_flat=True, **cosmo)) / cc.Gyr_s
        if Tzz[zz] < 0.01:
            Tzz[zz] = 0.01

    #ax3t.set_xscale('log')
    #ax3t.set_xlim(0.008, Txmax)

    ax4.set_xlabel('$\log M_*/M_\odot - 0.32 \log \dot{M_*}/M_\odot$yr$^{-1}$',
                   fontsize=12)
    ax4.set_ylabel('$\log Z_*/Z_\odot$', fontsize=12)

    #ax4t.set_xscale('log')
    #ax4t.set_xlim(0.008, Txmax)

    ax4.set_xlim(9, 12.3)
    ax4.set_ylim(y3min, y3max)
    #ax4.set_xscale('log')
    #ax4.yaxis.set_major_formatter(FormatStrFormatter('%.2f'))

    ax3.yaxis.labelpad = -2
    ax4.yaxis.labelpad = -2

    ####################
    ## Save
    ####################
    ax1.legend(loc=1, fontsize=11)
    ax2.legend(loc=3, fontsize=8)
    plt.savefig('MZ_' + ID0 + '_PA' + PA + '_pcl.pdf')
Example #21
0
def maketemp(inputs,
             zbest,
             Z=np.arange(-1.2, 0.45, 0.1),
             age=[0.01, 0.1, 0.3, 0.7, 1.0, 3.0],
             fneb=0,
             DIR_TMP='./templates/'):
    #
    # inputs      : Configuration file.
    # zbest(float): Best redshift at this iteration. Templates are generated based on this reshift.
    # Z (array)   : Stellar phase metallicity in logZsun.
    # age (array) : Age, in Gyr.
    # fneb (int)  : flag for adding nebular emissionself.
    #
    nage = np.arange(0, len(age), 1)
    fnc = Func(Z, nage)  # Set up the number of Age/ZZ
    bfnc = Basic(Z)

    ID = inputs['ID']
    PA = inputs['PA']
    try:
        DIR_EXTR = inputs['DIR_EXTR']
        if len(DIR_EXTR) == 0:
            DIR_EXTR = False
    except:
        DIR_EXTR = False
    DIR_FILT = inputs['DIR_FILT']
    try:
        CAT_BB_IND = inputs['CAT_BB_IND']
    except:
        CAT_BB_IND = False
    try:
        CAT_BB = inputs['CAT_BB']
    except:
        CAT_BB = False

    SFILT = inputs['FILTER']  # filter band string.
    SFILT = [x.strip() for x in SFILT.split(',')]
    FWFILT = fil_fwhm(SFILT, DIR_FILT)

    # If FIR data;
    try:
        DFILT = inputs['FIR_FILTER']  # filter band string.
        DFILT = [x.strip() for x in DFILT.split(',')]
        DFWFILT = fil_fwhm(DFILT, DIR_FILT)
        CAT_BB_DUST = inputs['CAT_BB_DUST']
        DT0 = float(inputs['TDUST_LOW'])
        DT1 = float(inputs['TDUST_HIG'])
        dDT = float(inputs['TDUST_DEL'])
        f_dust = True
        print('FIR is implemented.')
    except:
        print('No FIR is implemented.')
        f_dust = False
        pass

    #
    # Tau for MCMC parameter; not as fitting parameters.
    #
    tau0 = inputs['TAU0']
    tau0 = [float(x.strip()) for x in tau0.split(',')]

    print('############################')
    print('Making templates at %.4f' % (zbest))
    print('############################')
    ####################################################
    # Get extracted spectra.
    ####################################################
    #
    # Get ascii data.
    #
    #ninp1 = 0
    #ninp2 = 0
    f_spec = False
    try:
        spec_files = inputs['SPEC_FILE'].replace('$ID', '%s' % (ID))
        spec_files = [x.strip() for x in spec_files.split(',')]
        ninp0 = np.zeros(len(spec_files), dtype='int')
        for ff, spec_file in enumerate(spec_files):
            try:
                fd0 = np.loadtxt(DIR_EXTR + spec_file, comments='#')
                lm0tmp = fd0[:, 0]
                fobs0 = fd0[:, 1]
                eobs0 = fd0[:, 2]
                ninp0[ff] = len(lm0tmp)  #[con_tmp])
            except Exception:
                print('File, %s, cannot be open.' % (spec_file))
                pass
        # Constructing arrays.
        lm = np.zeros(np.sum(ninp0[:]), dtype='float32')
        fobs = np.zeros(np.sum(ninp0[:]), dtype='float32')
        eobs = np.zeros(np.sum(ninp0[:]), dtype='float32')
        fgrs = np.zeros(np.sum(ninp0[:]), dtype='int')  # FLAG for G102/G141.
        for ff, spec_file in enumerate(spec_files):
            try:
                fd0 = np.loadtxt(DIR_EXTR + spec_file, comments='#')
                lm0tmp = fd0[:, 0]
                fobs0 = fd0[:, 1]
                eobs0 = fd0[:, 2]
                for ii1 in range(ninp0[ff]):
                    if ff == 0:
                        ii = ii1
                    else:
                        ii = ii1 + np.sum(ninp0[:ff])
                    fgrs[ii] = ff
                    lm[ii] = lm0tmp[ii1]
                    fobs[ii] = fobs0[ii1]
                    eobs[ii] = eobs0[ii1]
                f_spec = True
            except Exception:
                pass
    except:
        print('No spec file is provided.')
        pass

    #############################
    # Extracting BB photometry:
    #############################
    if CAT_BB:
        fd0 = np.loadtxt(CAT_BB, comments='#')
        try:
            id0 = fd0[:, 0]
            ii0 = np.argmin(np.abs(id0[:] - int(ID)))
            if int(id0[ii0]) != int(ID):
                return -1
            fd = fd0[ii0, :]
        except:
            id0 = fd0[0]
            if int(id0) != int(ID):
                return -1
            fd = fd0[:]
        id = fd[0]
        fbb = np.zeros(len(SFILT), dtype='float32')
        ebb = np.zeros(len(SFILT), dtype='float32')
        for ii in range(len(SFILT)):
            fbb[ii] = fd[ii * 2 + 1]
            ebb[ii] = fd[ii * 2 + 2]
    elif CAT_BB_IND:  # if individual photometric catalog; made in get_sdss.py
        fd0 = fits.open(DIR_EXTR + CAT_BB_IND)
        hd0 = fd0[1].header
        bunit_bb = float(hd0['bunit'][:5])
        lmbb0 = fd0[1].data['wavelength']
        fbb0 = fd0[1].data['flux'] * bunit_bb
        ebb0 = 1 / np.sqrt(fd0[1].data['inverse_variance']) * bunit_bb

        unit = 'nu'
        try:
            unit = inputs['UNIT_SPEC']
        except:
            print('No param for UNIT_SPEC is found.')
            print('BB flux unit is assumed to Fnu.')
            pass

        if unit == 'lambda':
            print('#########################')
            print('Changed BB from Flam to Fnu')
            snbb0 = fbb0 / ebb0
            fbb = flamtonu(lmbb0, fbb0)
            ebb = fbb / snbb0
        else:
            snbb0 = fbb0 / ebb0
            fbb = fbb0
            ebb = ebb0

    else:
        fbb = np.zeros(len(SFILT), dtype='float32')
        ebb = np.zeros(len(SFILT), dtype='float32')
        for ii in range(len(SFILT)):
            fbb[ii] = 0
            ebb[ii] = -99  #1000

    # Dust flux;
    if f_dust:
        fdd = np.loadtxt(CAT_BB_DUST, comments='#')
        try:
            id0 = fdd[:, 0]
            ii0 = np.argmin(np.abs(id0[:] - int(ID)))
            if int(id0[ii0]) != int(ID):
                return -1
            fd = fdd[ii0, :]
        except:
            id0 = fdd[0]
            if int(id0) != int(ID):
                return -1
            fd = fdd[:]
        id = fd[0]
        fbb_d = np.zeros(len(DFILT), dtype='float32')
        ebb_d = np.zeros(len(DFILT), dtype='float32')
        for ii in range(len(DFILT)):
            fbb_d[ii] = fd[ii * 2 + 1]
            ebb_d[ii] = fd[ii * 2 + 2]

    #############################
    # Getting Morphology params.
    #############################
    Amp = 0
    f_morp = False
    if f_spec:
        try:
            if inputs['MORP'] == 'moffat' or inputs['MORP'] == 'gauss':
                f_morp = True
                try:
                    mor_file = inputs['MORP_FILE'].replace('$ID', '%s' % (ID))
                    fm = np.loadtxt(DIR_EXTR + mor_file, comments='#')
                    #Amp   = fm[0]
                    #gamma = fm[1]
                    Amp = fm[2]
                    gamma = fm[4]
                    if inputs['MORP'] == 'moffat':
                        #alp   = fm[2]
                        alp = fm[5]
                    else:
                        alp = 0
                except Exception:
                    print('Error in reading morphology params.')
                    print('No morphology convolution.')
                    #return -1
                    pass
            else:
                print('MORP Keywords does not match.')
                print('No morphology convolution.')
        except:
            pass

        ############################
        # Template convolution;
        ############################
        try:
            sig_temp = float(inputs['SIG_TEMP'])
        except:
            sig_temp = 50.
            print('Template resolution is unknown.')
            print('Set to %.1f km/s.' % (sig_temp))
        dellam = lm[1] - lm[0]  # AA/pix
        R_temp = c / (sig_temp * 1e3 * 1e10)
        sig_temp_pix = np.median(lm) / R_temp / dellam  # delta v in pixel;

        #
        sig_inst = 0  #65 #km/s for Manga

        # If grism;
        if f_morp:
            print('Templates convolution (intrinsic morphology).')
            if gamma > sig_temp_pix:
                sig_conv = np.sqrt(gamma**2 - sig_temp_pix**2)
            else:
                sig_conv = 0
                print('Template resolution is broader than Morphology.')
                print('No convolution is applied to templates.')

            xMof = np.arange(-5, 5.1, .1)  # dimension must be even.
            if inputs['MORP'] == 'moffat' and Amp > 0 and alp > 0:
                LSF = moffat(xMof, Amp, 0, np.sqrt(gamma**2 - sig_temp_pix**2),
                             alp)
                #print(np.sqrt(gamma**2-sig_temp_pix**2))
                print('Template convolution with Moffat.')
                #print('params are;',Amp, 0, gamma, alp)
            elif inputs['MORP'] == 'gauss':
                sigma = gamma
                LSF = gauss(xMof, Amp, np.sqrt(sigma**2 - sig_temp_pix**2))
                print('Template convolution with Gaussian.')
                print('params is sigma;', sigma)
            else:
                print('Something is wrong.')
                return -1

        else:  # For slit spectroscopy. To be updated...
            print('Templates convolution (intrinsic velocity).')
            f_disp = False
            try:
                vdisp = float(inputs['VDISP'])
                dellam = lm[1] - lm[0]  # AA/pix
                #R_disp = c/(vdisp*1e3*1e10)
                R_disp = c / (np.sqrt(vdisp**2 - sig_inst**2) * 1e3 * 1e10)
                vdisp_pix = np.median(
                    lm) / R_disp / dellam  # delta v in pixel;
                print('Templates are convolved at %.2f km/s.' % (vdisp))
                if vdisp_pix - sig_temp_pix > 0:
                    sig_conv = np.sqrt(vdisp_pix**2 - sig_temp_pix**2)
                else:
                    sig_conv = 0
            except:
                vdisp = 0.
                print('Templates are not convolved.')
                sig_conv = 0  #np.sqrt(sig_temp_pix**2)
                pass
            xMof = np.arange(-5, 5.1, .1)  # dimension must be even.
            Amp = 1.
            LSF = gauss(xMof, Amp, sig_conv)
    else:
        lm = []

    ####################################
    # Start generating templates
    ####################################
    #DIR_TMP = './templates/'
    #DIR_TMP = inputs['DIR_TEMP']
    f0 = fits.open(DIR_TMP + 'ms.fits')
    mshdu = f0[1]
    col00 = []
    col01 = []
    col02 = []
    for zz in range(len(Z)):
        for pp in range(len(tau0)):
            f1 = fits.open(DIR_TMP + 'spec_all.fits')
            spechdu = f1[1]
            Zbest = Z[zz]

            Na = len(age)
            Nz = 1
            param = np.zeros((Na, 6), dtype='float32')
            param[:, 2] = 1e99
            Ntmp = 1
            chi2 = np.zeros(Ntmp) + 1e99
            snorm = np.zeros(Ntmp)
            agebest = np.zeros(Ntmp)
            avbest = np.zeros(Ntmp)
            age_univ = cd.age(zbest, use_flat=True, **cosmo)

            if zz == 0 and pp == 0:
                lm0 = spechdu.data['wavelength']
                if fneb == 1:
                    spec0 = spechdu.data['efspec_' + str(zz) + '_0_' + str(pp)]
                    #logU  = f1[0].header['logU']
                else:
                    spec0 = spechdu.data['fspec_' + str(zz) + '_0_' + str(pp)]

            lmbest = np.zeros((Ntmp, len(lm0)), dtype='float32')
            fbest = np.zeros((Ntmp, len(lm0)), dtype='float32')
            lmbestbb = np.zeros((Ntmp, len(SFILT)), dtype='float32')
            fbestbb = np.zeros((Ntmp, len(SFILT)), dtype='float32')

            A = np.zeros(Na, dtype='float32') + 1

            spec_mul = np.zeros((Na, len(lm0)), dtype='float32')
            spec_mul_nu = np.zeros((Na, len(lm0)), dtype='float32')
            spec_mul_nu_conv = np.zeros((Na, len(lm0)), dtype='float64')

            ftmpbb = np.zeros((Na, len(SFILT)), dtype='float32')
            ltmpbb = np.zeros((Na, len(SFILT)), dtype='float32')

            ftmp_nu_int = np.zeros((Na, len(lm)), dtype='float32')
            spec_av_tmp = np.zeros((Na, len(lm)), dtype='float32')

            ms = np.zeros(Na, dtype='float32')
            Ls = np.zeros(Na, dtype='float32')
            ms[:] = mshdu.data['ms_' + str(zz)][:]  # [:] is necessary.
            Ls[:] = mshdu.data['Ls_' + str(zz)][:]
            Fuv = np.zeros(Na, dtype='float32')

            for ss in range(Na):
                wave = spechdu.data['wavelength']
                if fneb == 1:
                    spec_mul[ss] = spechdu.data['efspec_' + str(zz) + '_' +
                                                str(ss) + '_' + str(pp)]
                else:
                    spec_mul[ss] = spechdu.data['fspec_' + str(zz) + '_' +
                                                str(ss) + '_' + str(pp)]

                ###################
                # IGM attenuation.
                ###################
                spec_av_tmp = madau_igm_abs(wave, spec_mul[ss, :], zbest)
                spec_mul_nu[ss, :] = flamtonu(wave, spec_av_tmp)
                if len(lm) > 0:
                    try:
                        spec_mul_nu_conv[ss, :] = convolve(spec_mul_nu[ss],
                                                           LSF,
                                                           boundary='extend')
                    except:
                        spec_mul_nu_conv[ss, :] = spec_mul_nu[ss]
                        if zz == 0 and ss == 0:
                            print('Kernel is too small. No convolution.')
                else:
                    spec_mul_nu_conv[ss, :] = spec_mul_nu[ss]

                spec_sum = 0 * spec_mul[0]  # This is dummy file.
                DL = cd.luminosity_distance(
                    zbest, **cosmo) * Mpc_cm  # Luminositydistance in cm
                wavetmp = wave * (1. + zbest)
                #spec_av  = flamtonu(wavetmp, spec_sum) # Conversion from Flambda to Fnu.
                #ftmp_int = data_int(lm, wavetmp, spec_av)

                Lsun = 3.839 * 1e33  #erg s-1
                stmp_common = 1e10  # 1 tmp is in 1e10Lsun
                #ftmpbb[ss,:]           *= Lsun/(4.*np.pi*DL**2/(1.+zbest))
                #ftmpbb[ss,:]      *= (1./Ls[ss])*stmp_common
                spec_mul_nu_conv[ss, :] *= Lsun / (4. * np.pi * DL**2 /
                                                   (1. + zbest))
                spec_mul_nu_conv[ss, :] *= (
                    1. /
                    Ls[ss]) * stmp_common  # in unit of erg/s/Hz/cm2/ms[ss].
                ms[ss] *= (
                    1. / Ls[ss]
                ) * stmp_common  # M/L; 1 unit template has this mass in [Msolar].
                if f_spec:
                    ftmp_nu_int[ss, :] = data_int(lm, wavetmp,
                                                  spec_mul_nu_conv[ss, :])
                ltmpbb[ss, :], ftmpbb[ss, :] = filconv(SFILT, wavetmp,
                                                       spec_mul_nu_conv[ss, :],
                                                       DIR_FILT)

                # UV magnitude;
                #print('%s AA is used as UV reference.'%(xm_tmp[iiuv]))
                #print(ms[ss], (Lsun/(4.*np.pi*DL**2/(1.+zbest))))
                #print('m-M=',5*np.log10(DL/Mpc_cm*1e6/10))

                ##########################################
                # Writing out the templates to fits table.
                ##########################################
                if ss == 0 and pp == 0 and zz == 0:
                    # First file
                    nd1 = np.arange(0, len(lm), 1)
                    nd3 = np.arange(10000, 10000 + len(ltmpbb[ss, :]), 1)
                    nd_ap = np.append(nd1, nd3)
                    lm_ap = np.append(lm, ltmpbb[ss, :])

                    col1 = fits.Column(name='wavelength',
                                       format='E',
                                       unit='AA',
                                       array=lm_ap)
                    col2 = fits.Column(name='colnum',
                                       format='K',
                                       unit='',
                                       array=nd_ap)
                    col00 = [col1, col2]

                    # Second file
                    col3 = fits.Column(name='wavelength',
                                       format='E',
                                       unit='AA',
                                       array=wavetmp)
                    nd = np.arange(0, len(wavetmp), 1)
                    col4 = fits.Column(name='colnum',
                                       format='K',
                                       unit='',
                                       array=nd)
                    col01 = [col3, col4]

                spec_ap = np.append(ftmp_nu_int[ss, :], ftmpbb[ss, :])
                colspec = fits.Column(name='fspec_' + str(zz) + '_' + str(ss) +
                                      '_' + str(pp),
                                      format='E',
                                      unit='Fnu',
                                      disp='%s' % (age[ss]),
                                      array=spec_ap)
                col00.append(colspec)
                colspec_all = fits.Column(name='fspec_' + str(zz) + '_' +
                                          str(ss) + '_' + str(pp),
                                          format='E',
                                          unit='Fnu',
                                          disp='%s' % (age[ss]),
                                          array=spec_mul_nu_conv[ss, :])
                col01.append(colspec_all)

            #########################
            # Summarize the ML
            #########################
            if pp == 0:
                colms = fits.Column(name='ML_' + str(zz),
                                    format='E',
                                    unit='Msun/1e10Lsun',
                                    array=ms)
                col02.append(colms)

    #########################
    # Summarize the templates
    #########################
    coldefs_spec = fits.ColDefs(col00)
    hdu = fits.BinTableHDU.from_columns(coldefs_spec)
    hdu.writeto(DIR_TMP + 'spec_' + ID + '_PA' + PA + '.fits', overwrite=True)

    coldefs_spec = fits.ColDefs(col01)
    hdu2 = fits.BinTableHDU.from_columns(coldefs_spec)
    hdu2.writeto(DIR_TMP + 'spec_all_' + ID + '_PA' + PA + '.fits',
                 overwrite=True)

    coldefs_ms = fits.ColDefs(col02)
    hdu3 = fits.BinTableHDU.from_columns(coldefs_ms)
    hdu3.writeto(DIR_TMP + 'ms_' + ID + '_PA' + PA + '.fits', overwrite=True)

    ######################
    # Add dust component;
    ######################
    if f_dust:
        Temp = np.arange(DT0, DT1, dDT)
        lambda_d = np.arange(
            1e4, 1e7,
            1e3)  # RF wavelength, in AA. #* (1.+zbest) # 1um to 1000um;
        #lambda_d = np.arange(4000,1e7,1e3) # RF wavelength, in AA. #* (1.+zbest) # 1um to 1000um;
        # c in AA/s.
        kb = 1.380649e-23  # Boltzmann constant, in J/K
        hp = 6.62607015e-34  # Planck constant, in J*s

        # from Eq.3 of Bianchi 13
        kabs0 = 4.0  # in cm2/g
        beta_d = 2.08  #
        lam0 = 250. * 1e4  # mu m to AA
        kappa = kabs0 * (lam0 / lambda_d)**beta_d  # cm2/g
        kappa *= (1e8)**2  # AA2/g
        for tt in range(len(Temp)):
            if tt == 0:
                # For full;
                nd_d = np.arange(0, len(lambda_d), 1)
                colspec_dw = fits.Column(name='wavelength',
                                         format='E',
                                         unit='AA',
                                         array=lambda_d * (1. + zbest))
                col_dw = fits.Column(name='colnum',
                                     format='K',
                                     unit='',
                                     array=nd_d)
                col03 = [colspec_dw, col_dw]
            nu_d = c / lambda_d  # 1/s = Hz
            BT_nu = 2 * hp * nu_d[:]**3 / c**2 / (
                np.exp(hp * nu_d[:] / (kb * Temp[tt])) - 1
            )  # J*s * (1/s)^3 / (AA/s)^2 / sr = J / AA^2 / sr = J/s/AA^2/Hz/sr.
            # in side exp: J*s * (1/s) / (J/K * K) = 1;

            # if optically thin;
            #kappa = nu_d ** beta_d
            fnu_d = 1.0 / (
                4. * np.pi * DL**2 / (1. + zbest)
            ) * kappa * BT_nu  # 1/cm2 * AA2/g * J/s/AA^2/Hz = J/s/cm^2/Hz/g
            #fnu_d = 1.0 / (4.*np.pi*DL**2/(1.+zbest)) * BT_nu # 1/cm2 * AA2/g * J/s/AA^2/Hz = J/s/cm^2/Hz/g
            fnu_d *= 1.989e+33  # J/s/cm^2/Hz/Msun; i.e. 1 flux is in 1Msun
            fnu_d *= 1e7  # erg/s/cm^2/Hz/Msun.
            #fnu_d *= 1e9 # Now 1 flux is in 1e9Msun
            print('Somehow, crazy scale is required for FIR normalization...')
            fnu_d *= 1e40
            colspec_d = fits.Column(name='fspec_' + str(tt),
                                    format='E',
                                    unit='Fnu(erg/s/cm^2/Hz/Msun)',
                                    disp='%.2f' % (Temp[tt]),
                                    array=fnu_d)
            col03.append(colspec_d)
            #print('At z=%.2f, luminosity surface is %.2e cm^2'%(zbest,4.*np.pi*DL**2/(1.+zbest)))

            # Convolution;
            #ltmpbb_d, ftmpbb_d = filconv(DFILT,lambda_d*(1.+zbest),fnu_d,DIR_FILT)
            ALLFILT = np.append(SFILT, DFILT)
            ltmpbb_d, ftmpbb_d = filconv(ALLFILT, lambda_d * (1. + zbest),
                                         fnu_d, DIR_FILT)
            if False:
                #plt.plot(nu_d/1e9/(1.+zbest),fnu_d)
                #nubb_d = c / ltmpbb_d
                #plt.plot(nubb_d/1e9, ftmpbb_d, 'x')
                plt.plot(lambda_d / 1e4, fnu_d)
                plt.plot(lambda_d * (1. + zbest) / 1e4, fnu_d)
                plt.plot(ltmpbb_d / 1e4, ftmpbb_d, 'x')
                plt.show()
            if tt == 0:
                # For conv;
                col3 = fits.Column(name='wavelength',
                                   format='E',
                                   unit='AA',
                                   array=ltmpbb_d)
                nd_db = np.arange(0, len(ltmpbb_d), 1)
                col4 = fits.Column(name='colnum',
                                   format='K',
                                   unit='',
                                   array=nd_db)
                col04 = [col3, col4]
            colspec_db = fits.Column(name='fspec_' + str(tt),
                                     format='E',
                                     unit='Fnu',
                                     disp='%.2f' % (Temp[tt]),
                                     array=ftmpbb_d)
            col04.append(colspec_db)

        coldefs_d = fits.ColDefs(col03)
        hdu4 = fits.BinTableHDU.from_columns(coldefs_d)
        hdu4.writeto(DIR_TMP + 'spec_dust_all_' + ID + '_PA' + PA + '.fits',
                     overwrite=True)

        coldefs_db = fits.ColDefs(col04)
        hdu5 = fits.BinTableHDU.from_columns(coldefs_db)
        hdu5.writeto(DIR_TMP + 'spec_dust_' + ID + '_PA' + PA + '.fits',
                     overwrite=True)

    ##########################################
    # For observation.
    # Write out for the Multi-component fitting.
    ##########################################
    lamliml = 0.
    lamlimu = 20000.
    ebblim = 1e5
    ncolbb = 10000
    fw = open(DIR_TMP + 'spec_obs_' + ID + '_PA' + PA + '.cat', 'w')
    fw.write('# BB data (>%d) in this file are not used in fitting.\n' %
             (ncolbb))
    for ii in range(len(lm)):
        if fgrs[ii] == 0:  # G102
            if lm[ii] / (1. + zbest) > lamliml and lm[ii] / (1. +
                                                             zbest) < lamlimu:
                fw.write('%d %.5f %.5e %.5e\n' %
                         (ii, lm[ii], fobs[ii], eobs[ii]))
            else:
                fw.write('%d %.5f 0 1000\n' % (ii, lm[ii]))
        elif fgrs[ii] == 1:  # G141
            if lm[ii] / (1. + zbest) > lamliml and lm[ii] / (1. +
                                                             zbest) < lamlimu:
                fw.write('%d %.5f %.5e %.5e\n' %
                         (ii + 1000, lm[ii], fobs[ii], eobs[ii]))
            else:
                fw.write('%d %.5f 0 1000\n' % (ii + 1000, lm[ii]))

    for ii in range(len(ltmpbb[0, :])):
        if ebb[ii] > ebblim:
            fw.write('%d %.5f 0 1000\n' % (ii + ncolbb, ltmpbb[0, ii]))
        else:
            fw.write('%d %.5f %.5e %.5e\n' %
                     (ii + ncolbb, ltmpbb[0, ii], fbb[ii], ebb[ii]))

    fw.close()
    fw = open(DIR_TMP + 'spec_dust_obs_' + ID + '_PA' + PA + '.cat', 'w')
    if f_dust:
        nbblast = len(ltmpbb[0, :])
        for ii in range(len(ebb_d[:])):
            if ebb_d[ii] > ebblim:
                fw.write('%d %.5f 0 1000\n' %
                         (ii + ncolbb + nbblast, ltmpbb_d[ii + nbblast]))
            else:
                fw.write('%d %.5f %.5e %.5e\n' %
                         (ii + ncolbb + nbblast, ltmpbb_d[ii + nbblast],
                          fbb_d[ii], ebb_d[ii]))
    fw.close()

    fw = open(DIR_TMP + 'bb_obs_' + ID + '_PA' + PA + '.cat', 'w')
    for ii in range(len(ltmpbb[0, :])):
        if ebb[ii] > ebblim:
            fw.write('%d %.5f 0 1000 %.1f\n' %
                     (ii + ncolbb, ltmpbb[0, ii], FWFILT[ii] / 2.))
        else:
            fw.write('%d %.5f %.5e %.5e %.1f\n' %
                     (ii + ncolbb, ltmpbb[0, ii], fbb[ii], ebb[ii],
                      FWFILT[ii] / 2.))

    fw.close()
    fw = open(DIR_TMP + 'bb_dust_obs_' + ID + '_PA' + PA + '.cat', 'w')
    if f_dust:
        for ii in range(len(ebb_d[:])):
            if ebb_d[ii] > ebblim:
                fw.write('%d %.5f 0 1000 %.1f\n' %
                         (ii + ncolbb + nbblast, ltmpbb_d[ii + nbblast],
                          DFWFILT[ii] / 2.))
            else:
                fw.write('%d %.5f %.5e %.5e %.1f\n' %
                         (ii + ncolbb + nbblast, ltmpbb_d[ii + nbblast],
                          fbb_d[ii], ebb_d[ii], DFWFILT[ii] / 2.))
    fw.close()
Example #22
0
    da = cd.angular_diameter_distance(z[i], **Cosmology)
    #See equations 18-19 of David Hogg's arXiv:astro-ph/9905116v4

    dl = cd.luminosity_distance(z[i], **Cosmology)
    #Units are Mpc

    dVc = cd.diff_comoving_volume(z[i], **Cosmology)
    #The differential comoving volume element dV_c/dz/dSolidAngle.
    #Dimensions are volume per unit redshift per unit solid angle.
    #Units are Mpc**3 Steradians^-1.
    #See David Hogg's arXiv:astro-ph/9905116v4, equation 28

    tl = cd.lookback_time(z[i], **Cosmology)
    #See equation 30 of David Hogg's arXiv:astro-ph/9905116v4. Units are s.

    agetl = cd.age(z[i], **Cosmology)
    #Age at z is lookback time at z'->Infinity minus lookback time at z.

    tH = 3.09e17 / Cosmology['h']

    ez = cd.e_z(z[i], **Cosmology)
    #The unitless Hubble expansion rate at redshift z.
    #In David Hogg's (arXiv:astro-ph/9905116v4) formalism, this is
    #equivalent to E(z), defined in his eq. 14.

    if PlotNumber == 1:
        val[i] = dm / dh
        xtitle = "redshift z"
        ytitle = "Proper motion distance Dm/Dh"

    elif PlotNumber == 2:
Example #23
0
    4, 5, 8, 10, 11, 12, 13, 14, 16, 17, 19, 20, 21, 22, 23, 24, 25, 26, 27,
    28, 29, 31, 32, 34, 35, 36, 37, 39, 41, 42, 43, 44, 45, 47, 49, 50, 51, 53,
    55, 56, 58, 61, 62, 63, 64, 65, 66, 68, 70, 71, 73, 75, 78, 79, 81, 83, 84,
    88, 89, 90, 92, 93, 94, 95, 96, 98, 99
])
ID_ff_DE = np.array([3, 59])
ID_rf_DE = np.array([])
ID_fr_DE = np.array([
    2, 7, 9, 15, 18, 33, 38, 40, 52, 69, 72, 74, 76, 77, 80, 82, 85, 86, 87,
    91, 97, 100
])
test = [(4)]

cosmo = {'omega_M_0': 0.3, 'omega_lambda_0': 0.7, 'h': 0.7}
cosmo = cd.set_omega_k_0(cosmo)
ageUniv2 = cd.age(2.0, **cosmo) / cc.yr_s
ageUniv999 = cd.age(999.0, **cosmo) / cc.yr_s

xlin = np.linspace(1, 1e10, 100000)

for j in test:

    i = (np.abs(ID - j)).argmin()

    plt.figure(figsize=(4 * fsize, fsize))
    plt.title('{} ID {}'.format(revision.replace('_', ' '), j))
    plt.xlim(0, 1e10)
    #    plt.xlim(0.9*msa, 1.1*msa)
    plt.ylim(0.0, 1.1)

    sfr_in = 1 * (xlin - (ageUniv2 - msa_in[i])) * np.exp(
    def __init__(self, params=B2008,
                 MStar_bounds = ['extrapolate', float('NaN')],
                 phiStar_bounds = ['constant', float('NaN')],
                 alpha_bounds = ['constant', float('NaN')],
                 extrap_args = {},
                 extrap_var = 'z',
                 sedParams = {},
                 wavelength = 1500.,
                 **cosmo):
        
        for (k, v) in params.iteritems():
            params[k] = numpy.asarray(v)
            
        self.params = params
        self.MStar_bounds = MStar_bounds
        self.phiStar_bounds = phiStar_bounds
        self.alpha_bounds = alpha_bounds
        self.extrap_args = extrap_args
        self.extrap_var = extrap_var
        self.sedParams = sedParams
        self.wavelength = wavelength
        self.cosmo = cosmo

        self.zobs = params['z']
        self.tobs = cd.age(self.zobs, **cosmo)[0]
        self.MStar = params['MStar']
        self.phiStar = params['phiStar']
        self.alpha = params['alpha']

        if extrap_var == 't':
            self.xobs = self.tobs
            self._iPhotFunc = \
                       lambda t1, mag: (self.iPhotonRateDensity_t(t1,
                                                                  maglim=mag))
            
        elif extrap_var == 'z':
            self.xobs = self.zobs
            MStar_bounds = MStar_bounds[::-1]
            phiStar_bounds = phiStar_bounds[::-1]
            alpha_bounds = alpha_bounds[::-1]
            self._iPhotFunc = \
                        lambda z1, mag: (self.iPhotonRateDensity_z(z1,
                                                                   maglim=mag))
            
        self._MStarfunc = utils.Extrapolate1d(self.xobs, self.MStar,
                                              bounds_behavior=MStar_bounds,
                                              **extrap_args
                                              )
        print "M*:",
        print self._MStarfunc.extrap_string()

        self._phiStarfunc = utils.Extrapolate1d(self.xobs, self.phiStar,
                                                bounds_behavior=phiStar_bounds,
                                                **extrap_args
                                                )
        print "phi*:",
        print self._phiStarfunc.extrap_string()
        self._alphafunc = utils.Extrapolate1d(self.xobs, self.alpha,
                                              bounds_behavior=alpha_bounds,
                                              **extrap_args
                                              )
        print "alpha:",
        print self._alphafunc.extrap_string()
        
        self._SED = BrokenPowerlawSED(**sedParams)
        self._rQL = self._SED.iPhotonRateRatio(wavelength)

        for name, func in globals().items():
            if not name.startswith('schechter'):
                continue
            def newfunc(z, _name=name, _func=func, **kwargs):
                params = self.params_z(z)
                M = params['MStar']
                phi = params['phiStar']
                alpha = params['alpha']
                return _func(MStar=M, phiStar=phi, alpha=alpha, **kwargs)
            newfunc.__name__ = func.__name__
            newfunc.__doc__ = func.__doc__
            self.__dict__[name] = newfunc
def plotLFevo(hist=None,
              params=B2008,
              extrap_var='t',
              #maglim = -21.07 - 2.5 * numpy.log10(0.2)):
              maglim = -21. - 2.5 * numpy.log10(0.2),
              z_max=20.0,
              skipIon=True
              ):

    """Plot evolution of luminosity function params and total luminsity.

    Schechter function at each redshift is integrated up to maglim to
    find total luminsity.
    """

    for (k, v) in params.iteritems():
        params[k] = numpy.asarray(v)

    if hist is None:
        cosmo = cp.WMAP7_BAO_H0_mean(flat=True)
        hist = LFHistory(params, extrap_var=extrap_var, **cosmo)
    else:
        params = hist.params
        extrap_var = hist.extrap_var
        cosmo = hist.cosmo

    z = params['z']
    t = cd.age(z, **cosmo)[0] / cc.yr_s 
    MStar = params['MStar']
    phiStar = params['phiStar']
    alpha = params['alpha']

    if maglim is None:
        ltot = schechterTotLM(MStar=MStar, phiStar=phiStar, alpha=alpha)
    else:
        ltot = schechterCumuLM(magnitudeAB=maglim,
                               MStar=MStar, phiStar=phiStar, alpha=alpha)

    print hist._MStarfunc.extrap_string()

    zPlot = numpy.arange(z.min()-0.1, z_max, 0.1)
    tPlot = cd.age(zPlot, **cosmo)[0] / cc.yr_s
    newparams = hist.params_z(zPlot)
    MPlot = newparams['MStar']
    phiPlot = newparams['phiStar']
    alphaPlot = newparams['alpha']

    if maglim is None:
        ltotPlot = hist.schechterTotLM(zPlot)
    else:
        ltotPlot = hist.schechterCumuLM(zPlot, magnitudeAB=maglim)
    # From Table 6 of 2008ApJ...686..230B
    lB2008 =10.** numpy.array([26.18, 25.85, 25.72, 25.32, 25.14])

    iPhot = hist.iPhotonRateDensity_z(zPlot, maglim=maglim)
#    iPhotFunc = lambda t1: cc.yr_s * hist.iPhotonRateDensity_t(t1,
#                                                               maglim=maglim)

    if not skipIon:
        xH = hist.ionization(zPlot, maglim)
    import pylab
    pylab.figure(1)
    pylab.gcf().set_label('LFion_vs_z')
    if skipIon:
        pylab.subplot(111)
    else:
        pylab.subplot(211)
    pylab.plot(zPlot, iPhot)
    if not skipIon:
        pylab.subplot(212)
        pylab.plot(zPlot, xH)
        pylab.ylim(0.0, 1.5)
        
    pylab.figure(2)
    pylab.gcf().set_label('LFparams_vs_z')
    pylab.subplot(311)
    pylab.plot(z, MStar, '-')
    pylab.plot(z, MStar, 'o')
    pylab.plot(zPlot, MPlot, ':')

    pylab.subplot(312)
    pylab.plot(z, phiStar, '-')
    pylab.plot(z, phiStar, 'o')
    pylab.plot(zPlot, phiPlot, ':')

    pylab.subplot(313)
    pylab.plot(z, alpha, '-')
    pylab.plot(z, alpha, 'o')
    pylab.plot(zPlot, alphaPlot, ':')

    pylab.figure(3)
    pylab.gcf().set_label('LFparams_vs_t')
    pylab.subplot(311)
    pylab.plot(t, MStar, '-')
    pylab.plot(t, MStar, 'o')
    pylab.plot(tPlot, MPlot, ':')

    pylab.subplot(312)
    pylab.plot(t, phiStar, '-')
    pylab.plot(t, phiStar, '.')
    pylab.plot(tPlot, phiPlot, ':')

    pylab.subplot(313)
    pylab.plot(t, alpha, '-')
    pylab.plot(t, alpha, 'o')
    pylab.plot(tPlot, alphaPlot, ':')

    pylab.figure(4)
    pylab.gcf().set_label('LFlum_vs_z')
    pylab.subplot(121)
    pylab.plot(z, ltot, 'o')
    pylab.plot(z, lB2008, 'x')
    pylab.plot(zPlot, ltotPlot)

    pylab.subplot(122)
    pylab.plot(t, ltot, 'o')
    pylab.plot(t, lB2008, 'x')
    pylab.plot(tPlot, ltotPlot)
Example #26
0
def integrate_ion_recomb(z,
                         ion_func,
                         clump_fact_func,
                         xHe=1.0,
                         temp_gas=1e4,
                         alpha_B=None,
                         bubble=True,
                         **cosmo):
    """Integrate IGM ionization and recombination given an ionization function.
    
    Parameters:

    z: array 

       The redshift values at which to calculate the ionized
       fraction. This array should be in reverse numerical order. The
       first redshift specified should be early enough that the
       universe is still completely neutral.

    ion_func: 

       A function giving the ratio of the total density of emitted
       ionizing photons to the density hydrogen atoms (or hydrogen
       plus helium, if you prefer) as a function of redshift.

    temp_gas: 

       Gas temperature used to calculate the recombination coefficient
       if alpha_b is not specified.

    alpha_B:

       Optional recombination coefficient in units of cm^3
       s^-1. In alpha_B=None, it is calculated from temp_gas.

    clump_fact_func: function

      Function returning the clumping factor when given a redshift,
      defined as <n_HII^2>/<n_HII>^2. 

   cosmo: dict

      Dictionary specifying the cosmological parameters.

    Notes:

    We only track recombination of hydrogen, but if xHe > 0, then the
    density is boosted by the addition of xHe * nHe. This is
    eqiuvalent to assuming the the ionized fraction of helium is
    always proportional to the ionized fraction of hydrogen. If
    xHe=1.0, then helium is singly ionized in the same proportion as
    hydrogen. If xHe=2.0, then helium is fully ionized in the same
    proportion as hydrogen.
    
    We assume, as is fairly standard, that the ionized
    fraction is contained in fully ionized bubbles surrounded by a
    fully neutral IGM. The output is therefore the volume filling
    factor of ionized regions, not the ionized fraction of a
    uniformly-ionized IGM.

    I have also made the standard assumption that all ionized photons
    are immediately absorbed, which allows the two differential
    equations (one for ionization-recombination and one for
    emission-photoionizaion) to be combined into a single ODE. 

    """

    # Determine recombination coefficient.
    if alpha_B is None:
        alpha_B_cm = recomb_rate_coeff_HG(temp_gas, 'H', 'B')
    else:
        alpha_B_cm = alpha_B
    alpha_B = alpha_B_cm * cc.Gyr_s / (cc.Mpc_cm**3.)
    print(
        "Recombination rate alpha_B = %.4g (Mpc^3 Gyr^-1) = %.4g (cm^3 s^-1)" %
        (alpha_B, alpha_B_cm))

    # Normalize power spectrum.
    if 'deltaSqr' not in cosmo:
        cosmo['deltaSqr'] = cp.norm_power(**cosmo)

    # Calculate useful densities.
    rho_crit, rho_0, n_He_0, n_H_0 = cden.baryon_densities(**cosmo)

    # Boost density to approximately account for helium.
    nn = (n_H_0 + xHe * n_He_0)

    # Function used in the integration.
    # Units: (Mpc^3 Gyr^-1) * Mpc^-3 = Gyr^-1
    coeff_rec_func = lambda z1: (clump_fact_func(z1) * alpha_B * nn *
                                 (1. + z1)**3.)

    # Generate a function that converts age of the universe to z.
    red_func = cd.quick_redshift_age_function(zmax=1.1 * numpy.max(z),
                                              zmin=-0.0,
                                              dz=0.01,
                                              **cosmo)

    ref_func_Gyr = lambda t1: red_func(t1 * cc.Gyr_s)

    # Convert specified redshifts to cosmic time (age of the universe).
    t = cd.age(z, **cosmo)[0] / cc.Gyr_s

    # Integrate to find u(z) = x(z) - w(z), where w is the ionization fraction
    u = si.odeint(_udot,
                  y0=0.0,
                  t=t,
                  args=(coeff_rec_func, ref_func_Gyr, ion_func, bubble))
    u = u.flatten()

    w = ion_func(z)
    x = u + w
    #x[x > 1.0] = 1.0
    return x, w, t
Example #27
0
def integrate_ion_recomb_collapse(z,
                                  coeff_ion,
                                  temp_min=1e4,
                                  passed_min_mass=False,
                                  temp_gas=1e4,
                                  alpha_B=None,
                                  clump_fact_func=clumping_factor_BKP,
                                  **cosmo):
    """IGM ionization state with recombinations from halo collapse
    fraction. Integrates an ODE describing IGM ionization and
    recombination rates.

    z: array 

       The redshift values at which to calculate the ionized
       fraction. This array should be in reverse numerical order. The
       first redshift specified should be early enough that the
       universe is still completely neutral.

    coeff_ion: 

       The coefficient converting the collapse fraction to ionized
       fraction, neglecting recombinations. Equivalent to the product
       (f_star * f_esc_gamma * N_gamma) in the BKP paper.


    temp_min: 

       See docs for ionization_from_collapse. Either the minimum virial
       temperature or minimum mass of halos contributing to
       reionization.

    passed_temp_min: 

       See documentation for ionization_from_collapse.

    temp_gas: 

       Gas temperature used to calculate the recombination coefficient
       if alpha_b is not specified.

    alpha_B:

       Optional recombination coefficient in units of cm^3
       s^-1. In alpha_B=None, it is calculated from temp_gas.

    clump_fact_func: function

      Function returning the clumping factor when given a redshift.

   cosmo: dict

      Dictionary specifying the cosmological parameters.

    We assume, as is fairly standard, that the ionized
    fraction is contained in fully ionized bubbles surrounded by a
    fully neutral IGM. The output is therefore the volume filling
    factor of ionized regions, not the ionized fraction of a
    uniformly-ionized IGM.

    I have also made the standard assumption that all ionized photons
    are immediately absorbed, which allows the two differential
    equations (one for ionization-recombination and one for
    emission-photoionizaion) to be combined into a single ODE.

    """

    # Determine recombination coefficient.
    if alpha_B is None:
        alpha_B_cm = recomb_rate_coeff_HG(temp_gas, 'H', 'B')
    else:
        alpha_B_cm = alpha_B
    alpha_B = alpha_B_cm / (cc.Mpc_cm**3.)
    print("Recombination rate alpha_B = %.4g (Mpc^3 s^-1) = %.4g (cm^3 s^-1)" %
          (alpha_B, alpha_B_cm))

    # Normalize power spectrum.
    if 'deltaSqr' not in cosmo:
        cosmo['deltaSqr'] = cp.norm_power(**cosmo)

    # Calculate useful densities.
    rho_crit, rho_0, n_He_0, n_H_0 = cden.baryon_densities(**cosmo)

    # Function used in the integration.
    # Units: (Mpc^3 s^-1) * Mpc^-3 = s^-1
    coeff_rec_func = lambda z: (clump_fact_func(z)**2. * alpha_B * n_H_0 *
                                (1. + z)**3.)

    # Generate a function that converts redshift to age of the universe.
    redfunc = cd.quick_redshift_age_function(zmax=1.1 * numpy.max(z),
                                             zmin=-0.0,
                                             **cosmo)
    # Function used in the integration.
    ionfunc = quick_ion_col_function(coeff_ion,
                                     temp_min,
                                     passed_min_mass=passed_min_mass,
                                     zmax=1.1 * numpy.max(z),
                                     zmin=-0.0,
                                     zstep=0.1,
                                     **cosmo)

    # Convert specified redshifts to cosmic time (age of the universe).
    t = cd.age(z, **cosmo)

    # Integrate to find u(z) = x(z) - w(z), where w is the ionization fraction
    u = si.odeint(_udot, y0=0.0, t=t, args=(coeff_rec_func, redfunc, ionfunc))
    u = u.flatten()

    w = ionization_from_collapse(z,
                                 coeff_ion,
                                 temp_min,
                                 passed_min_mass=passed_min_mass,
                                 **cosmo)
    x = u + w
    x[x > 1.0] = 1.0
    return x, w, t
Example #28
0
def current_age(snapshot):
    import cosmolopy.distance as cd
    import cosmolopy.constants as cc
    cosmo = snapshot.cosmo
    return cd.age(**cosmo) / cc.Gyr_s  # Gyr
    da = cd.angular_diameter_distance(z[i],**Cosmology)
    #See equations 18-19 of David Hogg's arXiv:astro-ph/9905116v4
    
    dl = cd.luminosity_distance(z[i],**Cosmology)
    #Units are Mpc
    
    dVc = cd.diff_comoving_volume(z[i], **Cosmology)
    #The differential comoving volume element dV_c/dz/dSolidAngle.
    #Dimensions are volume per unit redshift per unit solid angle.
    #Units are Mpc**3 Steradians^-1.
    #See David Hogg's arXiv:astro-ph/9905116v4, equation 28

    tl = cd.lookback_time(z[i],**Cosmology)
    #See equation 30 of David Hogg's arXiv:astro-ph/9905116v4. Units are s.
    
    agetl = cd.age(z[i],**Cosmology)
    #Age at z is lookback time at z'->Infinity minus lookback time at z.
    
    tH = 3.09e17/Cosmology['h']
    
    ez = cd.e_z(z[i],**Cosmology)
    #The unitless Hubble expansion rate at redshift z.
    #In David Hogg's (arXiv:astro-ph/9905116v4) formalism, this is
    #equivalent to E(z), defined in his eq. 14.
    
    if PlotNumber == 1:
        val[i] = dm/dh
        xtitle = "redshift z"
        ytitle = "Proper motion distance Dm/Dh"

    elif PlotNumber == 2: