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
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
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