예제 #1
0
 def test_regression(self, mock_data):
     wave = doppler_shift(doppler_shift(mock_data[0], 1e3), -1e3)
     assert np.allclose(wave, mock_data[0])
예제 #2
0
 def test_redshit(self, mock_data):
     wave = doppler_shift(mock_data[0], 1e3)
     assert np.all(wave > mock_data[0])
예제 #3
0
 def test_no_change(self, mock_data):
     wave = doppler_shift(mock_data[0], 0)
     assert np.allclose(wave, mock_data[0])
예제 #4
0
 def test_blueshift(self, mock_data):
     wave = doppler_shift(mock_data[0], -1e3)
     assert np.all(wave < mock_data[0])
예제 #5
0
    def __call__(self):
        """
        Performs the transformations according to the parameters available in
        ``self.params``
        Returns
        -------
        flux, cov : tuple
            The transformed flux and covariance matrix from the model
        """
        wave = self.min_dv_wave
        fluxes = self.bulk_fluxes

        if "vsini" in self.params:
            fluxes = rotational_broaden(wave, fluxes, self.params["vsini"])

        if "vz" in self.params:
            wave = doppler_shift(wave, self.params["vz"])

        fluxes = resample(wave, fluxes, self.data.wave)

        if "Av" in self.params:
            fluxes = extinct(self.data.wave, fluxes, self.params["Av"])

        if "cheb" in self.params:
            # force constant term to be 1 to avoid degeneracy with log_scale
            coeffs = [1, *self.cheb]
            fluxes = chebyshev_correct(self.data.wave, fluxes, coeffs)

        # Scale factor from emulator normalization
        flux_scalar = self.flux_scalar_func(self.grid_params)[0]

        # Only rescale flux_mean and flux_std
        if "log_scale" in self.params:
            scale = np.exp(self.params["log_scale"]) * flux_scalar
            fluxes[-2:] = rescale(fluxes[-2:], scale)

        weights, weights_cov = self.emulator(self.grid_params)

        L, flag = cho_factor(weights_cov, overwrite_a=True)

        # Decompose the bulk_fluxes (see emulator/emulator.py for the ordering)
        *eigenspectra, flux_mean, flux_std = fluxes

        # Complete the reconstruction
        X = eigenspectra * flux_std
        flux = weights @ X + flux_mean

        # Renorm to data flux if no "log_scale" provided
        if "log_scale" not in self.params:
            factor = _get_renorm_factor(self.data.wave, flux * flux_scalar,
                                        self.data.flux) * flux_scalar
            flux = rescale(flux, factor)
            X = rescale(X, factor)

        cov = X.T @ cho_solve((L, flag), X)

        # Poisson Noise Scaling
        if "global_cov:sigma_amp" in self.params:
            poisson_scale = self.params["global_cov:sigma_amp"]
        else:
            poisson_scale = 1

        # Trivial covariance
        np.fill_diagonal(cov,
                         cov.diagonal() + (poisson_scale * self.data.sigma**2))

        # Trival and global covariance
        if "global_cov" in self.params:
            if "global_cov" not in self.frozen or self._glob_cov is None:
                if "global_cov:log_amp" in self.params.keys():
                    ag = np.exp(self.params["global_cov:log_amp"])
                else:
                    ag = self.params["global_cov:amp"]
                if "global_cov:log_ls" in self.params.keys():
                    lg = np.exp(self.params["global_cov:log_ls"])
                else:
                    lg = self.params["global_cov:ls"]
                T = self.params["T"]
                self._glob_cov = global_covariance_matrix(
                    self.data.wave, T, ag, lg)

        if self._glob_cov is not None:
            cov += self._glob_cov

        # Local covariance
        if "local_cov" in self.params:
            if "local_cov" not in self.frozen or self._loc_cov is None:
                self._loc_cov = 0
                for kernel in self.params.as_dict()["local_cov"]:
                    mu = kernel["mu"]
                    amplitude = np.exp(kernel["log_amp"])
                    sigma = np.exp(kernel["log_sigma"])
                    self._loc_cov += local_covariance_matrix(
                        self.data.wave, amplitude, mu, sigma)

        if self._loc_cov is not None:
            cov += self._loc_cov

        return flux, cov