def calc_elemvar_table(savename,_mywindows=False,_no_indiv_windows=False):
    if _mywindows: import window
    # Restore the file with the synthetic spectra with all variations
    if os.path.exists(savename):
        with open(savename,'rb') as savefile:
            baseline= pickle.load(savefile)
            elem_synspec= pickle.load(savefile)
    else:
        raise IOError("File %s with synthetic spectra does not exists; compute this first with apogee/test/test_windows.py" % savename)
    # Compute the whole table
    elems= ['C','N','O','Na','Mg','Al','Si','S','K','Ca','Ti','V','Mn','Fe',
            'Ni']
    table= []
    # Loop through synthetic spectra varying one element
    for elem in elems:
        col= []
        # Now look at the windows for each element
        for elemc in elems:
            if not _no_indiv_windows:
                si, ei= apwindow.waveregions(elemc,asIndex=True,pad=0,dr='13')
            if _mywindows:
                elemWeights= window.read(elemc,dr='13')
            else:
                elemWeights= apwindow.read(elemc,dr='13')
            elemWeights/= numpy.nansum(elemWeights)
            # Start with total
            col.append(numpy.sqrt(numpy.nansum((elemWeights\
                                         *(elem_synspec[elem][1]-elem_synspec[elem][0])**2.))/numpy.nansum(elemWeights)))
            if not _no_indiv_windows:
                for s,e in zip(si,ei):
                    col.append(numpy.sqrt(numpy.nansum((elemWeights\
                                                 *(elem_synspec[elem][1]-elem_synspec[elem][0])**2.)[s:e])/numpy.nansum(elemWeights[s:e])))
        table.append(col)
    return table
Exemple #2
0
def read(elem,apStarWavegrid=True,dr=None):
    """
    NAME:
       read
    PURPOSE:
       read the window weights for a given element, modified to only return 'good' windows
    INPUT:
       elem - element
       apStarWavegrid= (True) if True, output the window onto the apStar wavelength grid, otherwise just give the ASPCAP version (blue+green+red directly concatenated)
       dr= read the window corresponding to this data release       
    OUTPUT:
       Array with window weights
    HISTORY:
       2015-01-25 - Written - Bovy (IAS)
       2015-09-02 - Modified for only returning 'good' windows - Bovy (UofT)
    """
    out= apwindow.read(elem,apStarWavegrid=True,dr=dr)
    out[bad(elem)]= 0.
    if not apStarWavegrid:
        return toAspcapGrid(out)
    else:
        return out
