Instruction:
How would you implement a function in Python 3 that
loads the FITS file and populate the object with its data.

Response:
def load_fits(self):
        '''
        Load the FITS file from disk and populate the
        class instance with its data.

        '''

        log.info("Loading FITS file for %d." % (self.ID))
        with pyfits.open(self.fitsfile) as f:

            # Params and long cadence data
            self.loaded = True
            self.is_parent = False
            try:
                self.X1N = f[2].data['X1N']
            except KeyError:
                self.X1N = None
            self.aperture = f[3].data
            self.aperture_name = f[1].header['APNAME']
            try:
                self.bkg = f[1].data['BKG']
            except KeyError:
                self.bkg = 0.
            self.bpad = f[1].header['BPAD']
            self.cbv_minstars = []
            self.cbv_num = f[1].header.get('CBVNUM', 1)
            self.cbv_niter = f[1].header['CBVNITER']
            self.cbv_win = f[1].header['CBVWIN']
            self.cbv_order = f[1].header['CBVORD']
            self.cadn = f[1].data['CADN']
            self.cdivs = f[1].header['CDIVS']
            self.cdpp = f[1].header['CDPP']
            self.cdppr = f[1].header['CDPPR']
            self.cdppv = f[1].header['CDPPV']
            self.cdppg = f[1].header['CDPPG']
            self.cv_min = f[1].header['CVMIN']
            self.fpix = f[2].data['FPIX']
            self.pixel_images = [f[4].data['STAMP1'],
                                 f[4].data['STAMP2'], f[4].data['STAMP3']]
            self.fraw = f[1].data['FRAW']
            self.fraw_err = f[1].data['FRAW_ERR']
            self.giter = f[1].header['GITER']
            self.gmaxf = f[1].header.get('GMAXF', 200)
            self.gp_factor = f[1].header['GPFACTOR']
            try:
                self.hires = f[5].data
            except:
                self.hires = None
            self.kernel_params = np.array([f[1].header['GPWHITE'],
                                           f[1].header['GPRED'],
                                           f[1].header['GPTAU']])
            try:
                self.kernel = f[1].header['KERNEL']
                self.kernel_params = np.append(
                    self.kernel_params,
                    [f[1].header['GPGAMMA'],
                     f[1].header['GPPER']])
            except KeyError:
                self.kernel = 'Basic'
            self.pld_order = f[1].header['PLDORDER']
            self.lam_idx = self.pld_order
            self.leps = f[1].header['LEPS']
            self.mag = f[0].header['KEPMAG']
            self.max_pixels = f[1].header['MAXPIX']
            self.model = self.fraw - f[1].data['FLUX']
            self.nearby = []
            for i in range(99):
                try:
                    ID = f[1].header['NRBY%02dID' % (i + 1)]
                    x = f[1].header['NRBY%02dX' % (i + 1)]
                    y = f[1].header['NRBY%02dY' % (i + 1)]
                    mag = f[1].header['NRBY%02dM' % (i + 1)]
                    x0 = f[1].header['NRBY%02dX0' % (i + 1)]
                    y0 = f[1].header['NRBY%02dY0' % (i + 1)]
                    self.nearby.append(
                        {'ID': ID, 'x': x, 'y': y,
                         'mag': mag, 'x0': x0, 'y0': y0})
                except KeyError:
                    break
            self.neighbors = []
            for c in range(99):
                try:
                    self.neighbors.append(f[1].header['NEIGH%02d' % (c + 1)])
                except KeyError:
                    break
            self.oiter = f[1].header['OITER']
            self.optimize_gp = f[1].header['OPTGP']
            self.osigma = f[1].header['OSIGMA']
            self.planets = []
            for i in range(99):
                try:
                    t0 = f[1].header['P%02dT0' % (i + 1)]
                    per = f[1].header['P%02dPER' % (i + 1)]
                    dur = f[1].header['P%02dDUR' % (i + 1)]
                    self.planets.append((t0, per, dur))
                except KeyError:
                    break
            self.quality = f[1].data['QUALITY']
            self.saturated = f[1].header['SATUR']
            self.saturation_tolerance = f[1].header['SATTOL']
            self.time = f[1].data['TIME']
            self._norm = np.array(self.fraw)

            # Chunk arrays
            self.breakpoints = []
            self.cdpp_arr = []
            self.cdppv_arr = []
            self.cdppr_arr = []
            for c in range(99):
                try:
                    self.breakpoints.append(f[1].header['BRKPT%02d' % (c + 1)])
                    self.cdpp_arr.append(f[1].header['CDPP%02d' % (c + 1)])
                    self.cdppr_arr.append(f[1].header['CDPPR%02d' % (c + 1)])
                    self.cdppv_arr.append(f[1].header['CDPPV%02d' % (c + 1)])
                except KeyError:
                    break
            self.lam = [[f[1].header['LAMB%02d%02d' % (c + 1, o + 1)]
                        for o in range(self.pld_order)]
                        for c in range(len(self.breakpoints))]
            if self.model_name == 'iPLD':
                self.reclam = [[f[1].header['RECL%02d%02d' % (c + 1, o + 1)]
                               for o in range(self.pld_order)]
                               for c in range(len(self.breakpoints))]

            # Masks
            self.badmask = np.where(self.quality & 2 ** (QUALITY_BAD - 1))[0]
            self.nanmask = np.where(self.quality & 2 ** (QUALITY_NAN - 1))[0]
            self.outmask = np.where(self.quality & 2 ** (QUALITY_OUT - 1))[0]
            self.recmask = np.where(self.quality & 2 ** (QUALITY_REC - 1))[0]
            self.transitmask = np.where(
                self.quality & 2 ** (QUALITY_TRN - 1))[0]

            # CBVs
            self.XCBV = np.empty((len(self.time), 0))
            for i in range(99):
                try:
                    self.XCBV = np.hstack(
                        [self.XCBV,
                         f[1].data['CBV%02d' % (i + 1)].reshape(-1, 1)])
                except KeyError:
                    break

        # These are not stored in the fits file; we don't need them
        self.saturated_aperture_name = None
        self.apertures = None
        self.Xpos = None
        self.Ypos = None
        self.fpix_err = None
        self.parent_model = None
        self.lambda_arr = None
        self.meta = None
        self._transit_model = None
        self.transit_depth = None


Instruction:
Can you implement a function in Python 3 that
plots sample postage stamps for the target with the aperture outline marked as well as a high - res target image.

Response:
def plot_aperture(self, show=True):
        '''
        Plot sample postage stamps for the target with the aperture
        outline marked, as well as a high-res target image (if available).

        :param bool show: Show the plot or return the `(fig, ax)` instance? \
               Default :py:obj:`True`

        '''

        # Set up the axes
        fig, ax = pl.subplots(2, 2, figsize=(6, 8))
        fig.subplots_adjust(top=0.975, bottom=0.025, left=0.05,
                            right=0.95, hspace=0.05, wspace=0.05)
        ax = ax.flatten()
        fig.canvas.set_window_title(
            '%s %d' % (self._mission.IDSTRING, self.ID))
        super(Everest, self).plot_aperture(ax, labelsize=12)

        if show:
            pl.show()
            pl.close()
        else:
            return fig, ax


Instruction:
Can you generate the documentation for the following Python 3 function
def plot(self, show=True, plot_raw=True, plot_gp=True,
             plot_bad=True, plot_out=True, plot_cbv=True,
             simple=False):
        '''
        Plots the final de-trended light curve.

        :param bool show: Show the plot or return the `(fig, ax)` instance? \
               Default :py:obj:`True`
        :param bool plot_raw: Show the raw light curve? Default :py:obj:`True`
        :param bool plot_gp: Show the GP model prediction? \
               Default :py:obj:`True`
        :param bool plot_bad: Show and indicate the bad data points? \
               Default :py:obj:`True`
        :param bool plot_out: Show and indicate the outliers? \
               Default :py:obj:`True`
        :param bool plot_cbv: Plot the CBV-corrected light curve? \
               Default :py:obj:`True`. If :py:obj:`False`, plots the \
               de-trended but uncorrected light curve.

        '''

        log.info('Plotting the light curve...')

        # Set up axes
        if plot_raw:
            fig, axes = pl.subplots(2, figsize=(13, 9), sharex=True)
            fig.subplots_adjust(hspace=0.1)
            axes = [axes[1], axes[0]]
            if plot_cbv:
                fluxes = [self.fcor, self.fraw]
            else:
                fluxes = [self.flux, self.fraw]
            labels = ['EVEREST Flux', 'Raw Flux']
        else:
            fig, axes = pl.subplots(1, figsize=(13, 6))
            axes = [axes]
            if plot_cbv:
                fluxes = [self.fcor]
            else:
                fluxes = [self.flux]
            labels = ['EVEREST Flux']
        fig.canvas.set_window_title('EVEREST Light curve')

        # Set up some stuff
        time = self.time
        badmask = self.badmask
        nanmask = self.nanmask
        outmask = self.outmask
        transitmask = self.transitmask
        fraw_err = self.fraw_err
        breakpoints = self.breakpoints
        if self.cadence == 'sc':
            ms = 2
        else:
            ms = 4

        # Get the cdpps
        cdpps = [[self.get_cdpp(self.flux), self.get_cdpp_arr(self.flux)],
                 [self.get_cdpp(self.fraw), self.get_cdpp_arr(self.fraw)]]
        self.cdpp = cdpps[0][0]
        self.cdpp_arr = cdpps[0][1]

        for n, ax, flux, label, c in zip([0, 1], axes, fluxes, labels, cdpps):

            # Initialize CDPP
            cdpp = c[0]
            cdpp_arr = c[1]

            # Plot the good data points
            ax.plot(self.apply_mask(time), self.apply_mask(flux),
                    ls='none', marker='.', color='k', markersize=ms, alpha=0.5)

            # Plot the outliers
            bnmask = np.array(
                list(set(np.concatenate([badmask, nanmask]))), dtype=int)
            bmask = [i for i in self.badmask if i not in self.nanmask]

            def O1(x): return x[outmask]

            def O2(x): return x[bmask]

            def O3(x): return x[transitmask]
            if plot_out:
                ax.plot(O1(time), O1(flux), ls='none', color="#777777",
                        marker='.', markersize=ms, alpha=0.5)
            if plot_bad:
                ax.plot(O2(time), O2(flux), 'r.', markersize=ms, alpha=0.25)
            ax.plot(O3(time), O3(flux), 'b.', markersize=ms, alpha=0.25)

            # Plot the GP
            if n == 0 and plot_gp and self.cadence != 'sc':
                gp = GP(self.kernel, self.kernel_params)
                gp.compute(self.apply_mask(time), self.apply_mask(fraw_err))
                med = np.nanmedian(self.apply_mask(flux))
                y, _ = gp.predict(self.apply_mask(flux) - med, time)
                y += med
                ax.plot(self.apply_mask(time), self.apply_mask(
                    y), 'r-', lw=0.5, alpha=0.5)

            # Appearance
            if n == 0:
                ax.set_xlabel('Time (%s)' %
                              self._mission.TIMEUNITS, fontsize=18)
            ax.set_ylabel(label, fontsize=18)
            for brkpt in breakpoints[:-1]:
                ax.axvline(time[brkpt], color='r', ls='--', alpha=0.25)
            if len(cdpp_arr) == 2:
                ax.annotate('%.2f ppm' % cdpp_arr[0], xy=(0.02, 0.975),
                            xycoords='axes fraction',
                            ha='left', va='top', fontsize=12, color='r',
                            zorder=99)
                ax.annotate('%.2f ppm' % cdpp_arr[1], xy=(0.98, 0.975),
                            xycoords='axes fraction',
                            ha='right', va='top', fontsize=12,
                            color='r', zorder=99)
            elif len(cdpp_arr) < 6:
                for n in range(len(cdpp_arr)):
                    if n > 0:
                        x = (self.time[self.breakpoints[n - 1]] - self.time[0]
                             ) / (self.time[-1] - self.time[0]) + 0.02
                    else:
                        x = 0.02
                    ax.annotate('%.2f ppm' % cdpp_arr[n], xy=(x, 0.975),
                                xycoords='axes fraction',
                                ha='left', va='top', fontsize=10,
                                zorder=99, color='r')
            else:
                ax.annotate('%.2f ppm' % cdpp, xy=(0.02, 0.975),
                            xycoords='axes fraction',
                            ha='left', va='top', fontsize=12,
                            color='r', zorder=99)
            ax.margins(0.01, 0.1)

            # Get y lims that bound 99% of the flux
            f = np.concatenate([np.delete(f, bnmask) for f in fluxes])
            N = int(0.995 * len(f))
            hi, lo = f[np.argsort(f)][[N, -N]]
            pad = (hi - lo) * 0.1
            ylim = (lo - pad, hi + pad)
            ax.set_ylim(ylim)
            ax.get_yaxis().set_major_formatter(Formatter.Flux)

            # Indicate off-axis outliers
            for i in np.where(flux < ylim[0])[0]:
                if i in bmask:
                    color = "#ffcccc"
                    if not plot_bad:
                        continue
                elif i in outmask:
                    color = "#cccccc"
                    if not plot_out:
                        continue
                elif i in nanmask:
                    continue
                else:
                    color = "#ccccff"
                ax.annotate('', xy=(time[i], ylim[0]), xycoords='data',
                            xytext=(0, 15), textcoords='offset points',
                            arrowprops=dict(arrowstyle="-|>", color=color))
            for i in np.where(flux > ylim[1])[0]:
                if i in bmask:
                    color = "#ffcccc"
                    if not plot_bad:
                        continue
                elif i in outmask:
                    color = "#cccccc"
                    if not plot_out:
                        continue
                elif i in nanmask:
                    continue
                else:
                    color = "#ccccff"
                ax.annotate('', xy=(time[i], ylim[1]), xycoords='data',
                            xytext=(0, -15), textcoords='offset points',
                            arrowprops=dict(arrowstyle="-|>", color=color))

        # Show total CDPP improvement
        pl.figtext(0.5, 0.94, '%s %d' % (self._mission.IDSTRING, self.ID),
                   fontsize=18, ha='center', va='bottom')
        pl.figtext(0.5, 0.905,
                   r'$%.2f\ \mathrm{ppm} \rightarrow %.2f\ \mathrm{ppm}$' %
                   (self.cdppr, self.cdpp), fontsize=14,
                   ha='center', va='bottom')

        if show:
            pl.show()
            pl.close()
        else:
            if plot_raw:
                return fig, axes
            else:
                return fig, axes[0]

