def build_obs(fit_data, snr=10, **extras): import numpy as np import scipy import fsps import astropy import math from prospect.utils.obsutils import fix_obs import sedpy # The obs dictionary, empty for now obs = {} # These are the names of the relevant filters, # in the same order as the photometric data (see below) # And here we instantiate the `Filter()` objects using methods in `sedpy`, # and put the resultinf list of Filter objects in the "filters" key of the `obs` dictionary obs["filters"] = sedpy.observate.load_filters(fit_data['filtername']) # Now we store the measured fluxes for a single object, **in the same order as "filters"** # In this example we use a row of absolute AB magnitudes from Johnson et al. 2013 (NGC4163) # We then turn them into apparent magnitudes based on the supplied `ldist` meta-parameter. # You could also, e.g. read from a catalog. # The units of the fluxes need to be maggies (Jy/3631) so we will do the conversion here too. obs["maggies"] = [x / 3631 for x in fit_data['flux']] obs['maggies'] = np.array(obs['maggies']) # And now we store the uncertainties (again in units of maggies) # In this example we are going to fudge the uncertainties based on the supplied `snr` meta-parameter. obs["maggies_unc"] = [x / 3631 for x in fit_data["unc"]] obs['maggies_unc'] = np.array(obs['maggies_unc']) # Now we need a mask, which says which flux values to consider in the likelihood. # IMPORTANT: the mask is *True* for values that you *want* to fit, # and *False* for values you want to ignore. Here we ignore the spitzer bands. obs["phot_mask"] = np.array([True for f in obs["filters"]]) # This is an array of effective wavelengths for each of the filters. # It is not necessary, but it can be useful for plotting so we store it here as a convenience obs["phot_wave"] = np.array([f.wave_effective for f in obs["filters"]]) # We do not have a spectrum, so we set some required elements of the obs dictionary to None. # (this would be a vector of vacuum wavelengths in angstroms) obs["wavelength"] = None # (this would be the spectrum in units of maggies) obs["spectrum"] = None # (spectral uncertainties are given here) obs['unc'] = None # (again, to ignore a particular wavelength set the value of the # corresponding elemnt of the mask to *False*) obs['mask'] = None # This function ensures all required keys are present in the obs dictionary, # adding default values if necessary obs = fix_obs(obs) # Due to some unknown reason, fix_obs will change true to false in phot_mask.We do it again after the function. obs["phot_mask"] = np.array([True for f in obs["filters"]]) return obs
def build_obs(objid=objid, phottable=None, luminosity_distance=None, **kwargs): from prospect.utils.obsutils import fix_obs wl, flux, flux_err = prospector_wl_flux(path_spec, path_err) maggies, emaggies = phot_maggies(work_df_uvista) obs = {} filternames = [ "UVISTA_Ks", "UVISTA_H", "UVISTA_J", "UVISTA_Y", "IB427.SuprimeCam", "IB464.SuprimeCam", "IB484.SuprimeCam", "IB505.SuprimeCam", "IB527.SuprimeCam", "IB574.SuprimeCam", "IB624.SuprimeCam", "IB679.SuprimeCam", "IB709.SuprimeCam", "IB738.SuprimeCam", "IB767.SuprimeCam", "IB827.SuprimeCam", "spitzer_irac_ch1", "spitzer_irac_ch2", "spitzer_irac_ch3", "spitzer_irac_ch4", #"spitzer_mips_24", "galex_FUV", "galex_NUV", "u_megaprime_sagem", "B_subaru", "V_subaru", "g_subaru", "r_subaru", "i_subaru", "z_subaru", ] obs['filters'] = load_filters(filternames) obs['maggies'] = maggies floor_phot = 0.05 * obs['maggies'] obs['maggies_unc'] = np.clip(emaggies, floor_phot, np.inf) obs['wavelength'] = wl obs['spectrum'] = flux floor_spec = 0.01 * obs['spectrum'] obs['unc'] = np.clip(flux_err, floor_spec, np.inf) obs['objid'] = objid obs = fix_obs(obs) return obs
def build_obs(snr=50,mags=np.array({}),**extras): obs = {} BB = ['hsc_{0}'.format(b) for b in ['g','r','i','z','y']] NB = ['{0}'.format(b) for b in ['N708','N540']] filternames = BB + NB obs["filters"] = sedpy.observate.load_filters(filternames) obs["maggies"] = 10**(-0.4*mags) obs["maggies_unc"] = (1./snr) * obs["maggies"] obs["phot_wave"] = np.array([f.wave_effective for f in obs["filters"]]) obs["wavelength"] = None obs["spectrum"] = None obs['unc'] = None obs['mask'] = None obs = fix_obs(obs) return obs
def build_obs(binNum=0, infile=None, **extras): import numpy as np from astropy.table import Table from sedpy.observate import load_filters from prospect.utils.obsutils import fix_obs table = Table.read(infile) flux_columns = [col for col in table.colnames if col.endswith('_flux')] e_flux_columns = [col.replace('flux', 'err') for col in flux_columns] nPix_columns = [col.replace('flux', 'nPix') for col in flux_columns] use_columns = [col.replace('flux', 'use') for col in flux_columns] filternames = ['hff_' + col.replace('_flux', '') for col in flux_columns] fluxes = np.array(list(table[flux_columns][binNum])) / 3631 # in maggies e_fluxes = np.array(list( table[e_flux_columns][binNum])) / 3631 # in maggies nPixels = np.array(list(table[nPix_columns][binNum])) use_col = np.array(list(table[use_columns][binNum])) fluxes_per_pixel = fluxes / nPixels e_fluxes_per_pixel = e_fluxes / nPixels max_SNR = 20 SNR_acceptable = (fluxes_per_pixel / e_fluxes_per_pixel < max_SNR) e_fluxes_per_pixel[ ~SNR_acceptable] = fluxes_per_pixel[~SNR_acceptable] / max_SNR obs = {} obs['filters'] = load_filters(filternames) obs['maggies'], obs['maggies_unc'] = fluxes_per_pixel, e_fluxes_per_pixel obs['phot_mask'] = use_col obs['phot_wave'] = np.array([f.wave_effective for f in obs['filters']]) obs['wavelength'], obs['spectrum'] = None, None obs['unc'], obs['mask'] = None, None obs['binNum'], obs['nPixels'] = binNum, nPixels obs = fix_obs(obs) return obs
def build_cpz_obs(filter_selection, galaxy=None): """Build a dictionary of photometry (and eventually spectra?) Arguments are hyperparameters that are likely to change over runs :returns obs: A dictionary of observational data to use in the fit. """ obs = {} if galaxy is not None: obs["filters"], obs["maggies"], obs[ 'maggies_unc'] = load_photometry.load_galaxy_for_prospector( galaxy, filter_selection) else: # dummy galaxy obs["filters"], obs["maggies"], obs[ 'maggies_unc'] = load_photometry.load_dummy_galaxy_for_prospector( galaxy, filter_selection) # Now we need a mask, which says which flux values to consider in the likelihood. # IMPORTANT: the mask is *True* for values that you *want* to fit obs["phot_mask"] = np.array([True for _ in obs['filters']]) # This is an array of effective wavelengths for each of the filters. # It is not necessary, but it can be useful for plotting so we store it here as a convenience obs["phot_wave"] = np.array([f.wave_effective for f in obs["filters"]]) # We do not have a spectrum, so we set some required elements of the obs dictionary to None. # (this would be a vector of vacuum wavelengths in angstroms) # Note: could use the SDSS spectra here for truth label fitting obs["wavelength"] = None obs["spectrum"] = None obs['unc'] = None obs['mask'] = None # This function ensures all required keys are present in the obs dictionary, # adding default values if necessary obs = fix_obs(obs) return obs
def build_obs(objid=0, luminosity_distance=None, **kwargs): """Load photometry from an ascii file. Assumes the following columns: `objid`, `filterset`, [`mag0`,....,`magN`] where N >= 11. The User should modify this function (including adding keyword arguments) to read in their particular data format and put it in the required dictionary. :param objid: The object id for the row of the photomotery file to use. Integer. Requires that there be an `objid` column in the ascii file. :param phottable: Name (and path) of the ascii file containing the photometry. :param luminosity_distance: (optional) The Johnson 2013 data are given as AB absolute magnitudes. They can be turned into apparent magnitudes by supplying a luminosity distance. :returns obs: Dictionary of observational data. """ from prospect.utils.obsutils import fix_obs #filterlist = load_filters(['sdss_u0', 'sdss_g0', 'sdss_r0', 'sdss_i0', 'sdss_z0', # 'galex_FUV', 'galex_NUV', 'wise_w1', 'wise_w2', # 'wise_w3', 'wise_w4']) filterlist = load_filters(args.filters) microns = np.load('{0}/Prospector_files/wave.npy'.format(args.path)) angstroms = microns * 1e4 spec = np.load('{0}/Prospector_files/spec.npy'.format( args.path)) # units of Jy f_lambda_cgs = (1 / 33333) * (1 / (angstroms**2)) * spec mags = getSED(angstroms, f_lambda_cgs, filterlist=filterlist) # AB magnitudes #print('AB mags', mags) #np.save('ab_mags.npy', mags) maggies = 10**(-0.4 * mags) # convert to maggies wave_eff = np.zeros(len(filterlist)) for i in range(len(filterlist)): filterlist[i].get_properties() wave_eff[i] = filterlist[i].wave_effective print('maggies', maggies) print('effective wavelengths', wave_eff) # Build output dictionary. obs = {} obs['filters'] = filterlist obs['maggies'] = maggies obs['maggies_unc'] = obs['maggies'] * 0.07 obs['phot_mask'] = np.isfinite(np.squeeze(maggies)) obs['wavelength'] = None obs['spectrum'] = None obs['unc'] = None obs['objid'] = None # This ensures all required keys are present and adds some extra useful info obs = fix_obs(obs) return obs
def build_obs(path, tde): """Build a dictionary of observational data. :returns obs: A dictionary of observational data to use in the fit. """ from prospect.utils.obsutils import fix_obs import sedpy # The obs dictionary, empty for now obs = {} tde_dir = os.path.join(path, tde) try: band, wl_c, ab_mag, ab_mag_err, catalogs, apertures = np.loadtxt( os.path.join(tde_dir, 'host', 'host_phot_obs.txt'), dtype={'names': ( 'band', 'wl_0', 'ab_mag', 'ab_mag_err', 'catalog', 'apertures'), 'formats': ( 'U5', np.float, np.float, np.float, 'U10', 'U10')}, unpack=True, skiprows=2) except: raise Exception('We should run download_host_data() before trying to fit it.') filter_dic = {'WISE_W4': 'wise_w4', 'WISE_W3': 'wise_w3', 'WISE_W2': 'wise_w2', 'WISE_W1': 'wise_w1', 'UKIDSS_Y': 'UKIRT_Y', 'UKIDSS_J': 'UKIRT_J', 'UKIDSS_H': 'UKIRT_H', 'UKIDSS_K': 'UKIRT_K', '2MASS_J': 'twomass_J', '2MASS_H': 'twomass_H', '2MASS_Ks': 'twomass_Ks', 'PAN-STARRS_y': 'PAN-STARRS_y', 'PAN-STARRS_z': 'PAN-STARRS_z', 'PAN-STARRS_i': 'PAN-STARRS_i', 'PAN-STARRS_r': 'PAN-STARRS_r', 'PAN-STARRS_g': 'PAN-STARRS_g', 'DES_Y': 'decam_Y', 'DES_z': 'decam_z', 'DES_i': 'decam_i', 'DES_r': 'decam_r', 'DES_g': 'decam_g', 'SkyMapper_u': 'SkyMapper_u', 'SkyMapper_z': 'SkyMapper_z', 'SkyMapper_i': 'SkyMapper_i', 'SkyMapper_r': 'SkyMapper_r', 'SkyMapper_g': 'SkyMapper_g', 'SkyMapper_v': 'SkyMapper_v', 'SDSS_u': 'sdss_u0', 'SDSS_z': 'sdss_z0', 'SDSS_g': 'sdss_g0', 'SDSS_r': 'sdss_r0', 'SDSS_i': 'sdss_i0', 'GALEX_NUV': 'galex_NUV', 'GALEX_FUV': 'galex_FUV', 'Swift/UVOT_UVW1': 'uvot_w1', 'Swift/UVOT_UVW2': 'uvot_w2', 'Swift/UVOT_UVM2': 'uvot_m2', 'Swift/UVOT_V': 'uvot_V', 'Swift/UVOT_B': 'uvot_B', 'Swift/UVOT_U': 'uvot_U'} flag = np.isfinite(ab_mag * ab_mag_err) catalog_bands = [catalogs[i] + '_' + band[i] for i in range(len(catalogs))] filternames = [filter_dic[i] for i in catalog_bands] # And here we instantiate the `Filter()` objects using methods in `sedpy`, # and put the resultinf list of Filter objects in the "filters" key of the `obs` dictionary obs["filters"] = np.ndarray((0)) for i in range(len(filternames)): # print(filternames[i]) obs["filters"] = np.append(obs["filters"], sedpy.observate.Filter(filternames[i], directory=pkg_resources.resource_filename( "TDEpy", 'filters'))) obs["phot_wave"] = np.zeros(flag.shape) obs["phot_mask"] = np.zeros(flag.shape) obs["maggies"] = np.zeros(flag.shape) obs["maggies_unc"] = np.zeros(flag.shape) obs["phot_mask"] = np.ones(np.shape(flag), dtype=bool) # Measurments for i in range(len(flag)): if flag[i]: mags = np.array(ab_mag[i]) mags_err = np.array(ab_mag_err[i]) signal = tools.mag_to_flux(mags, wl_c[i]) noise = tools.dmag_to_df(mags_err, signal) snr = signal / noise obs["maggies"][i] = 10 ** (-0.4 * mags) obs["maggies_unc"][i] = obs["maggies"][i] * (1 / snr) obs["phot_wave"][i] = np.array(wl_c[i]) else: obs["maggies"][i] = 0 obs["maggies_unc"][i] = 10 ** (-0.4 * ab_mag[i]) obs["phot_wave"][i] = np.array(wl_c[i]) obs["wavelength"] = None obs["spectrum"] = None obs['unc'] = None obs['mask'] = None # This function ensures all required keys are present in the obs dictionary, # adding default values if necessary obs = fix_obs(obs) return obs
def build_obs(object_name="gc1", **extras): """Build a dictionary of observational data. In this example we will read from text files named <object_name>.spec.dat and <object_name>.phot.dat Parameters ---------- object_name : string The name of the object, used to find data files Returns ------- obs : dictionary A dictionary of observational data to use in the fit. """ from prospect.utils.obsutils import fix_obs from sedpy.observate import load_filters # The obs dictionary, empty for now obs = {} # These are the names of the relevant filters, # in the same order as the photometric data (see below) phot_file = "{}.phot.dat".format(object_name) spec_file = "{}.spec.dat".format(object_name) # --- Photometric Data --- # this is the description of the column formats if VERS == 2: stype = "S20" elif VERS == 3: stype = "U20" cols = [("filtername", stype), ("flux", np.float), ("unc", np.float)] # read the file phot = np.genfromtxt(phot_file, dtype=np.dtype(cols), skip_header=1) # And here we instantiate the `Filter()` objects using methods in `sedpy`, # and put the resulting list of Filter objects in the "filters" key of the `obs` dictionary # These Filter objects will perform projections of the model SED onto the filters. obs["filters"] = load_filters(phot["filtername"]) # Now we store the measured fluxes for a single object, **in the same order as "filters"** # The units of the fluxes need to be maggies (Jy/3631) so we will do the conversion here too. obs["maggies"] = phot["flux"] * 1e-3 / 3631 # And now we store the uncertainties (again in units of maggies) obs["maggies_unc"] = phot["unc"] * 1e-3 / 3631 # Now we need a mask, which says which flux values to consider in the likelihood. # IMPORTANT: the mask is *True* for values that you *want* to fit, # and *False* for values you want to ignore. Here we ignore the spitzer bands. obs["phot_mask"] = np.array( ['spitzer' not in f.name for f in obs["filters"]]) # This is an array of effective wavelengths for each of the filters. # It is not necessary, but it can be useful for plotting so we store it here as a convenience obs["phot_wave"] = np.array([f.wave_effective for f in obs["filters"]]) # --- Spectroscopic Data --- # this is the description of the column formats cols = [("wavelength", np.float), ("flux", np.float), ("unc", np.float)] # read the file spec = np.genfromtxt(spec_file, dtype=np.dtype(cols), skip_header=1) # add the wavelengths (restframe, vacuum) obs["wavelength"] = spec["wavelength"] # (this would be the spectrum in units of maggies) obs["spectrum"] = spec["flux"] * 1e-3 / 3631 # (spectral uncertainties are given here) obs['unc'] = spec["unc"] * 1e-3 / 3631 # (again, to ignore a particular wavelength set the value of the # corresponding elemnt of the mask to *False*) obs['mask'] = spec["unc"] > 0 # This function ensures all required keys are present in the obs dictionary, # adding default values if necessary obs = fix_obs(obs) # That's it! return obs
def load_obs(seed=1, nproc=1, nmin=10, verbose=False, sps=None): """Load the photometry for NGC5322. """ import sedpy from prospect.utils.obsutils import fix_obs # photometry in maggies and ivarmaggies phot = dict(FUV=[ 3.63e-4 * 1e3 / maggies2mJy, 1 / (9.76e-6 * 1e3 / maggies2mJy)**2 ], NUV=[ 1.87e-3 * 1e3 / maggies2mJy, 1 / (1.02e-5 * 1e3 / maggies2mJy)**2 ], g=[51032.92 * 1e-9, 0.060252897 * 1e18], r=[108675.04 * 1e-9, 0.019527867 * 1e18], z=[173005.16 * 1e-9, 0.011034269 * 1e18], W1=[126294.73 * 1e-9, 0.1742277 * 1e18], W2=[67562.625 * 1e-9, 0.03782868 * 1e18], W3=[34738.555 * 1e-9, 0.000105459614 * 1e18], W4=[32283.23 * 1e-9, 2.8181848e-06 * 1e18]) # Minimum uncertainties factor = 2.5 / np.log(10) minerr = dict(FUV=0.05, NUV=0.3, g=0.01, r=0.01, z=0.02, W1=0.02, W2=0.02, W3=0.05, W4=0.05) for key in phot.keys(): maggies = phot[key][0] ivarmaggies = phot[key][1] err = factor / np.sqrt(ivarmaggies) / maggies err2 = err**2 + minerr[key]**2 phot[key][1] = factor**2 / (maggies**2 * err2) galex = ['galex_FUV', 'galex_NUV'] ls = ['sdss_{}0'.format(b) for b in ['g', 'r', 'z']] wise = ['wise_w{}'.format(n) for n in ['1', '2', '3', '4']] filternames = galex + ls + wise obs = {} obs['redshift'] = 0.0060 obs["filters"] = sedpy.observate.load_filters(filternames) obs["maggies"] = np.array([phot[filt][0] for filt in phot.keys()]) obs["maggies_unc"] = np.array( [1 / np.sqrt(phot[filt][1]) for filt in phot.keys()]) # mask out W4 #obs["phot_mask"] = np.array(['w4' in f.name for f in obs["filters"]]) # Create a handy vector of effective wavelengths (optional) obs["phot_wave"] = [f.wave_effective for f in obs["filters"]] obs["wavelength"] = None # spectral wavelength obs["spectrum"] = None obs['unc'] = None # spectral uncertainties are given here obs['mask'] = [1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0] obs = fix_obs(obs) run_params = {} run_params['redshift'] = obs['redshift'] run_params['verbose'] = verbose run_params['debug'] = False run_params['seed'] = seed run_params['nproc'] = nproc run_params['param_file'] = '' # no parameter file run_params['min_method'] = 'lm' run_params['nmin'] = 1 if sps: run_params['sps_libraries'] = sps.ssp.libraries # dynesty Fitter parameters dyn_params = { 'nested_bound': 'multi', # bounding method 'nested_sample': 'unif', # 'unif', 'slice' # sampling method 'nested_nlive_init': 100, 'nested_nlive_batch': 100, 'nested_bootstrap': 0, 'nested_dlogz_init': 0.05, 'nested_weight_kwargs': { "pfrac": 1.0 }, #'nested_stop_kwargs': {"post_thresh": 0.05} } run_params.update(dyn_params) return obs, run_params
def build_obs(snr=10.0, filterset=["sdss_g0", "sdss_r0"], add_noise=True, **kwargs): """Make a mock dataset. Feel free to add more complicated kwargs, and put other things in the run_params dictionary to control how the mock is generated. :param snr: The S/N of the phock photometry. This can also be a vector of same lngth as the number of filters. :param filterset: A list of `sedpy` filter names. Mock photometry will be generated for these filters. :param add_noise: (optional, boolean, default: True) If True, add a realization of the noise to the mock spectrum """ from prospect.utils.obsutils import fix_obs # We'll put the mock data in this dictionary, just as we would for real # data. But we need to know which bands (and wavelengths if doing # spectroscopy) in which to generate mock data. mock = {} mock['wavelength'] = None # No spectrum mock['spectrum'] = None # No spectrum mock['filters'] = load_filters(filterset) # We need the models to make a mock sps = build_sps(**kwargs) mod = build_model(**kwargs) # Now we get the mock params from the kwargs dict params = {} for p in mod.params.keys(): if p in kwargs: params[p] = np.atleast_1d(kwargs[p]) # And build the mock mod.params.update(params) spec, phot, _ = mod.mean_model(mod.theta, mock, sps=sps) # Now store some ancillary, helpful info; # this information is not required to run a fit. mock['true_spectrum'] = spec.copy() mock['true_maggies'] = phot.copy() mock['mock_params'] = deepcopy(mod.params) mock['mock_snr'] = snr mock["phot_wave"] = np.array([f.wave_effective for f in mock["filters"]]) # And store the photometry, adding noise if desired pnoise_sigma = phot / snr if add_noise: pnoise = np.random.normal(0, 1, len(phot)) * pnoise_sigma mock['maggies'] = phot + pnoise else: mock['maggies'] = phot.copy() mock['maggies_unc'] = pnoise_sigma mock['phot_mask'] = np.ones(len(phot), dtype=bool) # This ensures all required keys are present mock = fix_obs(mock) return mock
def build_obs(snr=10, ldist=10.0, **extras): """Build a dictionary of photometry (and eventually spectra?) Arguments are hyperparameters that are likely to change over runs :param snr: The S/N to assign to the photometry, since none are reported in Johnson et al. 2013 :param ldist: The luminosity distance to assume for translating absolute magnitudes into apparent magnitudes. :returns obs: A dictionary of observational data to use in the fit. """ obs = {} # These are the names of the relevant filters, # in the same order as the photometric data (see below) galex = ['galex_FUV', 'galex_NUV'] spitzer = ['spitzer_irac_ch' + n for n in ['1', '2', '3', '4']] sdss = ['sdss_{0}0'.format(b) for b in ['u', 'g', 'r', 'i', 'z']] filternames = galex + sdss + spitzer # And here we instantiate the `Filter()` objects using methods in `sedpy`, # and put the resultinf list of Filter objects in the "filters" key of the `obs` dictionary obs["filters"] = sedpy.observate.load_filters(filternames) # Now we store the measured fluxes for a single object, **in the same order as "filters"** # In this example we use a row of absolute AB magnitudes from Johnson et al. 2013 (NGC4163) # We then turn them into apparent magnitudes based on the supplied `ldist` meta-parameter. # You could also, e.g. read from a catalog. # The units of the fluxes need to be maggies (Jy/3631) so we will do the conversion here too. M_AB = np.array([ -11.93, -12.37, -13.37, -14.22, -14.61, -14.86, -14.94, -14.09, -13.62, -13.23, -12.78 ]) dm = 25 + 5.0 * np.log10(ldist) mags = M_AB + dm obs["maggies"] = 10**(-0.4 * mags) # And now we store the uncertainties (again in units of maggies) # In this example we are going to fudge the uncertainties based on the supplied `snr` meta-parameter. obs["maggies_unc"] = (1. / snr) * obs["maggies"] # Now we need a mask, which says which flux values to consider in the likelihood. # IMPORTANT: the mask is *True* for values that you *want* to fit, # and *False* for values you want to ignore. Here we ignore the spitzer bands. obs["phot_mask"] = np.array( ['spitzer' not in f.name for f in obs["filters"]]) # This is an array of effective wavelengths for each of the filters. # It is not necessary, but it can be useful for plotting so we store it here as a convenience obs["phot_wave"] = np.array([f.wave_effective for f in obs["filters"]]) # We do not have a spectrum, so we set some required elements of the obs dictionary to None. # (this would be a vector of vacuum wavelengths in angstroms) # Note: could use the SDSS spectra here for truth label fitting obs["wavelength"] = None obs["spectrum"] = None obs['unc'] = None obs['mask'] = None # This function ensures all required keys are present in the obs dictionary, # adding default values if necessary obs = fix_obs(obs) return obs
def build_obs(self, obs=None, phot_mask=None, spec_mask=None, verbose=False, warnings=True, set_data=False): """ Build a dictionary containing observations in a prospector compatible format. Options ------- obs : [dict or None] Can load an already existing prospector compatible 'obs' dictionary. Automatically change the attributes to the given 'obs' dictionary. Default is None. phot_mask : [list(string) or None] Give a list of filters you want the SED fitting to be run on. The other filter measurements will be masked. If None, no mask is applied. Default is None. spec_mask : [tuple(float or None, float or None) or np.array or None] Give a tuple of two wavelength in AA (lower_limit, upper_limit) to run the SED fitting on the input spectrum between the given limits. The rest of the spectrum is masked. You can give None for a limit to keep the whole spectrum in that direction. You also can directly give your own mask array. If None, the whole spectrum is fitted. Default is None. verbose : [bool] If True, print the built observation dictionary. Default is False. warnings : [bool] If True, allow warnings to be printed. Default is True. set_data : [bool] If 'obs' is not None, set to True if you want to extract and set attributes from the given 'obs' dictionary. Default is False. Returns ------- Void """ from prospect.utils.obsutils import fix_obs if obs is not None: self._obs = fix_obs(obs) if set_data: self._set_data_from_obs(obs=self.obs, warnings=warnings) return from sedpy.observate import load_filters self._obs = {"filters":load_filters(io.filters_to_pysed(self.filters)) if self.has_phot_in() else None, "zspec":self.z, "name":self.name} ### Photometry ### if self.has_phot_in(): self._obs.update({"maggies":np.array([self.phot_in[_filt] for _filt in self.filters]), "maggies_unc":np.array([self.phot_in[_filt+".err"] for _filt in self.filters])}) if phot_mask is not None: self._obs["phot_mask"] = np.array([_f in phot_mask for _f in self.filters]) ### Spectrometry ### self._obs["wavelength"] = None if self.has_spec_in(): self._obs.update({"wavelength":np.array(self.spec_in["lbda"]), "spectrum":np.array(self.spec_in["spec"]), "unc":np.array(self.spec_in["spec.err"]) if "spec.err" in self.spec_in.keys() else None}) if spec_mask is not None: if type(spec_mask) in [list, tuple, np.ndarray] and len(spec_mask) == 2: _lim_low, _lim_up = spec_mask _spec_mask = np.ones(len(self.obs["wavelength"]), dtype = bool) if _lim_low is not None: _spec_mask &= self.obs["wavelength"] > _lim_low if _lim_up is not None: _spec_mask &= self.obs["wavelength"] < _lim_up self._obs["mask"] = _spec_mask elif type(spec_mask) in [list, tuple, np.ndarray] and len(spec_mask)==len(self.spec_in["lbda"]): self._obs["mask"] = np.array(spec_mask) else: if warnings: warn(f"Cannot apply a mask on spectrum because the 'spec_mask' you give is not compliant ({spec_mask})") self._obs = fix_obs(self._obs) if verbose: print(tools.get_box_title(title="Built obs", box="\n#=#\n# {} #\n#=#\n")) pprint(self.obs)
def build_obs(objid=0, phottable='demo_photometry.dat', luminosity_distance=None, **kwargs): """Load photometry from an ascii file. Assumes the following columns: `objid`, `filterset`, [`mag0`,....,`magN`] where N >= 11. The User should modify this function (including adding keyword arguments) to read in their particular data format and put it in the required dictionary. :param objid: The object id for the row of the photomotery file to use. Integer. Requires that there be an `objid` column in the ascii file. :param phottable: Name (and path) of the ascii file containing the photometry. :param luminosity_distance: (optional) The Johnson 2013 data are given as AB absolute magnitudes. They can be turned into apparent magnitudes by supplying a luminosity distance. :returns obs: Dictionary of observational data. """ # Writes your code here to read data. Can use FITS, h5py, astropy.table, # sqlite, whatever. # e.g.: # import astropy.io.fits as pyfits # catalog = pyfits.getdata(phottable) from prospect.utils.obsutils import fix_obs # Here we will read in an ascii catalog of magnitudes as a numpy structured # array with open(phottable, 'r') as f: # drop the comment hash header = f.readline().split()[1:] catalog = np.genfromtxt(phottable, comments='#', dtype=np.dtype([(n, np.float) for n in header])) # Find the right row ind = catalog['objid'] == float(objid) # Here we are dynamically choosing which filters to use based on the object # and a flag in the catalog. Feel free to make this logic more (or less) # complicated. filternames = filtersets[int(catalog[ind]['filterset'])] # And here we loop over the magnitude columns mags = [catalog[ind]['mag{}'.format(i)] for i in range(len(filternames))] mags = np.array(mags) # And since these are absolute mags, we can shift to any distance. if luminosity_distance is not None: dm = 25 + 5 * np.log10(luminosity_distance) mags += dm # Build output dictionary. obs = {} # This is a list of sedpy filter objects. See the # sedpy.observate.load_filters command for more details on its syntax. obs['filters'] = load_filters(filternames) # This is a list of maggies, converted from mags. It should have the same # order as `filters` above. obs['maggies'] = np.squeeze(10**(-mags/2.5)) # HACK. You should use real flux uncertainties obs['maggies_unc'] = obs['maggies'] * 0.07 # Here we mask out any NaNs or infs obs['phot_mask'] = np.isfinite(np.squeeze(mags)) # We have no spectrum. obs['wavelength'] = None obs['spectrum'] = None # Add unessential bonus info. This will be stored in output #obs['dmod'] = catalog[ind]['dmod'] obs['objid'] = objid # This ensures all required keys are present and adds some extra useful info obs = fix_obs(obs) return obs
def build_obs(infile=None, filterFile=None, binNum=0, **kwargs): ''' Construct the observations to use for fitting. Parameters ---------- fluxes : list, optional The fluxes to use. The default is None. errs : list, optional The uncertainties on the above fluxes. The default is None. filterset : list, optional The filters that the observations were taken in. The default is None. binNum : int, optional The bin number for the galaxy. The default is 0. **kwargs : kwargs Additional keyword arguments. Returns ------- obs : dict Dictionary of observational data. ''' import numpy as np from astropy.table import Table from sedpy.observate import load_filters from prospect.utils.obsutils import fix_obs with open(filterFile) as file: # open the file containing strings of the filters = [] # filters and create a list containing for line in file: # those strings filt = line.strip() filters.append(filt) table = Table.read(infile) flux_cols = [string for string in table.colnames if '_flux' in string] err_cols = [string for string in table.colnames if '_err' in string] nPix_cols = [string for string in table.colnames if '_nPix' in string] flux_table = table[flux_cols] # create a table using only the flux columns err_table = table[err_cols] # create a table using only the err columns nPix_table = table[nPix_cols] # create a table using only the nPix columns fluxes = list(flux_table[binNum]) # get the fluxes for the bin errs = list(err_table[binNum]) # get the uncertainties for the bin nPixels = list(nPix_table[binNum]) # get the number of pixels for the bin # build output dictionary. obs = {} # this is a list of sedpy filter objects. See the # sedpy.observate.load_filters command for more details on its syntax. filters_directory = 'D:\Documents\GitHub\HFF\hff_filters' # '/home/clawlorf/HFF/hff_filters/' obs['filters'] = load_filters(filters, directory=filters_directory) # this is a list of maggies, converted from fluxes. It should have the same # order as `filters` above. measures = np.array(fluxes) / 3631 / np.array(nPixels) obs['maggies'] = measures # this is a list of maggie uncertainties, converted from fluxes. It should # have the same order as `filters` above. uncerts = np.array(errs) / 3631 / np.array(nPixels) SN = measures / uncerts SN[SN > 100] = 100.0 # set the S/N maximum to 100 obs['maggies_unc'] = obs['maggies'] / SN # here we mask out any NaNs or infs obs['phot_mask'] = np.array([ False, True, True, False, True, False, True, False, False, True, False, True, False, True, True, True ]) #np.array([True]*len(filters)) # here we place the effective wavelengths for each of the filters obs['phot_wave'] = np.array([f.wave_effective for f in obs['filters']]) # we have no spectrum. obs['wavelength'] = None obs['spectrum'] = None obs['unc'] = None obs['mask'] = None # add unessential bonus info. This will be stored in output. obs['binNum'] = binNum # this ensures all required keys are present and adds extra useful info obs = fix_obs(obs) return obs
def build_obs(fluxes, fluxes_unc, bandpasses, **extras): """Build a dictionary of observational data. :param fluxes: Observed fluxes :param bandpasses: Bandpasses for the quoted observed fluxes :returns obs: A dictionary of observational data to use in the fit. """ # The obs dictionary, empty for now obs = {} # These are the names of the relevant filters, # in the same order as the photometric data (see below) # For our data """ 'CTIO_U', 'VIMOS_U', 'ACS_F435W', 'ACS_F606W', 'ACS_F775W', 'ACS_F814W', 'ACS_F850LP', 'WFC3_F098M', 'WFC3_F105W', 'WFC3_F125W', 'WFC3_F160W', 'ISAAC_KS', 'HAWKI_KS', 'IRAC_CH1', 'IRAC_CH2', 'IRAC_CH3', 'IRAC_CH4' """ ground_u = ['decam_u', 'LBT_LBCB_besselU'] hst = [ 'acs_wfc_f435w', 'acs_wfc_f606w', 'acs_wfc_f775w', 'acs_wfc_f814w', 'acs_wfc_f850lp', 'wfc3_ir_f098m', 'wfc3_ir_f105w', 'wfc3_ir_f125w', 'wfc3_ir_f140w', 'wfc3_ir_f160w' ] k_bands = ['HAWKI_Ks', 'Subaru_MOIRCS_K', 'CFHT_Wircam_Ks'] spitzer = ['spitzer_irac_ch' + n for n in ['1', '2', '3', '4']] filternames = ground_u + hst + k_bands + spitzer # This code block is necessary to ensure that we # handle negative since we're ignoring them, i.e., # need to make sure that we do not load the same # filters each time. The filters are only loaded # depending on the filters given in useable_filters. filternames_toload = [] for ft in filternames: if ft == 'decam_u': bp = 'CTIO' elif ft == 'LBT_LBCB_besselU': bp = 'LBC' elif ft == 'HAWKI_Ks': bp = 'HAWKI' elif ft == 'Subaru_MOIRCS_K': bp = 'MOIRCS' elif ft == 'CFHT_Wircam_Ks': bp = 'CFHT' else: bp = (ft.split('_')[-1]).upper() #print('\nft:', ft) for j in range(len(bandpasses)): bandpass = bandpasses[j] #print('bp and bandpass:'******'unc'] = None # (again, to ignore a particular wavelength set the value of the # corresponding elemnt of the mask to *False*) obs['mask'] = None # This function ensures all required keys are present in the obs dictionary, # adding default values if necessary obs = fix_obs(obs) return obs
def build_obs(snr=10.0, filterset=["sdss_g0", "sdss_r0"], add_noise=True, **kwargs): """Make a mock dataset. Feel free to add more complicated kwargs, and put other things in the run_params dictionary to control how the mock is generated. :param snr: The S/N of the phock photometry. This can also be a vector of same lngth as the number of filters. :param filterset: A list of `sedpy` filter names. Mock photometry will be generated for these filters. :param add_noise: (optional, boolean, default: True) If True, add a realization of the noise to the mock spectrum """ from prospect.utils.obsutils import fix_obs # We'll put the mock data in this dictionary, just as we would for real # data. But we need to know which bands (and wavelengths if doing # spectroscopy) in which to generate mock data. mock = {} mock['wavelength'] = None # No spectrum mock['spectrum'] = None # No spectrum mock['filters'] = load_filters(filterset) # We need the models to make a mock sps = build_sps(**kwargs) mod = build_model(**kwargs) # Now we get the mock params from the kwargs dict params = {} for p in mod.params.keys(): if p in kwargs: params[p] = np.atleast_1d(kwargs[p]) # And build the mock mod.params.update(params) spec, phot, _ = mod.mean_model(mod.theta, mock, sps=sps) # Now store some ancillary, helpful info; # this information is not required to run a fit. mock['true_spectrum'] = spec.copy() mock['true_maggies'] = phot.copy() mock['mock_params'] = deepcopy(mod.params) mock['mock_snr'] = snr mock["phot_wave"] = np.array([f.wave_effective for f in mock["filters"]]) # And store the photometry, adding noise if desired pnoise_sigma = phot / snr if add_noise: pnoise = np.random.normal(0, 1, len(phot)) * pnoise_sigma mock['maggies'] = phot + pnoise else: mock['maggies'] = phot.copy() mock['maggies_unc'] = pnoise_sigma mock['phot_mask'] = np.ones(len(phot), dtype=bool) # This ensures all required keys are present mock = fix_obs(mock) return mock
def build_obs(objid=0, phottable='demo_photometry.dat', luminosity_distance=None, **kwargs): """Load photometry from an ascii file. Assumes the following columns: `objid`, `filterset`, [`mag0`,....,`magN`] where N >= 11. The User should modify this function (including adding keyword arguments) to read in their particular data format and put it in the required dictionary. :param objid: The object id for the row of the photomotery file to use. Integer. Requires that there be an `objid` column in the ascii file. :param phottable: Name (and path) of the ascii file containing the photometry. :param luminosity_distance: (optional) The Johnson 2013 data are given as AB absolute magnitudes. They can be turned into apparent magnitudes by supplying a luminosity distance. :returns obs: Dictionary of observational data. """ # Writes your code here to read data. Can use FITS, h5py, astropy.table, # sqlite, whatever. # e.g.: # import astropy.io.fits as pyfits # catalog = pyfits.getdata(phottable) from prospect.utils.obsutils import fix_obs # Here we will read in an ascii catalog of magnitudes as a numpy structured # array with open(phottable, 'r') as f: # drop the comment hash header = f.readline().split()[1:] catalog = np.genfromtxt(phottable, comments='#', dtype=np.dtype([(n, np.float) for n in header])) # Find the right row ind = catalog['objid'] == float(objid) # Here we are dynamically choosing which filters to use based on the object # and a flag in the catalog. Feel free to make this logic more (or less) # complicated. filternames = filtersets[int(catalog[ind]['filterset'])] # And here we loop over the magnitude columns mags = [catalog[ind]['mag{}'.format(i)] for i in range(len(filternames))] mags = np.array(mags) # And since these are absolute mags, we can shift to any distance. if luminosity_distance is not None: dm = 25 + 5 * np.log10(luminosity_distance) mags += dm # Build output dictionary. obs = {} # This is a list of sedpy filter objects. See the # sedpy.observate.load_filters command for more details on its syntax. obs['filters'] = load_filters(filternames) # This is a list of maggies, converted from mags. It should have the same # order as `filters` above. obs['maggies'] = np.squeeze(10**(-mags / 2.5)) # HACK. You should use real flux uncertainties obs['maggies_unc'] = obs['maggies'] * 0.07 # Here we mask out any NaNs or infs obs['phot_mask'] = np.isfinite(np.squeeze(mags)) # We have no spectrum. obs['wavelength'] = None obs['spectrum'] = None # Add unessential bonus info. This will be stored in output #obs['dmod'] = catalog[ind]['dmod'] obs['objid'] = objid # This ensures all required keys are present and adds some extra useful info obs = fix_obs(obs) return obs
def build_obs(mags, snr=10, ldist=10.0, **extras): """Build a dictionary of observational data. In this example the data consist of photometry for a single nearby dwarf galaxy from Johnson et al. 2013. :param snr: The S/N to assign to the photometry, since none are reported in Johnson et al. 2013 :param ldist: The luminosity distance to assume for translating absolute magnitudes into apparent magnitudes. :returns obs: A dictionary of observational data to use in the fit. """ from prospect.utils.obsutils import fix_obs # The obs dictionary, empty for now obs = {} # These are the names of the relevant filters, # in the same order as the photometric data (see below) sdss_griz = ['sdss_{0}0'.format(b) for b in ['g', 'r', 'i', 'z']] y = ['decam_Y'] filternames = sdss_griz + y # And here we instantiate the `Filter()` objects using methods in `sedpy`, # and put the resultinf list of Filter objects in the "filters" key of the `obs` dictionary obs["filters"] = sedpy.observate.load_filters(filternames) # Now we store the measured fluxes for a single object, **in the same order as "filters"** # In this example we use a row of absolute AB magnitudes from Johnson et al. 2013 (NGC4163) # We then turn them into apparent magnitudes based on the supplied `ldist` meta-parameter. # You could also, e.g. read from a catalog. # The units of the fluxes need to be maggies (Jy/3631) so we will do the conversion here too. #M_AB = #dm = 25 + 5.0 * np.log10(ldist) #mags = np.array([17.41900063, 16.98089981, 16.8614006, 16.48570061, 16.27280045]) obs["maggies"] = 10**(-0.4 * mags) # And now we store the uncertainties (again in units of maggies) # In this example we are going to fudge the uncertainties based on the supplied `snr` meta-parameter. obs["maggies_unc"] = (1. / snr) * obs["maggies"] # This is an array of effective wavelengths for each of the filters. # It is not necessary, but it can be useful for plotting so we store it here as a convenience obs["phot_wave"] = np.array([f.wave_effective for f in obs["filters"]]) # We do not have a spectrum, so we set some required elements of the obs dictionary to None. # (this would be a vector of vacuum wavelengths in angstroms) obs["wavelength"] = None # (this would be the spectrum in units of maggies) obs["spectrum"] = None # (spectral uncertainties are given here) obs['unc'] = None # (again, to ignore a particular wavelength set the value of the # corresponding elemnt of the mask to *False*) obs['mask'] = None # This function ensures all required keys are present in the obs dictionary, # adding default values if necessary obs = fix_obs(obs) return obs