Instruction:
Write a Python 3 script to
submit a cluster job to compute and plot data for all targets in a given campaign. :param campaign: The K2 campaign number. If this is an :py:class:`int`, \ returns all targets in that campaign. If a :py:class:`float` \ in the form `X.Y`, runs the `Y^th` decile of campaign `X`. :param str queue: The queue to submit to. Default `None` (default queue) :param str email: The email to send job status notifications to. \ Default `None` :param int walltime: The number of hours to request. Default `100` :param int nodes: The number of nodes to request. Default `5` :param int ppn: The number of processors per node to request. Default `12` :param int mpn: Memory per node in gb to request. Default no setting.

Response:
def Run(campaign=0, EPIC=None, nodes=5, ppn=12, walltime=100,
        mpn=None, email=None, queue=None, **kwargs):
    '''
    Submits a cluster job to compute and plot data for all targets
    in a given campaign.

    :param campaign: The K2 campaign number. If this is an :py:class:`int`, \
           returns all targets in that campaign. If a :py:class:`float` \
           in the form `X.Y`, runs the `Y^th` decile of campaign `X`.
    :param str queue: The queue to submit to. Default `None` (default queue)
    :param str email: The email to send job status notifications to. \
           Default `None`
    :param int walltime: The number of hours to request. Default `100`
    :param int nodes: The number of nodes to request. Default `5`
    :param int ppn: The number of processors per node to request. Default `12`
    :param int mpn: Memory per node in gb to request. Default no setting.

    '''

    # Figure out the subcampaign
    if type(campaign) is int:
        subcampaign = -1
    elif type(campaign) is float:
        x, y = divmod(campaign, 1)
        campaign = int(x)
        subcampaign = round(y * 10)

    # DEV hack: limit backfill jobs to 10 hours
    if EVEREST_DEV and (queue == 'bf'):
        walltime = min(10, walltime)

    # Convert kwargs to string. This is really hacky. Pickle creates an array
    # of bytes, which we must convert into a regular string to pass to the pbs
    # script and then back into python. Decoding the bytes isn't enough, since
    # we have pesky escaped characters such as newlines that don't behave well
    # when passing this string around. My braindead hack is to replace newlines
    # with '%%%', then undo the replacement when reading the kwargs. This works
    # for most cases, but sometimes pickle creates a byte array that can't be
    # decoded into utf-8; this happens when trying to pass numpy arrays around,
    # for instance. This needs to be fixed in the future, but for now we'll
    # restrict the kwargs to be ints, floats, lists, and strings.
    try:
        strkwargs = pickle.dumps(kwargs, 0).decode(
            'utf-8').replace('\n', '%%%')
    except UnicodeDecodeError:
        raise ValueError('Unable to pickle `kwargs`. Currently the `kwargs` ' +
                         'values may only be `int`s, `float`s, `string`s, ' +
                         '`bool`s, or lists of these.')

    # Submit the cluster job
    pbsfile = os.path.join(EVEREST_SRC, 'missions', 'k2', 'run.pbs')
    if mpn is not None:
        str_n = 'nodes=%d:ppn=%d,feature=%dcore,mem=%dgb' % (
            nodes, ppn, ppn, mpn * nodes)
    else:
        str_n = 'nodes=%d:ppn=%d,feature=%dcore' % (nodes, ppn, ppn)
    str_w = 'walltime=%d:00:00' % walltime
    str_v = "EVEREST_DAT=%s,NODES=%d," % (EVEREST_DAT, nodes) + \
            "EPIC=%d," % (0 if EPIC is None else EPIC) + \
            "CAMPAIGN=%d,SUBCAMPAIGN=%d,STRKWARGS='%s'" % \
            (campaign, subcampaign, strkwargs)

    if EPIC is None:
        if subcampaign == -1:
            str_name = 'c%02d' % campaign
        else:
            str_name = 'c%02d.%d' % (campaign, subcampaign)
    else:
        str_name = 'EPIC%d' % EPIC
    str_out = os.path.join(EVEREST_DAT, 'k2', str_name + '.log')
    qsub_args = ['qsub', pbsfile,
                 '-v', str_v,
                 '-o', str_out,
                 '-j', 'oe',
                 '-N', str_name,
                 '-l', str_n,
                 '-l', str_w]
    if email is not None:
        qsub_args.append(['-M', email, '-m', 'ae'])
    if queue is not None:
        qsub_args += ['-q', queue]

    # Now we submit the job
    print("Submitting the job...")
    subprocess.call(qsub_args)


Instruction:
Here you have a function in Python 3, explain what it does
def _Publish(campaign, subcampaign, strkwargs):
    '''
    The actual function that publishes a given campaign; this must
    be called from ``missions/k2/publish.pbs``.

    '''

    # Get kwargs from string
    kwargs = pickle.loads(strkwargs.replace('%%%', '\n').encode('utf-8'))

    # Check the cadence
    cadence = kwargs.get('cadence', 'lc')

    # Model wrapper
    m = FunctionWrapper(EverestModel, season=campaign, publish=True, **kwargs)

    # Set up our custom exception handler
    sys.excepthook = ExceptionHook

    # Initialize our multiprocessing pool
    with Pool() as pool:
        # Are we doing a subcampaign?
        if subcampaign != -1:
            campaign = campaign + 0.1 * subcampaign
        # Get all the stars
        stars = GetK2Campaign(campaign, epics_only=True, cadence=cadence)

        # Run
        pool.map(m, stars)

Response:
The actual function that publishes a given campaign. This must
    be called from the Mission. pbs file.


Instruction:
Make a summary of the following Python 3 code
def Status(season=range(18), model='nPLD', purge=False, injection=False,
           cadence='lc', **kwargs):
    '''
    Shows the progress of the de-trending runs for the specified campaign(s).

    '''

    # Mission compatibility
    campaign = season

    # Injection?
    if injection:
        return InjectionStatus(campaign=campaign, model=model,
                               purge=purge, **kwargs)

    # Cadence
    if cadence == 'sc':
        model = '%s.sc' % model

    if not hasattr(campaign, '__len__'):
        if type(campaign) is int:
            # Return the subcampaigns
            all_stars = [s for s in GetK2Campaign(
                campaign, split=True, epics_only=True, cadence=cadence)]
            campaign = [campaign + 0.1 * n for n in range(10)]
        else:
            all_stars = [[s for s in GetK2Campaign(
                campaign, epics_only=True, cadence=cadence)]]
            campaign = [campaign]
    else:
        all_stars = [[s for s in GetK2Campaign(
            c, epics_only=True, cadence=cadence)] for c in campaign]

    print("CAMP      TOTAL      DOWNLOADED    PROCESSED      FITS    ERRORS")
    print("----      -----      ----------    ---------      ----    ------")
    for c, stars in zip(campaign, all_stars):
        if len(stars) == 0:
            continue
        down = 0
        proc = 0
        err = 0
        fits = 0
        bad = []
        remain = []
        total = len(stars)
        if os.path.exists(os.path.join(EVEREST_DAT, 'k2', 'c%02d' % c)):
            path = os.path.join(EVEREST_DAT, 'k2', 'c%02d' % c)
            for folder in [f for f in os.listdir(path) if f.endswith('00000')]:
                for subfolder in os.listdir(os.path.join(path, folder)):
                    ID = int(folder[:4] + subfolder)
                    if ID in stars:
                        if os.path.exists(os.path.join(EVEREST_DAT,
                                                       'k2', 'c%02d' % c,
                                                       folder,
                                                       subfolder, 'data.npz')):
                            down += 1
                        if os.path.exists(os.path.join(EVEREST_DAT, 'k2',
                                                       'c%02d' % c, folder,
                                                       subfolder, FITSFile(
                                                         ID, c,
                                                         cadence=cadence))):
                            fits += 1
                        if os.path.exists(os.path.join(EVEREST_DAT, 'k2',
                                                       'c%02d' % c, folder,
                                                       subfolder,
                                                       model + '.npz')):
                            proc += 1
                        elif os.path.exists(os.path.join(EVEREST_DAT, 'k2',
                                                         'c%02d' % c, folder,
                                                         subfolder,
                                                         model + '.err')):
                            err += 1
                            bad.append(folder[:4] + subfolder)
                            if purge:
                                os.remove(os.path.join(
                                    EVEREST_DAT, 'k2', 'c%02d' % c,
                                    folder, subfolder, model + '.err'))
                        else:
                            remain.append(folder[:4] + subfolder)
        if proc == total:
            cc = ct = cp = ce = GREEN
            cd = BLACK if down < total else GREEN
        else:
            cc = BLACK
            ct = BLACK
            cd = BLACK if down < total else BLUE
            cp = BLACK if proc < down or proc == 0 else BLUE
            ce = RED if err > 0 else BLACK
        cf = BLACK if fits < total else GREEN
        if type(c) is int:
            print("%s{:>4d}   \033[0m%s{:>8d}\033[0m%s{:>16d}\033[0m%s{:>13d}\033[0m%s{:>10d}\033[0m%s{:>10d}\033[0m".format(c, total, down, proc, fits, err)
                  % (cc, ct, cd, cp, cf, ce))
        else:
            print("%s{:>4.1f}   \033[0m%s{:>8d}\033[0m%s{:>16d}\033[0m%s{:>13d}\033[0m%s{:>10d}\033[0m%s{:>10d}\033[0m".format(c, total, down, proc, fits, err)
                  % (cc, ct, cd, cp, cf, ce))
        if len(remain) <= 25 and len(remain) > 0 and len(campaign) == 1:
            remain.extend(["         "] * (4 - (len(remain) % 4)))
            print()
            for A, B, C, D in zip(remain[::4], remain[1::4],
                                  remain[2::4], remain[3::4]):
                if A == remain[0]:
                    print("REMAIN:  %s   %s   %s   %s" % (A, B, C, D))
                    print()
                else:
                    print("         %s   %s   %s   %s" % (A, B, C, D))
                    print()
        if len(bad) and len(campaign) == 1:
            bad.extend(["         "] * (4 - (len(bad) % 4)))
            print()
            for A, B, C, D in zip(bad[::4], bad[1::4], bad[2::4], bad[3::4]):
                if A == bad[0]:
                    print("ERRORS:  %s   %s   %s   %s" % (A, B, C, D))
                    print()
                else:
                    print("         %s   %s   %s   %s" % (A, B, C, D))
                    print()

Response: Return the status of the K2 sub - campaigns.


