Beispiel #1
0
def gramsfit(data, ogrid, cgrid, ID = None, FITFLAG = None, DKPC = None, scale = False, \
             force_chemtype = None, n_accept = 100, compute_pars = True):
    """
    Compute chi-squared fits to observed SEDs of AGB/RSG candidates using the GRAMS O-rich and C-rich
    model grids.
    INPUT:
    data - Astropy table containing the observed fluxes and uncertainties over a number of broadband filters.
        Each row of the data table must contain the following columns:
        ID - unique identifier for each SED.
        FLUX/DFLUX - NBANDS-element arrays containing the observed fluxes and uncertainties in each of
                    NBANDS broadband filters.
        BANDMAP - NBANDS-element arrays of indices into the array of broadband filters
        DETFLAG - NBANDS-element arrays of Booleans, TRUE if the flux in that band is a detection limit.
                    In such a case, the value in DFLUX is taken to be the number of standard deviations
                    above the noise level of this detection limit.
        OPTIONAL COLUMNS:
        FITFLAG - NBANDS-element arrays of Booleans, TRUE if band is to be included in the fit.
                    Can also be fed as an input keyword to the function call.
        DKPC - distance in kpc to source. Can also be fed as input keyword to the function call.
    ogrid, cgrid - Astropy tables containing synthetic photometry for the GRAMS grid over a number of 
        broadband filters. Photometry can be computed from the synthetic spectra for any broadband filters 
        present in the SVO database: http://svo2.cab.inta-csic.es/theory/fps/
    OPTIONAL INPUT:
    ID - array of unique identifiers passed to the function. Overrides column present in the data table.
    FITFLAG - NBANDS-element arrays of Booleans, TRUE if the flux in that band is a detection limit. Overrides column
            present in the data table.
    DKPC - distance in kpc (scalar or array) passed to the function. Overrides column present in the data table.
    scale - Boolean. If TRUE, a best-fit luminosity scale factor is also computed as part of the fit. The
            effective distance to the source is then DKPC_eff = data['DKPC'] / np.sqrt(scale).
            See the get_scale method for details.
    force_chemtype - scalar or array containing either 'o' or 'c', overrides the best-fit chemical type computed
            from the chi-squared fit.
    n_accept - scalar, number of models with lowest chi-squares used to compute the parameter uncertainties.
    compute_pars - Boolean. If TRUE, best-fit parameter values and related uncertainties are computed using
            the specified n_accept value.
    OUTPUT:
    fit - Astropy table containing the following columns for each input SED:
        chisq_o, chisq_c - n_accept-element arrays with the lowest n_accept chi-squared values computed for each 
        chemical type.
        chemtype - chemical type assigned based on comparing the lowest chi-squared values of each chemical type.
        modelindex_o, modelindex_c - n_accept-element arrays with indices into the model grids for the models with 
                the lowest chi-squared values for each chemical type.
        scale_o, scale_c - n_accept-element arrays containing best-fit luminosity scale factors for each of the 
                n_accept models with the lowest chi-squared values for each chemical type.
        If compute_pars is True, best-fit values and uncertainties (from the n_accept models with lowest 
                chi-squared values) are computed for the following parameters for each chemical type:
                Lum, Teff, logg, Rin, tau1, DPR, Tin, scale, and tau10 (O-rich) or tau11_3 (C-rich).
    """
    #In case the user has input the table names instead of the tables, read in the tables.
    #Also, scale the data fluxes to the distace at which the models are computed.
    d = data.copy()
    og = ogrid.copy()
    cg = cgrid.copy()
    data, ogrid, cgrid = prep_input(d,
                                    og,
                                    cg,
                                    ID=ID,
                                    FITFLAG=FITFLAG,
                                    DKPC=DKPC)
    d = 0
    og = 0
    cg = 0
    #computing chi-squares
    if scale:
        chisq_o, chisq_c, modelindex_o, modelindex_c, scale_o, scale_c = \
            get_chisq(data, ogrid['Fphot'], cgrid['Fphot'], n_accept = n_accept, scale = True)
    else:
        chisq_o, chisq_c, modelindex_o, modelindex_c, scale_o, scale_c = \
            get_chisq(data, ogrid['Fphot'], cgrid['Fphot'], n_accept = n_accept, scale = scale)
    #set chemical types
    chemtype = get_chemtype(chisq_o[:, 0], chisq_c[:, 0])
    #scale data fluxes back to data['DKPC'] values, create a table to store output
    try:
        modeldkpc = float(ogrid.meta['DISTKPC'])
    except:
        modeldkpc = 50.12
    distscale = (
        np.repeat(data['DKPC'][:, np.newaxis], data['FLUX'].shape[1], axis=1) /
        modeldkpc)**2
    data['FLUX'] /= distscale
    data['DFLUX'] /= distscale
    fit = Table([data['ID'], chemtype, chisq_o, chisq_c, modelindex_o, modelindex_c, scale_o, scale_c], \
                 names = ('ID', 'chemtype', 'chisq_o', 'chisq_c', 'modelindex_o', 'modelindex_c', 'scale_o', 'scale_c'))
    #Compute best-fit parameter values
    if compute_pars:
        po, po_err, pc, pc_err = get_pars(fit, ogrid, cgrid)
        for c in po.columns:
            fit[c + '_o'] = po[c]
            fit[c + '_o_err'] = po_err[c]
        for c in pc.columns:
            fit[c + '_c'] = pc[c]
            fit[c + '_c_err'] = pc_err[c]
        print("...done.")
    #Force chemical types
    if force_chemtype is not None:
        nforce = len(force_chemtype)
        if nforce == 1:
            force_chemtype = np.repeat(force_chemtype, ndata).copy()
        ct = np.array([f.strip().lower() for f in list(force_chemtype)])
        if ((ct == 'o') & (ct == 'c')).sum() < len(ct):
            raise ValueError(
                "ERROR! Chemical type can only be either 'O' or 'C'!")
        else:
            print("Forcing chemical types as specified by force_chemtype...")
            fit.chemtype = ct

    return fit