Response: Plot the final de - trended light curve.


Instruction:
Make a summary of the following Python 3 code
def dvs(self):
        '''
        Shows the data validation summary (DVS) for the target.

        '''

        DVS(self.ID, season=self.season, mission=self.mission,
            model=self.model_name, clobber=self.clobber)

Response: Shows the data validation summary for the target.


Instruction:
Can you write a function in Python 3 where it
plots the light curve for the target de - trended with a given pipeline.

Response:
def plot_pipeline(self, pipeline, *args, **kwargs):
        '''
        Plots the light curve for the target de-trended with a given pipeline.

        :param str pipeline: The name of the pipeline (lowercase). Options \
               are 'everest2', 'everest1', and other mission-specific \
               pipelines. For `K2`, the available pipelines are 'k2sff' \
               and 'k2sc'.

        Additional :py:obj:`args` and :py:obj:`kwargs` are passed directly to
        the :py:func:`pipelines.plot` function of the mission.

        '''

        if pipeline != 'everest2':
            return getattr(missions, self.mission).pipelines.plot(self.ID,
                                                                  pipeline,
                                                                  *args,
                                                                  **kwargs)

        else:

            # We're going to plot the everest 2 light curve like we plot
            # the other pipelines for easy comparison
            plot_raw = kwargs.get('plot_raw', False)
            plot_cbv = kwargs.get('plot_cbv', True)
            show = kwargs.get('show', True)

            if plot_raw:
                y = self.fraw
                ylabel = 'Raw Flux'
            elif plot_cbv:
                y = self.fcor
                ylabel = "EVEREST2 Flux"
            else:
                y = self.flux
                ylabel = "EVEREST2 Flux"

            # Remove nans
            bnmask = np.concatenate([self.nanmask, self.badmask])
            time = np.delete(self.time, bnmask)
            flux = np.delete(y, bnmask)

            # Plot it
            fig, ax = pl.subplots(1, figsize=(10, 4))
            fig.subplots_adjust(bottom=0.15)
            ax.plot(time, flux, "k.", markersize=3, alpha=0.5)

            # Axis limits
            N = int(0.995 * len(flux))
            hi, lo = flux[np.argsort(flux)][[N, -N]]
            pad = (hi - lo) * 0.1
            ylim = (lo - pad, hi + pad)
            ax.set_ylim(ylim)

            # Plot bad data points
            ax.plot(self.time[self.badmask], y[self.badmask],
                    "r.", markersize=3, alpha=0.2)

            # Show the CDPP
            ax.annotate('%.2f ppm' % self._mission.CDPP(flux),
                        xy=(0.98, 0.975), xycoords='axes fraction',
                        ha='right', va='top', fontsize=12, color='r',
                        zorder=99)

            # Appearance
            ax.margins(0, None)
            ax.set_xlabel("Time (%s)" % self._mission.TIMEUNITS, fontsize=16)
            ax.set_ylabel(ylabel, fontsize=16)
            fig.canvas.set_window_title("EVEREST2: EPIC %d" % (self.ID))

            if show:
                pl.show()
                pl.close()
            else:
                return fig, ax


Instruction:
Here you have a function in Python 3, explain what it does
def get_pipeline(self, *args, **kwargs):
        '''
        Returns the `time` and `flux` arrays for the target obtained by a given
        pipeline.

        Options :py:obj:`args` and :py:obj:`kwargs` are passed directly to
        the :py:func:`pipelines.get` function of the mission.

        '''

        return getattr(missions, self.mission).pipelines.get(self.ID, *args,
                                                             **kwargs)

Response:
Returns the time and flux arrays for the target obtained by a given
        pipeline.


Instruction:
Implement a function in Python 3 to
mask all of the transits and eclipses of a given planet.

Response:
def mask_planet(self, t0, period, dur=0.2):
        '''
        Mask all of the transits/eclipses of a given planet/EB. After calling
        this method, you must re-compute the model by calling
        :py:meth:`compute` in order for the mask to take effect.

        :param float t0: The time of first transit (same units as light curve)
        :param float period: The period of the planet in days
        :param foat dur: The transit duration in days. Default 0.2

        '''

        mask = []
        t0 += np.ceil((self.time[0] - dur - t0) / period) * period
        for t in np.arange(t0, self.time[-1] + dur, period):
            mask.extend(np.where(np.abs(self.time - t) < dur / 2.)[0])
        self.transitmask = np.array(
            list(set(np.concatenate([self.transitmask, mask]))))


Instruction:
Can you write a function in Python 3 where it
plots the weights for the current light.

