Пример #1
0
 def calc_age_pdf(self,fehdist='casagrande'):
     """
     NAME:
        calc_age_pdf
     PURPOSE:
        calculate the age PDF for a uniform SFH for a given metallicity 
        distribution
     INPUT:
        fehdist= either:
           1) a single metallicity 
           2) 'casagrande': local metallicity distribution following Casagrande et al. (2011)
           3) a function giving
     OUTPUT:
         a function between 800 Myr and 10 Gyr giving the age distribution
     HISTORY:
        2014-02-27 - Written in this form - Bovy (IAS)
     """
     if isinstance(fehdist,(int,float,numpy.float32,numpy.float64)):
         pz= numpy.zeros(len(self._zs))
         pz[numpy.argmin(numpy.fabs(self._zs-isodist.FEH2Z(fehdist,zsolar=zsolar())))]= 1.
     elif isinstance(fehdist,str) and fehdist.lower() == 'casagrande':
         pz= numpy.array([localfehdist(isodist.Z2FEH(z,zsolar=zsolar()))/z for z in self._zs])
     else:
         pz= numpy.array([fehdist(isodist.Z2FEH(z,zsolar=zsolar()))/z for z in self._zs])
     pz/= numpy.sum(pz)
     agezdist= self._omega/self._coarsemass
     pz= numpy.tile(pz,(len(self._coarselages),1)).T
     postage= numpy.nansum(pz*agezdist,axis=0)/numpy.nansum(pz,axis=0)/10.**self._coarselages
     postage= postage[self._coarselages > numpy.log10(0.8)]
     postage/= numpy.nanmax(postage)
     lages= self._coarselages[self._coarselages > numpy.log10(0.8)]
     postage_spline= interpolate.InterpolatedUnivariateSpline(lages,
                                                              numpy.log(postage),
                                                              k=3)
     return lambda x: dummy_page(x,copy.copy(postage_spline))
Пример #2
0
def sample_iso_MH(fehbin=[-0.6, 0.2],
                  agebin=[0., 13.],
                  n=1000,
                  agebias=False,
                  imftype='chabrier2003',
                  isochrones='Padova'):
    #Load pre-computed parsec isochrone grid
    iso_file = open('../savs/' + isochrones + '_grid_' + imftype + '.sav')
    iso_grid = pickle.load(iso_file)
    #add rgb age bias if agebias = True
    if agebias == True:
        iso_grid[:, 6] *= agebias(10**iso_grid[:, 0])
    #Perform sample cuts (logg and J-K)
    gridcuts = (iso_grid[:, 3] > 1.8) & (iso_grid[:, 3] <
                                         3.0) & (iso_grid[:, 5] > 0.5)
    cutgrid = iso_grid[gridcuts]
    n_weights = cutgrid[:, 6] * (10**cutgrid[:, 0] / cutgrid[:, 1])
    #make [Fe/H], age cut
    fehcut = (isodist.Z2FEH(cutgrid[:,1])>=fehbin[0])&(isodist.Z2FEH(cutgrid[:,1])<fehbin[1])\
      &(10**cutgrid[:,0] >= agebin[0])&(10**cutgrid[:,0] < agebin[1])
    # compute CDF of M_H
    sorter_H = numpy.argsort(cutgrid[:, 4][fehcut])
    cdf_H = numpy.cumsum(n_weights[fehcut][sorter_H]) / numpy.sum(
        n_weights[fehcut])
    #Interpolate CDF and take n samples
    intercdf_H = interp1d(cdf_H, cutgrid[:, 4][fehcut][sorter_H])
    rand = numpy.random.uniform(size=n, low=0.0001, high=0.999999)
    model_MH = intercdf_H(rand)
    return model_MH
Пример #3
0
def loggteffcut(teff, z, upper=True):
    if not upper:
        return 1.8
    else:
        feh = isodist.Z2FEH(z, zsolar=zsolar())
        this_teff = (4760. - 4607.) / (-0.4) * feh + 4607.
        return 0.0018 * (teff - this_teff) + 2.5
Пример #4
0
def Gdist(tG, ZG):
    """The distribution of G for the local metallicity distribution
    REWRITE TO TAKE A Z(G) FUNCTION OBTAINED THROUGH INTERPOLATION"""
    try:
        tZ = ZG(tG)
        tjac = numpy.fabs(ZG.derivatives(tG)[0] / tZ / numpy.log(10.))
    except ValueError:
        return 0.
    # Add Jacobian
    return localfehdist(isodist.Z2FEH(tZ, zsolar=0.017)) * tjac