Instruction:
Here you have a function in Python 3, explain what it does
def InjectionStatus(campaign=range(18), model='nPLD', purge=False,
                    depths=[0.01, 0.001, 0.0001], **kwargs):
    '''
    Shows the progress of the injection de-trending runs for
    the specified campaign(s).

    '''

    if not hasattr(campaign, '__len__'):
        if type(campaign) is int:
            # Return the subcampaigns
            all_stars = [s for s in GetK2Campaign(
                campaign, split=True, epics_only=True)]
            campaign = [campaign + 0.1 * n for n in range(10)]
        else:
            all_stars = [[s for s in GetK2Campaign(campaign, epics_only=True)]]
            campaign = [campaign]
    else:
        all_stars = [[s for s in GetK2Campaign(
            c, epics_only=True)] for c in campaign]
    print("CAMP      MASK       DEPTH     TOTAL      DONE     ERRORS")
    print("----      ----       -----     -----      ----     ------")
    for c, stars in zip(campaign, all_stars):
        if len(stars) == 0:
            continue
        done = [[0 for d in depths], [0 for d in depths]]
        err = [[0 for d in depths], [0 for d in depths]]
        total = len(stars)
        if os.path.exists(os.path.join(EVEREST_DAT, 'k2', 'c%02d' % c)):
            path = os.path.join(EVEREST_DAT, 'k2', 'c%02d' % c)
            for folder in os.listdir(path):
                for subfolder in os.listdir(os.path.join(path, folder)):
                    ID = int(folder[:4] + subfolder)
                    for m, mask in enumerate(['U', 'M']):
                        for d, depth in enumerate(depths):
                            if os.path.exists(
                                os.path.join(
                                    EVEREST_DAT, 'k2', 'c%02d' % c, folder,
                                    subfolder, '%s_Inject_%s%g.npz' %
                                    (model, mask, depth))):
                                done[m][d] += 1
                            elif os.path.exists(
                                    os.path.join(
                                        EVEREST_DAT, 'k2', 'c%02d' % c, folder,
                                        subfolder, '%s_Inject_%s%g.err' %
                                        (model, mask, depth))):
                                err[m][d] += 1
        for d, depth in enumerate(depths):
            for m, mask in enumerate(['F', 'T']):
                if done[m][d] == total:
                    color = GREEN
                else:
                    color = BLACK
                if err[m][d] > 0:
                    errcolor = RED
                else:
                    errcolor = ''
                if type(c) is int:
                    print("%s{:>4d}{:>8s}{:>14g}{:>10d}{:>10d}%s{:>9d}\033[0m".format(
                        c, mask, depth, total, done[m][d], err[m][d]) % (color, errcolor))
                else:
                    print("%s{:>4.1f}{:>8s}{:>14g}{:>10d}{:>10d}%s{:>9d}\033[0m".format(
                        c, mask, depth, total, done[m][d], err[m][d]) % (color, errcolor))

Response: A simple status message for the injection of a single resource.


Instruction:
Implement a function in Python 3 to
construct the primary HDU file containing basic header info.

Response:
def PrimaryHDU(model):
    '''
    Construct the primary HDU file containing basic header info.

    '''

    # Get mission cards
    cards = model._mission.HDUCards(model.meta, hdu=0)
    if 'KEPMAG' not in [c[0] for c in cards]:
        cards.append(('KEPMAG', model.mag, 'Kepler magnitude'))

    # Add EVEREST info
    cards.append(('COMMENT', '************************'))
    cards.append(('COMMENT', '*     EVEREST INFO     *'))
    cards.append(('COMMENT', '************************'))
    cards.append(('MISSION', model.mission, 'Mission name'))
    cards.append(('VERSION', EVEREST_MAJOR_MINOR, 'EVEREST pipeline version'))
    cards.append(('SUBVER', EVEREST_VERSION, 'EVEREST pipeline subversion'))
    cards.append(('DATE', strftime('%Y-%m-%d'),
                  'EVEREST file creation date (YYYY-MM-DD)'))

    # Create the HDU
    header = pyfits.Header(cards=cards)
    hdu = pyfits.PrimaryHDU(header=header)

    return hdu


Instruction:
Create a Python 3 function to
construct the data HDU file containing the arrays and observing info.

Response:
def LightcurveHDU(model):
    '''
    Construct the data HDU file containing the arrays and the observing info.

    '''

    # Get mission cards
    cards = model._mission.HDUCards(model.meta, hdu=1)

    # Add EVEREST info
    cards.append(('COMMENT', '************************'))
    cards.append(('COMMENT', '*     EVEREST INFO     *'))
    cards.append(('COMMENT', '************************'))
    cards.append(('MISSION', model.mission, 'Mission name'))
    cards.append(('VERSION', EVEREST_MAJOR_MINOR, 'EVEREST pipeline version'))
    cards.append(('SUBVER', EVEREST_VERSION, 'EVEREST pipeline subversion'))
    cards.append(('DATE', strftime('%Y-%m-%d'),
                  'EVEREST file creation date (YYYY-MM-DD)'))
    cards.append(('MODEL', model.name, 'Name of EVEREST model used'))
    cards.append(('APNAME', model.aperture_name, 'Name of aperture used'))
    cards.append(('BPAD', model.bpad, 'Chunk overlap in cadences'))
    for c in range(len(model.breakpoints)):
        cards.append(
            ('BRKPT%02d' % (c + 1), model.breakpoints[c],
             'Light curve breakpoint'))
    cards.append(('CBVNUM', model.cbv_num, 'Number of CBV signals to recover'))
    cards.append(('CBVNITER', model.cbv_niter,
                  'Number of CBV SysRem iterations'))
    cards.append(('CBVWIN', model.cbv_win, 'Window size for smoothing CBVs'))
    cards.append(('CBVORD', model.cbv_order, 'Order when smoothing CBVs'))
    cards.append(('CDIVS', model.cdivs, 'Cross-validation subdivisions'))
    cards.append(('CDPP', model.cdpp, 'Average de-trended CDPP'))
    cards.append(('CDPPR', model.cdppr, 'Raw CDPP'))
    cards.append(('CDPPV', model.cdppv, 'Average validation CDPP'))
    cards.append(('CDPPG', model.cdppg, 'Average GP-de-trended CDPP'))
    for i in range(99):
        try:
            cards.append(('CDPP%02d' % (i + 1),
                          model.cdpp_arr[i] if not np.isnan(
                model.cdpp_arr[i]) else 0, 'Chunk de-trended CDPP'))
            cards.append(('CDPPR%02d' % (
                i + 1), model.cdppr_arr[i] if not np.isnan(
                model.cdppr_arr[i]) else 0, 'Chunk raw CDPP'))
            cards.append(('CDPPV%02d' % (i + 1),
                          model.cdppv_arr[i] if not np.isnan(
                model.cdppv_arr[i]) else 0, 'Chunk validation CDPP'))
        except:
            break
    cards.append(
        ('CVMIN', model.cv_min, 'Cross-validation objective function'))
    cards.append(
        ('GITER', model.giter, 'Number of GP optimiziation iterations'))
    cards.append(
        ('GMAXF', model.giter, 'Max number of GP function evaluations'))
    cards.append(('GPFACTOR', model.gp_factor,
                  'GP amplitude initialization factor'))
    cards.append(('KERNEL', model.kernel, 'GP kernel name'))
    if model.kernel == 'Basic':
        cards.append(
            ('GPWHITE', model.kernel_params[0],
             'GP white noise amplitude (e-/s)'))
        cards.append(
            ('GPRED', model.kernel_params[1],
             'GP red noise amplitude (e-/s)'))
        cards.append(
            ('GPTAU', model.kernel_params[2],
             'GP red noise timescale (days)'))
    elif model.kernel == 'QuasiPeriodic':
        cards.append(
            ('GPWHITE', model.kernel_params[0],
             'GP white noise amplitude (e-/s)'))
        cards.append(
            ('GPRED', model.kernel_params[1], 'GP red noise amplitude (e-/s)'))
        cards.append(('GPGAMMA', model.kernel_params[2], 'GP scale factor'))
        cards.append(('GPPER', model.kernel_params[3], 'GP period (days)'))
    for c in range(len(model.breakpoints)):
        for o in range(model.pld_order):
            cards.append(('LAMB%02d%02d' % (c + 1, o + 1),
                          model.lam[c][o], 'Cross-validation parameter'))
            if model.name == 'iPLD':
                cards.append(('RECL%02d%02d' % (c + 1, o + 1),
                              model.reclam[c][o],
                              'Cross-validation parameter'))
    cards.append(('LEPS', model.leps, 'Cross-validation tolerance'))
    cards.append(('MAXPIX', model.max_pixels, 'Maximum size of TPF aperture'))
    for i, source in enumerate(model.nearby[:99]):
        cards.append(('NRBY%02dID' %
                      (i + 1), source['ID'], 'Nearby source ID'))
        cards.append(
            ('NRBY%02dX' % (i + 1), source['x'], 'Nearby source X position'))
        cards.append(
            ('NRBY%02dY' % (i + 1), source['y'], 'Nearby source Y position'))
        cards.append(
            ('NRBY%02dM' % (i + 1), source['mag'], 'Nearby source magnitude'))
        cards.append(('NRBY%02dX0' %
                      (i + 1), source['x0'], 'Nearby source reference X'))
        cards.append(('NRBY%02dY0' %
                      (i + 1), source['y0'], 'Nearby source reference Y'))
    for i, n in enumerate(model.neighbors):
        cards.append(
            ('NEIGH%02d' % i, model.neighbors[i],
             'Neighboring star used to de-trend'))
    cards.append(('OITER', model.oiter, 'Number of outlier search iterations'))
    cards.append(('OPTGP', model.optimize_gp, 'GP optimization performed?'))
    cards.append(
        ('OSIGMA', model.osigma, 'Outlier tolerance (standard deviations)'))
    for i, planet in enumerate(model.planets):
        cards.append(
            ('P%02dT0' % (i + 1), planet[0], 'Planet transit time (days)'))
        cards.append(
            ('P%02dPER' % (i + 1), planet[1], 'Planet transit period (days)'))
        cards.append(
            ('P%02dDUR' % (i + 1), planet[2],
             'Planet transit duration (days)'))
    cards.append(('PLDORDER', model.pld_order, 'PLD de-trending order'))
    cards.append(('SATUR', model.saturated, 'Is target saturated?'))
    cards.append(('SATTOL', model.saturation_tolerance,
                  'Fractional saturation tolerance'))

    # Add the EVEREST quality flags to the QUALITY array
    quality = np.array(model.quality)
    quality[np.array(model.badmask, dtype=int)] += 2 ** (QUALITY_BAD - 1)
    quality[np.array(model.nanmask, dtype=int)] += 2 ** (QUALITY_NAN - 1)
    quality[np.array(model.outmask, dtype=int)] += 2 ** (QUALITY_OUT - 1)
    quality[np.array(model.recmask, dtype=int)] += 2 ** (QUALITY_REC - 1)
    quality[np.array(model.transitmask, dtype=int)] += 2 ** (QUALITY_TRN - 1)

    # When de-trending, we interpolated to fill in NaN fluxes. Here
    # we insert the NaNs back in, since there's no actual physical
    # information at those cadences.
    flux = np.array(model.flux)
    flux[model.nanmask] = np.nan

    # Create the arrays list
    arrays = [pyfits.Column(name='CADN', format='D', array=model.cadn),
              pyfits.Column(name='FLUX', format='D', array=flux, unit='e-/s'),
              pyfits.Column(name='FRAW', format='D',
                            array=model.fraw, unit='e-/s'),
              pyfits.Column(name='FRAW_ERR', format='D',
                            array=model.fraw_err, unit='e-/s'),
              pyfits.Column(name='QUALITY', format='J', array=quality),
              pyfits.Column(name='TIME', format='D',
                            array=model.time, unit='BJD - 2454833')]

    # Add the CBVs
    if model.fcor is not None:
        arrays += [pyfits.Column(name='FCOR', format='D',
                                 array=model.fcor, unit='e-/s')]
        for n in range(model.XCBV.shape[1]):
            arrays += [pyfits.Column(name='CBV%02d' %
                                     (n + 1), format='D',
                                     array=model.XCBV[:, n])]

    # Did we subtract a background term?
    if hasattr(model.bkg, '__len__'):
        arrays.append(pyfits.Column(name='BKG', format='D',
                                    array=model.bkg, unit='e-/s'))

    # Create the HDU
    header = pyfits.Header(cards=cards)
    cols = pyfits.ColDefs(arrays)
    hdu = pyfits.BinTableHDU.from_columns(cols, header=header, name='ARRAYS')

    return hdu