def fit_func(elem,
             name,
             spectra,
             spectra_errs,
             T,
             dat_type,
             run_number,
             location,
             sigma_val=None):  ###Fitting function
    """Return fit residuals from quadratic fit, spectral errors for desired element, fluxes for desired element,
    an appropriately-sized array of effective temperatures, the quadratic fitting parameters, the residuals, 
    errors, temperatures, and fluxes with NaNs removed, and the normalized elemental weights.
    
    Functions:
        Reads in the DR14 windows.
        Obtains the indices of pixels of the absorption lines and saves the flux value and uncertainty for 
        each star in these pixels.
        Performs the quadratic fit on each pixel using weight_lsq() and computes the residuals using residuals().
        Obtains the flux values, uncertainties, fits, residuals, and temperatures with NaNs removed.
        Writes the residuals and fit parameters to .hdf5 files.
    
    Parameters
    ----------
    elem : str
    	Element name (i.e. 'AL')
    name : str
    	Name of desired cluster (i.e. 'NGC 2682')
    spectra : tuple
    	Array of floats representing the spectra of the desired cluster
    spectra_errs : tuple
    	Array of floats representing the spectral uncertainties of the desired cluster
    T : tuple
    	Array of floats representing the effective temperature of each star in the cluster
    dat_type : str
    	Indicates whether the data being examined is the data or a simulation
     run_number : int
		Number of the run by which to label files
	location : str
		If running locally, set to 'personal'.  If running on the server, set to 'server'.
    sigma_val : float, optional
    	Indicates the value of sigma being used for the simulation in question, if applicable (default is None)

    Returns
    -------
    elem_res : tuple
    	Array of floats representing the fit residuals, with original positioning of points maintained
    final_err : tuple
    	Array of floats representing the spectral uncertainties from the lines of the desired element,
    	with original positioning of points maintained
    final_points : tuple
    	Array of floats representing the fluxes from the lines of the desired element, with original 
    	positioning of points maintained
    temp_array : tuple
    	Array of floats representing the effective temperature of each star in the cluster, with a row for
    	each pixel of the desired element
    elem_a : tuple
    	Array of floats representing the fitting parameters for the quadratic terms in the fits for each pixel of
    	the desired element
    elem_b : tuple
    	Array of floats representing the fitting parameters for the linear terms in the fits for each pixel of
    	the desired element
    elem_c : tuple
    	Array of floats representing the fitting parameters for the constant terms in the fits for each pixel of
    	the desired element
    nanless_res : tuple
    	Array of floats representing the fit residuals, with NaNs removed
    nanless_T : tuple
    	Array of floats representing the effective temperature of each star in the cluster, with a row for 
    	each pixel of the desired element, with NaNs removed
    nanless_points : tuple
    	Array of floats representing the fluxes from the lines of the desired element, with NaNs removed
    normed_weights : tuple
    	Array of floats representing the weight of each elemental window, normalized to 1
    """

    change_dr('12')  ###Switch data-release to 12
    #Find the DR14 windows from the DR12 windows
    dr12_elem_windows = window.read(
        elem)  ###Read in the DR12 windows for the element in question
    change_dr('14')  ###Switch back to DR14
    dr14_elem_windows_12 = np.concatenate(
        (dr12_elem_windows[246:3274], dr12_elem_windows[3585:6080],
         dr12_elem_windows[6344:8335]
         ))  ###Fit the dr12 windows to dr14 ("hacked" dr14 windows)
    normalized_dr14_elem_windows_12 = (
        dr14_elem_windows_12 - np.nanmin(dr14_elem_windows_12)) / (
            np.nanmax(dr14_elem_windows_12) - np.nanmin(dr14_elem_windows_12)
        )  ###Normalize the hacked dr14 windows to 1

    #Get the indices of the lines
    ind_12 = np.argwhere(
        normalized_dr14_elem_windows_12 > 0
    )  ###Get the indices of all of the pixels of the absorption lines of the element in question
    ind_12 = ind_12.flatten(
    )  ###Get rid of the extra dimension produced by np.argwhere

    #Get the fluxes and errors from spectra
    len_spectra = len(spectra)  ###Number of stars
    elem_points_12 = np.zeros(
        (len(ind_12), len_spectra)
    )  ###Array for values of the points in the spectra that are at the indices of the elemental lines in DR12
    elem_err_12 = np.zeros(
        (len(ind_12), len_spectra)
    )  ###Array for values of the errors in the spectra that are at the indices of the elemental lines in DR12
    for i in range(0,
                   len(ind_12)):  ###Iterate through the DR12 elemental indices
        for j in range(0, len_spectra):  ###Iterate through the stars
            elem_points_12[i][j] = spectra[j][ind_12[
                i]]  ###Get the values of the points in the spectra at these indices in DR12
            elem_err_12[i][j] = spectra_errs[j][ind_12[
                i]]  #APOGEE measured errors ###Get the values of the errors in the spectra at these indices in DR12

    #Use only pixels with more than 5 points
    final_points_12 = []  ###Empty list for the final DR12 points
    final_err_12 = []  ###Empty list for the final DR12 errors
    final_inds_12 = []  ###Empty list for the final DR12 elemental line indices
    for i in range(
            len(elem_points_12)):  ###Iterate through the DR12 flux points
        if np.count_nonzero(
                ~np.isnan(elem_points_12[i])
        ) >= 5:  ###If the number of points in each pixel that are not NaNs is greater than or equal to 5
            final_points_12.append(elem_points_12[i])  ###Append those points
            final_err_12.append(elem_err_12[i])  ###Append those errors
            final_inds_12.append(ind_12[i])  ###Append those indices
    final_points_12 = np.array(final_points_12)  ###Make into array
    final_err_12 = np.array(final_err_12)  ###Make into array
    final_inds_12 = np.array(final_inds_12)  ###Make into array
    if len(
            final_inds_12
    ) == 0:  ###If no indices are left (i.e. if there are less than 5 points in every pixel)
        print('Warning: less than 5 points for every pixel, skipping ',
              elem)  ###Skip and don't finish this element
    else:  ###If there are enough points left
        dr12_weights = normalized_dr14_elem_windows_12[
            final_inds_12]  ###Get all of the weights of the elemental pixels for DR12
        sorted_dr12_weights = np.sort(
            dr12_weights)  ###Sort these weights from smallest to largest

        #Get windows
        if location == 'personal':  ###If running on Mac
            window_file = pd.read_hdf(
                '/Users/chloecheng/Personal/dr14_windows.hdf5',
                'window_df')  ###Get file I made for DR14 windows
        elif location == 'server':  ###If running on the server
            window_file = pd.read_hdf(
                '/geir_data/scr/ccheng/AST425/Personal/dr14_windows.hdf5',
                'window_df')  ###Get file I made for DR14 windows

        dr14_elem_windows_14 = window_file[
            elem].values  ###Get the DR14 windows for the element in question
        normalized_dr14_elem_windows_14 = (
            dr14_elem_windows_14 - np.min(dr14_elem_windows_14)) / (
                np.max(dr14_elem_windows_14) - np.min(dr14_elem_windows_14)
            )  ###Normalize these windows to 1

        #Get the indices of the lines
        if elem == 'C' or elem == 'N' or elem == 'FE':  ###If we're looking at one of the elements with order ~1000 pixels
            ind = np.argwhere(
                normalized_dr14_elem_windows_14 > np.min(
                    sorted_dr12_weights[int(len(sorted_dr12_weights) * 0.7):])
            )  ###Get rid of the smallest 70% of the DR12 pixels
        else:  ###For all of the other elements
            ind = np.argwhere(
                normalized_dr14_elem_windows_14 > 0)  ###Get all of the pixels
        ind = ind.flatten(
        )  ###Get rid of the extra dimension from argwhere (try to streamline this)

        #Get the fluxes and errors from spectra
        #Limits of DR12 detectors
        dr12_d1_left = 322  ###Left limit of detector 1
        dr12_d1_right = 3242  ###Right limit of detector 1
        dr12_d2_left = 3648  ###Left limit of detector 2
        dr12_d2_right = 6048  ###Right limit of detector 2
        dr12_d3_left = 6412  ###Left limit of detector 3
        dr12_d3_right = 8306  ###Right limit of detector 3

        elem_points = np.zeros(
            (len(ind), len_spectra)
        )  ###Make an empty array to hold the values of the spectra at the elemental indices
        elem_err = np.zeros(
            (len(ind), len_spectra)
        )  ###Make an empty array to hold the values of the spectral errors at the elemental indices
        for i in range(0, len(ind)):  ###Iterate through the elemental indices
            for j in range(
                    0, len_spectra):  ###Iterate through the number of stars
                ###If the indices are outside of the bounds of the DR12 detectors (these bounds should be right)
                if ind[i] < dr12_d1_left or (
                        dr12_d1_right < ind[i] < dr12_d2_left) or (
                            dr12_d2_right < ind[i] <
                            dr12_d3_left) or ind[i] > dr12_d3_right:
                    elem_points[i][
                        j] = np.nan  ###Set the point to NaN and ignore
                    elem_err[i][j] = np.nan  ###Set the error to NaN and ignore
                else:  ###If the indices are within the bounds of the DR12 detectors
                    elem_points[i][j] = spectra[j][
                        ind[i]]  ###Get the corresponding point in the spectra
                    elem_err[i][j] = spectra_errs[j][ind[
                        i]]  #APOGEE measured errors ###Get the corresponding point in the spectral errors

        #Use only pixels with more than 5 points
        final_points = [
        ]  ###Make an array for the final set of spectral points
        final_err = [
        ]  ###Make an array for the final set of spectral error points
        final_inds = [
        ]  ###Make an array for the final set of elemental indices
        for i in range(len(
                elem_points)):  ###Iterate through the points we just obtained
            if np.count_nonzero(
                    ~np.isnan(elem_points[i])
            ) >= 5:  ###If the number of non-NaNs in the pixel is greater than or equal to 5
                final_points.append(elem_points[i])  ###Append the points
                final_err.append(elem_err[i])  ###Append the errors
                final_inds.append(ind[i])  ###Append the indices
        final_points = np.array(final_points)  ###Make into array
        final_err = np.array(final_err)  ###Make into array
        final_inds = np.array(final_inds)  ###Make into array

        if len(final_points) == 0:  ###If all pixels have less than 5 points
            print('Warning: less than 5 points for every pixel, skipping ',
                  elem)  ###Skip the element and end here
        else:  ###If there are some pixels remaining

            #Create an appropriately-sized array of temperatures to mask as well
            temp_array = np.full(
                (final_points.shape), T
            )  ###Create an array of the temperatures that is the same size as the spectral points, but each row is the same set of temperatures
            for i in range(
                    0,
                    len(final_points)):  ###Iterate through the spectral points
                for j in range(0, len_spectra):  ###Iterate through the stars
                    if np.isnan(final_points[i][j]):  ###If the point is a NaN
                        temp_array[i][
                            j] = np.nan  ###Mask the corresponding point in the temperature array

            #Do fits with non-nan numbers
            nanless_inds = np.isfinite(
                final_points)  ###Get the indices of the non-NaN points
            fits = []  ###Create an empty list for the fit parameters
            for i in range(
                    len(final_points)):  ###Iterate through the spectral points
                fits.append(
                    weight_lsq(final_points[i][nanless_inds[i]],
                               temp_array[i][nanless_inds[i]],
                               final_err[i][nanless_inds[i]])
                )  ###Fit using weight_lsq function and all points that are not NaNs
            for i in range(len(fits)):  ###Iterate through the fits
                fits[i] = np.array(
                    fits[i])  ###Make each sub-list into an array
            fits = np.array(fits)  ###Make the whole list into an array
            ###Check the order of these as well - I think it should be fine if you just change the order in weight_lsq bc still return a, b, c in the order 0, 1, 2
            elem_a = fits[:, 0]  ###Get the a-parameter
            elem_b = fits[:, 1]  ###Get the b-parameter
            elem_c = fits[:, 2]  ###Get the c-parameter

            elem_fits = np.zeros_like(
                final_points)  ###Create an array to save the actual fits
            for i in range(0,
                           len(final_points)):  ###Iterate through the points
                elem_fits[i] = elem_a[i] * temp_array[i]**2 + elem_b[
                    i] * temp_array[i] + elem_c[i]  ###Fit quadratically

            #Calculate residuals
            elem_res = residuals(final_points,
                                 elem_fits)  ###Calculate the fit residuals

            #Remove nans from fits, residuals, errors, and temperatures for plotting and cumulative distribution
            #calculation purposes
            nanless_fits = []  ###Create an empty list for the nanless fits
            nanless_res = [
            ]  ###Create an empty list for the nanless fit residuals
            nanless_err = []  ###Create an empty list for the nanless errors
            nanless_T = [
            ]  ###Create an empty list for the nanless temperatures
            nanless_points = [
            ]  ###Create an empty list for the nanless spectral points
            for i in range(
                    len(final_points)):  ###Iterate through the spectral points
                nanless_fits.append(
                    elem_fits[i][nanless_inds[i]])  ###Append the nanless fits
                nanless_res.append(elem_res[i][
                    nanless_inds[i]])  ###Append the nanless residuals
                nanless_err.append(final_err[i][
                    nanless_inds[i]])  ###Append the nanless errors
                nanless_T.append(temp_array[i][
                    nanless_inds[i]])  ###Append the nanless temperatures
                nanless_points.append(final_points[i][
                    nanless_inds[i]])  ###Append the nanless points
            for i in range(
                    len(final_points)):  ###Turn all sub lists into arrays
                nanless_fits[i] = np.array(nanless_fits[i])
                nanless_res[i] = np.array(nanless_res[i])
                nanless_err[i] = np.array(nanless_err[i])
                nanless_T[i] = np.array(nanless_T[i])
                nanless_points[i] = np.array(nanless_points[i])
            nanless_fits = np.array(
                nanless_fits)  ###Turn all lists into arrays
            nanless_res = np.array(nanless_res)
            nanless_err = np.array(nanless_err)
            nanless_T = np.array(nanless_T)
            nanless_points = np.array(nanless_points)

            #Get the weights for later
            weights = normalized_dr14_elem_windows_14[
                final_inds]  ###Get the weights fo the DR14 lines that we're using
            normed_weights = weights / np.sum(
                weights)  ###Normalize the weights

            #File-saving
            #If we are looking at the data
            timestr = time.strftime("%Y%m%d_%H%M%S")  ###date_time string
            name_string = str(name).replace(' ',
                                            '')  ###cluster name, remove space
            pid = str(os.getpid())  ###PID string
            if sigma_val == None:  ###IF we are looking at the data
                if location == 'personal':  ###If running on Mac
                    path_dat = '/Users/chloecheng/Personal/run_files/' + name_string + '/' + name_string + '_' + str(
                        elem) + '_' + 'fit_res' + '_' + str(
                            dat_type) + '_' + timestr + '_' + pid + '_' + str(
                                run_number) + '.hdf5'  ###Use this path
                elif location == 'server':  ###If running on server
                    path_dat = '/geir_data/scr/ccheng/AST425/Personal/run_files/' + name_string + '/' + name_string + '_' + str(
                        elem) + '_' + 'fit_res' + '_' + str(
                            dat_type) + '_' + timestr + '_' + pid + '_' + str(
                                run_number) + '.hdf5'  ###Use this path

                #If the file exists, output the desired variables
                if glob.glob(
                        path_dat
                ):  ###If the file already exists, don't write anything
                    return elem_res, final_err, final_points, temp_array, elem_a, elem_b, elem_c, nanless_res, nanless_err, nanless_T, nanless_points, normed_weights
                #If the file does not exist, create file and output the desired variables
                else:  ###If the file does not exist, write all fitting information
                    file = h5py.File(path_dat, 'w')
                    file['points'] = final_points
                    file['residuals'] = elem_res
                    file['err_200'] = final_err
                    file['a_param'] = elem_a
                    file['b_param'] = elem_b
                    file['c_param'] = elem_c
                    file.close()
                    return elem_res, final_err, final_points, temp_array, elem_a, elem_b, elem_c, nanless_res, nanless_err, nanless_T, nanless_points, normed_weights
            #If we are looking at simulations
            else:  ###If we are looking at a simulation
                if location == 'personal':  ###If running from Mac
                    path_sim = '/Users/chloecheng/Personal/run_files/' + name_string + '/' + name_string + '_' + str(
                        elem) + '_' + 'fit_res' + '_' + str(
                            dat_type) + '_' + timestr + '_' + pid + '_' + str(
                                run_number) + '.hdf5'  ###Use this path
                elif location == 'server':  ###If running on server
                    path_sim = '/geir_data/scr/ccheng/AST425/Personal/run_files/' + name_string + '/' + name_string + '_' + str(
                        elem) + '_' + 'fit_res' + '_' + str(
                            dat_type) + '_' + timestr + '_' + pid + '_' + str(
                                run_number) + '.hdf5'  ###Use this path

                #If the file exists, append to the file
                if glob.glob(path_sim):  ###If the file exists
                    file = h5py.File(path_sim, 'a')  ###Append to the file
                    #If the group for the particular value of sigma exists, don't do anything
                    if glob.glob(
                            str(sigma_val)
                    ):  ###If this value of sigma has already been tested, don't write anything
                        file.close()
                    #If not, append a new group to the file for the particular value of sigma
                    else:  ###If it has not been tested, write all fitting information to a group named after the value of sigma
                        grp = file.create_group(str(sigma_val))
                        grp['points'] = final_points
                        grp['residuals'] = elem_res
                        grp['err_200'] = final_err
                        grp['a_param'] = elem_a
                        grp['b_param'] = elem_b
                        grp['c_param'] = elem_c
                        file.close()
                #If the file does not exist, create a new file
                else:  ###If the file does not exist, write all of the fitting information to a group named after the value of sigma
                    file = h5py.File(path_sim, 'w')
                    grp = file.create_group(str(sigma_val))
                    grp['points'] = final_points
                    grp['residuals'] = elem_res
                    grp['err_200'] = final_err
                    grp['a_param'] = elem_a
                    grp['b_param'] = elem_b
                    grp['c_param'] = elem_c
                    file.close()
                return elem_res, final_err, final_points, temp_array, elem_a, elem_b, elem_c, nanless_res, nanless_err, nanless_T, nanless_points, normed_weights
