def plot_folded_orbit(self, ax=None, nbins: int = 100): phase = self.phase - 0.5 * self.period sids = argsort(phase) pb, fb, eb = downsample_time(phase[sids], self.flux[sids], phase.ptp() / nbins) ax.errorbar(pb, fb, eb, fmt='k.') ax.autoscale(axis='x', tight=True) setp(ax, xlabel='Phase [d]', ylabel='Normalized flux')
def plot_folded_planets(self, bwidth: float = 10): fig, axs = subplots(1, self.nplanets, figsize=(13, 6), sharey=True) pv = self.de.minimum_location.copy() for ipl in range(self.nplanets): planets = set(arange(self.nplanets)) planets.remove(ipl) mflux = self.transit_model(pv, planets=[ipl]) rflux = self.transit_model(pv, planets=planets) oflux = self.ofluxa / rflux phase = (fold(self.timea, pv[3 + 4 * ipl], pv[2 + 4 * ipl], 0.5) - 0.5) * pv[3 + 4 * ipl] m = abs(phase) < 0.5 * self.bldur sids = argsort(phase[m]) phase, mflux, oflux = phase[m][sids], mflux[m][sids], oflux[m][ sids] bp, bf, be = downsample_time(phase, oflux, bwidth / 24 / 60) axs[ipl].errorbar(bp, bf, be, fmt='ok') axs[ipl].plot(phase, oflux, '.', alpha=0.25) axs[ipl].plot(phase, mflux, 'k') setp(axs, xlim=(-0.5 * self.bldur, 0.5 * self.bldur), ylim=(0.996, 1.004)) fig.tight_layout() return fig
def plot_flux_vs_time(self, ax = None): transits = self.zero_epoch + unique(epoch(self.time, self.zero_epoch, self.period)) * self.period [ax.axvline(t, ls='--', alpha=0.5, lw=1) for t in transits] ax.plot(self.time, self.flux) tb, fb, eb = downsample_time(self.time, self.flux, 1 / 24) ax.plot(tb, fb, 'k', lw=1) setp(ax, xlabel=f'Time [BJD]', ylabel='Normalized flux', xlim=self.time[[0,-1]])
def plot_folded_tess_transit(self, method='de', pv=None, figsize=None, ylim=None): assert method in ('de', 'mc') if pv is None: if method == 'de': pv = self.de.minimum_location else: df = self.posterior_samples(derived_parameters=False) pv = df.median.values etess = self._ntess t = self.timea[:etess] fo = self.ofluxa[:etess] fm = squeeze(self.transit_model(self.de.population))[self.de.minimum_index, :etess] bl = squeeze(self.baseline(self.de.population))[self.de.minimum_index, :etess] fig, ax = subplots(figsize=figsize) phase = pv[1] * (fold(t, pv[1], pv[0], 0.5) - 0.5) sids = argsort(phase) phase = phase[sids] bp, bf, be = downsample_time(phase, (fo / bl)[sids], 4 / 24 / 60) ax.plot(phase, (fo / bl)[sids], 'k.', alpha=0.2) ax.errorbar(bp, bf, be, fmt='ko') ax.plot(phase, fm[sids], 'k') setp(ax, ylim=ylim, xlabel='Time', ylabel='Normalised flux') return fig
def plot_folded_tess_transit(self, method: str = 'de', pv: ndarray = None, binwidth: float = 1, plot_model: bool = True, plot_unbinned: bool = True, plot_binned: bool = True, xlim: tuple = None, ylim: tuple = None, ax=None, figsize: tuple = None): assert method in ('de', 'mc') if pv is None: if method == 'de': pv = self.de.minimum_location else: df = self.posterior_samples(derived_parameters=False) pv = df.median().values if ax is None: fig, ax = subplots(figsize=figsize) else: fig, ax = None, ax ax.autoscale(enable=True, axis='x', tight=True) etess = self._ntess t = self.timea[:etess] fo = self.ofluxa[:etess] fm = squeeze(self.transit_model(pv))[:etess] bl = squeeze(self.baseline(pv))[:etess] phase = 24 * pv[1] * (fold(t, pv[1], pv[0], 0.5) - 0.5) sids = argsort(phase) phase = phase[sids] bp, bf, be = downsample_time(phase, (fo / bl)[sids], binwidth / 60) if plot_unbinned: ax.plot(phase, (fo / bl)[sids], 'k.', alpha=0.1, ms=2) if plot_binned: ax.errorbar(bp, bf, be, fmt='ko', ms=3) if plot_model: ax.plot(phase, fm[sids], 'k') setp(ax, ylim=ylim, xlim=xlim, xlabel='Time - T$_c$ [h]', ylabel='Normalised flux') if fig is not None: fig.tight_layout() return fig
def plot_folded_tess_transit(self, solution: str = 'de', pv: ndarray = None, binwidth: float = 1, plot_model: bool = True, plot_unbinned: bool = True, plot_binned: bool = True, xlim: tuple = None, ylim: tuple = None, ax=None, figsize: tuple = None): if pv is None: if solution.lower() == 'local': pv = self._local_minimization.x elif solution.lower() in ('de', 'global'): pv = self.de.minimum_location elif solution.lower() in ('mcmc', 'mc'): pv = self.posterior_samples().median().values else: raise NotImplementedError("'solution' should be either 'local', 'global', or 'mcmc'") if ax is None: fig, ax = subplots(figsize=figsize) else: fig, ax = None, ax ax.autoscale(enable=True, axis='x', tight=True) etess = self._ntess t = self.timea[:etess] fo = self.ofluxa[:etess] fm = squeeze(self.transit_model(pv))[:etess] bl = squeeze(self.baseline(pv))[:etess] phase = 24 * pv[1] * (fold(t, pv[1], pv[0], 0.5) - 0.5) sids = argsort(phase) phase = phase[sids] bp, bf, be = downsample_time(phase, (fo / bl)[sids], binwidth / 60) if plot_unbinned: ax.plot(phase, (fo / bl)[sids], 'k.', alpha=0.1, ms=2) if plot_binned: ax.errorbar(bp, bf, be, fmt='ko', ms=3) if plot_model: ax.plot(phase, fm[sids], 'k') setp(ax, ylim=ylim, xlim=xlim, xlabel='Time - T$_c$ [h]', ylabel='Normalised flux') if fig is not None: fig.tight_layout() return fig
def plot_even_odd(self, axs=None, nbins: int = 20, alpha=0.2): for i, ms in enumerate(('even', 'odd')): m = self.transit_fits[ms] sids = argsort(m.phase) phase = m.phase[sids] pmask = abs(phase) < 1.5 * self.duration phase = phase[pmask] fmod = m.fmod[sids][pmask] fobs = m.fobs[sids][pmask] pb, fb, eb = downsample_time(phase, fobs, phase.ptp() / nbins) mask = isfinite(pb) pb, fb, eb = pb[mask], fb[mask], eb[mask] axs[0].errorbar(24 * pb, fb, eb, fmt='o-', label=ms) axs[1].plot(phase, fmod, label=ms) axs[1].legend(loc='upper right') for ax in axs: ax.autoscale(axis='x', tight='true') setp(axs[0], ylabel='Normalized flux') setp(axs, xlabel='Phase [h]')
def plot_transit_fit(self, ax=None, full_phase: bool = False, mode='all', nbins: int = 20, alpha=0.2): zero_epoch, period, duration = self.parameters[['tc', 'p', 't14']].iloc[0].copy() hdur = duration * array([-0.5, 0.5]) phase = self.phase sids = argsort(phase) phase = phase[sids] pmask = ones(phase.size, bool) if full_phase else abs(phase) < 1.5 * duration if pmask.sum() < 100: alpha = 1 if self.mode == 'all': fmod = self.ftra[sids] fobs = self.fobs[sids] / self.fbase[sids] else: fmod = self.fmod[sids] fobs = self.fobs[sids] ax.plot(24 * phase[pmask], fobs[pmask], '.', alpha=alpha) ax.plot(24 * phase[pmask], fmod[pmask], 'w', lw=5, alpha=0.5, zorder=99) ax.plot(24 * phase[pmask], fmod[pmask], 'k', zorder=100) # if duration > 1 / 24: pb, fb, eb = downsample_time(phase[pmask], fobs[pmask], phase[pmask].ptp() / nbins) mask = isfinite(pb) pb, fb, eb = pb[mask], fb[mask], eb[mask] ax.errorbar(24 * pb, fb, eb, fmt='k.') ylim = fb.min() - 2 * eb.max(), fb.max() + 2 * eb.max() # else: # ylim = fobs[pmask].min(), fobs[pmask].max() ax.get_yaxis().get_major_formatter().set_useOffset(False) ax.axvline(0, alpha=0.25, ls='--', lw=1) [ax.axvline(24 * hd, alpha=0.25, ls='-', lw=1) for hd in hdur] ax.autoscale(axis='x', tight='true') setp(ax, ylim=ylim, xlabel='Phase [h]', ylabel='Normalised flux')
def plot_folded_planets(self, passband: str, method: str = 'de', bwidth: float = 10, axs=None, pv: ndarray = None, nsamples: int = 100, limp=(2.5, 97.5, 16, 84), limc: str = 'darkblue', lima: float = 0.15, ylines=None): from pytransit.lpf.tesslpf import downsample_time if axs is None: fig, axs = subplots(1, self.nplanets, sharey='all') else: fig, axs = None, axs if pv is None: if method == 'de': if self.de is None: raise ValueError( "The global optimizer hasn't been initialized.") pvp = None pv = self.de.minimum_location elif method == 'mcmc': if self.sampler is None: raise ValueError("The sampler hasn't been initialized.") df = self.posterior_samples(derived_parameters=False) pvp = permutation(df.values)[:nsamples, :] pv = median(pvp, 0) else: if pv.ndim == 1: pvp = None pv = pv else: pvp = permutation(pv)[:nsamples, :] pv = median(pvp, 0) is_pb = self.pbids == self.passbands.index(passband) pbmask = zeros(self.timea.size, 'bool') for sl, cpb in zip(self.lcslices, is_pb): if cpb: pbmask[sl] = 1 tcids = [ self.ps.names.index(f'tc_{i + 1}') for i in range(self.nplanets) ] prids = [ self.ps.names.index(f'p_{i + 1}') for i in range(self.nplanets) ] t0s = pv[tcids] prs = pv[prids] for ipl in range(self.nplanets): planets = set(arange(self.nplanets)) planets.remove(ipl) if pvp is None: mflux = squeeze(self.transit_model(pv, planets=[ipl]))[pbmask] rflux = squeeze(self.transit_model(pv, planets=planets))[pbmask] mflim = None fbline = self.baseline(pv)[pbmask] else: mfluxes = self.transit_model(pvp, planets=[ipl])[:, pbmask] rfluxes = self.transit_model(pvp, planets=planets)[:, pbmask] fblines = self.baseline(pvp)[:, pbmask] mflux = median(mfluxes, 0) mflim = percentile(mfluxes, limp, 0) rflux = median(rfluxes, 0) fbline = median(fblines, 0) oflux = self.ofluxa[pbmask] / rflux / fbline phase = (fold(self.timea[pbmask], prs[ipl], t0s[ipl], 0.5) - 0.5) * prs[ipl] m = abs(phase) < 0.5 * self.bldur sids = argsort(phase[m]) if m.sum() > 0: phase, mflux, oflux = phase[m][sids], mflux[m][sids], oflux[m][ sids] bp, bf, be = downsample_time(phase, oflux, bwidth / 24 / 60) if mflim is not None: for il in range(mflim.shape[0] // 2): axs[ipl].fill_between(phase, mflim[2 * il, m][sids], mflim[2 * il + 1, m][sids], fc=limc, alpha=lima) axs[ipl].errorbar(bp, bf, be, fmt='ok') axs[ipl].plot(phase, oflux, '.', alpha=0.25) axs[ipl].plot(phase, mflux, 'k') if ylines is not None: axs[ipl].fill_between(phase, mflux, 1, fc='w', zorder=-99) for yl in ylines: axs[ipl].axhline(yl, lw=1, ls='--', c='k', alpha=0.5, zorder=-100) setp(axs, xlim=(-0.5 * self.bldur, 0.5 * self.bldur), ylim=(0.996, 1.004)) if fig is not None: fig.tight_layout() return fig