Exemple #1
0
def tophat(elem,dr=None,apStarWavegrid=True):
    """
    NAME:
       tophat
    PURPOSE:
       return an array with True in the window of a given element and False otherwise, only for 'good' windows
    INPUT:
       elem - element     
       dr= read the window corresponding to this data release       
       apStarWavegrid= (True) if True, output the window onto the apStar wavelength grid, otherwise just give the ASPCAP version (blue+green+red directly concatenated)
    OUTPUT:
       array on apStar grid
    HISTORY:
       2015-01-26 - Written - Bovy (IAS@KITP)
       2015-09-02 - Modified for only returning 'good' windows - Bovy (UofT)
    """
    out= apwindow.tophat(elem,apStarWavegrid=True,dr=dr)
    out[bad(elem)]= 0.
    if not apStarWavegrid:
        return toAspcapGrid(out)
    else:
        return out
Exemple #2
0
def test_windows(options):
    elems = [
        'C', 'N', 'O', 'Na', 'Mg', 'Al', 'Si', 'S', 'K', 'Ca', 'Ti', 'V', 'Mn',
        'Fe', 'Ni', 'Ce', 'Co', 'Cr', 'Cu', 'Ge', 'Nd', 'P', 'Rb', 'Y'
    ]
    if options.savefilename is None or \
            not os.path.exists(options.savefilename):
        # Set default linelist for Turbospectrum or MOOG
        if options.linelist is None and options.moog:
            linelist = 'moog.201312161124.vac'
        elif options.linelist is None:
            linelist = 'turbospec.201312161124'
        else:
            linelist = options.linelist
        # set up a model atmosphere for the requested atmospheric parameters
        if options.arcturus:
            options.teff = 4286.
            options.logg = 1.66
            options.metals = -0.52
            options.am = 0.4
            options.cm = 0.09
            options.vm = 1.7
        atm = atlas9.Atlas9Atmosphere(teff=options.teff,
                                      logg=options.logg,
                                      metals=options.metals,
                                      am=options.am,
                                      cm=options.cm)
        # create baseline
        if options.moog:
            baseline= \
                apogee.modelspec.moog.synth(modelatm=atm,
                                            linelist=linelist,
                                            lsf='all',cont='aspcap',
                                            vmacro=6.,isotopes='arcturus',
                                            vmicro=options.vm)
        else:
            baseline= \
                apogee.modelspec.turbospec.synth(modelatm=atm,
                                                 linelist=linelist,
                                                 lsf='all',cont='aspcap',
                                                 vmacro=6.,isotopes='arcturus',
                                                 vmicro=options.vm)
        # Loop through elements
        elem_synspec = {}
        # Run through once to simulate all differences
        for elem in elems:
            # First check that this element has windows
            elemPath = apwindow.path(elem, dr=options.dr)
            if not os.path.exists(elemPath): continue
            # Simulate deltaAbu up and down
            print "Working on %s" % (elem.capitalize())
            abu = [atomic_number(elem), -options.deltaAbu, options.deltaAbu]
            if options.moog:
                synspec= \
                    apogee.modelspec.moog.synth(abu,
                                                modelatm=atm,
                                                linelist=linelist,
                                                lsf='all',cont='aspcap',
                                                vmacro=6.,
                                                isotopes='arcturus',
                                                vmicro=options.vm)
            else:
                synspec= \
                    apogee.modelspec.turbospec.synth(abu,
                                                     modelatm=atm,
                                                     linelist=linelist,
                                                     lsf='all',cont='aspcap',
                                                     vmacro=6.,
                                                     isotopes='arcturus',
                                                     vmicro=options.vm)
            elem_synspec[elem] = synspec
        if not options.savefilename is None:
            save_pickles(options.savefilename, baseline, elem_synspec)
    else:
        with open(options.savefilename, 'rb') as savefile:
            baseline = pickle.load(savefile)
            elem_synspec = pickle.load(savefile)
    # Now run through the different elements again and plot windows for each
    # with elements that vary significantly
    colors = sns.color_palette("colorblind")
    plotelems = [
        elem if not elem in ['C', 'N', 'O', 'Fe'] else '%s1' % elem
        for elem in elems
    ]
    plotelems.extend(['C2', 'N2', 'O2', 'Fe2'])
    for pelem in plotelems:
        if '1' in pelem or '2' in pelem: elem = pelem[:-1]
        else: elem = pelem
        if not elem in elem_synspec: continue
        # Figure out which elements have significant variations in these
        # windows and always plot the element that should vary
        elemIndx = apwindow.tophat(elem, dr=options.dr)
        elemWeights = apwindow.read(elem, dr=options.dr)
        elemWeights /= numpy.nansum(elemWeights)
        # Start with the element in question
        splot.windows(1. + options.amplify *
                      (elem_synspec[elem][0] - baseline[0]),
                      pelem,
                      color=colors[0],
                      yrange=[0., 1.4],
                      plot_weights=True,
                      zorder=len(elems))
        splot.windows(1. + options.amplify *
                      (elem_synspec[elem][1] - baseline[0]),
                      pelem,
                      color=colors[0],
                      overplot=True,
                      zorder=len(elems))
        elem_shown = [elem]
        # Run through the rest to figure out the order
        elemVar = numpy.zeros(len(elems))
        for ii, altElem in enumerate(elems):
            if altElem == elem: continue
            if not altElem in elem_synspec: continue
            elemVar[ii] = 0.5 * numpy.nansum(
                (elem_synspec[altElem][0] - baseline[0])**2. * elemWeights)
            elemVar[ii] += 0.5 * numpy.nansum(
                (elem_synspec[altElem][1] - baseline[0])**2. * elemWeights)
        jj = 0
        sortindx = numpy.argsort(elemVar)[::-1]
        for altElem in numpy.array(elems)[sortindx]:
            if altElem == elem: continue
            if not altElem in elem_synspec: continue
            if numpy.fabs(\
                numpy.nanmax([(elem_synspec[altElem][0]-baseline[0])[elemIndx],
                            (elem_synspec[altElem][1]-baseline[0])[elemIndx]]))\
                            > options.varthreshold:
                jj += 1
                if jj >= len(colors): jj = len(colors) - 1
                elem_shown.append(altElem)
                splot.windows(1. + options.amplify *
                              (elem_synspec[altElem][0] - baseline[0]),
                              pelem,
                              color=colors[jj],
                              overplot=True,
                              zorder=len(elems) - jj)
                splot.windows(1. + options.amplify *
                              (elem_synspec[altElem][1] - baseline[0]),
                              pelem,
                              color=colors[jj],
                              overplot=True,
                              zorder=len(elems) - jj)
        t = pyplot.gca().transData
        fig = pyplot.gcf()
        for s, c in zip(elem_shown, colors[:jj + 1]):
            xc = 0.05
            if elem == 'K' or elem == 'Ce' or elem == 'Ge' or elem == 'Nd' \
                    or elem == 'Rb':
                xc = apwindow.waveregions(elem, dr=options.dr,
                                          pad=3)[0][0] - 15000. + 1.
            text = pyplot.text(xc,
                               1.2,
                               " " + (r"$\mathrm{%s}$" % s) + " ",
                               color=c,
                               transform=t,
                               size=16.,
                               backgroundcolor='w')
            text.draw(fig.canvas.get_renderer())
            ex = text.get_window_extent()
            t = transforms.offset_copy(text._transform,
                                       x=1.5 * ex.width,
                                       units='dots')
        # Save
        bovy_plot.bovy_end_print(options.plotfilename.replace('ELEM', pelem))
    return None