Exemple #4
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 #5
0
def windows(*args, **kwargs):
    """
    NAME:
       windows
    PURPOSE:
       plot the spectral windows for a given element
    INPUT:
       Either:
          (a) wavelength, spectrum (\AA,spectrum units)
          (b) spectrum (assumed on standard APOGEE re-sampled wavelength grid)
          (c) location ID, APOGEE ID (default loads aspcapStar, loads extension ext(=1); apStar=True loads apStar spectrum)
          +element string (e.g., 'Al'); Adding 1 and 2 splits the windows into two
    KEYWORDS:
       plot_weights= (False) if True, also plot the weights for the windows (assumes that the spectrum is on the apStarWavegrid)
       markLines= mark the location of 'lines' (see apogee.spec.window.lines)
       apogee.spec.plot.waveregions keywords
    OUTPUT:
       plot to output
       The final axes allow one to put additional labels on the plot, e.g., for adding the APOGEE ID:
       bovy_plot.bovy_text(r'$\mathrm{%s}$' % '2M02420597+0837017',top_left=True)       
       Note that an ID (e.g., the apogee ID) and Teff, logg, metallicity, and alpha-enhancement labels can be added using the keywords label* above
    HISTORY:
       2015-01-26 - Written (based on older code) - Bovy (IAS)
    """
    pad = kwargs.pop('pad', 3)
    try:
        si, ei = apwindow.waveregions(args[2], pad=pad, asIndex=True)
    except IOError:
        try:
            si, ei = apwindow.waveregions(args[2][:-1], pad=pad, asIndex=True)
        except IOError:
            raise IOError(
                "Windows for element %s could not be loaded, please specify an existing APOGEE element"
                % ((args[2].lower().capitalize())))
        if args[2][-1] == '1':
            si = si[:len(si) // 2]
            ei = ei[:len(ei) // 2]
        else:
            si = si[len(si) // 2:]
            ei = ei[len(ei) // 2:]
        # Remove the number from the element
        newargs = (args[0], args[1], args[2][:-1])
        for ii in range(len(args) - 3):
            newargs = newargs + (args[ii + 3], )
        args = newargs
    # Also get the number and total width of all of the windows
    dlam = apwindow.total_dlambda(args[2], pad=pad)
    numw = apwindow.num(args[2])
    # Set spacing between windows
    if numw > 20:
        kwargs['skipdx'] = 0.003
        kwargs['_noskipdiags'] = True
    elif numw > 15:
        kwargs['skipdx'] = 0.01
    # Set initial space to zero
    kwargs['_startendskip'] = 0
    # Set initial figure width
    if not kwargs.get('overplot', False) and not 'fig_width' in kwargs:
        if dlam > 150.:
            kwargs['fig_width'] = 8.4
        else:
            kwargs['fig_width'] = 4.2
    # Don't tick x
    kwargs['_noxticks'] = True
    # Label the largest wavelength in angstrom
    kwargs['_labelwav'] = True
    # Don't label the lines unless explicitly asked for
    kwargs['labelLines'] = kwargs.get('labelLines', False)
    # Plot the weights as well
    if kwargs.pop('plot_weights', False):
        kwargs['_plotw'] = apwindow.read(args[2], apStarWavegrid=True)
        if kwargs.get('apStar', False):
            kwargs['yrange'] = kwargs.get('yrange',
                                          [0., 1.1 * numpy.nanmax(args[1])])
        else:
            kwargs['yrange'] = kwargs.get('yrange', [0., 1.2])
    # mark the 'lines'
    markLines = kwargs.get('markLines', not 'overplot' in kwargs)
    if markLines and not '_markwav' in kwargs:
        kwargs['_markwav'] = apwindow.lines(args[2])
    # Plot
    waveregions(args[0],
                args[1],
                startindxs=si,
                endindxs=ei,
                *args[3:],
                **kwargs)
    # Add label
    bovy_plot.bovy_text(r'$\mathrm{%s}$' % ((args[2].lower().capitalize())),
                        top_left=True,
                        fontsize=10,
                        backgroundcolor='w')
    return None
Exemple #6
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))
Exemple #7
0
def windows(*args,**kwargs):
    """
    NAME:
       windows
    PURPOSE:
       plot the spectral windows for a given element
    INPUT:
       Either:
          (a) wavelength, spectrum (\AA,spectrum units)
          (b) spectrum (assumed on standard APOGEE re-sampled wavelength grid)
          (c) location ID, APOGEE ID (default loads aspcapStar, loads extension ext(=1); apStar=True loads apStar spectrum)
          +element string (e.g., 'Al'); Adding 1 and 2 splits the windows into two
    KEYWORDS:
       plot_weights= (False) if True, also plot the weights for the windows (assumes that the spectrum is on the apStarWavegrid)
       markLines= mark the location of 'lines' (see apogee.spec.window.lines)
       apogee.spec.plot.waveregions keywords
    OUTPUT:
       plot to output
       The final axes allow one to put additional labels on the plot, e.g., for adding the APOGEE ID:
       bovy_plot.bovy_text(r'$\mathrm{%s}$' % '2M02420597+0837017',top_left=True)       
       Note that an ID (e.g., the apogee ID) and Teff, logg, metallicity, and alpha-enhancement labels can be added using the keywords label* above
    HISTORY:
       2015-01-26 - Written (based on older code) - Bovy (IAS)
    """
    pad= kwargs.pop('pad',3)
    try:
        si,ei= apwindow.waveregions(args[2],pad=pad,asIndex=True)
    except IOError:
        try:
            si, ei= apwindow.waveregions(args[2][:-1],pad=pad,asIndex=True)
        except IOError:
            raise IOError("Windows for element %s could not be loaded, please specify an existing APOGEE element" % ((args[2].lower().capitalize())))
        if args[2][-1] == '1':
            si= si[:len(si)//2]
            ei= ei[:len(ei)//2]
        else:
            si= si[len(si)//2:]
            ei= ei[len(ei)//2:]
        # Remove the number from the element
        newargs= (args[0],args[1],args[2][:-1])
        for ii in range(len(args)-3):
            newargs= newargs+(args[ii+3],)
        args= newargs
    # Also get the number and total width of all of the windows
    dlam= apwindow.total_dlambda(args[2],pad=pad)
    numw= apwindow.num(args[2])
    # Set spacing between windows
    if numw > 20:
        kwargs['skipdx']= 0.003
        kwargs['_noskipdiags']= True
    elif numw > 15:
        kwargs['skipdx']= 0.01
    # Set initial space to zero
    kwargs['_startendskip']= 0
    # Set initial figure width
    if not kwargs.get('overplot',False) and not 'fig_width' in kwargs:
        if dlam > 150.:
            kwargs['fig_width']= 8.4
        else:
            kwargs['fig_width']= 4.2
    # Don't tick x
    kwargs['_noxticks']= True
    # Label the largest wavelength in angstrom
    kwargs['_labelwav']= True
    # Don't label the lines unless explicitly asked for
    kwargs['labelLines']= kwargs.get('labelLines',False)
    # Plot the weights as well
    if kwargs.pop('plot_weights',False):
        kwargs['_plotw']= apwindow.read(args[2],apStarWavegrid=True)
        if kwargs.get('apStar',False):
            kwargs['yrange']= kwargs.get('yrange',
                                         [0.,1.1*numpy.nanmax(args[1])])
        else:
            kwargs['yrange']= kwargs.get('yrange',[0.,1.2])
    # mark the 'lines'
    markLines= kwargs.get('markLines',not 'overplot' in kwargs)
    if markLines and not '_markwav' in kwargs:
        kwargs['_markwav']= apwindow.lines(args[2])
    # Plot
    waveregions(args[0],args[1],startindxs=si,endindxs=ei,
                *args[3:],**kwargs)
    # Add label
    bovy_plot.bovy_text(r'$\mathrm{%s}$' % ((args[2].lower().capitalize())),
                        top_left=True,fontsize=10,backgroundcolor='w')
    return None
def fit_func(elem, name, spectra, spectra_errs, T, dat_type, run_number, location, sigma_val=None):
    """Return fit residuals from quadratic fit, spectral errors for desired element, fluxes for desired element,
    an appropriately-sized array of effective temperatures, the quadratic fitting parameters, the residuals, 
    errors, temperatures, and fluxes with NaNs removed, and the normalized elemental weights.
    
    Functions:
        Reads in the DR14 windows.
        Obtains the indices of pixels of the absorption lines and saves the flux value and uncertainty for 
        each star in these pixels.
        Performs the quadratic fit on each pixel using weight_lsq() and computes the residuals using residuals().
        Obtains the flux values, uncertainties, fits, residuals, and temperatures with NaNs removed.
        Writes the residuals and fit parameters to .hdf5 files.
    
    Parameters
    ----------
    elem : str
    	Element name (i.e. 'AL')
    name : str
    	Name of desired cluster (i.e. 'NGC 2682')
    spectra : tuple
    	Array of floats representing the spectra of the desired cluster
    spectra_errs : tuple
    	Array of floats representing the spectral uncertainties of the desired cluster
    T : tuple
    	Array of floats representing the effective temperature of each star in the cluster
    dat_type : str
    	Indicates whether the data being examined is the data or a simulation
     run_number : int
		Number of the run by which to label files
	location : str
		If running locally, set to 'personal'.  If running on the server, set to 'server'.
    sigma_val : float, optional
    	Indicates the value of sigma being used for the simulation in question, if applicable (default is None)

    Returns
    -------
    elem_res : tuple
    	Array of floats representing the fit residuals, with original positioning of points maintained
    final_err : tuple
    	Array of floats representing the spectral uncertainties from the lines of the desired element,
    	with original positioning of points maintained
    final_points : tuple
    	Array of floats representing the fluxes from the lines of the desired element, with original 
    	positioning of points maintained
    temp_array : tuple
    	Array of floats representing the effective temperature of each star in the cluster, with a row for
    	each pixel of the desired element
    elem_a : tuple
    	Array of floats representing the fitting parameters for the quadratic terms in the fits for each pixel of
    	the desired element
    elem_b : tuple
    	Array of floats representing the fitting parameters for the linear terms in the fits for each pixel of
    	the desired element
    elem_c : tuple
    	Array of floats representing the fitting parameters for the constant terms in the fits for each pixel of
    	the desired element
    nanless_res : tuple
    	Array of floats representing the fit residuals, with NaNs removed
    nanless_T : tuple
    	Array of floats representing the effective temperature of each star in the cluster, with a row for 
    	each pixel of the desired element, with NaNs removed
    nanless_points : tuple
    	Array of floats representing the fluxes from the lines of the desired element, with NaNs removed
    normed_weights : tuple
    	Array of floats representing the weight of each elemental window, normalized to 1
    """
    
    change_dr('12')
    #Find the DR14 windows from the DR12 windows
    dr12_elem_windows = window.read(elem)
    change_dr('14')
    dr14_elem_windows_12 = np.concatenate((dr12_elem_windows[246:3274], dr12_elem_windows[3585:6080], dr12_elem_windows[6344:8335]))
    normalized_dr14_elem_windows_12 = (dr14_elem_windows_12 - np.nanmin(dr14_elem_windows_12))/(np.nanmax(dr14_elem_windows_12) - np.nanmin(dr14_elem_windows_12))
    
    #Get the indices of the lines 
    ind_12 = np.argwhere(normalized_dr14_elem_windows_12 > 0)
    ind_12 = ind_12.flatten()
    
    #Get the fluxes and errors from spectra
    len_spectra = len(spectra)
    elem_points_12 = np.zeros((len(ind_12), len_spectra))
    elem_err_12 = np.zeros((len(ind_12), len_spectra))
    for i in range(0, len(ind_12)):
    	for j in range(0, len_spectra):
    		elem_points_12[i][j] = spectra[j][ind_12[i]]
    		elem_err_12[i][j] = spectra_errs[j][ind_12[i]] #APOGEE measured errors
    		
    #Use only pixels with more than 5 points
    final_points_12 = []
    final_err_12 = []
    final_inds_12 = []
    for i in range(len(elem_points_12)):
    	if np.count_nonzero(~np.isnan(elem_points_12[i])) >= 5:
    		final_points_12.append(elem_points_12[i])
    		final_err_12.append(elem_err_12[i])
    		final_inds_12.append(ind_12[i])
    final_points_12 = np.array(final_points_12)
    final_err_12 = np.array(final_err_12)
    final_inds_12 = np.array(final_inds_12)
    if len(final_inds_12) == 0:
    	print('Warning: less than 5 points for every pixel, skipping ', elem)
    else:
    	dr12_weights = normalized_dr14_elem_windows_12[final_inds_12]
    	sorted_dr12_weights = np.sort(dr12_weights)
    	
    	#Get windows
    	if location == 'personal':
    		window_file = pd.read_hdf('/Users/chloecheng/Personal/dr14_windows.hdf5', 'window_df') 
    	elif location == 'server':
    		window_file = pd.read_hdf('/geir_data/scr/ccheng/AST425/Personal/dr14_windows.hdf5', 'window_df')
    		
    	dr14_elem_windows_14 = window_file[elem].values
    	normalized_dr14_elem_windows_14 = (dr14_elem_windows_14 - np.min(dr14_elem_windows_14))/(np.max(dr14_elem_windows_14) - np.min(dr14_elem_windows_14))
    	
    	#Get the indices of the lines 
    	if elem == 'C' or elem == 'N' or elem == 'FE':
    		ind = np.argwhere(normalized_dr14_elem_windows_14 > np.min(sorted_dr12_weights[int(len(sorted_dr12_weights)*0.7):]))
    	else:
    		ind = np.argwhere(normalized_dr14_elem_windows_14 > 0)
    	ind = ind.flatten()
    	
    	#Get the fluxes and errors from spectra
    	elem_points = np.zeros((len(ind), len_spectra))
    	elem_err = np.zeros((len(ind), len_spectra))
    	for i in range(0, len(ind)):
    		for j in range(0, len_spectra):
    			elem_points[i][j] = spectra[j][ind[i]]
    			elem_err[i][j] = spectra_errs[j][ind[i]] #APOGEE measured errors
    	
    	#Use only pixels with more than 5 points
    	final_points = []
    	final_err = []
    	final_inds = []
    	for i in range(len(elem_points)):
    		if np.count_nonzero(~np.isnan(elem_points[i])) >= 5:
    			final_points.append(elem_points[i])
    			final_err.append(elem_err[i])
    			final_inds.append(ind[i])
    	final_points = np.array(final_points)
    	final_err = np.array(final_err)
    	final_inds = np.array(final_inds)
    	
    	if len(final_points) == 0:
    		print('Warning: less than 5 points for every pixel, skipping ', elem)
    	else:
    	
    		#Create an appropriately-sized array of temperatures to mask as well
    		temp_array = np.full((final_points.shape), T)
    		for i in range(0, len(final_points)):
    			for j in range(0, len_spectra):
    				if np.isnan(final_points[i][j]):
    					temp_array[i][j] = np.nan
    					
    		#Do fits with non-nan numbers
    		nanless_inds = np.isfinite(final_points)
    		fits = []
    		for i in range(len(final_points)):
    			fits.append(weight_lsq(final_points[i][nanless_inds[i]], temp_array[i][nanless_inds[i]], final_err[i][nanless_inds[i]]))
    		for i in range(len(fits)):
    			fits[i] = np.array(fits[i])
    		fits = np.array(fits)
    		elem_a = fits[:,0]
    		elem_b = fits[:,1]
    		elem_c = fits[:,2]
    		
    		elem_fits = np.zeros_like(final_points)
    		for i in range(0, len(final_points)):
    			elem_fits[i] = elem_a[i]*temp_array[i]**2 + elem_b[i]*temp_array[i] + elem_c[i]
    			
    		#Calculate residuals
    		elem_res = residuals(final_points, elem_fits)
    		
    		#Remove nans from fits, residuals, errors, and temperatures for plotting and cumulative distribution 
    		#calculation purposes
    		nanless_fits = []
    		nanless_res = []
    		nanless_err = []
    		nanless_T = []
    		nanless_points = []
    		for i in range(len(final_points)):
    			nanless_fits.append(elem_fits[i][nanless_inds[i]])
    			nanless_res.append(elem_res[i][nanless_inds[i]])
    			nanless_err.append(final_err[i][nanless_inds[i]])
    			nanless_T.append(temp_array[i][nanless_inds[i]])
    			nanless_points.append(final_points[i][nanless_inds[i]])
    		for i in range(len(final_points)):
    			nanless_fits[i] = np.array(nanless_fits[i])
    			nanless_res[i] = np.array(nanless_res[i])
    			nanless_err[i] = np.array(nanless_err[i])
    			nanless_T[i] = np.array(nanless_T[i])
    			nanless_points[i] = np.array(nanless_points[i])
    		nanless_fits = np.array(nanless_fits)
    		nanless_res = np.array(nanless_res)
    		nanless_err = np.array(nanless_err)
    		nanless_T = np.array(nanless_T)
    		nanless_points = np.array(nanless_points)
    		
    		#Get the weights for later
    		weights = normalized_dr14_elem_windows_14[final_inds]
    		normed_weights = weights/np.sum(weights)
    		
    		#File-saving 
    		#If we are looking at the data
    		timestr = time.strftime("%Y%m%d_%H%M%S")
    		name_string = str(name).replace(' ', '')
    		pid = str(os.getpid())
    		if sigma_val == None:
    			if location == 'personal':
    				path_dat = '/Users/chloecheng/Personal/run_files_' + name_string + '_' + str(elem) + '/' + name_string + '/' + name_string + '_' + str(elem) + '_' + 'fit_res' + '_' + str(dat_type) + '_' + timestr + '_' + pid + '_' + str(run_number) + '.hdf5'
    			elif location == 'server':
    				path_dat = '/geir_data/scr/ccheng/AST425/Personal/run_files_' + name_string + '_' + str(elem) + '/' + name_string + '/' + name_string + '_' + str(elem) + '_' + 'fit_res' + '_' + str(dat_type) + '_' + timestr + '_' + pid + '_' + str(run_number) + '.hdf5'
    	
    			#If the file exists, output the desired variables
    			if glob.glob(path_dat):
    				return elem_res, final_err, final_points, temp_array, elem_a, elem_b, elem_c, nanless_res, nanless_err, nanless_T, nanless_points, normed_weights
    			#If the file does not exist, create file and output the desired variables
    			else:
    				file = h5py.File(path_dat, 'w')
    				file['points'] = final_points
    				file['residuals'] = elem_res
    				file['err_200'] = final_err
    				file['a_param'] = elem_a
    				file['b_param'] = elem_b
    				file['c_param'] = elem_c
    				file.close()
    				return elem_res, final_err, final_points, temp_array, elem_a, elem_b, elem_c, nanless_res, nanless_err, nanless_T, nanless_points, normed_weights
    		#If we are looking at simulations
    		else:
    			if location == 'personal':
    				path_sim = '/Users/chloecheng/Personal/run_files_' + name_string + '_' + str(elem) + '/' + name_string + '/' + name_string + '_' + str(elem) + '_' + 'fit_res' + '_' + str(dat_type) + '_' + timestr + '_' + pid + '_' + str(run_number) + '.hdf5'
    			elif location == 'server':
    				path_sim = '/geir_data/scr/ccheng/AST425/Personal/run_files_' + name_string + '_' + str(elem) + '/' + name_string  + '/' + name_string  + '_' + str(elem) + '_' + 'fit_res' + '_' + str(dat_type) + '_' + timestr + '_' + pid + '_' + str(run_number) + '.hdf5'
    	
    			#If the file exists, append to the file
    			if glob.glob(path_sim):
    				file = h5py.File(path_sim, 'a')
    				#If the group for the particular value of sigma exists, don't do anything
    				if glob.glob(str(sigma_val)):
    					file.close()
    				#If not, append a new group to the file for the particular value of sigma
    				else:
    					grp = file.create_group(str(sigma_val))
    					grp['points'] = final_points
    					grp['residuals'] = elem_res
    					grp['err_200'] = final_err
    					grp['a_param'] = elem_a
    					grp['b_param'] = elem_b
    					grp['c_param'] = elem_c
    					file.close()
    			#If the file does not exist, create a new file
    			else:
    				file = h5py.File(path_sim, 'w')
    				grp = file.create_group(str(sigma_val))
    				grp['points'] = final_points
    				grp['residuals'] = elem_res
    				grp['err_200'] = final_err
    				grp['a_param'] = elem_a
    				grp['b_param'] = elem_b
    				grp['c_param'] = elem_c
    				file.close()
    			return elem_res, final_err, final_points, temp_array, elem_a, elem_b, elem_c, nanless_res, nanless_err, nanless_T, nanless_points, normed_weights
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