Instruction:
Write a Python 3 function for
constructing the HDU containing the pixel - level light curve.

Response:
def PixelsHDU(model):
    '''
    Construct the HDU containing the pixel-level light curve.

    '''

    # Get mission cards
    cards = model._mission.HDUCards(model.meta, hdu=2)

    # Add EVEREST info
    cards = []
    cards.append(('COMMENT', '************************'))
    cards.append(('COMMENT', '*     EVEREST INFO     *'))
    cards.append(('COMMENT', '************************'))
    cards.append(('MISSION', model.mission, 'Mission name'))
    cards.append(('VERSION', EVEREST_MAJOR_MINOR, 'EVEREST pipeline version'))
    cards.append(('SUBVER', EVEREST_VERSION, 'EVEREST pipeline subversion'))
    cards.append(('DATE', strftime('%Y-%m-%d'),
                  'EVEREST file creation date (YYYY-MM-DD)'))

    # Create the HDU
    header = pyfits.Header(cards=cards)

    # The pixel timeseries
    arrays = [pyfits.Column(name='FPIX', format='%dD' %
                            model.fpix.shape[1], array=model.fpix)]

    # The first order PLD vectors for all the neighbors (npixels, ncadences)
    X1N = model.X1N
    if X1N is not None:
        arrays.append(pyfits.Column(name='X1N', format='%dD' %
                                    X1N.shape[1], array=X1N))

    cols = pyfits.ColDefs(arrays)
    hdu = pyfits.BinTableHDU.from_columns(cols, header=header, name='PIXELS')

    return hdu


Instruction:
Explain what the following Python 3 code does
def ApertureHDU(model):
    '''
    Construct the HDU containing the aperture used to de-trend.

    '''

    # Get mission cards
    cards = model._mission.HDUCards(model.meta, hdu=3)

    # Add EVEREST info
    cards.append(('COMMENT', '************************'))
    cards.append(('COMMENT', '*     EVEREST INFO     *'))
    cards.append(('COMMENT', '************************'))
    cards.append(('MISSION', model.mission, 'Mission name'))
    cards.append(('VERSION', EVEREST_MAJOR_MINOR, 'EVEREST pipeline version'))
    cards.append(('SUBVER', EVEREST_VERSION, 'EVEREST pipeline subversion'))
    cards.append(('DATE', strftime('%Y-%m-%d'),
                  'EVEREST file creation date (YYYY-MM-DD)'))

    # Create the HDU
    header = pyfits.Header(cards=cards)
    hdu = pyfits.ImageHDU(data=model.aperture,
                          header=header, name='APERTURE MASK')

    return hdu

Response: Construct the HDU containing the aperture used to de - trend.


Instruction:
How would you explain what the following Python 3 function does
def ImagesHDU(model):
    '''
    Construct the HDU containing sample postage stamp images of the target.

    '''

    # Get mission cards
    cards = model._mission.HDUCards(model.meta, hdu=4)

    # Add EVEREST info
    cards.append(('COMMENT', '************************'))
    cards.append(('COMMENT', '*     EVEREST INFO     *'))
    cards.append(('COMMENT', '************************'))
    cards.append(('MISSION', model.mission, 'Mission name'))
    cards.append(('VERSION', EVEREST_MAJOR_MINOR, 'EVEREST pipeline version'))
    cards.append(('SUBVER', EVEREST_VERSION, 'EVEREST pipeline subversion'))
    cards.append(('DATE', strftime('%Y-%m-%d'),
                  'EVEREST file creation date (YYYY-MM-DD)'))

    # The images
    format = '%dD' % model.pixel_images[0].shape[1]
    arrays = [pyfits.Column(name='STAMP1', format=format,
                            array=model.pixel_images[0]),
              pyfits.Column(name='STAMP2', format=format,
                            array=model.pixel_images[1]),
              pyfits.Column(name='STAMP3', format=format,
                            array=model.pixel_images[2])]

    # Create the HDU
    header = pyfits.Header(cards=cards)
    cols = pyfits.ColDefs(arrays)
    hdu = pyfits.BinTableHDU.from_columns(
        cols, header=header, name='POSTAGE STAMPS')

    return hdu

Response: Construct the HDU containing sample postage stamp images of the target.


Instruction:
Can you implement a function in Python 3 that
constructs the HDU containing the hi res image of the target.

Response:
def HiResHDU(model):
    '''
    Construct the HDU containing the hi res image of the target.

    '''

    # Get mission cards
    cards = model._mission.HDUCards(model.meta, hdu=5)

    # Add EVEREST info
    cards.append(('COMMENT', '************************'))
    cards.append(('COMMENT', '*     EVEREST INFO     *'))
    cards.append(('COMMENT', '************************'))
    cards.append(('MISSION', model.mission, 'Mission name'))
    cards.append(('VERSION', EVEREST_MAJOR_MINOR, 'EVEREST pipeline version'))
    cards.append(('SUBVER', EVEREST_VERSION, 'EVEREST pipeline subversion'))
    cards.append(('DATE', strftime('%Y-%m-%d'),
                  'EVEREST file creation date (YYYY-MM-DD)'))

    # Create the HDU
    header = pyfits.Header(cards=cards)
    if model.hires is not None:
        hdu = pyfits.ImageHDU(
            data=model.hires, header=header, name='HI RES IMAGE')
    else:
        hdu = pyfits.ImageHDU(data=np.empty(
            (0, 0), dtype=float), header=header, name='HI RES IMAGE')
    return hdu


Instruction:
Can you generate a brief explanation for the following Python 3 code
def MakeFITS(model, fitsfile=None):
    '''
    Generate a FITS file for a given :py:mod:`everest` run.

    :param model: An :py:mod:`everest` model instance

    '''

    # Get the fits file name
    if fitsfile is None:
        outfile = os.path.join(model.dir, model._mission.FITSFile(
            model.ID, model.season, model.cadence))
    else:
        outfile = os.path.join(model.dir, fitsfile)
    if os.path.exists(outfile) and not model.clobber:
        return
    elif os.path.exists(outfile):
        os.remove(outfile)

    log.info('Generating FITS file...')

    # Create the HDUs
    primary = PrimaryHDU(model)
    lightcurve = LightcurveHDU(model)
    pixels = PixelsHDU(model)
    aperture = ApertureHDU(model)
    images = ImagesHDU(model)
    hires = HiResHDU(model)

    # Combine to get the HDUList
    hdulist = pyfits.HDUList(
        [primary, lightcurve, pixels, aperture, images, hires])

    # Output to the FITS file
    hdulist.writeto(outfile)

    return

Response: Generates a FITS file for a given model instance.


Instruction:
Implement a function in Python 3 to
retrieve a serializer register as name.

Response:
def get_serializer(name, **options):
    '''Retrieve a serializer register as *name*. If the serializer is not
available a ``ValueError`` exception will raise.
A common usage pattern::

    qs = MyModel.objects.query().sort_by('id')
    s = odm.get_serializer('json')
    s.dump(qs)
'''
    if name in _serializers:
        serializer = _serializers[name]
        return serializer(**options)
    else:
        raise ValueError('Unknown serializer {0}.'.format(name))


Instruction:
Can you implement a function in Python 3 that
registers a new serializer to the library.

Response:
def register_serializer(name, serializer):
    '''\
Register a new serializer to the library.

:parameter name: serializer name (it can override existing serializers).
:parameter serializer: an instance or a derived class of a
    :class:`stdnet.odm.Serializer` class or a callable.
'''
    if not isclass(serializer):
        serializer = serializer.__class__
    _serializers[name] = serializer


Instruction:
Can you write a function in Python 3 where it
solves the linear problem A with a set of contiguous w - sized masks applied to the rows and columns of b.

Response:
def MaskSolve(A, b, w=5, progress=True, niter=None):
    '''
    Finds the solution `x` to the linear problem

        A x = b

    for all contiguous `w`-sized masks applied to
    the rows and columns of `A` and to the entries
    of `b`.

    Returns an array `X` of shape `(N - w + 1, N - w)`,
    where the `nth` row is the solution to the equation

        A[![n,n+w)] x = b[![n,n+w)]

    where ![n,n+w) indicates that indices in the range
    [n,n+w) have been masked.

    '''

    # Ensure we have choldate installed
    if cholupdate is None:
        log.info("Running the slow version of `MaskSolve`.")
        log.info("Install the `choldate` package for better performance.")
        log.info("https://github.com/rodluger/choldate")
        return MaskSolveSlow(A, b, w=w, progress=progress, niter=niter)

    # Number of data points
    N = b.shape[0]

    # How many iterations? Default is to go through
    # the entire dataset
    if niter is None:
        niter = N - w + 1

    # Our result matrix
    X = np.empty((niter, N - w))

    # Solve the first two steps explicitly.
    for n in range(2):
        mask = np.arange(n, w + n)
        A_ = np.delete(np.delete(A, mask, axis=0), mask, axis=1)
        b_ = np.delete(b, mask)
        U = cholesky(A_)
        X[n] = cho_solve((U, False), b_)

    # Iterate!
    for n in prange(1, niter - 1):

        # Update the data vector.
        b_[n] = b[n]

        # Remove a row.
        S33 = U[n + 1:, n + 1:]
        S23 = U[n, n + 1:]
        cholupdate(S33, S23)

        # Add a row.
        A12 = A[:n, n]
        A22 = A[n, n]
        A23 = A[n, n + w + 1:]
        S11 = U[:n, :n]
        S12 = solve_triangular(S11.T, A12, lower=True,
                               check_finite=False, trans=0, overwrite_b=True)
        S22 = np.sqrt(A22 - np.dot(S12.T, S12))
        S13 = U[:n, n + 1:]
        S23 = (A23 - np.dot(S12.T, S13)) / S22
        choldowndate(S33, np.array(S23))
        U[:n, n] = S12
        U[n, n] = S22
        U[n, n + 1:] = S23
        U[n + 1:, n + 1:] = S33

        # Now we can solve our linear equation
        X[n + 1] = cho_solve((U, False), b_)

    # Return the matrix
    return X