Пример #5
0
def imf_h_jk(plotfile,Z=None,dwarf=False,log=False,h=12.,basti=False,
             dartmouth=False,kroupa=False):
    #Read isochrones
    if basti:
        zs= numpy.array([0.0001,0.0003,0.0006,0.001,0.002,0.004,0.008,
                         0.01,0.0198,0.03,0.04])
    elif dartmouth:
        zs= isodist.FEH2Z(numpy.array([-2.5,-2.,-1.5,-1.,-0.5,0.,0.2,0.3,0.5]))
    else:
        zs= numpy.arange(0.0005,0.03005,0.0005)
    if Z is None:
        Zs= zs
    elif not basti and not dartmouth:
        if Z < 0.01:
            Zs= [Z-0.001,Z-0.0005,Z,Z+0.0005,Z+0.001] #build up statistics
        else:
            Zs= [Z-0.0005,Z,Z+0.0005] #build up statistics
    else:
        Zs= [Z]
    if basti:
        p= isodist.BastiIsochrone(Z=Zs)
    elif dartmouth:
        p= isodist.DartmouthIsochrone(feh=isodist.Z2FEH(Zs),onlyold=True)
    else:
        p= isodist.PadovaIsochrone(Z=Zs)
    #Get relevant data
    sample= []
    weights= []
    for logage in p.logages():
        for z in Zs:
            thisiso= p(logage,z)
            if basti: mini= thisiso['M_ini']
            elif dartmouth: mini= thisiso['M']
            else: mini= thisiso['M_ini']
            if basti:
                int_IMF= isodist.imf.lognormalChabrier2001(thisiso['M_ini'],
                                                           int=True)
                dmpm= numpy.roll(int_IMF,-1)-int_IMF
            elif dartmouth:
                int_IMF= isodist.imf.lognormalChabrier2001(thisiso['M'],
                                                           int=True)
                dmpm= numpy.roll(int_IMF,-1)-int_IMF
            else:
                if kroupa:
                    int_IMF= isodist.imf.kroupa2003(thisiso['M_ini'],int=True)
                    dmpm= numpy.roll(int_IMF,-1)-int_IMF
                else:
                    dmpm= numpy.roll(thisiso['int_IMF'],-1)-thisiso['int_IMF']
            for ii in range(1,len(mini)-1):
                if basti:
                    JK= thisiso['J'][ii]-thisiso['K'][ii]
                else:
                    JK= thisiso['J'][ii]-thisiso['Ks'][ii]
                H= thisiso['H'][ii]
                if JK < 0.: # or thisiso['logg'][ii] > 3.5:
                    continue
                if dmpm[ii] > 0.: 
                    if basti:
                        sample.append([thisiso['J'][ii]-thisiso['K'][ii],
                                       thisiso['H'][ii]])
                    else:
                        sample.append([thisiso['J'][ii]-thisiso['Ks'][ii],
                                       thisiso['H'][ii]])
                    if dartmouth:
                        if logage > numpy.log10(5.)+9.:
                            weights.append(2.*dmpm[ii]) #Dartmouth are linearly spaced, but spacing is bigger at > 5 Gyr
                        else:
                            weights.append(dmpm[ii]) #Dartmouth are linearly spaced?
                    else:
                        weights.append(dmpm[ii]*10**(logage-7.))
                    #weights.append(dmpm[ii]*10**(logage-7.)*numpy.exp((10.**(logage-7.))/800.))
                else: 
                    continue #no use in continuing here
    #Form array
    sample= numpy.array(sample)
    weights= numpy.array(weights)
    #Histogram
    if dwarf:
        hist, edges= numpy.histogramdd(sample,weights=weights,bins=51,
                                       range=[[0.,1.6],[2.,9.]])
    else:
        hist, edges= numpy.histogramdd(sample,weights=weights,bins=49,
                                       range=[[0.3,1.6],[-11.,2]])
    #Normalize each J-K
    for ii in range(len(hist[:,0])):
        hist[ii,:]/= numpy.nanmax(hist[ii,:])/numpy.nanmax(hist)
        rev= copy.copy(hist[ii,::-1]) #reverse, but in one go does not always work
        hist[ii,:]= rev
    #Plot
    bovy_plot.bovy_print()
    if log:
        hist= numpy.log(hist)
    bovy_plot.bovy_dens2d(hist.T,origin='lower',cmap='gist_yarg',
                          xrange=[edges[0][0],edges[0][-1]],
                          yrange=[edges[1][-1],edges[1][0]],
                          aspect=(edges[0][-1]-edges[0][0])/float(edges[1][-1]-edges[1][0]),
                          xlabel=r'$(J-K_s)_0\ [\mathrm{mag}]$',
                          ylabel=r'$M_H\ [\mathrm{mag}]$',
                          interpolation='nearest')
    #Add extinction arrow
    djk= 0.45
    dh= 1.55/1.5*djk
    from matplotlib.patches import FancyArrowPatch
    ax=pyplot.gca()
    ax.add_patch(FancyArrowPatch((1.,-2.),(1+djk,-2+dh),
                                 arrowstyle='->',mutation_scale=20,fill=True,
                                 lw=1.25))
    bovy_plot.bovy_text(1.05,-2.05,r'$\mathrm{extinction}$',
                        rotation=-math.atan(1.5/1.55*1.3/13.)/math.pi*180.,
                        size=14.)
    #Add color cut
    bovy_plot.bovy_plot([0.5,0.5],[-20.,20.],'--',color='0.6',overplot=True)
    ax.add_patch(FancyArrowPatch((0.5,-6.),(0.7,-6.),
                                 arrowstyle='->',mutation_scale=20,fill=True,
                                 lw=1.25,ls='dashed',color='0.6'))
    bovy_plot.bovy_text(0.43,-8.,r'$\mathrm{APOGEE\ color\ cut}$',rotation=90.,
                        size=14.)
    #Add twin y axis
    ax= pyplot.gca()
    def my_formatter(x, pos):
        """distance in kpc for m=h"""
        xs= 10.**((h-x)/5.-2.)
        return r'$%.0f$' % xs
    def my_formatter2(x, pos):
        """distance in kpc for m=h"""
        xs= 10.**((h-x)/5.+1.)
        return r'$%.0f$' % xs
    ax2= pyplot.twinx()
    if dwarf:
        major_formatter = FuncFormatter(my_formatter2)
    else:
        major_formatter = FuncFormatter(my_formatter)
    ax2.yaxis.set_major_formatter(major_formatter)
    ystep= ax.yaxis.get_majorticklocs()
    ystep= ystep[1]-ystep[0]
    ax2.yaxis.set_minor_locator(MultipleLocator(ystep/5.))
    ax2.yaxis.tick_right()
    ax2.yaxis.set_label_position('right')
    ymin, ymax= ax.yaxis.get_view_interval()
    ax2.yaxis.set_view_interval(ymin,ymax,ignore=True)
    if dwarf:
        ax2.set_ylabel('$\mathrm{distance\ for}\ H_0\ =\ %.1f\ [\mathrm{pc}]$' % h)
    else:
        ax2.set_ylabel('$\mathrm{distance\ for}\ H_0\ =\ %.1f\ [\mathrm{kpc}]$' % h)
    xstep= ax.xaxis.get_majorticklocs()
    xstep= xstep[1]-xstep[0]
    ax2.xaxis.set_minor_locator(MultipleLocator(xstep/5.))
    if Z is None:
        bovy_plot.bovy_end_print(plotfile)
    else:
        bovy_plot.bovy_text(r'$Z\ =\ %.3f$' % Z,top_right=True,size=14.)
        bovy_plot.bovy_end_print(plotfile)
    return None
