def test_apply_inverse(solver, seed=1234, N=201, yerr=0.1): np.random.seed(seed) # Set up the solver. kernel = 1.0 * kernels.ExpSquaredKernel(0.5) kwargs = dict() if solver == HODLRSolver: kwargs["tol"] = 1e-10 gp = GP(kernel, solver=solver, **kwargs) # Sample some data. x = np.sort(np.random.rand(N)) y = gp.sample(x) gp.compute(x, yerr=yerr) K = gp.get_matrix(x) K[np.diag_indices_from(K)] += yerr**2 b1 = np.linalg.solve(K, y) b2 = gp.apply_inverse(y) assert np.allclose(b1, b2) y = gp.sample(x, size=5).T b1 = np.linalg.solve(K, y) b2 = gp.apply_inverse(y) assert np.allclose(b1, b2)
def test_predict_single(solver, seed=1234, N=201, yerr=0.1): np.random.seed(seed) # Set up the solver. kernel = 1.0 * kernels.ExpSquaredKernel(0.5) kwargs = dict() if solver == HODLRSolver: kwargs["tol"] = 1e-8 gp = GP(kernel, solver=solver, **kwargs) x = np.sort(np.random.rand(N)) y = gp.sample(x) gp.compute(x, yerr=yerr) mu0, var0 = gp.predict(y, [0.0], return_var=True) mu, var = gp.predict(y, [0.0, 1.0], return_var=True) _, cov = gp.predict(y, [0.0, 1.0]) assert np.allclose(mu0, mu[0]) assert np.allclose(var0, var[0]) assert np.allclose(var0, cov[0, 0])
def test_gradient(solver, white_noise, seed=123, N=305, ndim=3, eps=1.32e-3): np.random.seed(seed) # Set up the solver. kernel = 1.0 * kernels.ExpSquaredKernel(0.5, ndim=ndim) kwargs = dict() if white_noise is not None: kwargs = dict(white_noise=white_noise, fit_white_noise=True) if solver == HODLRSolver: kwargs["tol"] = 1e-8 gp = GP(kernel, solver=solver, **kwargs) # Sample some data. x = np.random.rand(N, ndim) x = x[np.argsort(x[:, 0])] y = gp.sample(x) gp.compute(x, yerr=0.1) # Compute the initial gradient. grad0 = gp.grad_log_likelihood(y) vector = gp.get_parameter_vector() for i, v in enumerate(vector): # Compute the centered finite difference approximation to the gradient. vector[i] = v + eps gp.set_parameter_vector(vector) lp = gp.lnlikelihood(y) vector[i] = v - eps gp.set_parameter_vector(vector) lm = gp.lnlikelihood(y) vector[i] = v gp.set_parameter_vector(vector) grad = 0.5 * (lp - lm) / eps assert np.abs(grad - grad0[i]) < 5 * eps, \ "Gradient computation failed in dimension {0} ({1})\n{2}" \ .format(i, solver.__name__, np.abs(grad - grad0[i]))
def add_spots(self,QP=[5e-5,0.5,30.,28.]): """ This attribute add stellar variability using a Quasi-periodic Kernel The activity is added using a george Kernel """ if not hasattr(self,'flux_spots'): A = QP[0] le = QP[1] lp = QP[2] P = QP[3] from george import kernels, GP k = A * kernels.ExpSine2Kernel(gamma=1./2/lp,log_period=np.log(P)) * \ kernels.ExpSquaredKernel(metric=le) gp = GP(k) self.flux_spots = 1 + gp.sample(self.time) self.flux = self.flux * self.flux_spots self.spots = True
class MockLC: pb_names = "g' r' i' z'".split() pb_centers = 1e-9 * array([470, 640, 780, 900]) npb = len(pb_names) def __init__(self, setup: SimulationSetup, **kwargs): self.setup = self.s = s = setup self.t_exposure_d = Qty(kwargs.get('exptime', 60), 's').rescale('d') self.t_baseline_d = Qty(s.t_baseline, 'h').rescale('d') self.ldcs = s.ldcs self.tm = QuadraticModel(klims=(0.01, 0.99), nk=512) self.filters = "g' r' i' z'".split() self.npb = len(self.filters) self.k_apparent, self.p, self.a, self.b, self.i = s.orbital_parameters self.duration_d = Qty( duration_eccentric(self.p, self.k_apparent, self.a, self.i, 0, 0, 1), 'd') # Contamination # ------------- qe_be = TabulatedFilter('1024B_eXcelon', [ 300, 325, 350, 400, 450, 500, 700, 800, 850, 900, 950, 1050, 1150 ], [ 0.0, 0.1, 0.25, 0.60, 0.85, 0.92, 0.96, 0.85, 0.70, 0.50, 0.30, 0.05, 0.0 ]) qe_b = TabulatedFilter( '2014B', [300, 350, 500, 550, 700, 800, 1000, 1050], [0.10, 0.20, 0.90, 0.96, 0.90, 0.75, 0.11, 0.05]) qes = qe_be, qe_b, qe_be, qe_be self.instrument = instrument = Instrument( 'MuSCAT2', (sdss_g, sdss_r, sdss_i, sdss_z), qes) self.contaminator = SMContamination(instrument, "i'") self.hteff = setup.hteff self.cteff = setup.cteff self.i_contamination = setup.c self.k_true = setup.k_apparent / sqrt(1 - self.i_contamination) self.contamination = self.contaminator.contamination( self.i_contamination, self.hteff, self.cteff) @property def t_total_d(self): return self.duration_d + 2 * self.t_baseline_d @property def duration_h(self): return self.duration_d.rescale('h') @property def n_exp(self): return int(self.t_total_d // self.t_exposure_d) def __call__(self, rseed=0, ldcs=None, wnsigma=None, rnsigma=None, rntscale=0.5): return self.create(rseed, ldcs, wnsigma, rnsigma, rntscale) def create(self, rseed=0, ldcs=None, wnsigma=None, rnsigma=None, rntscale=0.5, nights=1): ldcs = ldcs if ldcs is not None else self.ldcs seed(rseed) self.time = linspace(-0.5 * float(self.t_total_d), 0.5 * float(self.t_total_d), self.n_exp) self.time = (tile(self.time, [nights, 1]) + (self.p * arange(nights))[:, newaxis]).ravel() self.npt = self.time.size self.tm.set_data(self.time) self.transit = zeros([self.npt, 4]) for i, (ldc, c) in enumerate(zip(ldcs, self.contamination)): self.transit[:, i] = self.tm.evaluate_ps(self.k_true, ldc, 0, self.p, self.a, self.i) self.transit[:, i] = c + (1 - c) * self.transit[:, i] # White noise # ----------- if wnsigma is not None: self.wnoise = multivariate_normal( zeros(atleast_2d(self.transit).shape[1]), diag(wnsigma)**2, self.npt) else: self.wnoise = zeros_like(self.transit) # Red noise # --------- if rnsigma and with_george: self.gp = GP(rnsigma**2 * ExpKernel(rntscale)) self.gp.compute(self.time) self.rnoise = self.gp.sample(self.time, self.npb).T self.rnoise -= self.rnoise.mean(0) else: self.rnoise = zeros_like(self.transit) # Final light curve # ----------------- self.time_h = Qty(self.time, 'd').rescale('h') self.flux = self.transit + self.wnoise + self.rnoise return self.lcdataset @property def lcdataset(self): return LCDataSet([ LCData(self.time, flux, pb) for pb, flux in zip(self.pb_names, self.flux.T) ], self.instrument) def plot(self, figsize=(13, 4), yoffset=0.01): fig, axs = pl.subplots(1, 3, figsize=figsize, sharex='all', sharey='all') yshift = yoffset * arange(4) axs[0].plot(self.time_h, self.flux + yshift) axs[1].plot(self.time_h, self.transit + yshift) axs[2].plot(self.time_h, 1 + self.rnoise + yshift) pl.setp(axs, xlabel='Time [h]', xlim=self.time_h[[0, -1]]) pl.setp(axs[0], ylabel='Normalised flux') [ pl.setp(ax, title=title) for ax, title in zip( axs, 'Transit model + noise, Transit model, Red noise'.split( ', ')) ] fig.tight_layout() return fig, axs def plot_color_difference(self, figsize=(13, 4)): fig, axs = pl.subplots(2, 3, figsize=figsize, sharex='all', sharey='all') [ ax.plot(self.time_h, 100 * (fl - self.transit[:, -1])) for ax, fl in zip(axs[0], self.transit[:, :-1].T) ] [ ax.plot(self.time_h, 100 * (fl - self.flux[:, -1])) for ax, fl in zip(axs[1], self.flux[:, :-1].T) ] [ pl.setp(ax, title='F$_{}$ - F$_z$'.format(pb)) for ax, pb in zip(axs[0], self.pb_names[:-1]) ] pl.setp(axs[:, 0], ylabel='$\Delta F$ [%]') pl.setp(axs[1, :], xlabel='Time [h]') pl.setp(axs, xlim=self.time_h[[0, -1]]) fig.tight_layout() return fig
class MockLC: pb_names = 'g r i z'.split() pb_centers = 1e-9 * array([470, 640, 780, 900]) npb = len(pb_names) def __init__(self, planet_name='wasp-80b', **kwargs): self.t_exposure_d = Qty(kwargs.get('exptime', 60), 's').rescale('d') self.t_baseline_d = Qty(kwargs.get('bltime', 0.5), 'h').rescale('d') self.ldcs = kwargs.get( 'ldcs', array([[0.80, 0.02], [0.61, 0.16], [0.45, 0.20], [0.36, 0.20]])) self.filters = 'g r i z'.split() self.npb = len(self.filters) self.planet = planet = exocat.searchPlanet(planet_name) self.star = star = planet.star self.p = kwargs.get('p', None) or float(planet.P) self.k = kwargs.get('k', None) or float( planet.R.rescale('R_s') / star.R) self.a = kwargs.get('a', None) or float( planet.getParam('semimajoraxis').rescale('R_s') / star.R) self.i = float(planet.getParam('inclination').rescale('rad')) self.b = kwargs.get('b', self.a * cos(self.i)) self.i = arccos(self.b / self.a) self.duration_d = Qty( of.duration_eccentric_f(self.p, self.k, self.a, self.i, 0, 0, 1), 'd') # Contamination # ------------- qe_be = TabulatedFilter('1024B_eXcelon', [ 300, 325, 350, 400, 450, 500, 700, 800, 850, 900, 950, 1050, 1150 ], [ 0.0, 0.1, 0.25, 0.60, 0.85, 0.92, 0.96, 0.85, 0.70, 0.50, 0.30, 0.05, 0.0 ]) qe_b = TabulatedFilter( '2014B', [300, 350, 500, 550, 700, 800, 1000, 1050], [0.10, 0.20, 0.90, 0.96, 0.90, 0.75, 0.11, 0.05]) qes = qe_be, qe_b, qe_be, qe_be instrument = Instrument('MuSCAT2', (sdss_g, sdss_r, sdss_i, sdss_z), qes) self.contaminator = SpectrumTool(instrument, "i'") self.i_contamination = kwargs.get('i_contamination', 0.0) self.cnteff = kwargs.get('contaminant_temperature', None) or float( star.T) self.k0 = self.k / np.sqrt(1 - self.i_contamination) self.contamination = self.contaminator.contamination( self.i_contamination, float(star.T), self.cnteff) @property def t_total_d(self): return self.duration_d + 2 * self.t_baseline_d @property def duration_h(self): return self.duration_d.rescale('h') @property def n_exp(self): return int(self.t_total_d // self.t_exposure_d) def __call__(self, rseed=0, ldcs=None, wnsigma=None, rnsigma=None, rntscale=0.5): return self.create(rseed, ldcs, wnsigma, rnsigma, rntscale) def create(self, rseed=0, ldcs=None, wnsigma=None, rnsigma=None, rntscale=0.5, nights=1): ldcs = ldcs if ldcs is not None else self.ldcs seed(rseed) self.time = linspace(-0.5 * float(self.t_total_d), 0.5 * float(self.t_total_d), self.n_exp) self.time = (tile(self.time, [nights, 1]) + (self.p * arange(nights))[:, newaxis]).ravel() self.npt = self.time.size self.transit = zeros([self.npt, 4]) for i, (ldc, c) in enumerate(zip(ldcs, self.contamination)): self.transit[:, i] = MA().evaluate(self.time, self.k0, ldc, 0, self.p, self.a, self.i, c=c) # White noise # ----------- if wnsigma is not None: self.wnoise = multivariate_normal( zeros(atleast_2d(self.transit).shape[1]), diag(wnsigma)**2, self.npt) else: self.wnoise = zeros_like(self.transit) # Red noise # --------- if rnsigma and with_george: self.gp = GP(rnsigma**2 * ExpKernel(rntscale)) self.gp.compute(self.time) self.rnoise = self.gp.sample(self.time, self.npb).T self.rnoise -= self.rnoise.mean(0) else: self.rnoise = zeros_like(self.transit) # Final light curve # ----------------- self.time_h = Qty(self.time, 'd').rescale('h') self.flux = self.transit + self.wnoise + self.rnoise return self.time_h, self.flux def plot(self, figsize=(13, 4)): fig, axs = pl.subplots(1, 3, figsize=figsize, sharex=True, sharey=True) yshift = 0.01 * arange(4) axs[0].plot(self.time_h, self.flux + yshift) axs[1].plot(self.time_h, self.transit + yshift) axs[2].plot(self.time_h, 1 + self.rnoise + yshift) pl.setp(axs, xlabel='Time [h]', xlim=self.time_h[[0, -1]]) pl.setp(axs[0], ylabel='Normalised flux') [ pl.setp(ax, title=title) for ax, title in zip( axs, 'Transit model + noise, Transit model, Red noise'.split( ', ')) ] fig.tight_layout() return fig, axs def plot_color_difference(self, figsize=(13, 4)): fig, axs = pl.subplots(2, 3, figsize=figsize, sharex=True, sharey=True) [ ax.plot(self.time_h, 100 * (fl - self.transit[:, -1])) for ax, fl in zip(axs[0], self.transit[:, :-1].T) ] [ ax.plot(self.time_h, 100 * (fl - self.flux[:, -1])) for ax, fl in zip(axs[1], self.flux[:, :-1].T) ] [ pl.setp(ax, title='F$_{}$ - F$_z$'.format(pb)) for ax, pb in zip(axs[0], self.pb_names[:-1]) ] pl.setp(axs[:, 0], ylabel='$\Delta F$ [%]') pl.setp(axs[1, :], xlabel='Time [h]') pl.setp(axs, xlim=self.time_h[[0, -1]]) fig.tight_layout() return fig