Instruction:
Can you generate the documentation for the following Python 3 function
def MaskSolveSlow(A, b, w=5, progress=True, niter=None):
    '''
    Identical to `MaskSolve`, but computes the solution
    the brute-force way.

    '''

    # Number of data points
    N = b.shape[0]

    # How many iterations? Default is to go through
    # the entire dataset
    if niter is None:
        niter = N - w + 1

    # Our result matrix
    X = np.empty((niter, N - w))

    # Iterate! The mask at step `n` goes from
    # data index `n` to data index `n+w-1` (inclusive).
    for n in prange(niter):
        mask = np.arange(n, n + w)
        An = np.delete(np.delete(A, mask, axis=0), mask, axis=1)
        Un = cholesky(An)
        bn = np.delete(b, mask)
        X[n] = cho_solve((Un, False), bn)

    return X

Response: Identical to MaskSolve but computes the solution of A and b in a brute - force way.


Instruction:
Here you have a function in Python 3, explain what it does
def unmasked(self, depth=0.01):
        return 1 - (np.hstack(self._O2) +
                    np.hstack(self._O3) / depth) / np.hstack(self._O1)

Response: Return the unmasked overfitting metric for a given transit depth.


Instruction:
Explain what the following Python 3 code does
def show(self):
        try:
            if platform.system().lower().startswith('darwin'):
                subprocess.call(['open', self.pdf])
            elif os.name == 'nt':
                os.startfile(self.pdf)
            elif os.name == 'posix':
                subprocess.call(['xdg-open', self.pdf])
            else:
                raise IOError("")
        except IOError:
            log.info("Unable to open the pdf. Try opening it manually:")
            log.info(self.pdf)

Response: Show the overfitting PDF summary.


Instruction:
Can you create a Python 3 function that
returns the current season for this target.

Response:
def season(self):
        """
        Return the current observing season.

        For *K2*, this is the observing campaign, while for *Kepler*,
        it is the current quarter.

        """
        try:
            self._season
        except AttributeError:
            self._season = self._mission.Season(self.ID)
            if hasattr(self._season, '__len__'):
                raise AttributeError(
                    "Please choose a campaign/season for this target: %s." %
                    self._season)
        return self._season


Instruction:
Can you write a function in Python 3 where it
computes the design matrix at the given indices and returns the X1 matrix.

Response:
def X(self, i, j=slice(None, None, None)):
        '''
        Computes the design matrix at the given *PLD* order and the given
        indices. The columns are the *PLD* vectors for the target at the
        corresponding order, computed as the product of the fractional pixel
        flux of all sets of :py:obj:`n` pixels, where :py:obj:`n` is the *PLD*
        order.

        '''

        X1 = self.fpix[j] / self.norm[j].reshape(-1, 1)
        X = np.product(list(multichoose(X1.T, i + 1)), axis=1).T
        if self.X1N is not None:
            return np.hstack([X, self.X1N[j] ** (i + 1)])
        else:
            return X


Instruction:
Can you write a function in Python 3 where it
plots miscellaneous de - trending information on the validation summary figure.

Response:
def plot_info(self, dvs):
        '''
        Plots miscellaneous de-trending information on the data
        validation summary figure.

        :param dvs: A :py:class:`dvs.DVS` figure instance

        '''

        axl, axc, axr = dvs.title()
        axc.annotate("%s %d" % (self._mission.IDSTRING, self.ID),
                     xy=(0.5, 0.5), xycoords='axes fraction',
                     ha='center', va='center', fontsize=18)

        axc.annotate(r"%.2f ppm $\rightarrow$ %.2f ppm" %
                     (self.cdppr, self.cdpp),
                     xy=(0.5, 0.2), xycoords='axes fraction',
                     ha='center', va='center', fontsize=8, color='k',
                     fontstyle='italic')

        axl.annotate("%s %s%02d: %s" %
                     (self.mission.upper(),
                      self._mission.SEASONCHAR, self.season, self.name),
                     xy=(0.5, 0.5), xycoords='axes fraction',
                     ha='center', va='center', fontsize=12,
                     color='k')

        axl.annotate(self.aperture_name if len(self.neighbors) == 0
                     else "%s, %d neighbors" %
                     (self.aperture_name, len(self.neighbors)),
                     xy=(0.5, 0.2), xycoords='axes fraction',
                     ha='center', va='center', fontsize=8, color='k',
                     fontstyle='italic')

        axr.annotate("%s %.3f" % (self._mission.MAGSTRING, self.mag),
                     xy=(0.5, 0.5), xycoords='axes fraction',
                     ha='center', va='center', fontsize=12,
                     color='k')

        if not np.isnan(self.cdppg) and self.cdppg > 0:
            axr.annotate(r"GP %.3f ppm" % (self.cdppg),
                         xy=(0.5, 0.2), xycoords='axes fraction',
                         ha='center', va='center', fontsize=8, color='k',
                         fontstyle='italic')


Instruction:
Create a Python 3 function to
compute the model for the current value of lambda.

Response:
def compute(self):
        '''
        Compute the model for the current value of lambda.

        '''

        # Is there a transit model?
        if self.transit_model is not None:
            return self.compute_joint()

        log.info('Computing the model...')

        # Loop over all chunks
        model = [None for b in self.breakpoints]
        for b, brkpt in enumerate(self.breakpoints):

            # Masks for current chunk
            m = self.get_masked_chunk(b)
            c = self.get_chunk(b)

            # This block of the masked covariance matrix
            mK = GetCovariance(self.kernel, self.kernel_params,
                               self.time[m], self.fraw_err[m])

            # Get median
            med = np.nanmedian(self.fraw[m])

            # Normalize the flux
            f = self.fraw[m] - med

            # The X^2 matrices
            A = np.zeros((len(m), len(m)))
            B = np.zeros((len(c), len(m)))

            # Loop over all orders
            for n in range(self.pld_order):

                # Only compute up to the current PLD order
                if (self.lam_idx >= n) and (self.lam[b][n] is not None):
                    XM = self.X(n, m)
                    XC = self.X(n, c)
                    A += self.lam[b][n] * np.dot(XM, XM.T)
                    B += self.lam[b][n] * np.dot(XC, XM.T)
                    del XM, XC

            # Compute the model
            W = np.linalg.solve(mK + A, f)
            model[b] = np.dot(B, W)

        # Free up some memory
        del A, B, W

        # Join the chunks after applying the correct offset
        if len(model) > 1:

            # First chunk
            self.model = model[0][:-self.bpad]

            # Center chunks
            for m in model[1:-1]:
                # Join the chunks at the first non-outlier cadence
                i = 1
                while len(self.model) - i in self.mask:
                    i += 1
                offset = self.model[-i] - m[self.bpad - i]
                self.model = np.concatenate(
                    [self.model, m[self.bpad:-self.bpad] + offset])

            # Last chunk
            i = 1
            while len(self.model) - i in self.mask:
                i += 1
            offset = self.model[-i] - model[-1][self.bpad - i]
            self.model = np.concatenate(
                [self.model, model[-1][self.bpad:] + offset])

        else:

            self.model = model[0]

        # Subtract the global median
        self.model -= np.nanmedian(self.model)

        # Get the CDPP and reset the weights
        self.cdpp_arr = self.get_cdpp_arr()
        self.cdpp = self.get_cdpp()
        self._weights = None


Instruction:
Given the following Python 3 function, write the documentation
def compute_joint(self):
        '''
        Compute the model in a single step, allowing for a light curve-wide
        transit model. This is a bit more expensive to compute.

        '''

        # Init
        log.info('Computing the joint model...')
        A = [None for b in self.breakpoints]
        B = [None for b in self.breakpoints]

        # We need to make sure that we're not masking the transits we are
        # trying to fit!
        # NOTE: If there happens to be an index that *SHOULD* be masked during
        # a transit (cosmic ray, detector anomaly), update `self.badmask`
        # to include that index.
        # Bad data points are *never* used in the regression.
        if self.transit_model is not None:
            outmask = np.array(self.outmask)
            transitmask = np.array(self.transitmask)
            transit_inds = np.where(
                np.sum([tm(self.time) for tm in self.transit_model],
                       axis=0) < 0)[0]
            self.outmask = np.array(
                [i for i in self.outmask if i not in transit_inds])
            self.transitmask = np.array(
                [i for i in self.transitmask if i not in transit_inds])

        # Loop over all chunks
        for b, brkpt in enumerate(self.breakpoints):

            # Masks for current chunk
            m = self.get_masked_chunk(b, pad=False)
            c = self.get_chunk(b, pad=False)

            # The X^2 matrices
            A[b] = np.zeros((len(m), len(m)))
            B[b] = np.zeros((len(c), len(m)))

            # Loop over all orders
            for n in range(self.pld_order):

                # Only compute up to the current PLD order
                if (self.lam_idx >= n) and (self.lam[b][n] is not None):
                    XM = self.X(n, m)
                    XC = self.X(n, c)
                    A[b] += self.lam[b][n] * np.dot(XM, XM.T)
                    B[b] += self.lam[b][n] * np.dot(XC, XM.T)
                    del XM, XC

        # Merge chunks. BIGA and BIGB are sparse, but unfortunately
        # scipy.sparse doesn't handle sparse matrix inversion all that
        # well when the *result* is not itself sparse. So we're sticking
        # with regular np.linalg.
        BIGA = block_diag(*A)
        del A
        BIGB = block_diag(*B)
        del B

        # Compute the full covariance matrix
        mK = GetCovariance(self.kernel, self.kernel_params, self.apply_mask(
             self.time), self.apply_mask(self.fraw_err))

        # The normalized, masked flux array
        f = self.apply_mask(self.fraw)
        med = np.nanmedian(f)
        f -= med

        # Are we computing a joint transit model?
        if self.transit_model is not None:

            # Get the unmasked indices
            m = self.apply_mask()

            # Subtract off the mean total transit model
            mean_transit_model = med * \
                np.sum([tm.depth * tm(self.time[m])
                        for tm in self.transit_model], axis=0)
            f -= mean_transit_model

            # Now add each transit model to the matrix of regressors
            for tm in self.transit_model:
                XM = tm(self.time[m]).reshape(-1, 1)
                XC = tm(self.time).reshape(-1, 1)
                BIGA += med ** 2 * tm.var_depth * np.dot(XM, XM.T)
                BIGB += med ** 2 * tm.var_depth * np.dot(XC, XM.T)
                del XM, XC

            # Dot the inverse of the covariance matrix
            W = np.linalg.solve(mK + BIGA, f)
            self.model = np.dot(BIGB, W)

            # Compute the transit weights and maximum likelihood transit model
            w_trn = med ** 2 * np.concatenate([tm.var_depth * np.dot(
                    tm(self.time[m]).reshape(1, -1), W)
                    for tm in self.transit_model])
            self.transit_depth = np.array(
                 [med * tm.depth + w_trn[i] for i, tm in
                  enumerate(self.transit_model)]) / med

            # Remove the transit prediction from the model
            self.model -= np.dot(np.hstack([tm(self.time).reshape(-1, 1)
                                 for tm in self.transit_model]),
                                 w_trn)

        else:

            # No transit model to worry about
            W = np.linalg.solve(mK + BIGA, f)
            self.model = np.dot(BIGB, W)

        # Subtract the global median
        self.model -= np.nanmedian(self.model)

        # Restore the mask
        if self.transit_model is not None:
            self.outmask = outmask
            self.transitmask = transitmask

        # Get the CDPP and reset the weights
        self.cdpp_arr = self.get_cdpp_arr()
        self.cdpp = self.get_cdpp()
        self._weights = None

