Exemple #1
0
    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
Exemple #2
0
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
Exemple #3
0
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
Exemple #4
0
    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