Response:
def _plot_weights(self, show=True):
        '''
        .. warning:: Untested!

        '''

        # Set up the axes
        fig = pl.figure(figsize=(12, 12))
        fig.subplots_adjust(top=0.95, bottom=0.025, left=0.1, right=0.92)
        fig.canvas.set_window_title(
            '%s %d' % (self._mission.IDSTRING, self.ID))
        ax = [pl.subplot2grid((80, 130), (20 * j, 25 * i), colspan=23,
                              rowspan=18)
              for j in range(len(self.breakpoints) * 2)
              for i in range(1 + 2 * (self.pld_order - 1))]
        cax = [pl.subplot2grid((80, 130),
                               (20 * j, 25 * (1 + 2 * (self.pld_order - 1))),
                               colspan=4, rowspan=18)
               for j in range(len(self.breakpoints) * 2)]
        ax = np.array(ax).reshape(2 * len(self.breakpoints), -1)
        cax = np.array(cax)

        # Check number of segments
        if len(self.breakpoints) > 3:
            log.error('Cannot currently plot weights for light ' +
                      'curves with more than 3 segments.')
            return

        # Loop over all PLD orders and over all chunks
        npix = len(self.fpix[1])
        ap = self.aperture.flatten()
        ncol = 1 + 2 * (len(self.weights[0]) - 1)
        raw_weights = np.zeros(
            (len(self.breakpoints), ncol, self.aperture.shape[0],
             self.aperture.shape[1]), dtype=float)
        scaled_weights = np.zeros(
            (len(self.breakpoints), ncol, self.aperture.shape[0],
             self.aperture.shape[1]), dtype=float)

        # Loop over orders
        for o in range(len(self.weights[0])):
            if o == 0:
                oi = 0
            else:
                oi = 1 + 2 * (o - 1)

            # Loop over chunks
            for b in range(len(self.weights)):

                c = self.get_chunk(b)
                rw_ii = np.zeros(npix)
                rw_ij = np.zeros(npix)
                sw_ii = np.zeros(npix)
                sw_ij = np.zeros(npix)
                X = np.nanmedian(self.X(o, c), axis=0)

                # Compute all sets of pixels at this PLD order, then
                # loop over them and assign the weights to the correct pixels
                sets = np.array(list(multichoose(np.arange(npix).T, o + 1)))
                for i, s in enumerate(sets):
                    if (o == 0) or (s[0] == s[1]):
                        # Not the cross-terms
                        j = s[0]
                        rw_ii[j] += self.weights[b][o][i]
                        sw_ii[j] += X[i] * self.weights[b][o][i]
                    else:
                        # Cross-terms
                        for j in s:
                            rw_ij[j] += self.weights[b][o][i]
                            sw_ij[j] += X[i] * self.weights[b][o][i]

                # Make the array 2D and plot it
                rw = np.zeros_like(ap, dtype=float)
                sw = np.zeros_like(ap, dtype=float)
                n = 0
                for i, a in enumerate(ap):
                    if (a & 1):
                        rw[i] = rw_ii[n]
                        sw[i] = sw_ii[n]
                        n += 1
                raw_weights[b][oi] = rw.reshape(*self.aperture.shape)
                scaled_weights[b][oi] = sw.reshape(*self.aperture.shape)

                if o > 0:
                    # Make the array 2D and plot it
                    rw = np.zeros_like(ap, dtype=float)
                    sw = np.zeros_like(ap, dtype=float)
                    n = 0
                    for i, a in enumerate(ap):
                        if (a & 1):
                            rw[i] = rw_ij[n]
                            sw[i] = sw_ij[n]
                            n += 1
                    raw_weights[b][oi + 1] = rw.reshape(*self.aperture.shape)
                    scaled_weights[b][oi +
                                      1] = sw.reshape(*self.aperture.shape)

        # Plot the images
        log.info('Plotting the PLD weights...')
        rdbu = pl.get_cmap('RdBu_r')
        rdbu.set_bad('k')
        for b in range(len(self.weights)):
            rmax = max([-raw_weights[b][o].min() for o in range(ncol)] +
                       [raw_weights[b][o].max() for o in range(ncol)])
            smax = max([-scaled_weights[b][o].min() for o in range(ncol)] +
                       [scaled_weights[b][o].max() for o in range(ncol)])
            for o in range(ncol):
                imr = ax[2 * b, o].imshow(raw_weights[b][o], aspect='auto',
                                          interpolation='nearest', cmap=rdbu,
                                          origin='lower', vmin=-rmax,
                                          vmax=rmax)
                ims = ax[2 * b + 1, o].imshow(scaled_weights[b][o],
                                              aspect='auto',
                                              interpolation='nearest',
                                              cmap=rdbu, origin='lower',
                                              vmin=-smax, vmax=smax)

            # Colorbars
            def fmt(x, pos):
                a, b = '{:.0e}'.format(x).split('e')
                b = int(b)
                if float(a) > 0:
                    a = r'+' + a
                elif float(a) == 0:
                    return ''
                return r'${} \times 10^{{{}}}$'.format(a, b)
            cbr = pl.colorbar(imr, cax=cax[2 * b], format=FuncFormatter(fmt))
            cbr.ax.tick_params(labelsize=8)
            cbs = pl.colorbar(
                ims, cax=cax[2 * b + 1], format=FuncFormatter(fmt))
            cbs.ax.tick_params(labelsize=8)

        # Plot aperture contours
        def PadWithZeros(vector, pad_width, iaxis, kwargs):
            vector[:pad_width[0]] = 0
            vector[-pad_width[1]:] = 0
            return vector
        ny, nx = self.aperture.shape
        contour = np.zeros((ny, nx))
        contour[np.where(self.aperture)] = 1
        contour = np.lib.pad(contour, 1, PadWithZeros)
        highres = zoom(contour, 100, order=0, mode='nearest')
        extent = np.array([-1, nx, -1, ny])
        for axis in ax.flatten():
            axis.contour(highres, levels=[
                         0.5], extent=extent, origin='lower', colors='r',
                         linewidths=1)

            # Check for saturated columns
            for x in range(self.aperture.shape[0]):
                for y in range(self.aperture.shape[1]):
                    if self.aperture[x][y] == AP_SATURATED_PIXEL:
                        axis.fill([y - 0.5, y + 0.5, y + 0.5, y - 0.5],
                                  [x - 0.5, x - 0.5, x + 0.5, x + 0.5],
                                  fill=False, hatch='xxxxx', color='r', lw=0)

            axis.set_xlim(-0.5, nx - 0.5)
            axis.set_ylim(-0.5, ny - 0.5)
            axis.set_xticks([])
            axis.set_yticks([])

        # Labels
        titles = [r'$1^{\mathrm{st}}$',
                  r'$2^{\mathrm{nd}}\ (i = j)$',
                  r'$2^{\mathrm{nd}}\ (i \neq j)$',
                  r'$3^{\mathrm{rd}}\ (i = j)$',
                  r'$3^{\mathrm{rd}}\ (i \neq j)$'] + ['' for i in range(10)]
        for i, axis in enumerate(ax[0]):
            axis.set_title(titles[i], fontsize=12)
        for j in range(len(self.weights)):
            ax[2 * j, 0].text(-0.55, -0.15, r'$%d$' % (j + 1),
                              fontsize=16, transform=ax[2 * j, 0].transAxes)
            ax[2 * j, 0].set_ylabel(r'$w_{ij}$', fontsize=18)
            ax[2 * j + 1,
                0].set_ylabel(r'$\bar{X}_{ij} \cdot w_{ij}$', fontsize=18)

        if show:
            pl.show()
            pl.close()
        else:
            return fig, ax, cax


Instruction:
Make a summary of the following Python 3 code
def _save_npz(self):
        '''
        Saves all of the de-trending information to disk in an `npz` file

        '''

        # Save the data
        d = dict(self.__dict__)
        d.pop('_weights', None)
        d.pop('_A', None)
        d.pop('_B', None)
        d.pop('_f', None)
        d.pop('_mK', None)
        d.pop('K', None)
        d.pop('dvs', None)
        d.pop('clobber', None)
        d.pop('clobber_tpf', None)
        d.pop('_mission', None)
        d.pop('debug', None)
        np.savez(os.path.join(self.dir, self.name + '.npz'), **d)

Response: Saves all of the de - trending information to disk in an npz file


Instruction:
Here you have a function in Python 3, explain what it does
def optimize(self, piter=3, pmaxf=300, ppert=0.1):
        '''
        Runs :py:obj:`pPLD` on the target in an attempt to further optimize the
        values of the PLD priors. See :py:class:`everest.detrender.pPLD`.

        '''

        self._save_npz()
        optimized = pPLD(self.ID, piter=piter, pmaxf=pmaxf,
                         ppert=ppert, debug=True, clobber=True)
        optimized.publish()
        self.reset()

Response: Optimize the current set of priors.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def plot_folded(self, t0, period, dur=0.2):
        '''
        Plot the light curve folded on a given `period` and centered at `t0`.
        When plotting folded transits, please mask them using
        :py:meth:`mask_planet` and re-compute the model using
        :py:meth:`compute`.

        :param float t0: The time at which to center the plot \
               (same units as light curve)
        :param float period: The period of the folding operation
        :param float dur: The transit duration in days. Default 0.2

        '''

        # Mask the planet
        self.mask_planet(t0, period, dur)

        # Whiten
        gp = GP(self.kernel, self.kernel_params, white=False)
        gp.compute(self.apply_mask(self.time), self.apply_mask(self.fraw_err))
        med = np.nanmedian(self.apply_mask(self.flux))
        y, _ = gp.predict(self.apply_mask(self.flux) - med, self.time)
        fwhite = (self.flux - y)
        fwhite /= np.nanmedian(fwhite)

        # Fold
        tfold = (self.time - t0 - period / 2.) % period - period / 2.

        # Crop
        inds = np.where(np.abs(tfold) < 2 * dur)[0]
        x = tfold[inds]
        y = fwhite[inds]

        # Plot
        fig, ax = pl.subplots(1, figsize=(9, 5))
        fig.subplots_adjust(bottom=0.125)
        ax.plot(x, y, 'k.', alpha=0.5)

        # Get ylims
        yfin = np.delete(y, np.where(np.isnan(y)))
        lo, hi = yfin[np.argsort(yfin)][[3, -3]]
        pad = (hi - lo) * 0.1
        ylim = (lo - pad, hi + pad)
        ax.set_ylim(*ylim)

        # Appearance
        ax.set_xlabel(r'Time (days)', fontsize=18)
        ax.set_ylabel(r'Normalized Flux', fontsize=18)
        fig.canvas.set_window_title(
            '%s %d' % (self._mission.IDSTRING, self.ID))

        pl.show()

Response: Plot the light curve folded on a given period and centered at t0.


Instruction:
Write a Python 3 function that can
plot the light curve de - trended with a join instrumental + transit model overlaid.

Response:
def plot_transit_model(self, show=True, fold=None, ax=None):
        '''
        Plot the light curve de-trended with a join instrumental + transit
        model with the best fit transit model overlaid. The transit model
        should be specified using the :py:obj:`transit_model` attribute
        and should be an instance or list of instances of
        :py:class:`everest.transit.TransitModel`.

        :param bool show: Show the plot, or return the `fig, ax` instances? \
               Default `True`
        :param str fold: The name of the planet/transit model on which to \
               fold. If only one model is present, can be set to \
               :py:obj:`True`. Default :py:obj:`False` \
               (does not fold the data).
        :param ax: A `matplotlib` axis instance to use for plotting. \
               Default :py:obj:`None`

        '''

        if self.transit_model is None:
            raise ValueError("No transit model provided!")
        if self.transit_depth is None:
            self.compute()
        if fold is not None:
            if (fold is True and len(self.transit_model) > 1) or \
               (type(fold) is not str):
                raise Exception(
                    "Kwarg `fold` should be the name of the transit " +
                    "model on which to fold the data.")
            if fold is True:
                # We are folding on the first index of `self.transit_model`
                fold = 0
            elif type(fold) is str:
                # Figure out the index of the transit model on which to fold
                fold = np.argmax(
                    [fold == tm.name for tm in self.transit_model])
            log.info('Plotting the transit model folded ' +
                     'on transit model index %d...' % fold)
        else:
            log.info('Plotting the transit model...')

        # Set up axes
        if ax is None:
            if fold is not None:
                fig, ax = pl.subplots(1, figsize=(8, 5))
            else:
                fig, ax = pl.subplots(1, figsize=(13, 6))
            fig.canvas.set_window_title('EVEREST Light curve')
        else:
            fig = pl.gcf()

        # Set up some stuff
        if self.cadence == 'sc':
            ms = 2
        else:
            ms = 4

        # Fold?
        if fold is not None:
            times = self.transit_model[fold].params.get('times', None)
            if times is not None:
                time = self.time - \
                    [times[np.argmin(np.abs(ti - times))] for ti in self.time]
                t0 = times[0]
            else:
                t0 = self.transit_model[fold].params.get('t0', 0.)
                period = self.transit_model[fold].params.get('per', 10.)
                time = (self.time - t0 - period / 2.) % period - period / 2.
            dur = 0.01 * \
                len(np.where(self.transit_model[fold](
                    np.linspace(t0 - 0.5, t0 + 0.5, 100)) < 0)[0])
        else:
            time = self.time
            ax.plot(self.apply_mask(time), self.apply_mask(self.flux),
                    ls='none', marker='.', color='k', markersize=ms, alpha=0.5)
            ax.plot(time[self.outmask], self.flux[self.outmask],
                    ls='none', marker='.', color='k', markersize=ms, alpha=0.5)
            ax.plot(time[self.transitmask], self.flux[self.transitmask],
                    ls='none', marker='.', color='k', markersize=ms, alpha=0.5)

        # Plot the transit + GP model
        med = np.nanmedian(self.apply_mask(self.flux))
        transit_model = \
            med * np.sum([depth * tm(self.time)
                          for tm, depth in zip(self.transit_model,
                                               self.transit_depth)], axis=0)
        gp = GP(self.kernel, self.kernel_params, white=False)
        gp.compute(self.apply_mask(self.time), self.apply_mask(self.fraw_err))
        y, _ = gp.predict(self.apply_mask(
            self.flux - transit_model) - med, self.time)
        if fold is not None:
            flux = (self.flux - y) / med
            ax.plot(self.apply_mask(time), self.apply_mask(flux),
                    ls='none', marker='.', color='k', markersize=ms, alpha=0.5)
            ax.plot(time[self.outmask], flux[self.outmask], ls='none',
                    marker='.', color='k', markersize=ms, alpha=0.5)
            ax.plot(time[self.transitmask], flux[self.transitmask],
                    ls='none', marker='.', color='k', markersize=ms, alpha=0.5)
            hires_time = np.linspace(-5 * dur, 5 * dur, 1000)
            hires_transit_model = 1 + \
                self.transit_depth[fold] * \
                self.transit_model[fold](hires_time + t0)
            ax.plot(hires_time, hires_transit_model, 'r-', lw=1, alpha=1)
        else:
            flux = self.flux
            y += med
            y += transit_model
            ax.plot(time, y, 'r-', lw=1, alpha=1)

        # Plot the bad data points
        bnmask = np.array(
            list(set(np.concatenate([self.badmask, self.nanmask]))), dtype=int)
        bmask = [i for i in self.badmask if i not in self.nanmask]
        ax.plot(time[bmask], flux[bmask], 'r.', markersize=ms, alpha=0.25)

        # Appearance
        ax.set_ylabel('EVEREST Flux', fontsize=18)
        ax.margins(0.01, 0.1)
        if fold is not None:
            ax.set_xlabel('Time From Transit Center (days)', fontsize=18)
            ax.set_xlim(-3 * dur, 3 * dur)
        else:
            ax.set_xlabel('Time (%s)' % self._mission.TIMEUNITS, fontsize=18)
            for brkpt in self.breakpoints[:-1]:
                ax.axvline(time[brkpt], color='r', ls='--', alpha=0.25)
            ax.get_yaxis().set_major_formatter(Formatter.Flux)

        # Get y lims that bound most of the flux
        if fold is not None:
            lo = np.min(hires_transit_model)
            pad = 1.5 * (1 - lo)
            ylim = (lo - pad, 1 + pad)
        else:
            f = np.delete(flux, bnmask)
            N = int(0.995 * len(f))
            hi, lo = f[np.argsort(f)][[N, -N]]
            pad = (hi - lo) * 0.1
            ylim = (lo - pad, hi + pad)
        ax.set_ylim(ylim)

        # Indicate off-axis outliers
        for i in np.where(flux < ylim[0])[0]:
            if i in bmask:
                color = "#ffcccc"
            else:
                color = "#ccccff"
            ax.annotate('', xy=(time[i], ylim[0]), xycoords='data',
                        xytext=(0, 15), textcoords='offset points',
                        arrowprops=dict(arrowstyle="-|>", color=color,
                        alpha=0.5))
        for i in np.where(flux > ylim[1])[0]:
            if i in bmask:
                color = "#ffcccc"
            else:
                color = "#ccccff"
            ax.annotate('', xy=(time[i], ylim[1]), xycoords='data',
                        xytext=(0, -15), textcoords='offset points',
                        arrowprops=dict(arrowstyle="-|>", color=color,
                        alpha=0.5))

        if show:
            pl.show()
            pl.close()
        else:
            return fig, ax