Response: Compute the joint model for the current set of breakpoints.


Instruction:
Given the following Python 3 function, write the documentation
def apply_mask(self, x=None):
        '''
        Returns the outlier mask, an array of indices corresponding to the
        non-outliers.

        :param numpy.ndarray x: If specified, returns the masked version of \
               :py:obj:`x` instead. Default :py:obj:`None`

        '''

        if x is None:
            return np.delete(np.arange(len(self.time)), self.mask)
        else:
            return np.delete(x, self.mask, axis=0)

Response:
Returns the outlier mask an array of indices corresponding to the
               non - outliers.


Instruction:
How would you explain what the following Python 3 function does
def get_chunk(self, b, x=None, pad=True):
        '''
        Returns the indices corresponding to a given light curve chunk.

        :param int b: The index of the chunk to return
        :param numpy.ndarray x: If specified, applies the mask to array \
               :py:obj:`x`. Default :py:obj:`None`

        '''

        M = np.arange(len(self.time))
        if b > 0:
            res = M[(M > self.breakpoints[b - 1] - int(pad) * self.bpad)
                    & (M <= self.breakpoints[b] + int(pad) * self.bpad)]
        else:
            res = M[M <= self.breakpoints[b] + int(pad) * self.bpad]
        if x is None:
            return res
        else:
            return x[res]

Response: Returns the indices corresponding to a given light curve chunk.


Instruction:
Explain what the following Python 3 code does
def get_weights(self):
        '''
        Computes the PLD weights vector :py:obj:`w`.

        ..warning :: Deprecated and not thoroughly tested.

        '''

        log.info("Computing PLD weights...")

        # Loop over all chunks
        weights = [None for i in range(len(self.breakpoints))]
        for b, brkpt in enumerate(self.breakpoints):

            # Masks for current chunk
            m = self.get_masked_chunk(b)
            c = self.get_chunk(b)

            # This block of the masked covariance matrix
            _mK = GetCovariance(self.kernel, self.kernel_params,
                                self.time[m], self.fraw_err[m])

            # This chunk of the normalized flux
            f = self.fraw[m] - np.nanmedian(self.fraw)

            # Loop over all orders
            _A = [None for i in range(self.pld_order)]
            for n in range(self.pld_order):
                if self.lam_idx >= n:
                    X = self.X(n, m)
                    _A[n] = np.dot(X, X.T)
                    del X

            # Compute the weights
            A = np.sum([l * a for l, a in zip(self.lam[b], _A)
                        if l is not None], axis=0)
            W = np.linalg.solve(_mK + A, f)
            weights[b] = [l * np.dot(self.X(n, m).T, W)
                          for n, l in enumerate(self.lam[b]) if l is not None]

        self._weights = weights

Response: Computes the PLD weights vector for all breakpoints.


Instruction:
Here you have a function in Python 3, explain what it does
def get_cdpp_arr(self, flux=None):
        '''
        Returns the CDPP value in *ppm* for each of the
        chunks in the light curve.

        '''

        if flux is None:
            flux = self.flux
        return np.array([self._mission.CDPP(flux[self.get_masked_chunk(b)],
                        cadence=self.cadence)
                        for b, _ in enumerate(self.breakpoints)])

Response: Returns the CDPP value in ppm for each of the logarithmic chunks in the light curve.


Instruction:
Can you tell what is the following Python 3 function doing
def get_cdpp(self, flux=None):
        '''
        Returns the scalar CDPP for the light curve.

        '''

        if flux is None:
            flux = self.flux
        return self._mission.CDPP(self.apply_mask(flux), cadence=self.cadence)

Response: Returns the scalar CDPP for the light curve.


Instruction:
Given the following Python 3 function, write the documentation
def plot_aperture(self, axes, labelsize=8):
        '''
        Plots the aperture and the pixel images at the beginning, middle,
        and end of the time series. Also plots a high resolution image of
        the target, if available.

        '''

        log.info('Plotting the aperture...')

        # Get colormap
        plasma = pl.get_cmap('plasma')
        plasma.set_bad(alpha=0)

        # Get aperture contour
        def PadWithZeros(vector, pad_width, iaxis, kwargs):
            vector[:pad_width[0]] = 0
            vector[-pad_width[1]:] = 0
            return vector
        ny, nx = self.pixel_images[0].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])

        # Plot first, mid, and last TPF image
        title = ['start', 'mid', 'end']
        for i, image in enumerate(self.pixel_images):
            ax = axes[i]
            ax.imshow(image, aspect='auto',
                      interpolation='nearest', cmap=plasma)
            ax.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:
                        ax.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)

            ax.axis('off')
            ax.set_xlim(-0.7, nx - 0.3)
            ax.set_ylim(-0.7, ny - 0.3)
            ax.annotate(title[i], xy=(0.5, 0.975), xycoords='axes fraction',
                        ha='center', va='top', size=labelsize, color='w')
            if i == 1:
                for source in self.nearby:
                    ax.annotate('%.1f' % source['mag'],
                                xy=(source['x'] - source['x0'],
                                    source['y'] - source['y0']),
                                ha='center', va='center', size=labelsize - 2,
                                color='w', fontweight='bold')

        # Plot hi res image
        if self.hires is not None:
            ax = axes[-1]
            ax.imshow(self.hires, aspect='auto',
                      extent=(-0.5, nx - 0.5, -0.5, ny - 0.5),
                      interpolation='bicubic', cmap=plasma)
            ax.contour(highres, levels=[0.5], extent=extent,
                       origin='lower', colors='r', linewidths=1)
            ax.axis('off')
            ax.set_xlim(-0.7, nx - 0.3)
            ax.set_ylim(-0.7, ny - 0.3)
            ax.annotate('hires', xy=(0.5, 0.975), xycoords='axes fraction',
                        ha='center', va='top', size=labelsize, color='w')
        else:
            ax = axes[-1]
            ax.axis('off')

Response: Plots the aperture and the pixel images at the beginning middle and end of the time series.


