def getSEDs(self, filter_names, absFlux=True, extLaw=None, inplace=False, filterLib=None, **kwargs): """ Extract integrated fluxes through filters Parameters ---------- filter_names : list list of filter names according to the filter lib or filter instances (no mixing between name and instances) absFlux : bool, optional returns absolute fluxes if set [capability should be removed] extLaw : extinction.ExtinctionLaw, optional apply extinction law if provided inplace : bool, optional if set, do not copy the grid and apply extinction on it filterLib : str, optional full filename to the filter library hd5 file **kwargs extra keywords will be forworded to extLaw Returns ------- memgrid : :class:`~beast.physicsmodel.helpers.grid.SEDGrid` instance grid info with memory backend """ if isinstance(filter_names[0], str): flist = phot.load_filters(filter_names, interp=True, lamb=self.lamb, filterLib=filterLib) _fnames = filter_names else: flist = phot.load_Integrationfilters(filter_names, interp=True, lamb=self.lamb) _fnames = [fk.name for fk in filter_names] if extLaw is not None: if not inplace: r = self.applyExtinctionLaw(extLaw, inplace=inplace, **kwargs) lamb, seds, grid = phot.extractSEDs(r, flist, absFlux=absFlux) else: self.applyExtinctionLaw(extLaw, inplace=inplace, **kwargs) lamb, seds, grid = phot.extractSEDs(self, flist, absFlux=absFlux) else: lamb, seds, grid = phot.extractSEDs(self, flist, absFlux=absFlux) memgrid = SEDGrid(lamb, seds, grid, backend=MemoryBackend) setattr(memgrid, "filters", _fnames) return memgrid
def hst_frac_matrix(filters, spectrum=None, progress=True, hst_fname=None, filterLib=None): """ Uses the Bohlin et al. (2013) provided spectroscopic absolute flux covariance matrix to generate the covariance matrix for the input set of HST filters. Parameters ---------- filters : filter names Keywords -------- progress: bool, optional if set, display a progress bar spectrum : 2 element tuple (wave, sed) wave = 1D numpy array with wavelengths in XX units spectrum = 1D numpy array with flux in ergs... hst_fname : str file with hst absflux covariance matrix filterLib: str full filename to the filter library hd5 file Returns ------- 2D numpy array giving the fractional covariance matrix (must be multiplied by the SED flux (x2) to get the true covariance matrix) ToDos: ------ - Probably better to do a proper integration than just a weighted sum (minor). """ # get the HST fractional covariance matrix at spectroscopic resolution if hst_fname is None: hst_fname = __ROOT__ + "/hst_whitedwarf_frac_covar.fits" hst_data = getdata(hst_fname, 1) waves = hst_data["WAVE"][0] frac_spec_covar = hst_data["COVAR"][0] n_waves = len(waves) # define a flat spectrum if it does not exist if spectrum is None: spectrum = (waves, np.full((n_waves), 1.0)) # read in the filter response functions flist = phot.load_filters(filters, filterLib=filterLib, interp=True, lamb=waves) # setup multiplication images to make it easy to compute the results n_filters = len(filters) mult_image = np.zeros((n_waves, n_waves, n_filters)) mult_image_spec = np.zeros((n_waves, n_waves, n_filters)) image_ones = np.full((n_waves, n_waves), 1.0) # band_ones = np.full((n_filters, n_filters), 1.0) for i in range(n_filters): mult_image[:, :, i] = image_ones * flist[i].transmit # handle single spectrum or many spectra if len(spectrum[1].shape) > 1: n_models = spectrum[1].shape[0] results = np.zeros((n_models, n_filters, n_filters)) else: n_models = 1 progress = False # setup the progress bar if progress is True: it = tqdm(list(range(n_models)), desc="Calculating absolute flux covariance matrices") else: it = list(range(n_models)) frac_covar_bands = np.zeros((n_filters, n_filters)) for k in it: if n_models == 1: interp_spectrum = np.interp(waves, spectrum[0], spectrum[1]) else: interp_spectrum = np.interp(waves, spectrum[0], spectrum[1][k, :]) for i in range(n_filters): mult_image_spec[:, :, i] = mult_image[:, :, i] * interp_spectrum for i in range(n_filters): for j in range(i, n_filters): frac_covar_bands[i, j] = np.sum(frac_spec_covar * mult_image_spec[:, :, i] * mult_image_spec[:, :, j].T) frac_covar_bands[i, j] /= np.sum(mult_image_spec[:, :, i] * mult_image_spec[:, :, j].T) # fill in the symmetric terms for i in range(n_filters): for j in range(0, i): frac_covar_bands[i, j] = frac_covar_bands[j, i] # add the term accounting for the uncertainty in the overall # zero point of the flux scale # (e.g., uncertainty in Vega at 5555 A) frac_covar_bands += 4.9e-5 if n_models > 1: results[k, :, :] = frac_covar_bands if n_models == 1: return frac_covar_bands else: return results
def plot_filters( filter_names, filterLib=None, save_name="beast_filters", xlim=[1.4e3, 2e4], ylim=[1e-4, 2], show_plot=True, ): """Plots transmission curves in log-log space. Parameters ---------- filter_names : list of str List of full names of filters to plot filterLib : str, optional Filter file (None=default) save_name : str, optional Filename to save plot as xlim : length 2 list Values to set plot x-limits to ylim : length 2 list Values to set plot y-limits to """ if not isinstance(filter_names, list): filter_names = [filter_names] fig, ax = plt.subplots(1, 1, figsize=(10, 6)) # wavelength grid in angstroms for response functions waves = np.logspace(3, np.log10(3e4), 501) # read in the filter response functions flist = phot.load_filters(filter_names, interp=True, lamb=waves, filterLib=filterLib) color_indices = np.log10(np.array(np.sort([f.norm for f in flist]))) color_indices -= color_indices.min() color_indices /= color_indices.max() cmap = mpl.cm.plasma # ax.set_prop_cycle(color=[cmap(i) for i in color_indices]) color = iter(cmap(np.linspace(0.2, 0.8, len(filter_names)))) for f in flist: c = next(color) ax.plot(f.wavelength, f.transmit, color=c, lw=2) ax.fill_between(f.wavelength, f.transmit, alpha=0.2, color=c) ax.text( np.nanmean(f.wavelength[f.transmit > 100.0 * ylim[0]]), 1.3 * np.nanmax(f.transmit[f.transmit > ylim[0]]), f.name.split("_")[-1], ha="center", color=c, ) ax.set_xscale("log") ax.set_yscale("log") ax.set_xlim(xlim) ax.set_ylim(ylim) ax.set_xlabel(r"$\lambda$ [$\mu m$]") ax.set_ylabel(r"$B_i(\lambda)$") # ax.set_xticks([0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 2.0]) ax.get_xaxis().set_major_formatter(mpl.ticker.ScalarFormatter()) fig.tight_layout() if show_plot: plt.show() else: return fig
def getSEDs(self, filter_names, absFlux=True, extLaw=None, inplace=False, filterLib=None, **kwargs): """ Extract integrated fluxes through filters Parameters ---------- filter_names: list list of filter names according to the filter lib or filter instances (no mixing between name and instances) absFlux:bool returns absolute fluxes if set extLaw: extinction.ExtinctionLaw apply extinction law if provided inplace:bool if set, do not copy the grid and apply extinction on it filterLib: str full filename to the filter library hd5 file **kwargs extra keywords will be forwrded to extLaw Returns ------- memgrid: MemoryGrid instance grid of SEDs """ if isinstance(filter_names[0], str): flist = phot.load_filters(filter_names, interp=True, lamb=self.lamb, filterLib=filterLib) _fnames = filter_names else: flist = phot.load_Integrationfilters(filter_names, interp=True, lamb=self.lamb) _fnames = [fk.name for fk in filter_names] if extLaw is not None: if not inplace: r = self.applyExtinctionLaw(extLaw, inplace=inplace, **kwargs) lamb, seds, grid = phot.extractSEDs(r, flist, absFlux=absFlux) else: self.applyExtinctionLaw(extLaw, inplace=inplace, **kwargs) lamb, seds, grid = phot.extractSEDs(self, flist, absFlux=absFlux) else: lamb, seds, grid = phot.extractSEDs(self, flist, absFlux=absFlux) memgrid = MemoryGrid(lamb, seds, grid) setattr(memgrid, "filters", _fnames) return memgrid