Instruction:
Write a Python 3 script to
interpolate certain elements in the array y and linearly interpolates over them returning an array y of the same length.

Response:
def Interpolate(time, mask, y):
    '''
    Masks certain elements in the array `y` and linearly
    interpolates over them, returning an array `y'` of the
    same length.

    :param array_like time: The time array
    :param array_like mask: The indices to be interpolated over
    :param array_like y: The dependent array

    '''

    # Ensure `y` doesn't get modified in place
    yy = np.array(y)
    t_ = np.delete(time, mask)
    y_ = np.delete(y, mask, axis=0)
    if len(yy.shape) == 1:
        yy[mask] = np.interp(time[mask], t_, y_)
    elif len(yy.shape) == 2:
        for n in range(yy.shape[1]):
            yy[mask, n] = np.interp(time[mask], t_, y_[:, n])
    else:
        raise Exception("Array ``y`` must be either 1- or 2-d.")
    return yy


Instruction:
Given the following Python 3 function, write the documentation
def Chunks(l, n, all=False):
    '''
    Returns a generator of consecutive `n`-sized chunks of list `l`.
    If `all` is `True`, returns **all** `n`-sized chunks in `l`
    by iterating over the starting point.

    '''

    if all:
        jarr = range(0, n - 1)
    else:
        jarr = [0]

    for j in jarr:
        for i in range(j, len(l), n):
            if i + 2 * n <= len(l):
                yield l[i:i + n]
            else:
                if not all:
                    yield l[i:]
                break

Response: Returns a generator of consecutive n - sized chunks of list l.


Instruction:
Given the following Python 3 function, write the documentation
def Smooth(x, window_len=100, window='hanning'):
    '''
    Smooth data by convolving on a given timescale.

    :param ndarray x: The data array
    :param int window_len: The size of the smoothing window. Default `100`
    :param str window: The window type. Default `hanning`

    '''

    if window_len == 0:
        return np.zeros_like(x)
    s = np.r_[2 * x[0] - x[window_len - 1::-1],
              x, 2 * x[-1] - x[-1:-window_len:-1]]
    if window == 'flat':
        w = np.ones(window_len, 'd')
    else:
        w = eval('np.' + window + '(window_len)')
    y = np.convolve(w / w.sum(), s, mode='same')
    return y[window_len:-window_len + 1]

Response: Smooth data by convolving on a given timescale.


Instruction:
Explain what the following Python 3 code does
def Scatter(y, win=13, remove_outliers=False):
    '''
    Return the scatter in ppm based on the median running standard deviation
    for a window size of :py:obj:`win` = 13 cadences (for K2, this
    is ~6.5 hours, as in VJ14).

    :param ndarray y: The array whose CDPP is to be computed
    :param int win: The window size in cadences. Default `13`
    :param bool remove_outliers: Clip outliers at 5 sigma before computing \
           the CDPP? Default `False`

    '''

    if remove_outliers:
        # Remove 5-sigma outliers from data
        # smoothed on a 1 day timescale
        if len(y) >= 50:
            ys = y - Smooth(y, 50)
        else:
            ys = y
        M = np.nanmedian(ys)
        MAD = 1.4826 * np.nanmedian(np.abs(ys - M))
        out = []
        for i, _ in enumerate(y):
            if (ys[i] > M + 5 * MAD) or (ys[i] < M - 5 * MAD):
                out.append(i)
        out = np.array(out, dtype=int)
        y = np.delete(y, out)
    if len(y):
        return 1.e6 * np.nanmedian([np.std(yi) / np.sqrt(win)
                                    for yi in Chunks(y, win, all=True)])
    else:
        return np.nan

Response: Computes the scatter in ppm based on the median running standard deviation of the series y.


Instruction:
Given the following Python 3 function, write the documentation
def SavGol(y, win=49):
    '''
    Subtracts a second order Savitsky-Golay filter with window size `win`
    and returns the result. This acts as a high pass filter.

    '''

    if len(y) >= win:
        return y - savgol_filter(y, win, 2) + np.nanmedian(y)
    else:
        return y

Response: Subtracts a second order Savitsky - Golay filter with window size win returns the result.


Instruction:
Write a Python 3 function that can
return the number of regressors for npix pixels and PLD order pld_order.

Response:
def NumRegressors(npix, pld_order, cross_terms=True):
    '''
    Return the number of regressors for `npix` pixels
    and PLD order `pld_order`.

    :param bool cross_terms: Include pixel cross-terms? Default :py:obj:`True`

    '''

    res = 0
    for k in range(1, pld_order + 1):
        if cross_terms:
            res += comb(npix + k - 1, k)
        else:
            res += npix
    return int(res)