Instruction:
Here you have a function in Python 3, explain what it does
def overfit(self, tau=None, plot=True, clobber=False, w=9, **kwargs):
        fname = os.path.join(self.dir, self.name + '_overfit.npz')
        figname = os.path.join(self.dir, self.name)

        # Compute
        if not os.path.exists(fname) or clobber:

            # Baseline
            med = np.nanmedian(self.fraw)

            # Default transit model
            if tau is None:
                tau = TransitShape(dur=0.1)

            # The overfitting metrics
            O1 = [None for brkpt in self.breakpoints]
            O2 = [None for brkpt in self.breakpoints]
            O3 = [None for brkpt in self.breakpoints]
            O4 = [None for brkpt in self.breakpoints]
            O5 = [None for brkpt in self.breakpoints]

            # Loop over all chunks
            for b, brkpt in enumerate(self.breakpoints):

                # Masks for current chunk
                m = self.get_masked_chunk(b, pad=False)
                time = self.time[m]
                ferr = self.fraw_err[m] / med
                y = self.fraw[m] / med - 1

                # The metrics we're computing here
                O1[b] = np.zeros(len(y)) * np.nan
                O2[b] = np.zeros(len(y)) * np.nan
                O3[b] = np.zeros(len(y)) * np.nan
                O4[b] = np.zeros(len(y)) * np.nan
                O5[b] = np.zeros(len(y)) * np.nan

                # Compute the astrophysical covariance and its inverse
                log.info("Computing the covariance...")
                if self.kernel == 'Basic':
                    wh, am, ta = self.kernel_params
                    wh /= med
                    am /= med
                    kernel_params = [wh, am, ta]
                elif self.kernel == 'QuasiPeriodic':
                    wh, am, ga, pe = self.kernel_params
                    wh /= med
                    am /= med
                    kernel_params = [wh, am, ga, pe]
                K = GetCovariance(self.kernel, kernel_params, time, ferr)
                Kinv = cho_solve((cholesky(K), False), np.eye(len(time)))

                # Loop over all orders
                log.info("Computing some large matrices...")
                X = [None for n in range(self.pld_order)]
                XL = [None for n in range(self.pld_order)]
                XLX = [None for n in range(self.pld_order)]
                for n in range(self.pld_order):
                    if (self.lam_idx >= n) and (self.lam[b][n] is not None):
                        X[n] = self.X(n, m, **kwargs)
                        XL[n] = (self.lam[b][n] / med ** 2) * X[n]
                        XLX[n] = np.dot(XL[n], X[n].T)
                X = np.hstack(X)
                XL = np.hstack(XL)
                XLX = np.sum(XLX, axis=0)

                # The full covariance
                C = XLX + K

                # The unmasked linear problem
                log.info("Solving the unmasked linear problem...")
                m = np.dot(XLX, np.linalg.solve(C, y))
                m -= np.nanmedian(m)
                f = y - m
                R = np.linalg.solve(C, XLX.T).T

                # The masked linear problem
                log.info("Solving the masked linear problem...")
                A = MaskSolve(C, y, w=w)

                # Now loop through and compute the metric
                log.info("Computing the overfitting metrics...")
                for n in prange(len(y)):

                    #
                    # *** Unmasked overfitting metric ***
                    #

                    # Evaluate the sparse transit model
                    TAU = tau(time, t0=time[n])
                    i = np.where(TAU < 0)[0]
                    TAU = TAU.reshape(-1, 1)

                    # Fast sparse algebra
                    AA = np.dot(np.dot(TAU[i].T, Kinv[i, :][:, i]), TAU[i])
                    BB = np.dot(TAU[i].T, Kinv[i, :])
                    CC = TAU - np.dot(R[:, i], TAU[i])
                    O1[b][n] = AA
                    O2[b][n] = np.dot(BB, CC)
                    O3[b][n] = np.dot(BB, f)
                    O4[b][n] = np.dot(BB, y)

                    #
                    # *** Masked overfitting metric ***
                    #

                    # The current mask and mask centerpoint
                    mask = np.arange(n, n + w)
                    j = n + (w + 1) // 2 - 1
                    if j >= len(y) - w:
                        continue

                    # The regularized design matrix
                    # This is the same as
                    # XLmX[:, n - 1] = \
                    #   np.dot(XL, np.delete(X, mask, axis=0).T)[:, n - 1]
                    if n == 0:
                        XLmX = np.dot(XL, np.delete(X, mask, axis=0).T)
                    else:
                        XLmX[:, n - 1] = np.dot(XL, X[n - 1, :].T)

                    # The linear solution to this step
                    m = np.dot(XLmX, A[n])

                    # Evaluate the sparse transit model
                    TAU = tau(time, t0=time[j])
                    i = np.where(TAU < 0)[0]
                    TAU = TAU[i].reshape(-1, 1)

                    # Dot the transit model in
                    den = np.dot(np.dot(TAU.T, Kinv[i, :][:, i]), TAU)
                    num = np.dot(TAU.T, Kinv[i, :])

                    # Compute the overfitting metric
                    # Divide this number by a depth
                    # to get the overfitting for that
                    # particular depth.
                    O5[b][j] = -np.dot(num, y - m) / den

            # Save!
            np.savez(fname, O1=O1, O2=O2, O3=O3, O4=O4, O5=O5)

        else:

            data = np.load(fname)
            O1 = data['O1']
            O2 = data['O2']
            O3 = data['O3']
            O4 = data['O4']
            O5 = data['O5']

        # Plot
        if plot and (clobber or not os.path.exists(figname + '_overfit.pdf')):

            log.info("Plotting the overfitting metrics...")

            # Masked time array
            time = self.apply_mask(self.time)

            # Plot the final corrected light curve
            ovr = OVERFIT()
            self.plot_info(ovr)

            # Loop over the two metrics
            for kind, axes, axesh in zip(['unmasked', 'masked'],
                                         [ovr.axes1, ovr.axes2],
                                         [ovr.axes1h, ovr.axes2h]):

                # Loop over three depths
                for depth, ax, axh in zip([0.01, 0.001, 0.0001], axes, axesh):

                    # Get the metric
                    if kind == 'unmasked':
                        metric = 1 - (np.hstack(O2) +
                                      np.hstack(O3) / depth) / np.hstack(O1)
                        color = 'r'
                    elif kind == 'masked':
                        metric = np.hstack(O5) / depth
                        color = 'b'
                    else:
                        raise ValueError("Invalid metric.")

                    # Median and median absolute deviation
                    med = np.nanmedian(metric)
                    mad = np.nanmedian(np.abs(metric - med))

                    # Plot the metric as a function of time
                    ax.plot(time, metric, 'k.', alpha=0.5, ms=2)
                    ax.plot(time, metric, 'k-', alpha=0.1, lw=0.5)
                    ylim = (-0.2, 1.0)
                    ax.margins(0, None)
                    ax.axhline(0, color='k', lw=1, alpha=0.5)
                    ax.set_ylim(*ylim)
                    if kind == 'masked' and depth == 0.0001:
                        ax.set_xlabel('Time (days)', fontsize=14)
                    else:
                        ax.set_xticklabels([])

                    # Plot the histogram
                    rng = (max(ylim[0], np.nanmin(metric)),
                           min(ylim[1], np.nanmax(metric)))
                    axh.hist(metric, bins=30, range=rng,
                             orientation="horizontal",
                             histtype="step", fill=False, color='k')
                    axh.axhline(med, color=color, ls='-', lw=1)
                    axh.axhspan(med - mad, med + mad, color=color, alpha=0.1)
                    axh.axhline(0, color='k', lw=1, alpha=0.5)
                    axh.yaxis.tick_right()
                    axh.set_ylim(*ax.get_ylim())
                    axh.set_xticklabels([])

                    bbox = dict(fc="w", ec="1", alpha=0.5)
                    info = r"$\mathrm{med}=%.3f$" % med + \
                        "\n" + r"$\mathrm{mad}=%.3f$" % mad
                    axh.annotate(info, xy=(0.1, 0.925),
                                 xycoords='axes fraction',
                                 ha="left", va="top", bbox=bbox, color=color)

                    bbox = dict(fc="w", ec="1", alpha=0.95)
                    ax.annotate("%s overfitting metric" % kind,
                                xy=(1-0.035, 0.92),
                                xycoords='axes fraction',
                                ha='right', va='top',
                                bbox=bbox, color=color)

            pl.figtext(0.025, 0.77, "depth = 0.01", rotation=90,
                       ha='left', va='center', fontsize=18)
            pl.figtext(0.025, 0.48, "depth = 0.001", rotation=90,
                       ha='left', va='center', fontsize=18)
            pl.figtext(0.025, 0.19, "depth = 0.0001", rotation=90,
                       ha='left', va='center', fontsize=18)

            ovr.fig.savefig(figname + '_overfit.pdf')
            log.info("Saved plot to %s_overfit.pdf" % figname)
            pl.close()

        return Overfitting(O1, O2, O3, O4, O5, figname + '_overfit.pdf')

Response: r This routine computes the masked unmasked overfitting metrics for the light curve.