Exemple #3
0
def elemchi2(spec,specerr,
             elem,elem_linspace=(-0.5,0.5,11),tophat=False,
             fparam=None,
             teff=4750.,logg=2.5,metals=0.,am=0.,nm=0.,cm=0.,vm=None,
             lib='GK',pca=True,sixd=True,dr=None,
             offile=None,
             inter=3,f_format=1,f_access=None,
             verbose=False):
    """
    NAME:
       elemchi2
    PURPOSE:
       Calculate the chi^2 for a given element
    INPUT:
       Either:
          (1) location ID - single or list/array of location IDs
              APOGEE ID - single or list/array of APOGEE IDs; loads aspcapStar
          (2) spec - spectrum: can be (nwave) or (nspec,nwave)
              specerr - spectrum errors: can be (nwave) or (nspec,nwave)
       elem - element to consider (e.g., 'Al')
       elem_linspace= ((-0.5,0.5,11)) numpy.linspace range of abundance, relative to the relevant value in fparam / metals,am,nm,cm
       tophat= (False) if True, don't use the value of weights, just use them to define windows that have weight equal to one
       Input parameters (can be 1D arrays)
          Either:
             (1) fparam= (None) output of ferre.fit
             (2) teff= (4750.) Effective temperature (K)
                 logg= (2.5) log10 surface gravity / cm s^-2
                 metals= (0.) overall metallicity
                 am= (0.) [alpha/M]
                 nm= (0.) [N/M]
                 cm= (0.) [C/M]
                 vm= if using the 7D library, also specify the microturbulence
       Library options:
          lib= ('GK') spectral library
          pca= (True) if True, use a PCA compressed library
          sixd= (True) if True, use the 6D library (w/o vm)
          dr= data release
       FERRE options:
          inter= (3) order of the interpolation
          f_format= (1) file format (0=ascii, 1=unf)
          f_access= (None) 0: load whole library, 1: use direct access (for small numbers of interpolations), None: automatically determine a good value (currently, 1)
       verbose= (False) if True, run FERRE in verbose mode
    OUTPUT:
       chi^2
    HISTORY:
       2015-03-12 - Written - Bovy (IAS)
    """
    # Parse fparam
    if not fparam is None:
        teff= fparam[:,paramIndx('TEFF')]
        logg= fparam[:,paramIndx('LOGG')]
        metals= fparam[:,paramIndx('METALS')]
        am= fparam[:,paramIndx('ALPHA')]
        nm= fparam[:,paramIndx('N')]
        cm= fparam[:,paramIndx('C')]
        if sixd:
            vm= None
        else:
            vm= fparam[:,paramIndx('LOG10VDOP')]        
    # parse spec, specerr input
    nspec= len(teff)
    if len(spec.shape) == 1:
        spec= numpy.reshape(spec,(1,spec.shape[0]))
        specerr= numpy.reshape(specerr,(1,specerr.shape[0]))
    # Read the weights
    if tophat:
        weights= apwindow.tophat(elem,apStarWavegrid=False,dr=dr)
    else:
        weights= apwindow.read(elem,apStarWavegrid=False,dr=dr)
        weights/= numpy.sum(weights)
    # Decide which parameter to vary
    nvelem= elem_linspace[2]
    var_elem= numpy.tile(numpy.linspace(*elem_linspace),(nspec,1))   
    if elem.lower() == 'c':
        cm= var_elem+numpy.tile(cm,(nvelem,1)).T
    elif elem.lower() == 'n':
        nm= var_elem+numpy.tile(nm,(nvelem,1)).T
    elif elem.lower() in ['o','mg','s','si','ca','ti']:
        am= var_elem+numpy.tile(am,(nvelem,1)).T
    else:
        metals= var_elem+numpy.tile(metals,(nvelem,1)).T
    # Upgrade dimensionality of other parameters for interpolate input
    teff= numpy.tile(teff,(nvelem,1)).T
    logg= numpy.tile(logg,(nvelem,1)).T
    if not sixd:
        vm= numpy.tile(vm,(nvelem,1)).T.flatten()
    if not elem.lower() == 'c':
        cm= numpy.tile(cm,(nvelem,1)).T
    if not elem.lower() == 'n':
        nm= numpy.tile(nm,(nvelem,1)).T
    if not elem.lower() in ['o','mg','s','si','ca','ti']:
        am= numpy.tile(am,(nvelem,1)).T
    if elem.lower() in ['c','n','o','mg','s','si','ca','ti']:
        metals= numpy.tile(metals,(nvelem,1)).T
    # Get interpolated spectra, [nspec,nwave]
    ispec= interpolate(teff.flatten(),logg.flatten(),metals.flatten(),
                       am.flatten(),nm.flatten(),cm.flatten(),vm=vm,
                       lib=lib,pca=pca,sixd=sixd,dr=dr,
                       inter=inter,f_format=f_format,f_access=f_access,
                       verbose=verbose,apStarWavegrid=False)
    dspec= numpy.tile(spec,(1,nvelem)).reshape((nspec*nvelem,spec.shape[1]))
    dspecerr= numpy.tile(specerr,
                         (1,nvelem)).reshape((nspec*nvelem,spec.shape[1]))
    tchi2= _chi2(ispec,dspec,dspecerr,numpy.tile(weights,(nspec*nvelem,1)))
    return numpy.reshape(tchi2,(nspec,nvelem))