Instruction:
Make a summary of the following Python 3 code
def Downbin(x, newsize, axis=0, operation='mean'):
    '''
    Downbins an array to a smaller size.

    :param array_like x: The array to down-bin
    :param int newsize: The new size of the axis along which to down-bin
    :param int axis: The axis to operate on. Default 0
    :param str operation: The operation to perform when down-binning. \
           Default `mean`
    '''

    assert newsize < x.shape[axis], \
        "The new size of the array must be smaller than the current size."
    oldsize = x.shape[axis]
    newshape = list(x.shape)
    newshape[axis] = newsize
    newshape.insert(axis + 1, oldsize // newsize)
    trim = oldsize % newsize
    if trim:
        xtrim = x[:-trim]
    else:
        xtrim = x

    if operation == 'mean':
        xbin = np.nanmean(xtrim.reshape(newshape), axis=axis + 1)
    elif operation == 'sum':
        xbin = np.nansum(xtrim.reshape(newshape), axis=axis + 1)
    elif operation == 'quadsum':
        xbin = np.sqrt(np.nansum(xtrim.reshape(newshape) ** 2, axis=axis + 1))
    elif operation == 'median':
        xbin = np.nanmedian(xtrim.reshape(newshape), axis=axis + 1)
    else:
        raise ValueError("`operation` must be either `mean`, " +
                         "`sum`, `quadsum`, or `median`.")

    return xbin

Response: Downbin an array - like x to a smaller size.


Instruction:
Can you tell what is the following Python 3 function doing
def register_with_model(self, name, model):
        '''Called during the creation of a the :class:`StdModel`
class when :class:`Metaclass` is initialised. It fills
:attr:`Field.name` and :attr:`Field.model`. This is an internal
function users should never call.'''
        if self.name:
            raise FieldError('Field %s is already registered\
 with a model' % self)
        self.name = name
        self.attname = self.get_attname()
        self.model = model
        meta = model._meta
        self.meta = meta
        meta.dfields[name] = self
        meta.fields.append(self)
        if not self.primary_key:
            self.add_to_fields()
        else:
            model._meta.pk = self

Response:
Called during the creation of a the Metaclass when the Metaclass is initialised. It fills
. name and
. model. This is an internal
function users should never call.


Instruction:
How would you implement a function in Python 3 that
adds this : class:`Field` to the fields of the model.

Response:
def add_to_fields(self):
        '''Add this :class:`Field` to the fields of :attr:`model`.'''
        meta = self.model._meta
        meta.scalarfields.append(self)
        if self.index:
            meta.indices.append(self)


Instruction:
Can you generate a brief explanation for the following Python 3 code
def get_lookup(self, remaining, errorClass=ValueError):
        '''called by the :class:`Query` method when it needs to build
lookup on fields with additional nested fields. This is the case of
:class:`ForeignKey` and :class:`JSONField`.

:param remaining: the :ref:`double underscored` fields if this :class:`Field`
:param errorClass: Optional exception class to use if the *remaining* field
    is not valid.'''
        if remaining:
            raise errorClass('Cannot use nested lookup on field %s' % self)
        return (self.attname, None)

Response:
called by the : class : Query method when it needs to build
lookup on fields with additional nested fields.


Instruction:
Make a summary of the following Python 3 code
def get_value(self, instance, *bits):
        '''Retrieve the value :class:`Field` from a :class:`StdModel`
``instance``.

:param instance: The :class:`StdModel` ``instance`` invoking this function.
:param bits: Additional information for nested fields which derives from
    the :ref:`double underscore <tutorial-underscore>` notation.
:return: the value of this :class:`Field` in the ``instance``. can raise
    :class:`AttributeError`.

This method is used by the :meth:`StdModel.get_attr_value` method when
retrieving values form a :class:`StdModel` instance.
'''
        if bits:
            raise AttributeError
        else:
            return getattr(instance, self.attname)

Response: Retrieve the value of this field from a : class:`StdModel instance.


Instruction:
How would you code a function in Python 3 to
set the value for this field in a instance.

Response:
def set_value(self, instance, value):
        '''Set the ``value`` for this :class:`Field` in a ``instance``
of a :class:`StdModel`.'''
        setattr(instance, self.attname, self.to_python(value))


Instruction:
Can you implement a function in Python 3 that
converts a list of delimiters to corresponding regular expressions

Response:
def delimiters_to_re(delimiters):
    """convert delimiters to corresponding regular expressions"""

    # caching
    delimiters = tuple(delimiters)
    if delimiters in re_delimiters:
        re_tag = re_delimiters[delimiters]
    else:
        open_tag, close_tag = delimiters

        # escape
        open_tag = ''.join([c if c.isalnum() else '\\' + c for c in open_tag])
        close_tag = ''.join([c if c.isalnum() else '\\' + c for c in close_tag])

        re_tag = re.compile(open_tag + r'([#^>&{/!=]?)\s*(.*?)\s*([}=]?)' + close_tag, re.DOTALL)
        re_delimiters[delimiters] = re_tag

    return re_tag


Instruction:
Can you create a Python 3 function that
checks if the string text [ start end ) is standalone by checking for backwards and blankspaces

Response:
def is_standalone(text, start, end):
    """check if the string text[start:end] is standalone by checking forwards
    and backwards for blankspaces
    :text: TODO
    :(start, end): TODO
    :returns: the start of next index after text[start:end]

    """
    left = False
    start -= 1
    while start >= 0 and text[start] in spaces_not_newline:
        start -= 1

    if start < 0 or text[start] == '\n':
        left = True

    right = re_space.match(text, end)
    return (start+1, right.end()) if left and right else None


Instruction:
Implement a Python 3 function for
compiling a template into a token tree.

Response:
def compiled(template, delimiters=DEFAULT_DELIMITERS):
    """Compile a template into token tree

    :template: TODO
    :delimiters: TODO
    :returns: the root token

    """
    re_tag = delimiters_to_re(delimiters)

    # variable to save states
    tokens = []
    index = 0
    sections = []
    tokens_stack = []

    # root token
    root = Root('root')
    root.filters = copy.copy(filters)

    m = re_tag.search(template, index)
    while m is not None:
        token = None
        last_literal = None
        strip_space = False

        if m.start() > index:
            last_literal = Literal('str', template[index:m.start()], root=root)
            tokens.append(last_literal)

        # parse token
        prefix, name, suffix = m.groups()

        if prefix == '=' and suffix == '=':
            # {{=| |=}} to change delimiters
            delimiters = re.split(r'\s+', name)
            if len(delimiters) != 2:
                raise SyntaxError('Invalid new delimiter definition: ' + m.group())
            re_tag = delimiters_to_re(delimiters)
            strip_space = True

        elif prefix == '{' and suffix == '}':
            # {{{ variable }}}
            token = Variable(name, name, root=root)

        elif prefix == '' and suffix == '':
            # {{ name }}
            token = Variable(name, name, root=root)
            token.escape = True

        elif suffix != '' and suffix != None:
            raise SyntaxError('Invalid token: ' + m.group())

        elif prefix == '&':
            # {{& escaped variable }}
            token = Variable(name, name, root=root)

        elif prefix == '!':
            # {{! comment }}
            token = Comment(name, root=root)
            if len(sections) <= 0:
                # considered as standalone only outside sections
                strip_space = True

        elif prefix == '>':
            # {{> partial}}
            token = Partial(name, name, root=root)
            strip_space = True

            pos = is_standalone(template, m.start(), m.end())
            if pos:
                token.indent = len(template[pos[0]:m.start()])

        elif prefix == '#' or prefix == '^':
            # {{# section }} or # {{^ inverted }}

            # strip filter
            sec_name = name.split('|')[0].strip()
            token = Section(sec_name, name, root=root) if prefix == '#' else Inverted(name, name, root=root)
            token.delimiter = delimiters
            tokens.append(token)

            # save the tokens onto stack
            token = None
            tokens_stack.append(tokens)
            tokens = []

            sections.append((sec_name, prefix, m.end()))
            strip_space = True

        elif prefix == '/':
            tag_name, sec_type, text_end = sections.pop()
            if tag_name != name:
                raise SyntaxError("unclosed tag: '" + tag_name + "' Got:" + m.group())

            children = tokens
            tokens = tokens_stack.pop()

            tokens[-1].text = template[text_end:m.start()]
            tokens[-1].children = children
            strip_space = True

        else:
            raise SyntaxError('Unknown tag: ' + m.group())

        if token is not None:
            tokens.append(token)

        index = m.end()
        if strip_space:
            pos = is_standalone(template, m.start(), m.end())
            if pos:
                index = pos[1]
                if last_literal: last_literal.value = last_literal.value.rstrip(spaces_not_newline)

        m = re_tag.search(template, index)

    tokens.append(Literal('str', template[index:]))
    root.children = tokens
    return root


Instruction:
Given the following Python 3 function, write the documentation
def _escape(self, text):
        ret = EMPTYSTRING if text is None else str(text)
        if self.escape:
            return html_escape(ret)
        else:
            return ret

Response: Escape text according to self. escape


Instruction:
Explain what the following Python 3 code does
def _lookup(self, dot_name, contexts):

        # process filters
        filters = [x for x in map(lambda x: x.strip(), dot_name.split('|'))]
        dot_name = filters[0]
        filters = filters[1:]

        # should support paths like '../../a.b.c/../d', etc.
        if not dot_name.startswith('.'):
            dot_name = './' + dot_name

        paths = dot_name.split('/')
        last_path = paths[-1]

        # path like '../..' or ./../. etc.
        refer_context = last_path == '' or last_path == '.' or last_path == '..'
        paths = paths if refer_context else paths[:-1]

        # count path level
        level = 0
        for path in paths:
            if path == '..':
                level -= 1
            elif path != '.':
                # ../a.b.c/.. in the middle
                level += len(path.strip('.').split('.'))

        names = last_path.split('.')

        # fetch the correct context
        if refer_context or names[0] == '':
            try:
                value = contexts[level-1]
            except:
                value = None
        else:
            # support {{a.b.c.d.e}} like lookup
            value = lookup(names[0], contexts, level)

        # lookup for variables
        if not refer_context:
            for name in names[1:]:
                try:
                    # a.num (a.1, a.2) to access list
                    index = parse_int(name)
                    name = parse_int(name) if isinstance(value, (list, tuple)) else name
                    value = value[name]
                except:
                    # not found
                    value = None
                    break;

        # apply filters
        for f in filters:
            try:
                func = self.root.filters[f]
                value = func(value)
            except:
                continue

        return value

Response: lookup value for names like a. b. c and handle filters as well


Instruction:
Create a Python 3 function to
render the children tokens

Response:
def _render_children(self, contexts, partials):
        """Render the children tokens"""
        ret = []
        for child in self.children:
            ret.append(child._render(contexts, partials))
        return EMPTYSTRING.join(ret)


Instruction:
Write a Python 3 script to
render section of the value

Response:
def _render(self, contexts, partials):
        """render section"""
        val = self._lookup(self.value, contexts)
        if not val:
            # false value
            return EMPTYSTRING

        # normally json has types: number/string/list/map
        # but python has more, so we decide that map and string should not iterate
        # by default, other do.
        if hasattr(val, "__iter__") and not isinstance(val, (str, dict)):
            # non-empty lists
            ret = []

            for item in val:
                contexts.append(item)
                ret.append(self._render_children(contexts, partials))
                contexts.pop()

            if len(ret) <= 0:
                # empty lists
                return EMPTYSTRING

            return self._escape(''.join(ret))
        elif callable(val):
            # lambdas
            new_template = val(self.text)
            value = inner_render(new_template, contexts, partials, self.delimiter)
        else:
            # context
            contexts.append(val)
            value = self._render_children(contexts, partials)
            contexts.pop()

        return self._escape(value)


Instruction:
Given the following Python 3 function, write the documentation
def Setup():
    '''
    Called when the code is installed. Sets up directories and downloads
    the K2 catalog.

    '''

    if not os.path.exists(os.path.join(EVEREST_DAT, 'k2', 'cbv')):
        os.makedirs(os.path.join(EVEREST_DAT, 'k2', 'cbv'))
    GetK2Stars(clobber=False)

Response:
Called when the code is installed. Sets up directories and downloads
    the K2 catalog.


Instruction:
Make a summary of the following Python 3 code
def CDPP(flux, mask=[], cadence='lc'):
    '''
    Compute the proxy 6-hr CDPP metric.

    :param array_like flux: The flux array to compute the CDPP for
    :param array_like mask: The indices to be masked
    :param str cadence: The light curve cadence. Default `lc`

    '''

    # 13 cadences is 6.5 hours
    rmswin = 13
    # Smooth the data on a 2 day timescale
    svgwin = 49

    # If short cadence, need to downbin
    if cadence == 'sc':
        newsize = len(flux) // 30
        flux = Downbin(flux, newsize, operation='mean')

    flux_savgol = SavGol(np.delete(flux, mask), win=svgwin)
    if len(flux_savgol):
        return Scatter(flux_savgol / np.nanmedian(flux_savgol),
                       remove_outliers=True, win=rmswin)
    else:
        return np.nan

Response: Compute the proxy 6 - hr CDPP metric.


Instruction:
Can you tell what is the following Python 3 function doing
def GetData(EPIC, season=None, cadence='lc', clobber=False, delete_raw=False,
            aperture_name='k2sff_15', saturated_aperture_name='k2sff_19',
            max_pixels=75, download_only=False, saturation_tolerance=-0.1,
            bad_bits=[1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13, 14, 16, 17],
            get_hires=True,
            get_nearby=True, **kwargs):
    '''
    Returns a :py:obj:`DataContainer` instance with the
    raw data for the target.

    :param int EPIC: The EPIC ID number
    :param int season: The observing season (campaign). Default :py:obj:`None`
    :param str cadence: The light curve cadence. Default `lc`
    :param bool clobber: Overwrite existing files? Default :py:obj:`False`
    :param bool delete_raw: Delete the FITS TPF after processing it? \
           Default :py:obj:`False`
    :param str aperture_name: The name of the aperture to use. Select \
           `custom` to call :py:func:`GetCustomAperture`. Default `k2sff_15`
    :param str saturated_aperture_name: The name of the aperture to use if \
           the target is saturated. Default `k2sff_19`
    :param int max_pixels: Maximum number of pixels in the TPF. Default 75
    :param bool download_only: Download raw TPF and return? Default \
           :py:obj:`False`
    :param float saturation_tolerance: Target is considered saturated \
           if flux is within this fraction of the pixel well depth. \
           Default -0.1
    :param array_like bad_bits: Flagged :py:obj`QUALITY` bits to consider \
           outliers when computing the model. \
           Default `[1,2,3,4,5,6,7,8,9,11,12,13,14,16,17]`
    :param bool get_hires: Download a high resolution image of the target? \
           Default :py:obj:`True`
    :param bool get_nearby: Retrieve location of nearby sources? \
           Default :py:obj:`True`

    '''

    # Campaign no.
    if season is None:
        campaign = Season(EPIC)
        if hasattr(campaign, '__len__'):
            raise AttributeError(
                "Please choose a campaign/season for this target: %s."
                % campaign)
    else:
        campaign = season

    # Is there short cadence data available for this target?
    short_cadence = HasShortCadence(EPIC, season=campaign)
    if cadence == 'sc' and not short_cadence:
        raise ValueError("Short cadence data not available for this target.")

    # Local file name
    filename = os.path.join(EVEREST_DAT, 'k2', 'c%02d' % campaign,
                            ('%09d' % EPIC)[:4] + '00000', ('%09d' % EPIC)[4:],
                            'data.npz')

    # Download?
    if clobber or not os.path.exists(filename):

        # Get the TPF
        tpf = os.path.join(KPLR_ROOT, 'data', 'k2', 'target_pixel_files',
                           str(EPIC), 'ktwo%09d-c%02d_lpd-targ.fits.gz'
                           % (EPIC, campaign))
        sc_tpf = os.path.join(KPLR_ROOT, 'data', 'k2', 'target_pixel_files',
                              str(EPIC), 'ktwo%09d-c%02d_spd-targ.fits.gz'
                              % (EPIC, campaign))
        if clobber or not os.path.exists(tpf):
            kplr_client.k2_star(EPIC).get_target_pixel_files(fetch=True)

        with pyfits.open(tpf) as f:
            qdata = f[1].data

            # Get the TPF aperture
            tpf_aperture = (f[2].data & 2) // 2

            # Get the enlarged TPF aperture
            tpf_big_aperture = np.array(tpf_aperture)
            for i in range(tpf_big_aperture.shape[0]):
                for j in range(tpf_big_aperture.shape[1]):
                    if f[2].data[i][j] == 1:
                        for n in [(i - 1, j), (i + 1, j),
                                  (i, j - 1), (i, j + 1)]:
                            if n[0] >= 0 and n[0] < tpf_big_aperture.shape[0]:
                                if n[1] >= 0 and n[1] < \
                                        tpf_big_aperture.shape[1]:
                                    if tpf_aperture[n[0]][n[1]] == 1:
                                        tpf_big_aperture[i][j] = 1

        # Is there short cadence data?
        if short_cadence:
            with pyfits.open(sc_tpf) as f:
                sc_qdata = f[1].data

        # Get K2SFF apertures
        try:
            k2sff = kplr.K2SFF(EPIC, sci_campaign=campaign)
            k2sff_apertures = k2sff.apertures
            if delete_raw:
                os.remove(k2sff._file)
        except:
            k2sff_apertures = [None for i in range(20)]

        # Make a dict of all our apertures
        # We're not getting K2SFF apertures 0-9 any more
        apertures = {'tpf': tpf_aperture, 'tpf_big': tpf_big_aperture}
        for i in range(10, 20):
            apertures.update({'k2sff_%02d' % i: k2sff_apertures[i]})

        # Get the header info
        fitsheader = [pyfits.getheader(tpf, 0).cards,
                      pyfits.getheader(tpf, 1).cards,
                      pyfits.getheader(tpf, 2).cards]
        if short_cadence:
            sc_fitsheader = [pyfits.getheader(sc_tpf, 0).cards,
                             pyfits.getheader(sc_tpf, 1).cards,
                             pyfits.getheader(sc_tpf, 2).cards]
        else:
            sc_fitsheader = None

        # Get a hi res image of the target
        if get_hires:
            hires = GetHiResImage(EPIC)
        else:
            hires = None

        # Get nearby sources
        if get_nearby:
            nearby = GetSources(EPIC)
        else:
            nearby = []

        # Delete?
        if delete_raw:
            os.remove(tpf)
            if short_cadence:
                os.remove(sc_tpf)

        # Get the arrays
        cadn = np.array(qdata.field('CADENCENO'), dtype='int32')
        time = np.array(qdata.field('TIME'), dtype='float64')
        fpix = np.array(qdata.field('FLUX'), dtype='float64')
        fpix_err = np.array(qdata.field('FLUX_ERR'), dtype='float64')
        qual = np.array(qdata.field('QUALITY'), dtype=int)

        # Get rid of NaNs in the time array by interpolating
        naninds = np.where(np.isnan(time))
        time = Interpolate(np.arange(0, len(time)), naninds, time)

        # Get the motion vectors (if available!)
        pc1 = np.array(qdata.field('POS_CORR1'), dtype='float64')
        pc2 = np.array(qdata.field('POS_CORR2'), dtype='float64')
        if not np.all(np.isnan(pc1)) and not np.all(np.isnan(pc2)):
            pc1 = Interpolate(time, np.where(np.isnan(pc1)), pc1)
            pc2 = Interpolate(time, np.where(np.isnan(pc2)), pc2)
        else:
            pc1 = None
            pc2 = None

        # Do the same for short cadence
        if short_cadence:
            sc_cadn = np.array(sc_qdata.field('CADENCENO'), dtype='int32')
            sc_time = np.array(sc_qdata.field('TIME'), dtype='float64')
            sc_fpix = np.array(sc_qdata.field('FLUX'), dtype='float64')
            sc_fpix_err = np.array(sc_qdata.field('FLUX_ERR'), dtype='float64')
            sc_qual = np.array(sc_qdata.field('QUALITY'), dtype=int)
            sc_naninds = np.where(np.isnan(sc_time))
            sc_time = Interpolate(
                np.arange(0, len(sc_time)), sc_naninds, sc_time)
            sc_pc1 = np.array(sc_qdata.field('POS_CORR1'), dtype='float64')
            sc_pc2 = np.array(sc_qdata.field('POS_CORR2'), dtype='float64')
            if not np.all(np.isnan(sc_pc1)) and not np.all(np.isnan(sc_pc2)):
                sc_pc1 = Interpolate(
                    sc_time, np.where(np.isnan(sc_pc1)), sc_pc1)
                sc_pc2 = Interpolate(
                    sc_time, np.where(np.isnan(sc_pc2)), sc_pc2)
            else:
                sc_pc1 = None
                sc_pc2 = None
        else:
            sc_cadn = None
            sc_time = None
            sc_fpix = None
            sc_fpix_err = None
            sc_qual = None
            sc_pc1 = None
            sc_pc2 = None

        # Static pixel images for plotting
        pixel_images = [fpix[0], fpix[len(fpix) // 2], fpix[len(fpix) - 1]]

        # Atomically write to disk.
        # http://stackoverflow.com/questions/2333872/
        # atomic-writing-to-file-with-python
        if not os.path.exists(os.path.dirname(filename)):
            os.makedirs(os.path.dirname(filename))
        f = NamedTemporaryFile("wb", delete=False)
        np.savez_compressed(f, cadn=cadn, time=time, fpix=fpix,
                            fpix_err=fpix_err,
                            qual=qual, apertures=apertures,
                            pc1=pc1, pc2=pc2, fitsheader=fitsheader,
                            pixel_images=pixel_images, nearby=nearby,
                            hires=hires,
                            sc_cadn=sc_cadn, sc_time=sc_time, sc_fpix=sc_fpix,
                            sc_fpix_err=sc_fpix_err, sc_qual=sc_qual,
                            sc_pc1=sc_pc1, sc_pc2=sc_pc2,
                            sc_fitsheader=sc_fitsheader)
        f.flush()
        os.fsync(f.fileno())
        f.close()
        shutil.move(f.name, filename)

        if download_only:
            return

    # Load
    data = np.load(filename)
    apertures = data['apertures'][()]
    pixel_images = data['pixel_images']
    nearby = data['nearby']
    hires = data['hires'][()]

    if cadence == 'lc':
        fitsheader = data['fitsheader']
        cadn = data['cadn']
        time = data['time']
        fpix = data['fpix']
        fpix_err = data['fpix_err']
        qual = data['qual']
        pc1 = data['pc1']
        pc2 = data['pc2']
    elif cadence == 'sc':
        fitsheader = data['sc_fitsheader']
        cadn = data['sc_cadn']
        time = data['sc_time']
        fpix = data['sc_fpix']
        fpix_err = data['sc_fpix_err']
        qual = data['sc_qual']
        pc1 = data['sc_pc1']
        pc2 = data['sc_pc2']
    else:
        raise ValueError("Invalid value for the cadence.")

    # Select the "saturated aperture" to check if the star is saturated
    # If it is, we will use this aperture instead
    if saturated_aperture_name == 'custom':
        saturated_aperture = GetCustomAperture(data)
    else:
        if saturated_aperture_name is None:
            saturated_aperture_name = 'k2sff_19'
        saturated_aperture = apertures[saturated_aperture_name]
        if saturated_aperture is None:
            log.error("Invalid aperture selected. Defaulting to `tpf_big`.")
            saturated_aperture_name = 'tpf_big'
            saturated_aperture = apertures[saturated_aperture_name]

    # HACK: Some C05 K2SFF apertures don't match the target pixel file
    # pixel grid size. This is likely because they're defined on the M67
    # superstamp. For now, let's ignore these stars.
    if saturated_aperture.shape != fpix.shape[1:]:
        log.error("Aperture size mismatch!")
        return None

    # Compute the saturation flux and the 97.5th percentile
    # flux in each pixel of the saturated aperture. We're going
    # to compare these to decide if the star is saturated.
    satflx = SaturationFlux(EPIC, campaign=campaign) * \
        (1. + saturation_tolerance)
    f97 = np.zeros((fpix.shape[1], fpix.shape[2]))
    for i in range(fpix.shape[1]):
        for j in range(fpix.shape[2]):
            if saturated_aperture[i, j]:
                # Let's remove NaNs...
                tmp = np.delete(fpix[:, i, j], np.where(
                    np.isnan(fpix[:, i, j])))
                # ... and really bad outliers...
                if len(tmp):
                    f = SavGol(tmp)
                    med = np.nanmedian(f)
                    MAD = 1.4826 * np.nanmedian(np.abs(f - med))
                    bad = np.where((f > med + 10. * MAD) |
                                   (f < med - 10. * MAD))[0]
                    np.delete(tmp, bad)
                    # ... so we can compute the 97.5th percentile flux
                    i97 = int(0.975 * len(tmp))
                    tmp = tmp[np.argsort(tmp)[i97]]
                    f97[i, j] = tmp

    # Check if any of the pixels are actually saturated
    if np.nanmax(f97) <= satflx:
        log.info("No saturated columns detected.")
        saturated = False
    else:
        log.info("Saturated pixel(s) found. Switching to aperture `%s`." %
                 saturated_aperture_name)
        aperture_name = saturated_aperture_name
        saturated = True

    # Now grab the aperture we'll actually use
    if aperture_name == 'custom':
        aperture = GetCustomAperture(data)
    else:
        if aperture_name is None:
            aperture_name = 'k2sff_15'
        aperture = apertures[aperture_name]
        if aperture is None:
            log.error("Invalid aperture selected. Defaulting to `tpf_big`.")
            aperture_name = 'tpf_big'
            aperture = apertures[aperture_name]

    # HACK: Some C05 K2SFF apertures don't match the target pixel file
    # pixel grid size. This is likely because they're defined on the M67
    # superstamp. For now, let's ignore these stars.
    if aperture.shape != fpix.shape[1:]:
        log.error("Aperture size mismatch!")
        return None

    # Now we check if the aperture is too big. Can lead to memory errors...
    # Treat saturated and unsaturated stars differently.
    if saturated:

        # Need to check if we have too many pixels *after* collapsing columns.
        # Sort the apertures in decreasing order of pixels, but keep the apert.
        # chosen by the user first.
        aperture_names = np.array(list(apertures.keys()))
        npix_per_aperture = np.array(
            [np.sum(apertures[k]) for k in aperture_names])
        aperture_names = aperture_names[np.argsort(npix_per_aperture)[::-1]]
        aperture_names = np.append([aperture_name], np.delete(
            aperture_names, np.argmax(aperture_names == aperture_name)))

        # Loop through them. Pick the first one that satisfies
        # the `max_pixels` constraint
        for aperture_name in aperture_names:
            aperture = apertures[aperture_name]
            aperture[np.isnan(fpix[0])] = 0
            ncol = 0
            apcopy = np.array(aperture)
            for j in range(apcopy.shape[1]):
                if np.any(f97[:, j] > satflx):
                    apcopy[:, j] = 0
                    ncol += 1
            if np.sum(apcopy) + ncol <= max_pixels:
                break
        if np.sum(apcopy) + ncol > max_pixels:
            log.error(
                "No apertures available with fewer than %d pixels. Aborting."
                % max_pixels)
            return None

        # Now, finally, we collapse the saturated columns into single pixels
        # and make the pixel array 2D
        ncol = 0
        fpixnew = []
        ferrnew = []

        # HACK: K2SFF sometimes clips the heads/tails of saturated columns
        # That's really bad, since that's where all the information is. Let's
        # artificially extend the aperture by two pixels at the top and bottom
        # of each saturated column. This *could* increase contamination, but
        # it's unlikely since the saturated target is by definition really
        # bright
        ext = 0
        for j in range(aperture.shape[1]):
            if np.any(f97[:, j] > satflx):
                for i in range(aperture.shape[0]):
                    if (aperture[i, j] == 0) and \
                            (np.nanmedian(fpix[:, i, j]) > 0):
                        if (i + 2 < aperture.shape[0]) and \
                                aperture[i + 2, j] == 1:
                            aperture[i, j] = 2
                            ext += 1
                        elif (i + 1 < aperture.shape[0]) and \
                                aperture[i + 1, j] == 1:
                            aperture[i, j] = 2
                            ext += 1
                        elif (i - 1 >= 0) and aperture[i - 1, j] == 1:
                            aperture[i, j] = 2
                            ext += 1
                        elif (i - 2 >= 0) and aperture[i - 2, j] == 1:
                            aperture[i, j] = 2
                            ext += 1
        if ext:
            log.info("Extended saturated columns by %d pixel(s)." % ext)

        for j in range(aperture.shape[1]):
            if np.any(f97[:, j] > satflx):
                marked = False
                collapsed = np.zeros(len(fpix[:, 0, 0]))
                collapsed_err2 = np.zeros(len(fpix[:, 0, 0]))
                for i in range(aperture.shape[0]):
                    if aperture[i, j]:
                        if not marked:
                            aperture[i, j] = AP_COLLAPSED_PIXEL
                            marked = True
                        else:
                            aperture[i, j] = AP_SATURATED_PIXEL
                        collapsed += fpix[:, i, j]
                        collapsed_err2 += fpix_err[:, i, j] ** 2
                if np.any(collapsed):
                    fpixnew.append(collapsed)
                    ferrnew.append(np.sqrt(collapsed_err2))
                    ncol += 1
            else:
                for i in range(aperture.shape[0]):
                    if aperture[i, j]:
                        fpixnew.append(fpix[:, i, j])
                        ferrnew.append(fpix_err[:, i, j])
        fpix2D = np.array(fpixnew).T
        fpix_err2D = np.array(ferrnew).T
        log.info("Collapsed %d saturated column(s)." % ncol)

    else:

        # Check if there are too many pixels
        if np.sum(aperture) > max_pixels:

            # This case is simpler: we just pick the largest aperture
            # that's less than or equal to `max_pixels`
            keys = list(apertures.keys())
            npix = np.array([np.sum(apertures[k]) for k in keys])
            aperture_name = keys[np.argmax(npix * (npix <= max_pixels))]
            aperture = apertures[aperture_name]
            aperture[np.isnan(fpix[0])] = 0
            if np.sum(aperture) > max_pixels:
                log.error("No apertures available with fewer than " +
                          "%d pixels. Aborting." % max_pixels)
                return None
            log.warn(
                "Selected aperture is too big. Proceeding with aperture " +
                "`%s` instead." % aperture_name)

        # Make the pixel flux array 2D
        aperture[np.isnan(fpix[0])] = 0
        ap = np.where(aperture & 1)
        fpix2D = np.array([f[ap] for f in fpix], dtype='float64')
        fpix_err2D = np.array([p[ap] for p in fpix_err], dtype='float64')

    # Compute the background
    binds = np.where(aperture ^ 1)
    if RemoveBackground(EPIC, campaign=campaign) and (len(binds[0]) > 0):
        bkg = np.nanmedian(np.array([f[binds]
                                     for f in fpix], dtype='float64'), axis=1)
        # Uncertainty of the median:
        # http://davidmlane.com/hyperstat/A106993.html
        bkg_err = 1.253 * np.nanmedian(np.array([e[binds] for e in fpix_err],
                                       dtype='float64'), axis=1) \
            / np.sqrt(len(binds[0]))
        bkg = bkg.reshape(-1, 1)
        bkg_err = bkg_err.reshape(-1, 1)
    else:
        bkg = 0.
        bkg_err = 0.

    # Make everything 2D and remove the background
    fpix = fpix2D - bkg
    fpix_err = np.sqrt(fpix_err2D ** 2 + bkg_err ** 2)
    flux = np.sum(fpix, axis=1)
    ferr = np.sqrt(np.sum(fpix_err ** 2, axis=1))

    # Get NaN data points
    nanmask = np.where(np.isnan(flux) | (flux == 0))[0]

    # Get flagged data points -- we won't train our model on them
    badmask = []
    for b in bad_bits:
        badmask += list(np.where(qual & 2 ** (b - 1))[0])

    # Flag >10 sigma outliers -- same thing.
    tmpmask = np.array(list(set(np.concatenate([badmask, nanmask]))))
    t = np.delete(time, tmpmask)
    f = np.delete(flux, tmpmask)
    f = SavGol(f)
    med = np.nanmedian(f)
    MAD = 1.4826 * np.nanmedian(np.abs(f - med))
    bad = np.where((f > med + 10. * MAD) | (f < med - 10. * MAD))[0]
    badmask.extend([np.argmax(time == t[i]) for i in bad])

    # Campaign 2 hack: the first day or two are screwed up
    if campaign == 2:
        badmask.extend(np.where(time < 2061.5)[0])

    # TODO: Fix time offsets in first half of
    # Campaign 0. See note in everest 1.0 code

    # Finalize the mask
    badmask = np.array(sorted(list(set(badmask))))

    # Interpolate the nans
    fpix = Interpolate(time, nanmask, fpix)
    fpix_err = Interpolate(time, nanmask, fpix_err)

    # Return
    data = DataContainer()
    data.ID = EPIC
    data.campaign = campaign
    data.cadn = cadn
    data.time = time
    data.fpix = fpix
    data.fpix_err = fpix_err
    data.nanmask = nanmask
    data.badmask = badmask
    data.aperture = aperture
    data.aperture_name = aperture_name
    data.apertures = apertures
    data.quality = qual
    data.Xpos = pc1
    data.Ypos = pc2
    data.meta = fitsheader
    data.mag = fitsheader[0]['KEPMAG'][1]
    data.pixel_images = pixel_images
    data.nearby = nearby
    data.hires = hires
    data.saturated = saturated
    data.bkg = bkg

    return data

Response: Retrieves the raw data for a given aperture.


Instruction:
Write a Python 3 function that can
return neighbors random bright stars on the same module as the EPIC.

Response:
def GetNeighbors(EPIC, season=None, model=None, neighbors=10,
                 mag_range=(11., 13.),
                 cdpp_range=None, aperture_name='k2sff_15',
                 cadence='lc', **kwargs):
    '''
    Return `neighbors` random bright stars on the same module as `EPIC`.

    :param int EPIC: The EPIC ID number
    :param str model: The :py:obj:`everest` model name. Only used when \
           imposing CDPP bounds. Default :py:obj:`None`
    :param int neighbors: Number of neighbors to return. Default 10
    :param str aperture_name: The name of the aperture to use. Select \
           `custom` to call \
           :py:func:`GetCustomAperture`. Default `k2sff_15`
    :param str cadence: The light curve cadence. Default `lc`
    :param tuple mag_range: (`low`, `high`) values for the Kepler magnitude. \
           Default (11, 13)
    :param tuple cdpp_range: (`low`, `high`) values for the de-trended CDPP. \
           Default :py:obj:`None`

    '''

    # Zero neighbors?
    if neighbors == 0:
        return []

    # Get the IDs
    # Campaign no.
    if season is None:
        campaign = Season(EPIC)
        if hasattr(campaign, '__len__'):
            raise AttributeError(
                "Please choose a campaign/season for this target: %s."
                % campaign)
    else:
        campaign = season
    epics, kepmags, channels, short_cadence = np.array(GetK2Stars()[
                                                       campaign]).T
    short_cadence = np.array(short_cadence, dtype=bool)
    epics = np.array(epics, dtype=int)
    c = GetNeighboringChannels(Channel(EPIC, campaign=season))

    # Manage kwargs
    if aperture_name is None:
        aperture_name = 'k2sff_15'
    if mag_range is None:
        mag_lo = -np.inf
        mag_hi = np.inf
    else:
        mag_lo = mag_range[0]
        mag_hi = mag_range[1]
        # K2-specific tweak. The short cadence stars are preferentially
        # really bright ones, so we won't get many neighbors if we
        # stick to the default magnitude range! I'm
        # therefore enforcing a lower magnitude cut-off of 8.
        if cadence == 'sc':
            mag_lo = 8.
    if cdpp_range is None:
        cdpp_lo = -np.inf
        cdpp_hi = np.inf
    else:
        cdpp_lo = cdpp_range[0]
        cdpp_hi = cdpp_range[1]
    targets = []

    # First look for nearby targets, then relax the constraint
    # If still no targets, widen magnitude range
    for n in range(3):

        if n == 0:
            nearby = True
        elif n == 1:
            nearby = False
        elif n == 2:
            mag_lo -= 1
            mag_hi += 1

        # Loop over all stars
        for star, kp, channel, sc in zip(epics, kepmags, channels, short_cadence):

            # Preliminary vetting
            if not (((channel in c) if nearby else True) and (kp < mag_hi) \
                    and (kp > mag_lo) and (sc if cadence == 'sc' else True)):
                continue

            # Reject if self or if already in list
            if (star == EPIC) or (star in targets):
                continue

            # Ensure raw light curve file exists
            if not os.path.exists(
                    os.path.join(TargetDirectory(star, campaign), 'data.npz')):
                continue

            # Ensure crowding is OK. This is quite conservative, as we
            # need to prevent potential astrophysical false positive
            # contamination from crowded planet-hosting neighbors when
            # doing neighboring PLD.
            contam = False
            data = np.load(os.path.join(
                TargetDirectory(star, campaign), 'data.npz'))
            aperture = data['apertures'][()][aperture_name]

            # Check that the aperture exists!
            if aperture is None:
                continue

            fpix = data['fpix']
            for source in data['nearby'][()]:
                # Ignore self
                if source['ID'] == star:
                    continue
                # Ignore really dim stars
                if source['mag'] < kp - 5:
                    continue
                # Compute source position
                x = int(np.round(source['x'] - source['x0']))
                y = int(np.round(source['y'] - source['y0']))
                # If the source is within two pixels of the edge
                # of the target aperture, reject the target
                for j in [x - 2, x - 1, x, x + 1, x + 2]:
                    if j < 0:
                        # Outside the postage stamp
                        continue
                    for i in [y - 2, y - 1, y, y + 1, y + 2]:
                        if i < 0:
                            # Outside the postage stamp
                            continue
                        try:
                            if aperture[i][j]:
                                # Oh-oh!
                                contam = True
                        except IndexError:
                            # Out of bounds... carry on!
                            pass
            if contam:
                continue

            # HACK: This happens for K2SFF M67 targets in C05.
            # Let's skip them
            if aperture.shape != fpix.shape[1:]:
                continue

            # Reject if the model is not present
            if model is not None:
                if not os.path.exists(os.path.join(
                        TargetDirectory(star, campaign), model + '.npz')):
                    continue

                # Reject if CDPP out of range
                if cdpp_range is not None:
                    cdpp = np.load(os.path.join(TargetDirectory(
                        star, campaign), model + '.npz'))['cdpp']
                    if (cdpp > cdpp_hi) or (cdpp < cdpp_lo):
                        continue

            # Passed all the tests!
            targets.append(star)

            # Do we have enough? If so, return
            if len(targets) == neighbors:
                random.shuffle(targets)
                return targets

    # If we get to this point, we didn't find enough neighbors...
    # Return what we have anyway.
    return targets


Instruction:
Write a Python 3 script for
computing and plot the CDPP statistics between model and compare_to for all known K2 planets.

Response:
def PlanetStatistics(model='nPLD', compare_to='k2sff', **kwargs):
    '''
    Computes and plots the CDPP statistics comparison between `model` and
    `compare_to` for all known K2 planets.

    :param str model: The :py:obj:`everest` model name
    :param str compare_to: The :py:obj:`everest` model name or \
           other K2 pipeline name

    '''

    # Load all planet hosts
    f = os.path.join(EVEREST_SRC, 'missions', 'k2', 'tables', 'planets.tsv')
    epic, campaign, kp, _, _, _, _, _, _ = np.loadtxt(
        f, unpack=True, skiprows=2)
    epic = np.array(epic, dtype=int)
    campaign = np.array(campaign, dtype=int)
    cdpp = np.zeros(len(epic))
    saturated = np.zeros(len(epic), dtype=int)
    cdpp_1 = np.zeros(len(epic))

    # Get the stats
    for c in set(campaign):

        # Everest model
        f = os.path.join(EVEREST_SRC, 'missions', 'k2',
                         'tables', 'c%02d_%s.cdpp' % (int(c), model))
        e0, _, _, c0, _, _, _, _, s0 = np.loadtxt(f, unpack=True, skiprows=2)
        for i, e in enumerate(epic):
            if e in e0:
                j = np.argmax(e0 == e)
                cdpp[i] = c0[j]
                saturated[i] = s0[j]

        # Comparison model
        f = os.path.join(EVEREST_SRC, 'missions', 'k2', 'tables',
                         'c%02d_%s.cdpp' % (int(c), compare_to.lower()))
        if not os.path.exists(f):
            continue
        if compare_to.lower() in ['everest1', 'k2sff', 'k2sc']:
            e1, c1 = np.loadtxt(f, unpack=True, skiprows=2)
        else:
            e1, _, _, c1, _, _, _, _, _ = np.loadtxt(
                f, unpack=True, skiprows=2)
        for i, e in enumerate(epic):
            if e in e1:
                j = np.argmax(e1 == e)
                cdpp_1[i] = c1[j]

    sat = np.where(saturated == 1)
    unsat = np.where(saturated == 0)

    # Plot the equivalent of the Aigrain+16 figure
    fig, ax = pl.subplots(1)
    fig.canvas.set_window_title(
        'K2 Planet Hosts: %s versus %s' % (model, compare_to))
    x = kp
    y = (cdpp - cdpp_1) / cdpp_1
    ax.scatter(x[unsat], y[unsat], color='b', marker='.',
               alpha=0.5, zorder=-1, picker=True)
    ax.scatter(x[sat], y[sat], color='r', marker='.',
               alpha=0.5, zorder=-1, picker=True)
    ax.set_ylim(-1, 1)
    ax.set_xlim(8, 18)
    ax.axhline(0, color='gray', lw=2, zorder=-99, alpha=0.5)
    ax.axhline(0.5, color='gray', ls='--', lw=2, zorder=-99, alpha=0.5)
    ax.axhline(-0.5, color='gray', ls='--', lw=2, zorder=-99, alpha=0.5)
    ax.set_title(r'K2 Planet Hosts', fontsize=18)
    ax.set_ylabel(r'Relative CDPP', fontsize=18)
    ax.set_xlabel('Kepler Magnitude', fontsize=18)

    # Pickable points
    Picker = StatsPicker([ax], [kp], [y], epic,
                         model=model, compare_to=compare_to)
    fig.canvas.mpl_connect('pick_event', Picker)

    # Show
    pl.show()


Instruction:
Can you tell what is the following Python 3 function doing
def ShortCadenceStatistics(campaign=None, clobber=False, model='nPLD',
                           plot=True, **kwargs):
    '''
    Computes and plots the CDPP statistics comparison between short cadence
    and long cadence de-trended light curves

    :param campaign: The campaign number or list of campaign numbers. \
           Default is to plot all campaigns
    :param bool clobber: Overwrite existing files? Default :py:obj:`False`
    :param str model: The :py:obj:`everest` model name
    :param bool plot: Default :py:obj:`True`

    '''

    # Check campaign
    if campaign is None:
        campaign = np.arange(9)
    else:
        campaign = np.atleast_1d(campaign)

    # Update model name
    model = '%s.sc' % model

    # Compute the statistics
    for camp in campaign:
        sub = np.array(GetK2Campaign(
            camp, cadence='sc', epics_only=True), dtype=int)
        outfile = os.path.join(EVEREST_SRC, 'missions', 'k2',
                               'tables', 'c%02d_%s.cdpp' % (int(camp), model))
        if clobber or not os.path.exists(outfile):
            with open(outfile, 'w') as f:
                print("EPIC               Kp           Raw CDPP     " +
                      "Everest CDPP      Saturated", file=f)
                print("---------          ------       ---------    " +
                      "------------      ---------", file=f)
                all = GetK2Campaign(int(camp), cadence='sc')
                stars = np.array([s[0] for s in all], dtype=int)
                kpmgs = np.array([s[1] for s in all], dtype=float)
                for i, _ in enumerate(stars):
                    sys.stdout.write(
                        '\rProcessing target %d/%d...' % (i + 1, len(stars)))
                    sys.stdout.flush()
                    nf = os.path.join(EVEREST_DAT, 'k2', 'c%02d' % camp,
                                      ('%09d' % stars[i])[:4] + '00000',
                                      ('%09d' % stars[i])[4:], model + '.npz')
                    try:
                        data = np.load(nf)
                        print("{:>09d} {:>15.3f} {:>15.3f} {:>15.3f} {:>15d}".format(
                              stars[i], kpmgs[i], data['cdppr'][()], data['cdpp'][()],
                              int(data['saturated'])), file=f)
                    except:
                        print("{:>09d} {:>15.3f} {:>15.3f} {:>15.3f} {:>15d}".format(
                            stars[i], kpmgs[i], np.nan, np.nan, 0), file=f)
                print("")

    if not plot:
        return

    # Running lists
    xsat = []
    ysat = []
    xunsat = []
    yunsat = []
    xall = []
    yall = []
    epics = []

    # Plot
    for camp in campaign:

        # Load all stars
        sub = np.array(GetK2Campaign(
            camp, cadence='sc', epics_only=True), dtype=int)
        outfile = os.path.join(EVEREST_SRC, 'missions', 'k2',
                               'tables', 'c%02d_%s.cdpp' % (int(camp), model))
        epic, kp, cdpp6r, cdpp6, saturated = np.loadtxt(
            outfile, unpack=True, skiprows=2)
        epic = np.array(epic, dtype=int)
        saturated = np.array(saturated, dtype=int)

        # Get only stars in this subcamp
        inds = np.array([e in sub for e in epic])
        epic = epic[inds]
        kp = kp[inds]
        # HACK: camp 0 magnitudes are reported only to the nearest tenth,
        # so let's add a little noise to spread them out for nicer plotting
        kp = kp + 0.1 * (0.5 - np.random.random(len(kp)))
        cdpp6r = cdpp6r[inds]
        cdpp6 = cdpp6[inds]
        saturated = saturated[inds]
        sat = np.where(saturated == 1)
        unsat = np.where(saturated == 0)
        if not np.any([not np.isnan(x) for x in cdpp6]):
            continue

        # Get the long cadence stats
        compfile = os.path.join(EVEREST_SRC, 'missions', 'k2',
                                'tables', 'c%02d_%s.cdpp' % (int(camp),
                                                             model[:-3]))
        epic_1, _, _, cdpp6_1, _, _, _, _, saturated = np.loadtxt(
            compfile, unpack=True, skiprows=2)
        epic_1 = np.array(epic_1, dtype=int)
        inds = np.array([e in sub for e in epic_1])
        epic_1 = epic_1[inds]
        cdpp6_1 = cdpp6_1[inds]
        cdpp6_1 = sort_like(cdpp6_1, epic, epic_1)
        x = kp
        y = (cdpp6 - cdpp6_1) / cdpp6_1

        # Append to running lists
        xsat.extend(x[sat])
        ysat.extend(y[sat])
        xunsat.extend(x[unsat])
        yunsat.extend(y[unsat])
        xall.extend(x)
        yall.extend(y)
        epics.extend(epic)

    # Plot the equivalent of the Aigrain+16 figure
    fig, ax = pl.subplots(1)
    fig.canvas.set_window_title('K2 Short Cadence')

    ax.scatter(xunsat, yunsat, color='b', marker='.',
               alpha=0.35, zorder=-1, picker=True)
    ax.scatter(xsat, ysat, color='r', marker='.',
               alpha=0.35, zorder=-1, picker=True)
    ax.set_ylim(-1, 1)
    ax.set_xlim(8, 18)
    ax.axhline(0, color='gray', lw=2, zorder=-99, alpha=0.5)
    ax.axhline(0.5, color='gray', ls='--', lw=2, zorder=-99, alpha=0.5)
    ax.axhline(-0.5, color='gray', ls='--', lw=2, zorder=-99, alpha=0.5)
    ax.set_title(r'Short Versus Long Cadence', fontsize=18)
    ax.set_ylabel(r'Relative CDPP', fontsize=18)
    ax.set_xlabel('Kepler Magnitude', fontsize=18)

    # Bin the CDPP
    yall = np.array(yall)
    xall = np.array(xall)
    bins = np.arange(7.5, 18.5, 0.5)
    by = np.zeros_like(bins) * np.nan
    for b, bin in enumerate(bins):
        i = np.where((yall > -np.inf) & (yall < np.inf) &
                     (xall >= bin - 0.5) & (xall < bin + 0.5))[0]
        if len(i) > 10:
            by[b] = np.median(yall[i])
    ax.plot(bins[:9], by[:9], 'r--', lw=2)
    ax.plot(bins[8:], by[8:], 'k-', lw=2)

    # Pickable points
    Picker = StatsPicker([ax], [xall], [yall], epics, model=model[:-3],
                         compare_to=model[:-3], cadence='sc',
                         campaign=campaign)
    fig.canvas.mpl_connect('pick_event', Picker)

    # Show
    pl.show()

Response: Compute the CDPP statistics between short cadence and long cadence de - trended light curves.