Пример #6
0
 def plot_popmass(self):
     """
     NAME:
        plot_popmass
     PURPOSE:
        plot the stellar-population mass for each RC star
     INPUT:
         bovy_plot.bovy_plot **kwargs
     OUTPUT:
        bovy_plot.bovy_plot output
     HISTORY:
        2014-02-28 - Written in this form - Bovy (IAS)
     """
     if not _BOVY_PLOT_LOADED:
         raise ImportError("galpy.util.bovy_plot could not be imported")
     fehs = numpy.linspace(-1., 0.5, 101)
     lages = self._coarselages
     plotthis = numpy.empty((len(fehs), len(lages)))
     for ii in range(len(fehs)):
         for jj in range(len(lages)):
             plotthis[ii, jj] = self.popmass(fehs[ii], lages[jj])
     fig = pyplot.gcf()
     left, bottom, width, height = 0.1, 0.1, 0.8, 0.6
     axBottom = pyplot.axes([left, bottom, width, height])
     fig.sca(axBottom)
     xlimits = [fehs[0], fehs[-1]]
     dlages = (lages[1] - lages[0])
     ylimits = [lages[0] - dlages, lages[-1] + dlages]
     vmin, vmax = 0., 50000.
     vmin2, vmax2 = 0., 25000.
     zlabel = r'$\mathrm{Stellar\ population\ mass\ per\ RC\ star}\,(M_\odot)$'
     xlabel = r'$[\mathrm{Fe/H}]\,(\mathrm{dex})$'
     out = bovy_plot.bovy_dens2d(plotthis.T,
                                 origin='lower',
                                 cmap='jet',
                                 xrange=xlimits,
                                 yrange=ylimits,
                                 vmin=vmin,
                                 vmax=vmax,
                                 interpolation='nearest',
                                 colorbar=True,
                                 shrink=.9,
                                 zlabel=zlabel,
                                 overplot=True)
     extent = xlimits + ylimits
     pyplot.axis(extent)
     bovy_plot._add_axislabels(
         xlabel, r'$\log_{10}\,\mathrm{Age} / 1\,\mathrm{Gyr}$')
     bovy_plot._add_ticks()
     left, bottom, width, height = 0.1, 0.68, 0.64, 0.2
     axTop = pyplot.axes([left, bottom, width, height])
     fig.sca(axTop)
     #Plot the average over SFH
     lages = numpy.linspace(-1., 1., 16)
     mtrend = numpy.zeros(len(self._zs))
     exppage = 10.**self._coarselages * numpy.exp(
         (10.**(self._coarselages + 2.)) / 800.)  #e.g., Binney (2010)
     exexppage = 10.**self._coarselages * numpy.exp(
         (10.**(self._coarselages + 2.)) / 100.)  #e.g., Binney (2010)
     page = 10.**self._coarselages
     plotthis = self._coarsemass[:-1, :] / self._omega[:-1, :]
     mtrend = 1. / (numpy.sum(page * 1. / plotthis, axis=1) /
                    numpy.sum(page))
     expmtrend = 1. / (numpy.sum(exppage * 1. / plotthis, axis=1) /
                       numpy.sum(exppage))
     exexpmtrend = 1. / (numpy.sum(exexppage * 1. / plotthis, axis=1) /
                         numpy.sum(exexppage))
     fehs = isodist.Z2FEH(self._zs[:-1], zsolar=zsolar())
     pyplot.plot(fehs, mtrend, 'k-')
     pyplot.plot(fehs, expmtrend, 'k--')
     pyplot.plot(fehs, exexpmtrend, 'k-.')
     pyplot.ylim(vmin2, vmax2)
     pyplot.xlim(xlimits[0], xlimits[1])
     nullfmt = NullFormatter()  # no labels
     thisax = pyplot.gca()
     thisax.xaxis.set_major_formatter(nullfmt)
     bovy_plot._add_ticks()
     return out