Instruction:
Can you generate the documentation for the following Python 3 function
def Inject(ID, inj_model='nPLD', t0=None, per=None, dur=0.1, depth=0.001,
           mask=False, trn_win=5, poly_order=3, make_fits=False, **kwargs):
    '''
    Run one of the :py:obj:`everest` models with injected transits and attempt
    to recover the transit depth at the end with a simple linear regression
    with a polynomial baseline. The depth is stored in the
    :py:obj:`inject` attribute of the model (a dictionary) as
    :py:obj:`rec_depth`. A control injection is also performed, in which the
    transits are injected into the de-trended data; the recovered depth in
    the control run is stored in :py:obj:`inject`
    as :py:obj:`rec_depth_control`.

    :param int ID: The target id
    :param str inj_model: The name of the :py:obj:`everest` model to run. \
           Default `"nPLD"`
    :param float t0: The transit ephemeris in days. Default is to draw from \
           the uniform distributon [0., :py:obj:`per`)
    :param float per: The injected planet period in days. Default is to draw \
           from the uniform distribution [2, 10]
    :param float dur: The transit duration in days. Must be in the range \
           [0.05, 0.5]. Default 0.1
    :param float depth: The fractional transit depth. Default 0.001
    :param bool mask: Explicitly mask the in-transit cadences when computing \
           the PLD model? Default :py:obj:`False`
    :param float trn_win: The size of the transit window in units of the \
           transit duration
    :param int poly_order: The order of the polynomial used to fit the \
           continuum

    '''

    # Randomize the planet params
    if per is None:
        a = 3.
        b = 10.
        per = a + (b - a) * np.random.random()
    if t0 is None:
        t0 = per * np.random.random()

    # Get the actual class
    _model = eval(inj_model)
    inject = {'t0': t0, 'per': per, 'dur': dur, 'depth': depth, 'mask': mask,
              'poly_order': poly_order, 'trn_win': trn_win}

    # Define the injection class
    class Injection(_model):
        '''
        The :py:obj:`Injection` class is a special subclass of a
        user-selected :py:obj:`everest` model.
        See :py:func:`Inject` for more details.

        '''

        def __init__(self, *args, **kwargs):
            '''

            '''

            self.inject = kwargs.pop('inject', None)
            self.parent_class = kwargs.pop('parent_class', None)
            self.kwargs = kwargs
            super(Injection, self).__init__(*args, **kwargs)

        @property
        def name(self):
            '''

            '''

            if self.inject['mask']:
                maskchar = 'M'
            else:
                maskchar = 'U'
            return '%s_Inject_%s%g' % (self.parent_class,
                                       maskchar, self.inject['depth'])

        def load_tpf(self):
            '''
            Loads the target pixel files and injects transits at the pixel level.

            '''

            # Load the TPF
            super(Injection, self).load_tpf()
            log.info("Injecting transits...")

            # Inject the transits into the regular data
            transit_model = Transit(
                self.time, t0=self.inject['t0'], per=self.inject['per'],
                dur=self.inject['dur'], depth=self.inject['depth'])
            for i in range(self.fpix.shape[1]):
                self.fpix[:, i] *= transit_model
            self.fraw = np.sum(self.fpix, axis=1)
            if self.inject['mask']:
                self.transitmask = np.array(list(set(np.concatenate(
                    [self.transitmask, np.where(transit_model < 1.)[0]]))),
                    dtype=int)

            # Update the PLD normalization
            self.get_norm()

        def recover_depth(self):
            '''
            Recovers the injected transit depth from the long
            cadence data with a simple LLS solver.
            The results are all stored in the :py:obj:`inject`
            attribute of the model.

            '''

            # Control run
            transit_model = Transit(
                self.time, t0=self.inject['t0'], per=self.inject['per'],
                dur=self.inject['dur'], depth=self.inject['depth'])
            kwargs = dict(self.kwargs)
            kwargs.update({'clobber': False})
            control = eval(self.parent_class)(
                self.ID, is_parent=True, **kwargs)
            control.fraw *= transit_model

            # Get params
            log.info("Recovering transit depth...")
            t0 = self.inject['t0']
            per = self.inject['per']
            dur = self.inject['dur']
            depth = self.inject['depth']
            trn_win = self.inject['trn_win']
            poly_order = self.inject['poly_order']

            for run, tag in zip([self, control], ['', '_control']):

                # Compute the model
                mask = np.array(
                    list(set(np.concatenate([run.badmask, run.nanmask]))),
                    dtype=int)
                flux = np.delete(run.flux / np.nanmedian(run.flux), mask)
                time = np.delete(run.time, mask)
                transit_model = (Transit(time, t0=t0, per=per,
                                         dur=dur, depth=depth) - 1) / depth

                # Count the transits
                t0 += np.ceil((time[0] - dur - t0) / per) * per
                ttimes0 = np.arange(t0, time[-1] + dur, per)
                tinds = []
                for tt in ttimes0:
                    # Get indices for this chunk
                    inds = np.where(np.abs(time - tt) < trn_win * dur / 2.)[0]
                    # Ensure there's a transit in this chunk, and that
                    # there are enough points for the polynomial fit
                    if np.any(transit_model[inds] < 0.) and \
                            len(inds) > poly_order:
                        tinds.append(inds)

                # Our design matrix
                sz = (poly_order + 1) * len(tinds)
                X = np.empty((0, 1 + sz), dtype=float)
                Y = np.array([], dtype=float)
                T = np.array([], dtype=float)

                # Loop over all transits
                for i, inds in enumerate(tinds):
                    # Get the transit model
                    trnvec = transit_model[inds].reshape(-1, 1)
                    # Normalize the time array
                    t = time[inds]
                    t = (t - t[0]) / (t[-1] - t[0])
                    # Cumulative arrays
                    T = np.append(T, time[inds])
                    Y = np.append(Y, flux[inds])
                    # Polynomial vector
                    polyvec = np.array(
                        [t ** o for o in range(0, poly_order + 1)]).T
                    # Update the design matrix with this chunk
                    lzeros = np.zeros((len(t), i * (poly_order + 1)))
                    rzeros = np.zeros(
                        (len(t), sz - (i + 1) * (poly_order + 1)))
                    chunk = np.hstack((trnvec, lzeros, polyvec, rzeros))
                    X = np.vstack((X, chunk))

                # Get the relative depth
                A = np.dot(X.T, X)
                B = np.dot(X.T, Y)
                C = np.linalg.solve(A, B)
                rec_depth = C[0]

                # Get the uncertainties
                sig = 1.4826 * \
                    np.nanmedian(np.abs(flux - np.nanmedian(flux))
                                 ) / np.nanmedian(flux)
                cov = sig ** 2 * np.linalg.solve(A, np.eye(A.shape[0]))
                err = np.sqrt(np.diag(cov))
                rec_depth_err = err[0]

                # Store the results
                self.inject.update(
                    {'rec_depth%s' % tag: rec_depth,
                     'rec_depth_err%s' % tag: rec_depth_err})

                # Store the detrended, folded data
                D = (Y - np.dot(C[1:], X[:, 1:].T) +
                     np.nanmedian(Y)) / np.nanmedian(Y)
                T = (T - t0 - per / 2.) % per - per / 2.
                self.inject.update(
                    {'fold_time%s' % tag: T, 'fold_flux%s' % tag: D})

        def plot_final(self, ax):
            '''
            Plots the injection recovery results.

            '''

            from mpl_toolkits.axes_grid.inset_locator import inset_axes
            ax.axis('off')
            ax1 = inset_axes(ax, width="47%", height="100%", loc=6)
            ax2 = inset_axes(ax, width="47%", height="100%", loc=7)

            # Plot the recovered folded transits
            ax1.plot(self.inject['fold_time'],
                     self.inject['fold_flux'], 'k.', alpha=0.3)
            x = np.linspace(np.min(self.inject['fold_time']), np.max(
                self.inject['fold_time']), 500)
            try:
                y = Transit(
                    x, t0=0., per=self.inject['per'], dur=self.inject['dur'],
                    depth=self.inject['rec_depth'])
            except:
                # Log the error, and carry on
                exctype, value, tb = sys.exc_info()
                for line in traceback.format_exception_only(exctype, value):
                    l = line.replace('\n', '')
                    log.error(l)
                y = np.ones_like(x) * np.nan
            ax1.plot(x, y, 'r-')
            ax1.annotate('INJECTED', xy=(0.98, 0.025),
                         xycoords='axes fraction',
                         ha='right', va='bottom', fontsize=10, alpha=0.5,
                         fontweight='bold')
            ax1.annotate('True depth:\nRecovered depth:',
                         xy=(0.02, 0.025),
                         xycoords='axes fraction',
                         ha='left', va='bottom', fontsize=6, color='r')
            ax1.annotate('%.6f\n%.6f' % (self.inject['depth'],
                         self.inject['rec_depth']),
                         xy=(0.4, 0.025),
                         xycoords='axes fraction',
                         ha='left', va='bottom', fontsize=6, color='r')
            ax1.margins(0, None)
            ax1.ticklabel_format(useOffset=False)

            # Plot the recovered folded transits (control)
            ax2.plot(self.inject['fold_time_control'],
                     self.inject['fold_flux_control'], 'k.', alpha=0.3)
            x = np.linspace(np.min(self.inject['fold_time_control']), np.max(
                self.inject['fold_time_control']), 500)
            try:
                y = Transit(
                    x, t0=0., per=self.inject['per'], dur=self.inject['dur'],
                    depth=self.inject['rec_depth_control'])
            except:
                # Log the error, and carry on
                exctype, value, tb = sys.exc_info()
                for line in traceback.format_exception_only(exctype, value):
                    l = line.replace('\n', '')
                    log.error(l)
                y = np.ones_like(x) * np.nan
            ax2.plot(x, y, 'r-')
            ax2.annotate('CONTROL', xy=(0.98, 0.025), xycoords='axes fraction',
                         ha='right', va='bottom', fontsize=10, alpha=0.5,
                         fontweight='bold')
            ax2.annotate('True depth:\nRecovered depth:',
                         xy=(0.02, 0.025),
                         xycoords='axes fraction',
                         ha='left', va='bottom', fontsize=6, color='r')
            ax2.annotate('%.6f\n%.6f' % (self.inject['depth'],
                         self.inject['rec_depth_control']),
                         xy=(0.4, 0.025),
                         xycoords='axes fraction',
                         ha='left', va='bottom', fontsize=6, color='r')
            ax2.margins(0, None)
            ax2.ticklabel_format(useOffset=False)
            N = int(0.995 * len(self.inject['fold_flux_control']))
            hi, lo = self.inject['fold_flux_control'][np.argsort(
                self.inject['fold_flux_control'])][[N, -N]]
            fsort = self.inject['fold_flux_control'][np.argsort(
                self.inject['fold_flux_control'])]
            pad = (hi - lo) * 0.2
            ylim = (lo - 2 * pad, hi + pad)
            ax2.set_ylim(ylim)
            ax1.set_ylim(ylim)

            ax2.set_yticklabels([])
            for tick in ax1.get_xticklabels() + ax1.get_yticklabels() + \
                    ax2.get_xticklabels():
                tick.set_fontsize(5)

        def finalize(self):
            '''
            Calls the depth recovery routine at the end
            of the de-trending step.

            '''

            super(Injection, self).finalize()
            self.recover_depth()

    return Injection(ID, inject=inject, parent_class=inj_model,
                     make_fits=make_fits, **kwargs)

Response: This function creates a new state machine with injected transits and control runs.


Instruction:
How would you implement a function in Python 3 that
returns a list of objects of the same type.

Response:
def object(self, session):
        '''Instance of :attr:`model_type` with id :attr:`object_id`.'''
        if not hasattr(self, '_object'):
            pkname = self.model_type._meta.pkname()
            query = session.query(self.model_type).filter(**{pkname:
                                                             self.object_id})
            return query.items(callback=self.__set_object)
        else:
            return self._object


Instruction:
Given the following Python 3 function, write the documentation
def GetData(ID, season = None, cadence = 'lc', clobber = False, delete_raw = False,
            aperture_name = None, saturated_aperture_name = None,
            max_pixels = None, download_only = False, saturation_tolerance = None,
            bad_bits = None, **kwargs):
  '''
  Returns a :py:obj:`DataContainer` instance with the raw data for the target.

  :param int ID: The target ID number
  :param int season: The observing season. 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 :py:obj:`None`
  :param str saturated_aperture_name: The name of the aperture to use if the target is \
         saturated. Default :py:obj:`None`
  :param int max_pixels: Maximum number of pixels in the TPF. Default :py:obj:`None`
  :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 :py:obj:`None`
  :param array_like bad_bits: Flagged :py:obj`QUALITY` bits to consider outliers when \
         computing the model. Default :py:obj:`None`

  '''

  raise NotImplementedError('This mission is not yet supported.')

Response: Retrieves the raw data for the target.