def test_windows(options):
    elems= ['C','N','O','Na','Mg','Al','Si','S','K','Ca','Ti','V','Mn','Fe',
            'Ni','Ce','Co','Cr','Cu','Ge','Nd','P','Rb','Y']
    if options.savefilename is None or \
            not os.path.exists(options.savefilename):
        # Set default linelist for Turbospectrum or MOOG
        if options.linelist is None and options.moog:
            linelist= 'moog.201312161124.vac'
        elif options.linelist is None:
            linelist= 'turbospec.201312161124'
        else:
            linelist= options.linelist
        # set up a model atmosphere for the requested atmospheric parameters
        if options.arcturus:
            options.teff= 4286.
            options.logg= 1.66
            options.metals= -0.52
            options.am= 0.4
            options.cm= 0.09
            options.vm= 1.7
        atm= atlas9.Atlas9Atmosphere(teff=options.teff,logg=options.logg,
                                     metals=options.metals,
                                     am=options.am,cm=options.cm)
        # create baseline
        if options.moog:
            baseline= \
                apogee.modelspec.moog.synth(modelatm=atm,
                                            linelist=linelist,
                                            lsf='all',cont='aspcap',
                                            vmacro=6.,isotopes='arcturus',
                                            vmicro=options.vm)
        else:
            baseline= \
                apogee.modelspec.turbospec.synth(modelatm=atm,
                                                 linelist=linelist,
                                                 lsf='all',cont='aspcap',
                                                 vmacro=6.,isotopes='arcturus',
                                                 vmicro=options.vm)
        # Loop through elements
        elem_synspec= {}
        # Run through once to simulate all differences
        for elem in elems:
            # First check that this element has windows
            elemPath= apwindow.path(elem,dr=options.dr)
            if not os.path.exists(elemPath): continue
            # Simulate deltaAbu up and down
            print "Working on %s" % (elem.capitalize())
            abu= [atomic_number(elem),-options.deltaAbu,options.deltaAbu]
            if options.moog:
                synspec= \
                    apogee.modelspec.moog.synth(abu,
                                                modelatm=atm,
                                                linelist=linelist,
                                                lsf='all',cont='aspcap',
                                                vmacro=6.,
                                                isotopes='arcturus',
                                                vmicro=options.vm)
            else:
                synspec= \
                    apogee.modelspec.turbospec.synth(abu,
                                                     modelatm=atm,
                                                     linelist=linelist,
                                                     lsf='all',cont='aspcap',
                                                     vmacro=6.,
                                                     isotopes='arcturus',
                                                     vmicro=options.vm)
            elem_synspec[elem]= synspec
        if not options.savefilename is None:
            save_pickles(options.savefilename,baseline,elem_synspec)
    else:
        with open(options.savefilename,'rb') as savefile:
            baseline= pickle.load(savefile)
            elem_synspec= pickle.load(savefile)
    # Now run through the different elements again and plot windows for each
    # with elements that vary significantly
    colors= sns.color_palette("colorblind")
    plotelems= [elem if not elem in ['C','N','O','Fe'] else '%s1' % elem
                for elem in elems]
    plotelems.extend(['C2','N2','O2','Fe2'])
    for pelem in plotelems:
        if '1' in pelem or '2' in pelem: elem = pelem[:-1]
        else: elem= pelem
        if not elem in elem_synspec: continue
        # Figure out which elements have significant variations in these 
        # windows and always plot the element that should vary
        elemIndx= apwindow.tophat(elem,dr=options.dr)
        elemWeights= apwindow.read(elem,dr=options.dr)
        elemWeights/= numpy.nansum(elemWeights)
        # Start with the element in question
        splot.windows(1.+options.amplify*(elem_synspec[elem][0]-baseline[0]),
                      pelem,
                      color=colors[0],
                      yrange=[0.,1.4],
                      plot_weights=True,
                      zorder=len(elems))
        splot.windows(1.+options.amplify*(elem_synspec[elem][1]-baseline[0]),
                      pelem,
                      color=colors[0],overplot=True, 
                      zorder=len(elems))
        elem_shown= [elem]
        # Run through the rest to figure out the order
        elemVar= numpy.zeros(len(elems))
        for ii,altElem in enumerate(elems):
            if altElem == elem: continue
            if not altElem in elem_synspec: continue
            elemVar[ii]= 0.5*numpy.nansum((elem_synspec[altElem][0]-baseline[0])**2.*elemWeights)
            elemVar[ii]+= 0.5*numpy.nansum((elem_synspec[altElem][1]-baseline[0])**2.*elemWeights)
        jj= 0
        sortindx= numpy.argsort(elemVar)[::-1]
        for altElem in numpy.array(elems)[sortindx]:
            if altElem == elem: continue
            if not altElem in elem_synspec: continue
            if numpy.fabs(\
                numpy.nanmax([(elem_synspec[altElem][0]-baseline[0])[elemIndx],
                            (elem_synspec[altElem][1]-baseline[0])[elemIndx]]))\
                            > options.varthreshold:
                jj+= 1
                if jj >= len(colors): jj= len(colors)-1
                elem_shown.append(altElem)
                splot.windows(1.+options.amplify*(elem_synspec[altElem][0]-baseline[0]),
                              pelem,
                              color=colors[jj],overplot=True,
                              zorder=len(elems)-jj)
                splot.windows(1.+options.amplify*(elem_synspec[altElem][1]-baseline[0]),
                              pelem,
                              color=colors[jj],overplot=True,
                              zorder=len(elems)-jj)
        t = pyplot.gca().transData
        fig= pyplot.gcf()
        for s,c in zip(elem_shown,colors[:jj+1]):
            xc= 0.05
            if elem == 'K' or elem == 'Ce' or elem == 'Ge' or elem == 'Nd' \
                    or elem == 'Rb':
                xc= apwindow.waveregions(elem,dr=options.dr,
                                         pad=3)[0][0]-15000.+1.
            text = pyplot.text(xc,1.2," "+(r"$\mathrm{%s}$" % s)+" ",color=c,
                               transform=t,size=16.,backgroundcolor='w')
            text.draw(fig.canvas.get_renderer())
            ex= text.get_window_extent()
            t= transforms.offset_copy(text._transform,x=1.5*ex.width,
                                      units='dots')
        # Save
        bovy_plot.bovy_end_print(options.plotfilename.replace('ELEM',pelem))
    return None