Пример #7
0
 def __init__(self,
              dwarf=False,
              imfmodel='lognormalChabrier2001',
              Z=None,
              interpolate=False,
              expsfh=False,
              marginalizefeh=False,
              glon=None,
              dontgather=False,
              loggmax=None,
              basti=False):
     """
     NAME:
        __init__
     PURPOSE:
        initialize isomodel
     INPUT:
        Z= metallicity (if not set, use flat prior in Z over all Z; can be list)
        dwarf= (default: False) if True, use dwarf part
        imfmodel= (default: 'lognormalChabrier2001') IMF model to use (see isodist.imf code for options)
        interpolate= (default: False) if True, interpolate the binned representation
        expsfh= if True, use an exponentially-declining star-formation history
        marginalizefeh= if True, marginalize over the FeH distribution along line of sight glon
        glon - galactic longitude in rad of los for marginalizefeh
        dontgather= if True, don't gather surrounding Zs
        loggmax= if set, cut logg at this maximum
        basti= if True, use Basti isochrones (if False, use Padova)
     OUTPUT:
        object
     HISTORY:
        2012-02-17 - Written - Bovy (IAS)
     """
     #Read isochrones
     if basti:
         zs = numpy.array([
             0.0001, 0.0003, 0.0006, 0.001, 0.002, 0.004, 0.008, 0.01,
             0.0198, 0.03, 0.04
         ])
     else:
         zs = numpy.arange(0.0005, 0.03005, 0.0005)
     if marginalizefeh:
         Zs = numpy.arange(0.008, 0.031, 0.001)
         dFeHdZ = 1. / Zs
         pZs = feh_l(glon, isodist.Z2FEH(Zs)) * dFeHdZ
     elif Z is None:
         Zs = zs
     elif isinstance(Z, float):
         if basti or dontgather:
             Zs = [Z]
         elif Z < 0.001 or Z > 0.0295:
             Zs = [Z]
         elif Z < 0.0015 or Z > 0.029:
             Zs = [Z - 0.0005, Z, Z + 0.0005]  #build up statistics
         elif Z < 0.01:
             Zs = [Z - 0.001, Z - 0.0005, Z, Z + 0.0005,
                   Z + 0.001]  #build up statistics
         else:
             Zs = [Z - 0.0005, Z, Z + 0.0005]  #build up statistics
     if basti:
         p = isodist.BastiIsochrone(Z=Zs)
     else:
         p = isodist.PadovaIsochrone(Z=Zs)
     #Get relevant data
     sample = []
     weights = []
     for logage in p.logages():
         for zz in range(len(Zs)):
             thisiso = p(logage, Zs[zz], asrecarray=True)
             #Calculate int_IMF for this IMF model
             if not imfmodel == 'lognormalChabrier2001':  #That would be the default
                 if imfmodel == 'exponentialChabrier2001':
                     int_IMF = isodist.imf.exponentialChabrier2001(
                         thisiso.M_ini, int=True)
                 elif imfmodel == 'kroupa2003':
                     int_IMF = isodist.imf.kroupa2003(thisiso.M_ini,
                                                      int=True)
                 elif imfmodel == 'chabrier2003':
                     int_IMF = isodist.imf.chabrier2003(thisiso.M_ini,
                                                        int=True)
                 else:
                     raise IOError(
                         "imfmodel option not understood (non-existing model)"
                     )
             elif basti:
                 int_IMF = isodist.imf.lognormalChabrier2001(thisiso.M_ini,
                                                             int=True)
             else:
                 int_IMF = thisiso.int_IMF
             dN = numpy.roll(int_IMF, -1) - int_IMF
             for ii in range(1, len(int_IMF) - 1):
                 if basti:
                     JK = thisiso.J[ii] - thisiso.K[ii]
                 else:
                     JK = thisiso.J[ii] - thisiso.Ks[ii]
                 H = thisiso.H[ii]
                 if JK < 0.3 or (not loggmax is None
                                 and thisiso['logg'][ii] > loggmax):
                     continue
                 if dN[ii] > 0.:
                     sample.append([JK, H])
                     if marginalizefeh:
                         if H < (11. / -1.3 * (JK - 0.3)):
                             weights.append(
                                 0.
                             )  #HACK TO GET RID OF UNWANTED BRIGHT POINTS
                         elif expsfh:
                             weights.append(pZs[zz] * dN[ii] *
                                            10**(logage - 7.) * numpy.exp(
                                                (10.**(logage - 7.)) /
                                                800.))  #e.g., Binney (2010)
                         else:
                             weights.append(pZs[zz] * dN[ii] *
                                            10**(logage - 7.))
                     else:
                         if expsfh:
                             weights.append(dN[ii] * 10**(logage - 7.) *
                                            numpy.exp(
                                                (10.**(logage - 7.)) /
                                                800.))  #e.g., Binney (2010)
                         else:
                             weights.append(dN[ii] * 10**(logage - 7.))
                 else:
                     continue  #no use in continuing here
     #Form array
     sample = numpy.array(sample)
     weights = numpy.array(weights)
     self._sample = sample
     self._weights = weights
     #Histogram
     self._jkmin, self._jkmax = 0.3, 1.6
     if dwarf:
         self._hmin, self._hmax = 2., 9.
         self._nbins = 51
     else:
         self._hmin, self._hmax = -11., 2.
         self._nbins = 26  #49
     self._djk = (self._jkmax - self._jkmin) / float(self._nbins)
     self._dh = (self._hmax - self._hmin) / float(self._nbins)
     self._hist, self._edges = numpy.histogramdd(
         sample,
         weights=weights,
         bins=self._nbins,
         range=[[self._jkmin, self._jkmax], [self._hmin, self._hmax]])
     #Save
     self._Zs = Zs
     self._interpolate = interpolate
     self._dwarf = dwarf
     self._loghist = numpy.log(self._hist)
     self._loghist[(
         self._hist == 0.)] = -numpy.finfo(numpy.dtype(numpy.float64)).max
     if interpolate:
         #Form histogram grid
         jks = numpy.linspace(self._jkmin + self._djk / 2.,
                              self._jkmax - self._djk / 2., self._nbins)
         hs = numpy.linspace(self._hmin + self._dh / 2.,
                             self._hmax - self._dh / 2., self._nbins)
         self._interpolatedhist = scipy.interpolate.RectBivariateSpline(
             jks,
             hs,
             self._hist,
             bbox=[self._jkmin, self._jkmax, self._hmin, self._hmax],
             s=0.)
         #raise NotImplementedError("'interpolate=True' option for isomodel not implemented yet")
     return None