Instruction:
Write a Python 3 script for
returning neighbors from the specified model.

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

  :param int ID: The target 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 None
  :param str aperture_name: The name of the aperture to use. Select `custom` to call \
         :py:func:`GetCustomAperture`. Default :py:obj:`None`
  :param str cadence: The light curve cadence. Default `lc`
  :param tuple mag_range: (`low`, `high`) values for the Kepler magnitude. Default :py:obj:`None`
  :param tuple cdpp_range: (`low`, `high`) values for the de-trended CDPP. Default :py:obj:`None`

  '''

  raise NotImplementedError('This mission is not yet supported.')


Instruction:
Write a Python 3 script to
return the time and flux for a given EPIC ID and a given pipeline name.

Response:
def get(ID, pipeline='everest2', campaign=None):
    '''
    Returns the `time` and `flux` for a given EPIC `ID` and
    a given `pipeline` name.

    '''

    log.info('Downloading %s light curve for %d...' % (pipeline, ID))

    # Dev version hack
    if EVEREST_DEV:
        if pipeline.lower() == 'everest2' or pipeline.lower() == 'k2sff':
            from . import Season, TargetDirectory, FITSFile
            if campaign is None:
                campaign = Season(ID)
            fits = os.path.join(TargetDirectory(
                ID, campaign), FITSFile(ID, campaign))
            newdir = os.path.join(KPLR_ROOT, "data", "everest", str(ID))
            if not os.path.exists(newdir):
                os.makedirs(newdir)
            if os.path.exists(fits):
                shutil.copy(fits, newdir)

    if pipeline.lower() == 'everest2':
        s = k2plr.EVEREST(ID, version=2, sci_campaign=campaign)
        time = s.time
        flux = s.flux
    elif pipeline.lower() == 'everest1':
        s = k2plr.EVEREST(ID, version=1, sci_campaign=campaign)
        time = s.time
        flux = s.flux
    elif pipeline.lower() == 'k2sff':
        s = k2plr.K2SFF(ID, sci_campaign=campaign)
        time = s.time
        flux = s.fcor
        # Normalize to the median flux
        s = k2plr.EVEREST(ID, version=2, sci_campaign=campaign)
        flux *= np.nanmedian(s.flux)
    elif pipeline.lower() == 'k2sc':
        s = k2plr.K2SC(ID, sci_campaign=campaign)
        time = s.time
        flux = s.pdcflux
    elif pipeline.lower() == 'raw':
        s = k2plr.EVEREST(ID, version=2, raw=True, sci_campaign=campaign)
        time = s.time
        flux = s.flux
    else:
        raise ValueError('Invalid pipeline: `%s`.' % pipeline)

    return time, flux


Instruction:
Can you tell what is the following Python 3 function doing
def plot(ID, pipeline='everest2', show=True, campaign=None):
    '''
    Plots the de-trended flux for the given EPIC `ID` and for
    the specified `pipeline`.

    '''

    # Get the data
    time, flux = get(ID, pipeline=pipeline, campaign=campaign)

    # Remove nans
    mask = np.where(np.isnan(flux))[0]
    time = np.delete(time, mask)
    flux = np.delete(flux, mask)

    # 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)

    # Show the CDPP
    from .k2 import CDPP
    ax.annotate('%.2f ppm' % 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 (BJD - 2454833)", fontsize=16)
    ax.set_ylabel("%s Flux" % pipeline.upper(), fontsize=16)
    fig.canvas.set_window_title("%s: EPIC %d" % (pipeline.upper(), ID))

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

Response:
Plots the de - trended flux for the given EPIC ID and for
    the specified pipeline.


Instruction:
Here you have a function in Python 3, explain what it does
def get_cdpp(campaign, pipeline='everest2'):
    '''
    Computes the CDPP for a given `campaign` and a given `pipeline`.
    Stores the results in a file under "/missions/k2/tables/".

    '''

    # Imports
    from .k2 import CDPP
    from .utils import GetK2Campaign

    # Check pipeline
    assert pipeline.lower() in Pipelines, 'Invalid pipeline: `%s`.' % pipeline

    # Create file if it doesn't exist
    file = os.path.join(EVEREST_SRC, 'missions', 'k2',
                        'tables', 'c%02d_%s.cdpp' % (int(campaign), pipeline))
    if not os.path.exists(file):
        open(file, 'a').close()

    # Get all EPIC stars
    stars = GetK2Campaign(campaign, epics_only=True)
    nstars = len(stars)

    # Remove ones we've done
    with warnings.catch_warnings():
        warnings.simplefilter("ignore")
        done = np.loadtxt(file, dtype=float)
    if len(done):
        done = [int(s) for s in done[:, 0]]
    stars = list(set(stars) - set(done))
    n = len(done) + 1

    # Open the output file
    with open(file, 'a', 1) as outfile:

        # Loop over all to get the CDPP
        for EPIC in stars:

            # Progress
            sys.stdout.write('\rRunning target %d/%d...' % (n, nstars))
            sys.stdout.flush()
            n += 1

            # Get the CDPP
            try:
                _, flux = get(EPIC, pipeline=pipeline, campaign=campaign)
                mask = np.where(np.isnan(flux))[0]
                flux = np.delete(flux, mask)
                cdpp = CDPP(flux)
            except (urllib.error.HTTPError, urllib.error.URLError,
                    TypeError, ValueError, IndexError):
                print("{:>09d} {:>15.3f}".format(EPIC, 0), file=outfile)
                continue

            # Log to file
            print("{:>09d} {:>15.3f}".format(EPIC, cdpp), file=outfile)

Response: Compute the CDPP for a given campaign and pipeline.


Instruction:
How would you code a function in Python 3 to
compute the number of outliers for a given campaign and a given pipeline.

Response:
def get_outliers(campaign, pipeline='everest2', sigma=5):
    '''
    Computes the number of outliers for a given `campaign`
    and a given `pipeline`.
    Stores the results in a file under "/missions/k2/tables/".

    :param int sigma: The sigma level at which to clip outliers. Default 5

    '''

    # Imports
    from .utils import GetK2Campaign
    client = k2plr.API()

    # Check pipeline
    assert pipeline.lower() in Pipelines, 'Invalid pipeline: `%s`.' % pipeline

    # Create file if it doesn't exist
    file = os.path.join(EVEREST_SRC, 'missions', 'k2',
                        'tables', 'c%02d_%s.out' % (int(campaign), pipeline))
    if not os.path.exists(file):
        open(file, 'a').close()

    # Get all EPIC stars
    stars = GetK2Campaign(campaign, epics_only=True)
    nstars = len(stars)

    # Remove ones we've done
    with warnings.catch_warnings():
        warnings.simplefilter("ignore")
        done = np.loadtxt(file, dtype=float)
    if len(done):
        done = [int(s) for s in done[:, 0]]
    stars = list(set(stars) - set(done))
    n = len(done) + 1

    # Open the output file
    with open(file, 'a', 1) as outfile:

        # Loop over all to get the CDPP
        for EPIC in stars:

            # Progress
            sys.stdout.write('\rRunning target %d/%d...' % (n, nstars))
            sys.stdout.flush()
            n += 1

            # Get the number of outliers
            try:
                time, flux = get(EPIC, pipeline=pipeline, campaign=campaign)

                # Get the raw K2 data
                tpf = os.path.join(KPLR_ROOT, "data", "k2",
                                   "target_pixel_files",
                                   "%09d" % EPIC,
                                   "ktwo%09d-c%02d_lpd-targ.fits.gz"
                                   % (EPIC, campaign))
                if not os.path.exists(tpf):
                    client.k2_star(EPIC).get_target_pixel_files(fetch=True)
                with pyfits.open(tpf) as f:
                    k2_qual = np.array(f[1].data.field('QUALITY'), dtype=int)
                    k2_time = np.array(
                        f[1].data.field('TIME'), dtype='float64')
                    mask = []
                    for b in [1, 2, 3, 4, 5, 6, 7, 8, 9,
                              11, 12, 13, 14, 16, 17]:
                        mask += list(np.where(k2_qual & 2 ** (b - 1))[0])
                    mask = np.array(sorted(list(set(mask))))

                # Fill in missing cadences, if any
                tol = 0.005
                if not ((len(time) == len(k2_time)) and (np.abs(time[0]
                        - k2_time[0]) < tol) and (np.abs(time[-1]
                                                  - k2_time[-1]) < tol)):
                    ftmp = np.zeros_like(k2_time) * np.nan
                    j = 0
                    for i, t in enumerate(k2_time):
                        if np.abs(time[j] - t) < tol:
                            ftmp[i] = flux[j]
                            j += 1
                            if j == len(time) - 1:
                                break
                    flux = ftmp

                # Remove flagged cadences
                flux = np.delete(flux, mask)

                # Remove nans
                nanmask = np.where(np.isnan(flux))[0]
                flux = np.delete(flux, nanmask)

                # Iterative sigma clipping
                inds = np.array([], dtype=int)
                m = 1
                while len(inds) < m:
                    m = len(inds)
                    f = SavGol(np.delete(flux, inds))
                    med = np.nanmedian(f)
                    MAD = 1.4826 * np.nanmedian(np.abs(f - med))
                    inds = np.append(inds, np.where(
                        (f > med + sigma * MAD) | (f < med - sigma * MAD))[0])
                nout = len(inds)
                ntot = len(flux)

            except (urllib.error.HTTPError, urllib.error.URLError,
                    TypeError, ValueError, IndexError):
                print("{:>09d} {:>5d} {:>5d}".format(
                    EPIC, -1, -1), file=outfile)
                continue

            # Log to file
            print("{:>09d} {:>5d} {:>5d}".format(
                EPIC, nout, ntot), file=outfile)


Instruction:
Can you write a function in Python 3 where it
returns the name of the current Detrender subclass.

Response:
def name(self):
        '''
        Returns the name of the current :py:class:`Detrender` subclass.

        '''

        if self.cadence == 'lc':
            return self.__class__.__name__
        else:
            return '%s.sc' % self.__class__.__name__


Instruction:
Explain what the following Python 3 code does
def cv_compute(self, b, A, B, C, mK, f, m1, m2):
        '''
        Compute the model (cross-validation step only) for chunk :py:obj:`b`.

        '''

        A = np.sum([l * a for l, a in zip(self.lam[b], A)
                    if l is not None], axis=0)
        B = np.sum([l * b for l, b in zip(self.lam[b], B)
                    if l is not None], axis=0)
        W = np.linalg.solve(mK + A + C, f)
        if self.transit_model is None:
            model = np.dot(B, W)
        else:
            w_pld = np.concatenate([l * np.dot(self.X(n, m2).T, W)
                                    for n, l in enumerate(self.lam[b])
                                    if l is not None])
            model = np.dot(np.hstack(
                [self.X(n, m1) for n, l in enumerate(self.lam[b])
                 if l is not None]), w_pld)
        model -= np.nanmedian(model)

        return model

Response: Compute the model for a single chunk.


Instruction:
Write a Python 3 function that can
return a list of outliers for the current instance of the class.

Response:
def get_outliers(self):
        '''
        Performs iterative sigma clipping to get outliers.

        '''

        log.info("Clipping outliers...")
        log.info('Iter %d/%d: %d outliers' %
                 (0, self.oiter, len(self.outmask)))

        def M(x): return np.delete(x, np.concatenate(
            [self.nanmask, self.badmask, self.transitmask]), axis=0)
        t = M(self.time)
        outmask = [np.array([-1]), np.array(self.outmask)]

        # Loop as long as the last two outlier arrays aren't equal
        while not np.array_equal(outmask[-2], outmask[-1]):

            # Check if we've done this too many times
            if len(outmask) - 1 > self.oiter:
                log.error('Maximum number of iterations in ' +
                          '``get_outliers()`` exceeded. Skipping...')
                break

            # Check if we're going in circles
            if np.any([np.array_equal(outmask[-1], i) for i in outmask[:-1]]):
                log.error('Function ``get_outliers()`` ' +
                          'is going in circles. Skipping...')
                break

            # Compute the model to get the flux
            self.compute()

            # Get the outliers
            f = SavGol(M(self.flux))
            med = np.nanmedian(f)
            MAD = 1.4826 * np.nanmedian(np.abs(f - med))
            inds = np.where((f > med + self.osigma * MAD) |
                            (f < med - self.osigma * MAD))[0]

            # Project onto unmasked time array
            inds = np.array([np.argmax(self.time == t[i]) for i in inds])
            self.outmask = np.array(inds, dtype=int)

            # Add them to the running list
            outmask.append(np.array(inds))

            # Log
            log.info('Iter %d/%d: %d outliers' %
                     (len(outmask) - 2, self.oiter, len(self.outmask)))