Instruction:
How would you code a function in Python 3 to
calculate the fluxes of the source segment in a particular frequency range and returns the fluxes of the source segment in a particular frequency range.

Response:
def get_calfluxes(calflux,calfreq,spec_in,centerfreqs,oneflux):
    '''
    Given properties of the calibrator source, calculate fluxes of the source
    in a particular frequency range

    Parameters
    ----------
    calflux : float
        Known flux of calibrator source at a particular frequency
    calfreq : float
        Frequency where calibrator source has flux calflux (see above)
    spec_in : float
        Known power-law spectral index of calibrator source. Use convention flux(frequency) = constant * frequency^(spec_in)
    centerfreqs : 1D Array (float)
        Central frequency values of each coarse channel
    oneflux : boolean
        Use oneflux to choose between calculating the flux for each core channel (False)
        or using one value for the entire frequency range (True)
    '''

    const = calflux/np.power(calfreq,spec_in)
    if oneflux==False:
        return const*np.power(centerfreqs,spec_in)
    else:
        return const*np.power(np.mean(centerfreqs),spec_in)


Instruction:
Write a Python 3 script to
return the center frequency of each coarse channel in the frequency array.

Response:
def get_centerfreqs(freqs,chan_per_coarse):
    '''
    Returns central frequency of each coarse channel

    Parameters
    ----------
    freqs : 1D Array (float)
        Frequency values for each bin of the spectrum
    chan_per_coarse: int
        Number of frequency bins per coarse channel
    '''

    num_coarse = freqs.size/chan_per_coarse
    freqs = np.reshape(freqs,(num_coarse,chan_per_coarse))
    return np.mean(freqs,axis=1)


Instruction:
Can you generate a brief explanation for the following Python 3 code
def f_ratios(calON_obs,calOFF_obs,chan_per_coarse,**kwargs):
    '''
    Calculate f_ON, and f_OFF as defined in van Straten et al. 2012 equations 2 and 3

    Parameters
    ----------
    calON_obs : str
        Path to filterbank file (any format) for observation ON the calibrator source
    calOFF_obs : str
        Path to filterbank file (any format) for observation OFF the calibrator source
    '''
    #Calculate noise diode ON and noise diode OFF spectra (H and L) for both observations
    L_ON,H_ON = integrate_calib(calON_obs,chan_per_coarse,**kwargs)
    L_OFF,H_OFF = integrate_calib(calOFF_obs,chan_per_coarse,**kwargs)

    f_ON = H_ON/L_ON-1
    f_OFF = H_OFF/L_OFF-1

    return f_ON, f_OFF

Response: Calculate f_ON and f_OFF spectra for both calibration and non - calibration states.


Instruction:
Implement a function in Python 3 to
calculate the coarse channel spectrum and system temperature of the noise diode in Jy given two calibrator sources ON and OFF measurements.

Response:
def diode_spec(calON_obs,calOFF_obs,calflux,calfreq,spec_in,average=True,oneflux=False,**kwargs):
    '''
    Calculate the coarse channel spectrum and system temperature of the noise diode in Jy given two noise diode
    measurements ON and OFF the calibrator source with the same frequency and time resolution

    Parameters
    ----------
    calON_obs : str
        (see f_ratios() above)
    calOFF_obs : str
        (see f_ratios() above)
    calflux : float
        Known flux of calibrator source at a particular frequency
    calfreq : float
        Frequency where calibrator source has flux calflux (see above)
    spec_in : float
        Known power-law spectral index of calibrator source. Use convention flux(frequency) = constant * frequency^(spec_in)
    average : boolean
        Use average=True to return noise diode and Tsys spectra averaged over frequencies
    '''
    #Load frequencies and calculate number of channels per coarse channel
    obs = Waterfall(calON_obs,max_load=150)
    freqs = obs.populate_freqs()
    ncoarse = obs.calc_n_coarse_chan()
    nchans = obs.header['nchans']
    chan_per_coarse = nchans/ncoarse

    f_ON, f_OFF = f_ratios(calON_obs,calOFF_obs,chan_per_coarse,**kwargs)

    #Obtain spectrum of the calibrator source for the given frequency range
    centerfreqs = get_centerfreqs(freqs,chan_per_coarse)
    calfluxes = get_calfluxes(calflux,calfreq,spec_in,centerfreqs,oneflux)

    #C_o and Tsys as defined in van Straten et al. 2012
    C_o = calfluxes/(1/f_ON-1/f_OFF)
    Tsys = C_o/f_OFF

    #return coarse channel diode spectrum
    if average==True:
        return np.mean(C_o),np.mean(Tsys)
    else:
        return C_o,Tsys


Instruction:
Make a summary of the following Python 3 code
def get_Tsys(calON_obs,calOFF_obs,calflux,calfreq,spec_in,oneflux=False,**kwargs):
    '''
    Returns frequency dependent system temperature given observations on and off a calibrator source

    Parameters
    ----------
    (See diode_spec())
    '''
    return diode_spec(calON_obs,calOFF_obs,calflux,calfreq,spec_in,average=False,oneflux=False,**kwargs)[1]

Response: Returns frequency dependent system temperature given observations on and off a calibrator source.


Instruction:
Write a Python 3 function for
producing calibrated Stokes I for an observation given a noise diode and a frequency spectrum.

Response:
def calibrate_fluxes(main_obs_name,dio_name,dspec,Tsys,fullstokes=False,**kwargs):
    '''
    Produce calibrated Stokes I for an observation given a noise diode
    measurement on the source and a diode spectrum with the same number of
    coarse channels

    Parameters
    ----------
    main_obs_name : str
        Path to filterbank file containing final data to be calibrated
    dio_name : str
        Path to filterbank file for observation on the target source with flickering noise diode
    dspec : 1D Array (float) or float
        Coarse channel spectrum (or average) of the noise diode in Jy (obtained from diode_spec())
    Tsys : 1D Array (float) or float
        Coarse channel spectrum (or average) of the system temperature in Jy
    fullstokes: boolean
        Use fullstokes=True if data is in IQUV format or just Stokes I, use fullstokes=False if
        it is in cross_pols format
    '''

    #Find folded spectra of the target source with the noise diode ON and OFF
    main_obs = Waterfall(main_obs_name,max_load=150)
    ncoarse = main_obs.calc_n_coarse_chan()
    dio_obs = Waterfall(dio_name,max_load=150)
    dio_chan_per_coarse = dio_obs.header['nchans']/ncoarse
    dOFF,dON = integrate_calib(dio_name,dio_chan_per_coarse,fullstokes,**kwargs)

    #Find Jy/count for each coarse channel using the diode spectrum
    main_dat = main_obs.data
    scale_facs = dspec/(dON-dOFF)
    print(scale_facs)

    nchans = main_obs.header['nchans']
    obs_chan_per_coarse = nchans/ncoarse

    ax0_size = np.size(main_dat,0)
    ax1_size = np.size(main_dat,1)

    #Reshape data array of target observation and multiply coarse channels by the scale factors
    main_dat = np.reshape(main_dat,(ax0_size,ax1_size,ncoarse,obs_chan_per_coarse))
    main_dat = np.swapaxes(main_dat,2,3)

    main_dat = main_dat*scale_facs
    main_dat = main_dat-Tsys
    main_dat = np.swapaxes(main_dat,2,3)
    main_dat = np.reshape(main_dat,(ax0_size,ax1_size,nchans))

    #Write calibrated data to a new filterbank file with ".fluxcal" extension

    main_obs.data = main_dat
    main_obs.write_to_filterbank(main_obs_name[:-4]+'.fluxcal.fil')
    print('Finished: calibrated product written to ' + main_obs_name[:-4]+'.fluxcal.fil')


Instruction:
Write a Python 3 function for
returning the length of the blimpy header in bytes

Response:
def len_header(filename):
    """ Return the length of the blimpy header, in bytes

    Args:
        filename (str): name of file to open

    Returns:
        idx_end (int): length of header, in bytes
    """
    with  open(filename, 'rb') as f:
        header_sub_count = 0
        eoh_found = False
        while not eoh_found:
            header_sub = f.read(512)
            header_sub_count += 1
            if b'HEADER_END' in header_sub:
                idx_end = header_sub.index(b'HEADER_END') + len(b'HEADER_END')
                eoh_found = True
                break

        idx_end = (header_sub_count -1) * 512 + idx_end
    return idx_end


Instruction:
How would you code a function in Python 3 to
check if the file is a filterbank file or not.

Response:
def is_filterbank(filename):
    """ Open file and confirm if it is a filterbank file or not. """
    with open(filename, 'rb') as fh:
        is_fil = True

        # Check this is a blimpy file
        try:
            keyword, value, idx = read_next_header_keyword(fh)
            try:
                assert keyword == b'HEADER_START'
            except AssertionError:
                is_fil = False
        except KeyError:
            is_fil = False
        return is_fil


Instruction:
Given the following Python 3 function, write the documentation
def read_header(filename, return_idxs=False):
    with open(filename, 'rb') as fh:
        header_dict = {}
        header_idxs = {}

        # Check this is a blimpy file
        keyword, value, idx = read_next_header_keyword(fh)

        try:
            assert keyword == b'HEADER_START'
        except AssertionError:
            raise RuntimeError("Not a valid blimpy file.")

        while True:
            keyword, value, idx = read_next_header_keyword(fh)
            if keyword == b'HEADER_END':
                break
            else:
                header_dict[keyword] = value
                header_idxs[keyword] = idx

    if return_idxs:
        return header_idxs
    else:
        return header_dict

Response: Read blimpy header and return a Python dictionary of key - value pairs.


Instruction:
Can you tell what is the following Python 3 function doing
def fix_header(filename, keyword, new_value):

    # Read header data and return indexes of data offsets in file
    hd = read_header(filename)
    hi = read_header(filename, return_idxs=True)
    idx = hi[keyword]

    # Find out the datatype for the given keyword
    dtype = header_keyword_types[keyword]
    dtype_to_type = {b'<l'  : np.int32,
                     b'str' : bytes,
                     b'<d'  : np.float64,
                     b'angle' : to_sigproc_angle}
    value_dtype = dtype_to_type[dtype]

    # Generate the new string
    if isinstance(value_dtype, bytes):
        if len(hd[keyword]) == len(new_value):
            val_str = np.int32(len(new_value)).tostring() + new_value
        else:
            raise RuntimeError("String size mismatch. Cannot update without rewriting entire file.")
    else:
        val_str = value_dtype(new_value).tostring()

    # Write the new string to file
    with open(filename, 'rb+') as fh:
        fh.seek(idx)
        fh.write(val_str)

Response: Apply a quick patch - up to a Filterbank header by overwriting a header value.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def fil_double_to_angle(angle):

      negative = (angle < 0.0)
      angle = np.abs(angle)

      dd = np.floor((angle / 10000))
      angle -= 10000 * dd
      mm = np.floor((angle / 100))
      ss = angle - 100 * mm
      dd += mm/60.0 + ss/3600.0

      if negative:
          dd *= -1

      return dd

Response: Reads a little - endian double in ddmmss. s or hhmmss. s format and then converts to Float degrees or hours.


Instruction:
Given the following Python 3 function, write the documentation
def to_sigproc_keyword(keyword, value=None):

    keyword = bytes(keyword)

    if value is None:
        return np.int32(len(keyword)).tostring() + keyword
    else:
        dtype = header_keyword_types[keyword]

        dtype_to_type = {b'<l'  : np.int32,
                         b'str' : str,
                         b'<d'  : np.float64,
                         b'angle' : to_sigproc_angle}

        value_dtype = dtype_to_type[dtype]

        if value_dtype is str:
            return np.int32(len(keyword)).tostring() + keyword + np.int32(len(value)).tostring() + value
        else:
            return np.int32(len(keyword)).tostring() + keyword + value_dtype(value).tostring()

Response: Generates a serialized string for a sigproc keyword value pair


Instruction:
How would you code a function in Python 3 to
generate a serialzed sigproc header which can be written to disk.

Response:
def generate_sigproc_header(f):
    """ Generate a serialzed sigproc header which can be written to disk.

    Args:
        f (Filterbank object): Filterbank object for which to generate header

    Returns:
        header_str (str): Serialized string corresponding to header
    """

    header_string = b''
    header_string += to_sigproc_keyword(b'HEADER_START')

    for keyword in f.header.keys():
        if keyword == b'src_raj':
            header_string += to_sigproc_keyword(b'src_raj')  + to_sigproc_angle(f.header[b'src_raj'])
        elif keyword == b'src_dej':
            header_string += to_sigproc_keyword(b'src_dej')  + to_sigproc_angle(f.header[b'src_dej'])
        elif keyword == b'az_start' or keyword == b'za_start':
            header_string += to_sigproc_keyword(keyword)  + np.float64(f.header[keyword]).tostring()
        elif keyword not in header_keyword_types.keys():
            pass
        else:
            header_string += to_sigproc_keyword(keyword, f.header[keyword])

    header_string += to_sigproc_keyword(b'HEADER_END')
    return header_string


Instruction:
Can you create a Python 3 function that
converts an astropy. Angle to the ridiculous sigproc angle format string.

Response:
def to_sigproc_angle(angle_val):
    """ Convert an astropy.Angle to the ridiculous sigproc angle format string. """
    x = str(angle_val)

    if '.' in x:
        if 'h' in x:
                d, m, s, ss = int(x[0:x.index('h')]), int(x[x.index('h')+1:x.index('m')]), \
                int(x[x.index('m')+1:x.index('.')]), float(x[x.index('.'):x.index('s')])
        if 'd' in x:
            d, m, s, ss = int(x[0:x.index('d')]), int(x[x.index('d')+1:x.index('m')]), \
            int(x[x.index('m')+1:x.index('.')]), float(x[x.index('.'):x.index('s')])
    else:
        if 'h' in x:
            d, m, s = int(x[0:x.index('h')]), int(x[x.index('h')+1:x.index('m')]), \
            int(x[x.index('m')+1:x.index('s')])
        if 'd' in x:
            d, m, s = int(x[0:x.index('d')]), int(x[x.index('d')+1:x.index('m')]), \
            int(x[x.index('m')+1:x.index('s')])
        ss = 0
    num = str(d).zfill(2) + str(m).zfill(2) + str(s).zfill(2)+ '.' + str(ss).split(".")[-1]
    return np.float64(num).tostring()


Instruction:
Here you have a function in Python 3, explain what it does
def calc_n_ints_in_file(filename):
    # Load binary data
    h = read_header(filename)
    n_bytes  = int(h[b'nbits'] / 8)

    n_chans = h[b'nchans']
    n_ifs   = h[b'nifs']
    idx_data = len_header(filename)
    f = open(filename, 'rb')
    f.seek(idx_data)
    filesize = os.path.getsize(filename)
    n_bytes_data = filesize - idx_data

    if h[b'nbits'] == 2:
        n_ints = int(4 * n_bytes_data / (n_chans * n_ifs))
    else:
        n_ints = int(n_bytes_data / (n_bytes * n_chans * n_ifs))

    return n_ints

Response: Calculate the number of integrations in a given file


Instruction:
Implement a function in Python 3 to
convert a file to Sigproc filterbank format.

Response:
def make_fil_file(filename,out_dir='./', new_filename=None, max_load = None):
    ''' Converts file to Sigproc filterbank (.fil) format.  Default saves output in current dir.
    '''

    fil_file = Waterfall(filename, max_load = max_load)
    if not new_filename:
        new_filename = out_dir+filename.replace('.h5','.fil').split('/')[-1]

    if '.fil' not in new_filename:
        new_filename = new_filename+'.fil'

    fil_file.write_to_fil(new_filename)


Instruction:
Create a Python 3 function for
converting a Traceback into a dictionary representation

Response:
def to_dict(self):
        """Convert a Traceback into a dictionary representation"""
        if self.tb_next is None:
            tb_next = None
        else:
            tb_next = self.tb_next.to_dict()

        code = {
            'co_filename': self.tb_frame.f_code.co_filename,
            'co_name': self.tb_frame.f_code.co_name,
        }
        frame = {
            'f_globals': self.tb_frame.f_globals,
            'f_code': code,
        }
        return {
            'tb_frame': frame,
            'tb_lineno': self.tb_lineno,
            'tb_next': tb_next,
        }


Instruction:
How would you implement a function in Python 3 that
makes a subparser for a given type of DNS record.

Response:
def make_rr_subparser(subparsers, rec_type, args_and_types):
    """
    Make a subparser for a given type of DNS record
    """
    sp = subparsers.add_parser(rec_type)

    sp.add_argument("name", type=str)
    sp.add_argument("ttl", type=int, nargs='?')
    sp.add_argument(rec_type, type=str)

    for my_spec in args_and_types:
        (argname, argtype) = my_spec[:2]
        if len(my_spec) > 2:
            nargs = my_spec[2]
            sp.add_argument(argname, type=argtype, nargs=nargs)
        else:
            sp.add_argument(argname, type=argtype)
    return sp


Instruction:
How would you explain what the following Python 3 function does
def make_parser():
    line_parser = ZonefileLineParser()
    subparsers = line_parser.add_subparsers()

    # parse $ORIGIN
    sp = subparsers.add_parser("$ORIGIN")
    sp.add_argument("$ORIGIN", type=str)

    # parse $TTL
    sp = subparsers.add_parser("$TTL")
    sp.add_argument("$TTL", type=int)

    # parse each RR
    args_and_types = [
        ("mname", str), ("rname", str), ("serial", int), ("refresh", int),
        ("retry", int), ("expire", int), ("minimum", int)
    ]
    make_rr_subparser(subparsers, "SOA", args_and_types)

    make_rr_subparser(subparsers, "NS", [("host", str)])
    make_rr_subparser(subparsers, "A", [("ip", str)])
    make_rr_subparser(subparsers, "AAAA", [("ip", str)])
    make_rr_subparser(subparsers, "CNAME", [("alias", str)])
    make_rr_subparser(subparsers, "ALIAS", [("host", str)])
    make_rr_subparser(subparsers, "MX", [("preference", str), ("host", str)])
    make_txt_subparser(subparsers)
    make_rr_subparser(subparsers, "PTR", [("host", str)])
    make_rr_subparser(subparsers, "SRV", [("priority", int), ("weight", int), ("port", int), ("target", str)])
    make_rr_subparser(subparsers, "SPF", [("data", str)])
    make_rr_subparser(subparsers, "URI", [("priority", int), ("weight", int), ("target", str)])

    return line_parser

Response: Make an ArgumentParser that accepts DNS RRs


Instruction:
Can you implement a function in Python 3 that
serializes a list of tokens into a string.

Response:
def serialize(tokens):
    """
    Serialize tokens:
    * quote whitespace-containing tokens
    * escape semicolons
    """
    ret = []
    for tok in tokens:
        if " " in tok:
            tok = '"%s"' % tok

        if ";" in tok:
            tok = tok.replace(";", "\;")

        ret.append(tok)

    return " ".join(ret)


Instruction:
Implement a Python 3 function for
removing comments from a zonefile

Response:
def remove_comments(text):
    """
    Remove comments from a zonefile
    """
    ret = []
    lines = text.split("\n")
    for line in lines:
        if len(line) == 0:
            continue

        line = serialize(tokenize_line(line))
        ret.append(line)

    return "\n".join(ret)


Instruction:
Make a summary of the following Python 3 code
def flatten(text):
    lines = text.split("\n")

    # tokens: sequence of non-whitespace separated by '' where a newline was
    tokens = []
    for l in lines:
        if len(l) == 0:
            continue

        l = l.replace("\t", " ")
        tokens += filter(lambda x: len(x) > 0, l.split(" ")) + ['']

    # find (...) and turn it into a single line ("capture" it)
    capturing = False
    captured = []

    flattened = []
    while len(tokens) > 0:
        tok = tokens.pop(0)
        if not capturing and len(tok) == 0:
            # normal end-of-line
            if len(captured) > 0:
                flattened.append(" ".join(captured))
                captured = []
            continue

        if tok.startswith("("):
            # begin grouping
            tok = tok.lstrip("(")
            capturing = True

        if capturing and tok.endswith(")"):
            # end grouping.  next end-of-line will turn this sequence into a flat line
            tok = tok.rstrip(")")
            capturing = False

        captured.append(tok)

    return "\n".join(flattened)

Response: Flatten the text into a single line.


Instruction:
Write a Python 3 function that can
remove the CLASS from each DNS record if present.

Response:
def remove_class(text):
    """
    Remove the CLASS from each DNS record, if present.
    The only class that gets used today (for all intents
    and purposes) is 'IN'.
    """

    # see RFC 1035 for list of classes
    lines = text.split("\n")
    ret = []
    for line in lines:
        tokens = tokenize_line(line)
        tokens_upper = [t.upper() for t in tokens]

        if "IN" in tokens_upper:
            tokens.remove("IN")
        elif "CS" in tokens_upper:
            tokens.remove("CS")
        elif "CH" in tokens_upper:
            tokens.remove("CH")
        elif "HS" in tokens_upper:
            tokens.remove("HS")

        ret.append(serialize(tokens))

    return "\n".join(ret)


Instruction:
Can you implement a function in Python 3 that
adds a default name to the list of available users.

Response:
def add_default_name(text):
    """
    Go through each line of the text and ensure that
    a name is defined.  Use '@' if there is none.
    """
    global SUPPORTED_RECORDS

    lines = text.split("\n")
    ret = []
    for line in lines:
        tokens = tokenize_line(line)
        if len(tokens) == 0:
            continue

        if tokens[0] in SUPPORTED_RECORDS and not tokens[0].startswith("$"):
            # add back the name
            tokens = ['@'] + tokens

        ret.append(serialize(tokens))

    return "\n".join(ret)


Instruction:
Make a summary of the following Python 3 code
def parse_line(parser, record_token, parsed_records):

    global SUPPORTED_RECORDS

    line = " ".join(record_token)

    # match parser to record type
    if len(record_token) >= 2 and record_token[1] in SUPPORTED_RECORDS:
        # with no ttl
        record_token = [record_token[1]] + record_token
    elif len(record_token) >= 3 and record_token[2] in SUPPORTED_RECORDS:
        # with ttl
        record_token = [record_token[2]] + record_token
        if record_token[0] == "TXT":
            record_token = record_token[:2] + ["--ttl"] + record_token[2:]
    try:
        rr, unmatched = parser.parse_known_args(record_token)
        assert len(unmatched) == 0, "Unmatched fields: %s" % unmatched
    except (SystemExit, AssertionError, InvalidLineException):
        # invalid argument
        raise InvalidLineException(line)

    record_dict = rr.__dict__
    if record_token[0] == "TXT" and len(record_dict['txt']) == 1:
        record_dict['txt'] = record_dict['txt'][0]

    # what kind of record? including origin and ttl
    record_type = None
    for key in record_dict.keys():
        if key in SUPPORTED_RECORDS and (key.startswith("$") or record_dict[key] == key):
            record_type = key
            if record_dict[key] == key:
                del record_dict[key]
            break

    assert record_type is not None, "Unknown record type in %s" % rr

    # clean fields
    for field in record_dict.keys():
        if record_dict[field] is None:
            del record_dict[field]

    current_origin = record_dict.get('$ORIGIN', parsed_records.get('$ORIGIN', None))

    # special record-specific fix-ups
    if record_type == 'PTR':
        record_dict['fullname'] = record_dict['name'] + '.' + current_origin

    if len(record_dict) > 0:
        if record_type.startswith("$"):
            # put the value directly
            record_dict_key = record_type.lower()
            parsed_records[record_dict_key] = record_dict[record_type]
        else:
            record_dict_key = record_type.lower()
            parsed_records[record_dict_key].append(record_dict)

    return parsed_records

Response: Given the parser and a list of tokens and a current set of parsed records return the current set of parsed records.


Instruction:
Can you implement a function in Python 3 that
parses a zonefile into a dict.

Response:
def parse_lines(text, ignore_invalid=False):
    """
    Parse a zonefile into a dict.
    @text must be flattened--each record must be on one line.
    Also, all comments must be removed.
    """
    json_zone_file = defaultdict(list)
    record_lines = text.split("\n")
    parser = make_parser()

    for record_line in record_lines:
        record_token = tokenize_line(record_line)
        try:
            json_zone_file = parse_line(parser, record_token, json_zone_file)
        except InvalidLineException:
            if ignore_invalid:
                continue
            else:
                raise

    return json_zone_file


Instruction:
Given the following Python 3 function, write the documentation
def parse_zone_file(text, ignore_invalid=False):
    text = remove_comments(text)
    text = flatten(text)
    text = remove_class(text)
    text = add_default_name(text)
    json_zone_file = parse_lines(text, ignore_invalid=ignore_invalid)
    return json_zone_file

Response: Parse a zonefile into a dict.


Instruction:
Write a Python 3 function for
generating a DNS zonefile from a json - encoded description of the zone file and a template.

Response:
def make_zone_file(json_zone_file_input, origin=None, ttl=None, template=None):
    """
    Generate the DNS zonefile, given a json-encoded description of the
    zone file (@json_zone_file) and the template to fill in (@template)

    json_zone_file = {
        "$origin": origin server,
        "$ttl":    default time-to-live,
        "soa":     [ soa records ],
        "ns":      [ ns records ],
        "a":       [ a records ],
        "aaaa":    [ aaaa records ]
        "cname":   [ cname records ]
        "alias":   [ alias records ]
        "mx":      [ mx records ]
        "ptr":     [ ptr records ]
        "txt":     [ txt records ]
        "srv":     [ srv records ]
        "spf":     [ spf records ]
        "uri":     [ uri records ]
    }
    """

    if template is None:
        template = DEFAULT_TEMPLATE[:]

    # careful...
    json_zone_file = copy.deepcopy(json_zone_file_input)
    if origin is not None:
        json_zone_file['$origin'] = origin

    if ttl is not None:
        json_zone_file['$ttl'] = ttl

    soa_records = [json_zone_file.get('soa')] if json_zone_file.get('soa') else None

    zone_file = template
    zone_file = process_origin(json_zone_file.get('$origin', None), zone_file)
    zone_file = process_ttl(json_zone_file.get('$ttl', None), zone_file)
    zone_file = process_soa(soa_records, zone_file)
    zone_file = process_ns(json_zone_file.get('ns', None), zone_file)
    zone_file = process_a(json_zone_file.get('a', None), zone_file)
    zone_file = process_aaaa(json_zone_file.get('aaaa', None), zone_file)
    zone_file = process_cname(json_zone_file.get('cname', None), zone_file)
    zone_file = process_alias(json_zone_file.get('alias', None), zone_file)
    zone_file = process_mx(json_zone_file.get('mx', None), zone_file)
    zone_file = process_ptr(json_zone_file.get('ptr', None), zone_file)
    zone_file = process_txt(json_zone_file.get('txt', None), zone_file)
    zone_file = process_srv(json_zone_file.get('srv', None), zone_file)
    zone_file = process_spf(json_zone_file.get('spf', None), zone_file)
    zone_file = process_uri(json_zone_file.get('uri', None), zone_file)

    # remove newlines, but terminate with one
    zone_file = "\n".join(
        filter(
            lambda l: len(l.strip()) > 0, [tl.strip() for tl in zone_file.split("\n")]
        )
    ) + "\n"

    return zone_file


Instruction:
Here you have a function in Python 3, explain what it does
def process_origin(data, template):
    record = ""
    if data is not None:
        record += "$ORIGIN %s" % data

    return template.replace("{$origin}", record)

Response: Process the origin in a template.


Instruction:
How would you code a function in Python 3 to
process the TTL field in a template.

Response:
def process_ttl(data, template):
    """
    Replace {$ttl} in template with a serialized $TTL record
    """
    record = ""
    if data is not None:
        record += "$TTL %s" % data

    return template.replace("{$ttl}", record)


Instruction:
Create a Python 3 function for
processing a single SOA record in a template and return a set of serialized SOA records.

Response:
def process_soa(data, template):
    """
    Replace {SOA} in template with a set of serialized SOA records
    """
    record = template[:]

    if data is not None:

        assert len(data) == 1, "Only support one SOA RR at this time"
        data = data[0]

        soadat = []
        domain_fields = ['mname', 'rname']
        param_fields = ['serial', 'refresh', 'retry', 'expire', 'minimum']

        for f in domain_fields + param_fields:
            assert f in data.keys(), "Missing '%s' (%s)" % (f, data)

        data_name = str(data.get('name', '@'))
        soadat.append(data_name)

        if data.get('ttl') is not None:
            soadat.append( str(data['ttl']) )

        soadat.append("IN")
        soadat.append("SOA")

        for key in domain_fields:
            value = str(data[key])
            soadat.append(value)

        soadat.append("(")

        for key in param_fields:
            value = str(data[key])
            soadat.append(value)

        soadat.append(")")

        soa_txt = " ".join(soadat)
        record = record.replace("{soa}", soa_txt)

    else:
        # clear all SOA fields
        record = record.replace("{soa}", "")

    return record


Instruction:
Can you create a Python 3 function that
quotes a field in a list of DNS records. Return the new data records.

Response:
def quote_field(data, field):
    """
    Quote a field in a list of DNS records.
    Return the new data records.
    """
    if data is None:
        return None

    data_dup = copy.deepcopy(data)
    for i in xrange(0, len(data_dup)):
        data_dup[i][field] = '"%s"' % data_dup[i][field]
        data_dup[i][field] = data_dup[i][field].replace(";", "\;")

    return data_dup


Instruction:
Can you generate a brief explanation for the following Python 3 code
def process_rr(data, record_type, record_keys, field, template):
    if data is None:
        return template.replace(field, "")

    if type(record_keys) == list:
        pass
    elif type(record_keys) == str:
        record_keys = [record_keys]
    else:
        raise ValueError("Invalid record keys")

    assert type(data) == list, "Data must be a list"

    record = ""
    for i in xrange(0, len(data)):

        for record_key in record_keys:
            assert record_key in data[i].keys(), "Missing '%s'" % record_key

        record_data = []
        record_data.append( str(data[i].get('name', '@')) )
        if data[i].get('ttl') is not None:
            record_data.append( str(data[i]['ttl']) )

        record_data.append(record_type)
        record_data += [str(data[i][record_key]) for record_key in record_keys]
        record += " ".join(record_data) + "\n"

    return template.replace(field, record)

Response: Process the record_type records in the template.


Instruction:
Implement a function in Python 3 to
process TXT records in data with the serialized TXT records

Response:
def process_txt(data, template):
    """
    Replace {txt} in template with the serialized TXT records
    """
    if data is None:
        to_process = None
    else:
        # quote txt
        to_process = copy.deepcopy(data)
        for datum in to_process:
            if isinstance(datum["txt"], list):
                datum["txt"] = " ".join(['"%s"' % entry.replace(";", "\;")
                                         for entry in datum["txt"]])
            else:
                datum["txt"] = '"%s"' % datum["txt"].replace(";", "\;")
    return process_rr(to_process, "TXT", "txt", "{txt}", template)


Instruction:
Can you tell what is the following Python 3 function doing
def parse_schema_string(schema_string):
    if isinstance(schema_string, str):
        schema_string = schema_string.decode("utf8")
    schema_struct = json.loads(schema_string)

    return AvroSchemaParser().parse_schema_struct(schema_struct)

Response: Load and return a PySchema class from an avsc string


Instruction:
Explain what the following Python 3 code does
def _class_source(schema, indent):

    def_pattern = (
        "class {class_name}(pyschema.Record):\n"
        "{indent}# WARNING: This class was generated by pyschema.to_python_source\n"
        "{indent}# there is a risk that any modification made to this class will be overwritten\n"
        "{optional_namespace_def}"
        "{field_defs}\n"
    )
    if hasattr(schema, '_namespace'):
        optional_namespace_def = "{indent}_namespace = {namespace!r}\n".format(
            namespace=schema._namespace, indent=indent)
    else:
        optional_namespace_def = ""

    field_defs = [
        "{indent}{field_name} = {field!r}".format(field_name=field_name, field=field, indent=indent)
        for field_name, field in schema._fields.iteritems()
    ]
    if not field_defs:
        field_defs = ["{indent}pass".format(indent=indent)]

    return def_pattern.format(
        class_name=schema._schema_name,
        optional_namespace_def=optional_namespace_def,
        field_defs="\n".join(field_defs),
        indent=indent
    )

Response: Generate Python source code for one specific class


Instruction:
Create a Python 3 function to
dump record in json - encodable object format

Response:
def to_json_compatible(record):
    "Dump record in json-encodable object format"
    d = {}
    for fname, f in record._fields.iteritems():
        val = getattr(record, fname)
        if val is not None:
            d[fname] = f.dump(val)
    return d


Instruction:
Implement a Python 3 function for
loading from json - encodable

Response:
def from_json_compatible(schema, dct):
    "Load from json-encodable"
    kwargs = {}

    for key in dct:
        field_type = schema._fields.get(key)
        if field_type is None:
            raise ParseError("Unexpected field encountered in line for record %s: %s" % (schema.__name__, key))
        kwargs[key] = field_type.load(dct[key])

    return schema(**kwargs)


Instruction:
Can you implement a function in Python 3 that
loads a record from a json - compatible dictionary.

Response:
def load_json_dct(
        dct,
        record_store=None,
        schema=None,
        loader=from_json_compatible
):
    """ Create a Record instance from a json-compatible dictionary

    The dictionary values should have types that are json compatible,
    as if just loaded from a json serialized record string.

    :param dct:
        Python dictionary with key/value pairs for the record

    :param record_store:
        Record store to use for schema lookups (when $schema field is present)

    :param schema:
        PySchema Record class for the record to load.
        This will override any $schema fields specified in `dct`

    """
    if schema is None:
        if record_store is None:
            record_store = auto_store
        try:
            schema_name = dct.pop(SCHEMA_FIELD_NAME)
        except KeyError:
            raise ParseError((
                "Serialized record missing '{0}' "
                "record identifier and no schema supplied")
                .format(SCHEMA_FIELD_NAME)
            )
        try:
            schema = record_store.get(schema_name)
        except KeyError:
            raise ParseError(
                "Can't recognize record type %r"
                % (schema_name,), schema_name)

    # if schema is explicit, use that instead of SCHEMA_FIELD_NAME
    elif SCHEMA_FIELD_NAME in dct:
        dct.pop(SCHEMA_FIELD_NAME)

    record = loader(schema, dct)
    return record


Instruction:
Can you generate the documentation for the following Python 3 function
def loads(
        s,
        record_store=None,
        schema=None,
        loader=from_json_compatible,
        record_class=None  # deprecated in favor of schema
):
    """ Create a Record instance from a json serialized dictionary

    :param s:
        String with a json-serialized dictionary

    :param record_store:
        Record store to use for schema lookups (when $schema field is present)

    :param loader:
        Function called to fetch attributes from json. Typically shouldn't be used by end users

    :param schema:
        PySchema Record class for the record to load.
        This will override any $schema fields specified in `s`

    :param record_class:
        DEPRECATED option, old name for the `schema` parameter

    """
    if record_class is not None:
        warnings.warn(
            "The record_class parameter is deprecated in favour of schema",
            DeprecationWarning,
            stacklevel=2
        )
        schema = record_class
    if not isinstance(s, unicode):
        s = s.decode('utf8')
    if s.startswith(u"{"):
        json_dct = json.loads(s)
        return load_json_dct(json_dct, record_store, schema, loader)
    else:
        raise ParseError("Not a json record")

Response: Load a record from a json - serialized string.


Instruction:
Implement a function in Python 3 to
add a record class to the record store for retrieval at record load time.

Response:
def add_record(self, schema, _bump_stack_level=False):
        """ Add record class to record store for retrieval at record load time.

            Can be used as a class decorator
        """
        full_name = get_full_name(schema)
        has_namespace = '.' in full_name
        self._force_add(full_name, schema, _bump_stack_level, _raise_on_existing=has_namespace)
        if has_namespace and schema.__name__ not in self._schema_map:
            self._force_add(schema.__name__, schema, _bump_stack_level)
        return schema


Instruction:
Can you generate a brief explanation for the following Python 3 code
def get(self, record_name):
        if record_name in self._schema_map:
            return self._schema_map[record_name]
        else:
            last_name = record_name.split('.')[-1]
            return self._schema_map[last_name]

Response: Returns a matching record for the given name.


Instruction:
How would you implement a function in Python 3 that
returns a dictionary the field definition Should contain all fields that are required for the class

Response:
def repr_vars(self):
        """Return a dictionary the field definition

        Should contain all fields that are required for the definition of this field in a pyschema class"""
        d = OrderedDict()
        d["nullable"] = repr(self.nullable)
        d["default"] = repr(self.default)
        if self.description is not None:
            d["description"] = repr(self.description)
        return d


Instruction:
Explain what the following Python 3 code does
def mixin(cls, mixin_cls):
        for item_name in dir(mixin_cls):
            if item_name.startswith("__"):
                # don't copy magic properties
                continue
            item = getattr(mixin_cls, item_name)

            if isinstance(item, types.MethodType):
                # unbound method will cause problems
                # so get the underlying function instead
                item = item.im_func

            setattr(cls, item_name, item)
        return mixin_cls

Response: Decorator for mixing in additional functionality into field type


Instruction:
Implement a Python 3 function for
creating proper PySchema class from cls.

Response:
def from_class(metacls, cls, auto_store=True):
        """Create proper PySchema class from cls

        Any methods and attributes will be transferred to the
        new object
        """
        if auto_store:
            def wrap(cls):
                return cls
        else:
            wrap = no_auto_store()

        return wrap(metacls.__new__(
            metacls,
            cls.__name__,
            (Record,),
            dict(cls.__dict__)
        ))


Instruction:
Create a Python 3 function for
returning a python dict representing the jsonschema of a record.

Response:
def get_schema_dict(record, state=None):
    """Return a python dict representing the jsonschema of a record

    Any references to sub-schemas will be URI fragments that won't be
    resolvable without a root schema, available from get_root_schema_dict.
    """
    state = state or SchemaGeneratorState()
    schema = OrderedDict([
        ('type', 'object'),
        ('id', record._schema_name),
    ])
    fields = dict()
    for field_name, field_type in record._fields.iteritems():
        fields[field_name] = field_type.jsonschema_type_schema(state)

    required = set(fields.keys())
    schema['properties'] = fields
    schema['required'] = sorted(list(required))
    schema['additionalProperties'] = False

    state.record_schemas[record._schema_name] = schema
    return schema


Instruction:
Given the following Python 3 function, write the documentation
def get_root_schema_dict(record):
    state = SchemaGeneratorState()
    schema = get_schema_dict(record, state)
    del state.record_schemas[record._schema_name]
    if state.record_schemas:
        schema['definitions'] = dict()
        for name, sub_schema in state.record_schemas.iteritems():
            schema['definitions'][name] = sub_schema
    return schema

Response: Return a root jsonschema for a given record.


Instruction:
Implement a function in Python 3 to
load from json - encodable

Response:
def from_json_compatible(schema, dct):
    "Load from json-encodable"
    kwargs = {}

    for key in dct:
        field_type = schema._fields.get(key)
        if field_type is None:
            warnings.warn("Unexpected field encountered in line for record %s: %r" % (schema.__name__, key))
            continue
        kwargs[key] = field_type.avro_load(dct[key])

    return schema(**kwargs)


Instruction:
Make a summary of the following Python 3 code
def mr_reader(job, input_stream, loads=core.loads):
    for line in input_stream:
        yield loads(line),

Response:
Converts a file object with json serialised pyschema records
        to a stream of pyschema objects


Instruction:
Write a Python 3 function for
writing a stream of pyschema Records to a file object

Response:
def mr_writer(job, outputs, output_stream,
              stderr=sys.stderr, dumps=core.dumps):
    """ Writes a stream of json serialised pyschema Records to a file object

    Can be used as job.writer in luigi.hadoop.JobTask
    """
    for output in outputs:
        try:
            print >> output_stream, dumps(output)
        except core.ParseError, e:
            print >> stderr, e
            raise


Instruction:
Can you generate a brief explanation for the following Python 3 code
def ordereddict_push_front(dct, key, value):
    d = OrderedDict()
    d[key] = value
    d.update(dct)
    return d

Response: Set a value at the front of an OrderedDict


Instruction:
Write a Python 3 script for
generating a single filter expression for the given name and operator and value.

Response:
def gen_filter(name, op, value, is_or=False):
    """Generates a single filter expression for ``filter[]``."""
    if op not in OPERATORS:
        raise ValueError('Unknown operator {}'.format(op))
    result = u'{} {} {}'.format(name, op, escape_filter(value))
    if is_or:
        result = u'or ' + result
    return result


Instruction:
Here you have a function in Python 3, explain what it does
def from_dict(cls, d):
        if not d:
            raise ValueError('Empty dictionary!')
        items = list(d.items())
        key, value = items.pop(0)
        q = cls(key, u'=', value)
        for key, value in items:
            q = q & cls(key, u'=', value)
        return q

Response: Creates a query ( AND and = ) from a dictionary.


Instruction:
Can you create a Python 3 function that
specifies query string to use with the collection.

Response:
def query_string(self, **params):
        """Specify query string to use with the collection.

        Returns: :py:class:`SearchResult`
        """
        return SearchResult(self, self._api.get(self._href, **params))


Instruction:
Can you implement a function in Python 3 that
sends all filters to the API.

Response:
def raw_filter(self, filters):
        """Sends all filters to the API.

        No fancy, just a wrapper. Any advanced functionality shall be implemented as another method.

        Args:
            filters: List of filters (strings)

        Returns: :py:class:`SearchResult`
        """
        return SearchResult(self, self._api.get(self._href, **{"filter[]": filters}))


Instruction:
Here you have a function in Python 3, explain what it does
def all_include_attributes(self, attributes):
        self.reload(expand=True, attributes=attributes)
        entities = [Entity(self, r, attributes=attributes) for r in self._resources]
        self.reload()
        return entities

Response: Returns all entities present in the collection with attributes included.


Instruction:
Write a Python 3 function that can
return entity in correct collection.

Response:
def _get_entity_from_href(self, result):
        """Returns entity in correct collection.

        If the "href" value in result doesn't match the current collection,
        try to find the collection that the "href" refers to.
        """
        href_result = result['href']

        if self.collection._href.startswith(href_result):
            return Entity(self.collection, result, incomplete=True)

        href_match = re.match(r"(https?://.+/api[^?]*)/([a-z_-]+)", href_result)
        if not href_match:
            raise ValueError("Malformed href: {}".format(href_result))
        collection_name = href_match.group(2)
        entry_point = href_match.group(1)
        new_collection = Collection(
            self.collection.api,
            "{}/{}".format(entry_point, collection_name),
            collection_name
        )
        return Entity(new_collection, result, incomplete=True)


Instruction:
Make a summary of the following Python 3 code
def give_another_quote(q):
    for qc in QUOTES:
        if qc != q:
            return qc
    else:
        raise ValueError(u'Could not find a different quote for {}'.format(q))

Response: Returns a new quote if possible.


Instruction:
Can you generate the documentation for the following Python 3 function
def escape_filter(o):
    if o is None:
        return u'NULL'
    if isinstance(o, int):
        return str(o)
    if not isinstance(o, six.string_types):
        raise ValueError('Filters take only None, int or a string type')
    if not o:
        # Empty string
        return u"''"
    # Now enforce unicode
    o = unicode_process(o)
    if u'"' not in o:
        # Simple case, just put the quote that does not exist in the string
        return u'"' + o + u'"'
    elif u"'" not in o:
        # Simple case, just put the quote that does not exist in the string
        return u"'" + o + u"'"
    else:
        # Both are there, so start guessing
        # Empty strings are sorted out, so the string must contain something.
        # String with length == 1 are sorted out because if they have a quote, they would be quoted
        # with the another quote in preceeding branch. Therefore the string is at least 2 chars long
        # here which allows us to NOT check the length here.
        first_char = o[0]
        last_char = o[-1]
        if first_char in QUOTES and last_char in QUOTES:
            # The first and last chars definitely are quotes
            if first_char == last_char:
                # Simple, just put another ones around them
                quote = give_another_quote(first_char)
                return quote + o + quote
            else:
                # I don't like this but the nature of the escape is like that ...
                # Since now it uses both of the quotes, just pick the simple ones and surround it
                return u"'" + o + u"'"
        elif first_char not in QUOTES and last_char not in QUOTES:
            # First and last chars are not quotes, so a simple solution
            return u"'" + o + u"'"
        else:
            # One of the first or last chars is not a quote
            if first_char in QUOTES:
                quote = give_another_quote(first_char)
            else:
                # last_char
                quote = give_another_quote(last_char)
            return quote + o + quote

Response: Tries to escape the values that are passed to filter as correctly as possible.


Instruction:
Write a Python 3 function that can
make the plot with parallax performance predictions.

Response:
def makePlot(args):
  """
  Make the plot with parallax performance predictions.

  :argument args: command line arguments
  """
  gmag=np.linspace(5.7,20.0,101)

  vminiB1V=vminiFromSpt('B1V')
  vminiG2V=vminiFromSpt('G2V')
  vminiM6V=vminiFromSpt('M6V')

  vmagB1V=gmag-gminvFromVmini(vminiB1V)
  vmagG2V=gmag-gminvFromVmini(vminiG2V)
  vmagM6V=gmag-gminvFromVmini(vminiM6V)

  sigparB1V=parallaxErrorSkyAvg(gmag,vminiB1V)
  sigparB1Vmin=parallaxMinError(gmag,vminiB1V)
  sigparB1Vmax=parallaxMaxError(gmag,vminiB1V)

  sigparG2V=parallaxErrorSkyAvg(gmag,vminiG2V)
  sigparG2Vmin=parallaxMinError(gmag,vminiG2V)
  sigparG2Vmax=parallaxMaxError(gmag,vminiG2V)

  sigparM6V=parallaxErrorSkyAvg(gmag,vminiM6V)
  sigparM6Vmin=parallaxMinError(gmag,vminiM6V)
  sigparM6Vmax=parallaxMaxError(gmag,vminiM6V)

  fig=plt.figure(figsize=(10,6.5))

  if (args['gmagAbscissa']):
    plt.semilogy(gmag, sigparB1V, 'b', label='B1V')
    plt.semilogy(gmag, sigparG2V, 'g', label='G2V')
    plt.semilogy(gmag, sigparM6V, 'r', label='M6V')
    plt.xlim((5,20))
    plt.ylim((4,1000))
    plt.legend(loc=4)
    plt.xlabel('$G$ [mag]')
  else:
    ax=fig.add_subplot(111)
    plt.semilogy(vmagB1V, sigparB1V, 'b', label='B1V')
    #plt.semilogy(vmagG2V, sigparG2V, 'g', label='G2V')
    plt.semilogy(vmagM6V, sigparM6V, 'r', label='M6V')
    plt.fill_between(vmagB1V, sigparB1Vmin, sigparB1Vmax, color='b', alpha=0.3)
    plt.fill_between(vmagM6V, sigparM6Vmin, sigparM6Vmax, color='r', alpha=0.3)
    plt.xlim((5,22.5))
    plt.ylim((4,1000))
    plt.text(17.2,190,'B1V',color='b')
    plt.text(18,20,'M6V',color='r')
    plt.xlabel('$V$ [mag]')
    plt.text(7,17,'calibration noise floor', size=12, bbox=dict(boxstyle="round,pad=0.3",
                       ec=(0.0, 0.0, 0.0),
                       fc=(1.0, 1.0, 1.0),
                       ))
    plt.text(14.75,80,'photon noise', rotation=45, size=12, bbox=dict(boxstyle="round,pad=0.3",
                       ec=(0.0, 0.0, 0.0),
                       fc=(1.0, 1.0, 1.0),
                       ))
    ax.annotate('non-uniformity\nover the sky', xy=(21.5, 320),  xycoords='data',
                  xytext=(21.5,80), textcoords='data', ha='center', size='12',
                  bbox=dict(boxstyle="round,pad=0.3",ec=(0,0,0),fc=(1,1,1)),
                  arrowprops=dict(facecolor='black', shrink=0.15, width=1,
                    headwidth=6),
                  horizontalalignment='right', verticalalignment='top',
                  )
    ax.annotate('', xy=(21.5, 500),  xycoords='data',
                  xytext=(21.5,950), textcoords='data', ha='center', size='12',
                  arrowprops=dict(facecolor='black', shrink=0.15, width=1,
                    headwidth=6),
                  horizontalalignment='right', verticalalignment='bottom',
                  )

  plt.xticks(np.arange(6,24,2))
  ax = plt.gca().yaxis
  ax.set_major_formatter(matplotlib.ticker.ScalarFormatter())
  plt.ticklabel_format(axis='y',style='plain')
  plt.grid(which='both')
  plt.ylabel('End-of-mission parallax standard error [$\mu$as]')

  if (args['pdfOutput']):
    plt.savefig('ParallaxErrors.pdf')
  elif (args['pngOutput']):
    plt.savefig('ParallaxErrors.png')
  else:
    plt.show()


Instruction:
Given the following Python 3 function, write the documentation
def plotBrightLimitInV(gBright, pdf=False, png=False):
  vmini=np.linspace(0.0,6.0,1001)
  gminv=gminvFromVmini(vmini)
  vBright=gBright-gminv

  fig=plt.figure(figsize=(10,6.5))
  plt.plot(vmini,vBright,'b-')
  plt.xlabel('$(V-I)$')
  plt.ylabel('Bright limit of Gaia in $V$')
  plt.xlim(0,6)
  plt.ylim(5,11)
  plt.grid(which='both')
  plt.title("Bright limit in $G$: {0}".format(gBright))

  if (pdf):
    plt.savefig('VBandBrightLimit.pdf')
  elif (png):
    plt.savefig('VBandBrightLimit.png')
  else:
    plt.show()

Response: Plots the bright limit of Gaia in V as a function of ( V - I ).


Instruction:
Write a Python 3 function for
converting spherical coordinates to Cartesian coordinates.

Response:
def sphericalToCartesian(r, phi, theta):
  """
  Convert spherical to Cartesian coordinates. The input can be scalars or 1-dimensional numpy arrays.
  Note that the angle coordinates follow the astronomical convention of using elevation (declination,
  latitude) rather than its complement (pi/2-elevation), where the latter is commonly used in the
  mathematical treatment of spherical coordinates.

  Parameters
  ----------

  r     - length of input Cartesian vector.
  phi   - longitude-like angle (e.g., right ascension, ecliptic longitude) in radians
  theta - latitide-like angle (e.g., declination, ecliptic latitude) in radians

  Returns
  -------

  The Cartesian vector components x, y, z
  """
  ctheta=cos(theta)
  x=r*cos(phi)*ctheta
  y=r*sin(phi)*ctheta
  z=r*sin(theta)
  return x, y, z


Instruction:
Write a Python 3 function that can
convert cartesian coordinates to spherical coordinates.

Response:
def cartesianToSpherical(x, y, z):
  """
  Convert Cartesian to spherical coordinates. The input can be scalars or 1-dimensional numpy arrays.
  Note that the angle coordinates follow the astronomical convention of using elevation (declination,
  latitude) rather than its complement (pi/2-elevation), which is commonly used in the mathematical
  treatment of spherical coordinates.

  Parameters
  ----------

  x - Cartesian vector component along the X-axis
  y - Cartesian vector component along the Y-axis
  z - Cartesian vector component along the Z-axis

  Returns
  -------

  The spherical coordinates r=sqrt(x*x+y*y+z*z), longitude phi, latitude theta.

  NOTE THAT THE LONGITUDE ANGLE IS BETWEEN 0 AND +2PI. FOR r=0 AN EXCEPTION IS RAISED.
  """
  rCylSq=x*x+y*y
  r=sqrt(rCylSq+z*z)
  if any(r==0.0):
    raise Exception("Error: one or more of the points is at distance zero.")
  phi = arctan2(y,x)
  phi = where(phi<0.0, phi+2*pi, phi)
  return r, phi, arctan2(z,sqrt(rCylSq))


Instruction:
Write a Python 3 script for
returning the so - called normal triad as the vectors p q r

Response:
def normalTriad(phi, theta):
  """
  Calculate the so-called normal triad [p, q, r] which is associated with a spherical coordinate system .
  The three vectors are:

  p - The unit tangent vector in the direction of increasing longitudinal angle phi.
  q - The unit tangent vector in the direction of increasing latitudinal angle theta.
  r - The unit vector toward the point (phi, theta).

  Parameters
  ----------

  phi   - longitude-like angle (e.g., right ascension, ecliptic longitude) in radians
  theta - latitide-like angle (e.g., declination, ecliptic latitude) in radians

  Returns
  -------

  The normal triad as the vectors p, q, r
  """
  sphi=sin(phi)
  stheta=sin(theta)
  cphi=cos(phi)
  ctheta=cos(theta)
  p=array([-sphi, cphi, zeros_like(phi)])
  q=array([-stheta*cphi, -stheta*sphi, ctheta])
  r=array([ctheta*cphi, ctheta*sphi, stheta])
  return p, q, r


Instruction:
Make a summary of the following Python 3 code
def elementaryRotationMatrix(axis, rotationAngle):
  if (axis=="x" or axis=="X"):
    return array([[1.0, 0.0, 0.0], [0.0, cos(rotationAngle), sin(rotationAngle)], [0.0,
      -sin(rotationAngle), cos(rotationAngle)]])
  elif (axis=="y" or axis=="Y"):
    return array([[cos(rotationAngle), 0.0, -sin(rotationAngle)], [0.0, 1.0, 0.0], [sin(rotationAngle),
      0.0, cos(rotationAngle)]])
  elif (axis=="z" or axis=="Z"):
    return array([[cos(rotationAngle), sin(rotationAngle), 0.0], [-sin(rotationAngle),
      cos(rotationAngle), 0.0], [0.0, 0.0, 1.0]])
  else:
    raise Exception("Unknown rotation axis "+axis+"!")

Response: Constructs an elementary rotation matrix describing a rotation around the x y or z - axis.


Instruction:
Can you tell what is the following Python 3 function doing
def phaseSpaceToAstrometry(x, y, z, vx, vy, vz):
  u, phi, theta = cartesianToSpherical(x, y, z)
  parallax = _auMasParsec/u
  p, q, r = normalTriad(phi, theta)
  velocitiesArray=array([vx,vy,vz])
  if  isscalar(u):
    muphistar=dot(p,velocitiesArray)*parallax/_auKmYearPerSec
    mutheta=dot(q,velocitiesArray)*parallax/_auKmYearPerSec
    vrad=dot(r,velocitiesArray)
  else:
    muphistar=zeros_like(parallax)
    mutheta=zeros_like(parallax)
    vrad=zeros_like(parallax)
    for i in range(parallax.size):
      muphistar[i]=dot(p[:,i],velocitiesArray[:,i])*parallax[i]/_auKmYearPerSec
      mutheta[i]=dot(q[:,i],velocitiesArray[:,i])*parallax[i]/_auKmYearPerSec
      vrad[i]=dot(r[:,i],velocitiesArray[:,i])

  return phi, theta, parallax, muphistar, mutheta, vrad

Response: This function converts a phase space coordinates to astrometry observables.


Instruction:
Can you generate the documentation for the following Python 3 function
def astrometryToPhaseSpace(phi, theta, parallax, muphistar, mutheta, vrad):
  if any(parallax<=0.0):
    raise Exception("One or more of the input parallaxes is non-positive")
  x, y, z = sphericalToCartesian(_auMasParsec/parallax, phi, theta)
  p, q, r = normalTriad(phi, theta)
  transverseMotionArray = array([muphistar*_auKmYearPerSec/parallax, mutheta*_auKmYearPerSec/parallax,
    vrad])
  if isscalar(parallax):
    velocityArray=dot(transpose(array([p, q, r])),transverseMotionArray)
    vx = velocityArray[0]
    vy = velocityArray[1]
    vz = velocityArray[2]
  else:
    vx = zeros_like(parallax)
    vy = zeros_like(parallax)
    vz = zeros_like(parallax)
    for i in range(parallax.size):
      velocityArray = dot(transpose(array([p[:,i], q[:,i], r[:,i]])), transverseMotionArray[:,i])
      vx[i] = velocityArray[0]
      vy[i] = velocityArray[1]
      vz[i] = velocityArray[2]
  return x, y, z, vx, vy, vz

Response: This function calculates the phase space coordinates from the input astrometric parameters.


Instruction:
How would you explain what the following Python 3 function does
def makePlot(args):
  gmag=np.linspace(5.7,20.0,101)

  vminiB1V=vminiFromSpt('B1V')
  vminiG2V=vminiFromSpt('G2V')
  vminiM6V=vminiFromSpt('M6V')

  vmagB1V=gmag-gminvFromVmini(vminiB1V)
  vmagG2V=gmag-gminvFromVmini(vminiG2V)
  vmagM6V=gmag-gminvFromVmini(vminiM6V)

  sigmualphaB1V, sigmudeltaB1V = properMotionErrorSkyAvg(gmag,vminiB1V)
  sigmuB1V = np.sqrt(0.5*sigmualphaB1V**2+0.5*sigmudeltaB1V**2)
  sigmualphaB1V, sigmudeltaB1V = properMotionMinError(gmag,vminiB1V)
  sigmuB1Vmin = np.sqrt(0.5*sigmualphaB1V**2+0.5*sigmudeltaB1V**2)
  sigmualphaB1V, sigmudeltaB1V = properMotionMaxError(gmag,vminiB1V)
  sigmuB1Vmax = np.sqrt(0.5*sigmualphaB1V**2+0.5*sigmudeltaB1V**2)

  sigmualphaG2V, sigmudeltaG2V = properMotionErrorSkyAvg(gmag,vminiG2V)
  sigmuG2V = np.sqrt(0.5*sigmualphaG2V**2+0.5*sigmudeltaG2V**2)
  sigmualphaG2V, sigmudeltaG2V = properMotionMinError(gmag,vminiG2V)
  sigmuG2Vmin = np.sqrt(0.5*sigmualphaG2V**2+0.5*sigmudeltaG2V**2)
  sigmualphaG2V, sigmudeltaG2V = properMotionMaxError(gmag,vminiG2V)
  sigmuG2Vmax = np.sqrt(0.5*sigmualphaG2V**2+0.5*sigmudeltaG2V**2)

  sigmualphaM6V, sigmudeltaM6V = properMotionErrorSkyAvg(gmag,vminiM6V)
  sigmuM6V = np.sqrt(0.5*sigmualphaM6V**2+0.5*sigmudeltaM6V**2)
  sigmualphaM6V, sigmudeltaM6V = properMotionMinError(gmag,vminiM6V)
  sigmuM6Vmin = np.sqrt(0.5*sigmualphaM6V**2+0.5*sigmudeltaM6V**2)
  sigmualphaM6V, sigmudeltaM6V = properMotionMaxError(gmag,vminiM6V)
  sigmuM6Vmax = np.sqrt(0.5*sigmualphaM6V**2+0.5*sigmudeltaM6V**2)

  fig=plt.figure(figsize=(10,6.5))

  if (args['gmagAbscissa']):
    plt.semilogy(gmag, sigmuB1V, 'b', label='B1V')
    plt.semilogy(gmag, sigmuG2V, 'g', label='G2V')
    plt.semilogy(gmag, sigmuM6V, 'r', label='M6V')
    plt.xlim((5,20))
    plt.ylim((1,500))
    plt.legend(loc=4)
  else:
    ax=fig.add_subplot(111)
    plt.semilogy(vmagB1V, sigmuB1V, 'b', label='B1V')
    #plt.semilogy(vmagG2V, sigmuG2V, 'g', label='G2V')
    plt.semilogy(vmagM6V, sigmuM6V, 'r', label='M6V')
    plt.fill_between(vmagB1V, sigmuB1Vmin, sigmuB1Vmax, color='b', alpha=0.3)
    plt.fill_between(vmagM6V, sigmuM6Vmin, sigmuM6Vmax, color='r', alpha=0.3)
    plt.xlim((5,22.5))
    plt.ylim((1,500))
    plt.text(17.5,100,'B1V',color='b')
    plt.text(18,10,'M6V',color='r')
    plt.text(7,11,'calibration noise floor', size=12, bbox=dict(boxstyle="round,pad=0.3",
                       ec=(0.0, 0.0, 0.0),
                       fc=(1.0, 1.0, 1.0),
                       ))
    plt.text(14.75,50,'photon noise', rotation=45, size=12, bbox=dict(boxstyle="round,pad=0.3",
                       ec=(0.0, 0.0, 0.0),
                       fc=(1.0, 1.0, 1.0),
                       ))
    ax.annotate('non-uniformity\nover the sky', xy=(21.5, 80),  xycoords='data',
                  xytext=(21.5,30), textcoords='data', ha='center', size='12',
                  bbox=dict(boxstyle="round,pad=0.3",ec=(0,0,0),fc=(1,1,1)),
                  arrowprops=dict(facecolor='black', shrink=0.15, width=1,
                    headwidth=6),
                  horizontalalignment='right', verticalalignment='top',
                  )
    ax.annotate('', xy=(21.5, 170),  xycoords='data',
                  xytext=(21.5,380), textcoords='data', ha='center', size='12',
                  arrowprops=dict(facecolor='black', shrink=0.15, width=1,
                    headwidth=6),
                  horizontalalignment='right', verticalalignment='bottom',
                  )

  plt.xticks(np.arange(6,24,2))
  ax = plt.gca().yaxis
  ax.set_major_formatter(matplotlib.ticker.ScalarFormatter())
  plt.ticklabel_format(axis='y',style='plain')
  plt.grid(which='both')
  plt.xlabel('$V$ [mag]')
  plt.ylabel('End-of-mission $\\sigma_\\mu$ [$\mu$as/yr]')

  basename = 'ProperMotionErrors'
  if (args['pdfOutput']):
    plt.savefig(basename+'.pdf')
  elif (args['pngOutput']):
    plt.savefig(basename+'.png')
  else:
    plt.show()

Response:
Make the plot with the TOTAL proper
 ective motion.


Instruction:
Make a summary of the following Python 3 code
def parseCommandLineArguments():
  parser = argparse.ArgumentParser(description="Plot predicted Gaia sky averaged proper motion errors as a function of V")
  parser.add_argument("-p", action="store_true", dest="pdfOutput", help="Make PDF plot")
  parser.add_argument("-b", action="store_true", dest="pngOutput", help="Make PNG plot")
  parser.add_argument("-g", action="store_true", dest="gmagAbscissa", help="Plot performance vs G instead of V")
  args=vars(parser.parse_args())
  return args

Response: Parse command line arguments.


Instruction:
Can you generate the documentation for the following Python 3 function
def enum(typename, field_names):

    if isinstance(field_names, str):
        field_names = field_names.replace(',', ' ').split()
    d = dict((reversed(nv) for nv in enumerate(field_names)), __slots__ = ())
    return type(typename, (object,), d)()

Response: Create a new enumeration type.


Instruction:
How would you explain what the following Python 3 function does
def construct_covariance_matrix(cvec, parallax, radial_velocity, radial_velocity_error):

    if np.ndim(cvec)==1:
        cmat = np.zeros((1,6,6))
        nsources = 1
        cv = np.atleast_2d(cvec)
    else:
        nsources = cvec.shape[0]
        cmat = np.zeros((nsources,6,6))
        cv = cvec
    for k in range(nsources):
        cmat[k,0:5,0:5] = cv[k,0:5]**2

    iu = np.triu_indices(5,k=1)
    for k in range(10):
        i = iu[0][k]
        j = iu[1][k]
        cmat[:,i,j] = cv[:,i]*cv[:,j]*cv[:,k+5]
        cmat[:,j,i] = cmat[:,i,j]

    for k in range(nsources):
        cmat[k,0:5,5] = cmat[k,0:5,2]*np.atleast_1d(radial_velocity)[k]/auKmYearPerSec
    cmat[:,5,0:5] = cmat[:,0:5,5]
    cmat[:,5,5] = cmat[:,2,2]*(radial_velocity**2 + radial_velocity_error**2)/auKmYearPerSec**2 + \
            (parallax*radial_velocity_error/auKmYearPerSec)**2

    return np.squeeze(cmat)

Response: Constructs the covariance matrix for a single species.


Instruction:
Can you tell what is the following Python 3 function doing
def makePlot(gmag, pdf=False, png=False, rvs=False):
  vmini = np.linspace(-0.5,4.0,100)
  if (rvs):
    gminv = -vminGrvsFromVmini(vmini)
  else:
    gminv = gminvFromVmini(vmini)
  mvlimit100pc = gmag-5.0*np.log10(100.0)+5.0-gminv
  mvlimit1kpc = gmag-5.0*np.log10(1000.0)+5.0-gminv
  mvlimit10kpc = gmag-5.0*np.log10(10000.0)+5.0-gminv

  fig=plt.figure(figsize=(8,8))
  plt.plot(vmini,mvlimit100pc,'b')
  plt.text(vmini[50]-0.4,mvlimit100pc[50],"$d=100$ pc", horizontalalignment='right', va='top')
  plt.plot(vmini,mvlimit1kpc,'r')
  plt.text(vmini[50]-0.4,mvlimit1kpc[50],"$d=1000$ pc", horizontalalignment='right', va='top')
  plt.plot(vmini,mvlimit10kpc,'g')
  plt.text(vmini[50]-0.4,mvlimit10kpc[50],"$d=10000$ pc", horizontalalignment='right', va='top')
  ax=plt.gca()
  ax.set_ylim(ax.get_ylim()[::-1])
  plt.xlabel("$(V-I)$")
  plt.ylabel("$M_V$")
  if (rvs):
    plt.title("Distance limits for $G_\\mathrm{RVS}"+"={0}$".format(gmag))
  else:
    plt.title("Distance limits for $G={0}$".format(gmag))

  if (args['pdfOutput']):
    plt.savefig('GaiaSurveyLimits.pdf')
  elif (args['pngOutput']):
    plt.savefig('GaiaSurveyLimits.png')
  else:
    plt.show()

Response: Make a plot of a colour magnitude diagram of stars at G = 20.


Instruction:
Given the following Python 3 function, write the documentation
def vradErrorSkyAvg(vmag, spt):
  return _vradCalibrationFloor + _vradErrorBCoeff[spt]*exp(_vradErrorACoeff[spt]*(vmag-_vradMagnitudeZeroPoint))

Response: Calculates the radial velocity error from V and the spectral type.


Instruction:
Given the following Python 3 function, write the documentation
def plotCoordinateTransformationOnSky(transformation, outfile=None, myProjection='hammer',
    noTitle=False, noLabels=False, returnPlotObject=False):
    """
    Produce a sky-plot in a given coordinate system with the meridians and paralles for another
    coordinate system overlayed. The coordinate systems are specified through the
    pygaia.coordinates.Transformations enum. For example for Transformations.GAL2ECL the sky plot will be
    in Ecliptic coordinates with the Galactic coordinate grid overlayed.

    Keywords
    --------

    transformation - The coordinate transformation for which to make the plot (e.g.,
                     Transformations.GAL2ECL)
    outfile        - Save plot to this output file (default is to plot on screen). Make sure an extension
                     (.pdf, .png, etc) is included.
    myProjection   - Use this map projection (default is 'hammer', see basemap documentation)
    noTitle        - If true do not include the plot title.
    noLabels       - If true do not include plot labels.
    returnPlotObject - If true return the matplotlib object used for plotting. Further plot elements can
                       then be added.
    """
    ct = CoordinateTransformation(transformation)

    parallels=arange(-80.0,90.0,10.0)
    meridians=arange(0.0,375.0,15.0)
    meridianMax=degreesToRadians(85.0)
    parallelsMax=degreesToRadians(179.0)

    fig=plt.figure(figsize=(12,6))
    basemapInstance=Basemap(projection=myProjection,lon_0=0, celestial=True)
    basemapInstance.drawmapboundary()

    for thetaDeg in parallels:
      phi=linspace(-pi,pi,1001)
      theta=zeros_like(phi)+degreesToRadians(thetaDeg)
      phirot, thetarot = ct.transformSkyCoordinates(phi, theta)
      x ,y = basemapInstance(radiansToDegrees(phirot), radiansToDegrees(thetarot))

      indices=(phirot>=0.0)
      xplot=x[indices]
      yplot=y[indices]
      if any(indices):
        xplot, yplot = _orderGridlinePoints(xplot, yplot)
      plt.plot(xplot,yplot,'b-')

      indices=(phirot<0.0)
      xplot=x[indices]
      yplot=y[indices]
      if any(indices):
        xplot, yplot = _orderGridlinePoints(xplot, yplot)
      plt.plot(xplot,yplot,'b-')

    for phiDeg in meridians:
      theta=linspace(-meridianMax,meridianMax,1001)
      phi=zeros_like(theta)+degreesToRadians(phiDeg)
      phirot, thetarot = ct.transformSkyCoordinates(phi, theta)
      x ,y = basemapInstance(radiansToDegrees(phirot), radiansToDegrees(thetarot))

      indices=(phirot>=0.0)
      xplot=x[indices]
      yplot=y[indices]
      if any(indices):
        xplot, yplot = _orderGridlinePoints(xplot, yplot)
      plt.plot(xplot,yplot,'b-')

      indices=(phirot<0.0)
      xplot=x[indices]
      yplot=y[indices]
      if any(indices):
        xplot, yplot = _orderGridlinePoints(xplot, yplot)
      plt.plot(xplot,yplot,'b-')

    if (not noTitle):
      plt.title("Sky projection in " + ct.transformationStrings[1] + " coordinates with the corresponding " + ct.transformationStrings[0] + " grid overlayed")

    if (not noLabels):
      for theta in arange(-60,90,30):
        phirot, thetarot=ct.transformSkyCoordinates(0.0,degreesToRadians(theta))
        x, y = basemapInstance(radiansToDegrees(phirot), radiansToDegrees(thetarot))
        plt.text(x,y,"${0}$".format(theta),fontsize=16,va='bottom',ha='center',color='r')
      for phi in arange(-180,0,30):
        phirot, thetarot=ct.transformSkyCoordinates(degreesToRadians(phi),0.0)
        x, y = basemapInstance(radiansToDegrees(phirot), radiansToDegrees(thetarot))
        plt.text(x,y,"${0}$".format(phi),fontsize=16,va='bottom',ha='center',color='r')
      for phi in arange(30,180,30):
        phirot, thetarot=ct.transformSkyCoordinates(degreesToRadians(phi),0.0)
        x, y = basemapInstance(radiansToDegrees(phirot), radiansToDegrees(thetarot))
        plt.text(x,y,"${0}$".format(phi),fontsize=16,va='bottom',ha='center',color='r')

    if (outfile != None):
      plt.savefig(outfile)
    elif (returnPlotObject):
      return plt.gca(), basemapInstance
    else:
      plt.show()

Response: Plots a coordinate transformation on a sky - plot.


Instruction:
Make a summary of the following Python 3 code
def calcParallaxError(args):
  gmag=float(args['gmag'])
  vmini=float(args['vmini'])
  sigmaPar=parallaxErrorSkyAvg(gmag, vmini)
  gminv=gminvFromVmini(vmini)
  print("G = {0}".format(gmag))
  print("V = {0}".format(gmag-gminv))
  print("(V-I) = {0}".format(vmini))
  print("(G-V) = {0}".format(gminv))
  print("standard error = {0} muas".format(sigmaPar))

Response: Calculates the parallax error for the given input source magnitude and colour.


Instruction:
Write a Python 3 function for
parsing command line arguments.

Response:
def parseCommandLineArguments():
  """
  Set up command line parsing.
  """
  parser = argparse.ArgumentParser(description="Calculate parallax error for given G and (V-I)")
  parser.add_argument("gmag", help="G-band magnitude of source", type=float)
  parser.add_argument("vmini", help="(V-I) colour of source", type=float)

  args=vars(parser.parse_args())
  return args


Instruction:
Given the following Python 3 function, write the documentation
def gMagnitudeError(G):
  z=calcZ(G)
  return 1.0e-3*sqrt(0.04895*z*z + 1.8633*z + 0.0001985) * _scienceMargin

Response: Calculates the photometric standard error of a single - field - of - view transit G - band.


Instruction:
How would you code a function in Python 3 to
calculate the end of mission photometric standard error in the G - band.

Response:
def gMagnitudeErrorEoM(G, nobs=70):
  """
  Calculate the end of mission photometric standard error in the G band as a function
  of G. A 20% margin is included.

  Parameters
  ----------

  G     - Value(s) of G-band magnitude.

  Keywords
  --------

  nobs  - Number of observations collected (default 70).

  Returns
  -------

  The G band photometric standard error in units of magnitude.
  """
  return sqrt( (power(gMagnitudeError(G)/_scienceMargin,2) +
      _eomCalibrationFloorG*_eomCalibrationFloorG)/nobs ) * _scienceMargin


Instruction:
Write a Python 3 function for
calculating the photometric standard error of a single - field - of - view transit in the BP band.

Response:
def bpMagnitudeError(G, vmini):
  """
  Calculate the single-field-of-view-transit photometric standard error in the BP band as a function
  of G and (V-I). Note: this refers to the integrated flux from the BP spectrophotometer. A margin of 20%
  is included.

  Parameters
  ----------

  G     - Value(s) of G-band magnitude.
  vmini - Value(s) of (V-I) colour.

  Returns
  -------

  The BP band photometric standard error in units of magnitude.
  """
  z=calcZBpRp(G)
  a	=	-0.000562*power(vmini,3) + 0.044390*vmini*vmini + 0.355123*vmini + 1.043270
  b	=	-0.000400*power(vmini,3) + 0.018878*vmini*vmini + 0.195768*vmini + 1.465592
  c	=	+0.000262*power(vmini,3) + 0.060769*vmini*vmini - 0.205807*vmini - 1.866968
  return 1.0e-3*sqrt(power(10.0,a)*z*z+power(10.0,b)*z+power(10.0,c))


Instruction:
Can you generate a brief explanation for the following Python 3 code
def bpMagnitudeErrorEoM(G, vmini, nobs=70):
  return sqrt( (power(bpMagnitudeError(G, vmini)/_scienceMargin,2) +
      _eomCalibrationFloorBP*_eomCalibrationFloorBP)/nobs ) * _scienceMargin

Response: Calculates the end - of - mission photometric standard error in the BP band as a function of G and V - I.


Instruction:
Create a Python 3 function for
calculating the end - of - mission photometric standard error in the RP band as a function of G and V - I.

Response:
def rpMagnitudeErrorEoM(G, vmini, nobs=70):
  """
  Calculate the end-of-mission photometric standard error in the RP band as a function of G and (V-I).
  Note: this refers to the integrated flux from the RP spectrophotometer. A margin of 20% is included.

  Parameters
  ----------

  G     - Value(s) of G-band magnitude.
  vmini - Value(s) of (V-I) colour.

  Keywords
  --------

  nobs  - Number of observations collected (default 70).

  Returns
  -------

  The RP band photometric standard error in units of magnitude.
  """
  return sqrt( (power(rpMagnitudeError(G, vmini)/_scienceMargin,2) +
      _eomCalibrationFloorRP*_eomCalibrationFloorRP)/nobs ) * _scienceMargin


Instruction:
Write a Python 3 script to
make the plot with photometry performance predictions.

Response:
def makePlot(args):
  """
  Make the plot with photometry performance predictions.

  :argument args: command line arguments
  """
  gmag=np.linspace(3.0,20.0,171)

  vmini = args['vmini']

  vmag=gmag-gminvFromVmini(vmini)

  if args['eom']:
      sigmaG = gMagnitudeErrorEoM(gmag)
      sigmaGBp = bpMagnitudeErrorEoM(gmag, vmini)
      sigmaGRp = rpMagnitudeErrorEoM(gmag, vmini)
      yminmax = (1.0-4,0.1)
  else:
      sigmaG = gMagnitudeError(gmag)
      sigmaGBp = bpMagnitudeError(gmag, vmini)
      sigmaGRp = rpMagnitudeError(gmag, vmini)
      yminmax = (1.0-4,1)

  fig=plt.figure(figsize=(10,6.5))

  if (args['vmagAbscissa']):
    plt.semilogy(vmag, sigmaG, 'k', label='$\\sigma_G$')
    plt.semilogy(vmag, sigmaGBp, 'b', label='$\\sigma_{G_\\mathrm{BP}}$'+' for $(V-I)={0}$'.format(vmini))
    plt.semilogy(vmag, sigmaGRp, 'r', label='$\\sigma_{G_\\mathrm{RP}}$'+' for $(V-I)={0}$'.format(vmini))
    plt.xlim((6,20))
    #plt.ylim(yminmax)
    plt.legend(loc=0)
    plt.xlabel('$V$ [mag]')
  else:
    ax=fig.add_subplot(111)
    plt.semilogy(gmag, sigmaG, 'k', label='$\\sigma_G$')
    plt.semilogy(gmag, sigmaGBp, 'b', label='$\\sigma_{G_\\mathrm{BP}}$'+' for $(V-I)={0}$'.format(vmini))
    plt.semilogy(gmag, sigmaGRp, 'r', label='$\\sigma_{G_\\mathrm{RP}}$'+' for $(V-I)={0}$'.format(vmini))
    plt.xlim((6,20))
    #plt.ylim(yminmax)
    plt.legend(loc=0)
    plt.xlabel('$G$ [mag]')

  plt.xticks(np.arange(6,20,2))
  ax = plt.gca().yaxis
  #ax.set_major_formatter(matplotlib.ticker.ScalarFormatter())
  #plt.ticklabel_format(axis='y',style='plain')
  plt.grid(which='both')
  plt.ylabel('Photometric error [mag]')
  if args['eom']:
      plt.title('End-of-mission mean photometry: sky averaged errors for $(V-I)={0}$'.format(vmini), fontsize=14)
  else:
      plt.title('Single-FoV-transit photometry: sky averaged errors for $(V-I)={0}$'.format(vmini), fontsize=14)

  basename = 'PhotometricErrors'
  if (args['pdfOutput']):
    plt.savefig(basename+'.pdf')
  elif (args['pngOutput']):
    plt.savefig(basename+'.png')
  else:
    plt.show()


Instruction:
Create a Python 3 function for
calculating the value for the parameter z in the formula for parallax and G magnitude errors.

Response:
def calcZ(G):
  """
  Calculate the value for the parameter z in the formula for parallax and G magnitude errors as a
  function of G and (V-I).

  Parameters
  ----------

  G - Value of G-band magnitude.

  Returns
  -------

  Value of z.
  """
  gatefloor=power(10.0,0.4*(12.0-15.0))
  if isscalar(G):
   result=amax((gatefloor,power(10.0,0.4*(G-15.0))))
  else :
    result=power(10.0,0.4*(G-15.0))
    indices=(result<gatefloor)
    result[indices]=gatefloor
  return result


Instruction:
Can you generate the documentation for the following Python 3 function
def calcZBpRp(G):
  gatefloor=power(10.0,0.4*(11.0-15.0))
  if isscalar(G):
   result=amax((gatefloor,power(10.0,0.4*(G-15.0))))
  else :
    result=power(10.0,0.4*(G-15.0))
    indices=(result<gatefloor)
    result[indices]=gatefloor
  return result

Response: Calculates the value for the parameter z for BP and RP magnitude errors.


Instruction:
Given the following Python 3 function, write the documentation
def calcZAltStartGate(G):
  gatefloor=power(10.0,0.4*(13.3-15.0))
  if isscalar(G):
   result=amax((gatefloor,power(10.0,0.4*(G-15.0))))
  else :
    result=power(10.0,0.4*(G-15.0))
    indices=(result<gatefloor)
    result[indices]=gatefloor
  return result

Response: Calculates the value of z in the formula for the parallax errors.


Instruction:
Implement a Python 3 function for
returning the average number of transits across the Gaia focal plane over ecliptic latitude.

Response:
def averageNumberOfTransits(beta):
  """
  Returns the number of transits across the Gaia focal plane averaged over ecliptic longitude.

  Parameters
  ----------

  beta - Value(s) of the Ecliptic latitude.

  Returns
  -------

  Average number of transits for the input values of beta.
  """
  indices = array(floor(abs(sin(beta))*_numStepsSinBeta), dtype=int)
  indices[(indices==_numStepsSinBeta)] = _numStepsSinBeta-1
  return _averageTransitNumber[indices]


Instruction:
Here you have a function in Python 3, explain what it does
def angularDistance(phi1, theta1, phi2, theta2):
    # Formula below is more numerically stable than arccos( sin(theta1)*sin(theta2) +
    # cos(phi2-phi1)*cos(theta1)*cos(theta2) )
    # See: https://en.wikipedia.org/wiki/Great-circle_distance
    return arctan( sqrt((cos(theta2)*sin(phi2-phi1))**2 +
        (cos(theta1)*sin(theta2)-sin(theta1)*cos(theta2)*cos(phi2-phi1))**2) / (sin(theta1)*sin(theta2) +
            cos(phi2-phi1)*cos(theta1)*cos(theta2)) )

Response: Calculates the angular distance between two pairs of sky coordinates.


Instruction:
Make a summary of the following Python 3 code
def transformCartesianCoordinates(self, x, y, z):
        xrot, yrot, zrot = dot(self.rotationMatrix,[x,y,z])
        return xrot, yrot, zrot

Response: Rotates Cartesian coordinates from one reference system to another using the rotation matrix.


Instruction:
Make a summary of the following Python 3 code
def transformSkyCoordinates(self, phi, theta):
        r=ones_like(phi)
        x, y, z = sphericalToCartesian(r, phi, theta)
        xrot, yrot, zrot = self.transformCartesianCoordinates(x, y, z)
        r, phirot, thetarot = cartesianToSpherical(xrot, yrot, zrot)
        return phirot, thetarot

Response: Converts sky coordinates from one reference system to another making use of the rotation matrix with the rotation matrix with the class initialized.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def transformProperMotions(self, phi, theta, muphistar, mutheta):
        c, s = self._getJacobian(phi,theta)
        return c*muphistar+s*mutheta, c*mutheta-s*muphistar

Response: This function transforms the given longitude - like angle and proper motion values into a proper motion vector.


Instruction:
Can you create a Python 3 function that
converts the sky coordinate errors from one reference system to another, including the covariance term. Equations (1.5.4) and (1.5.20) from section 1.5 in the Hipparcos Explanatory Volume 1 are used. Parameters ---------- phi - The longitude-like angle of the position of the source (radians). theta - The latitude-like angle of the position of the source (radians). sigPhiStar - Standard error in the longitude-like angle of the position of the source (radians or sexagesimal units, including cos(latitude) term) sigTheta - Standard error in the latitude-like angle of the position of the source (radians or sexagesimal units) Keywords (optional) ------------------- rhoPhiTheta - Correlation coefficient of the position errors. Set to zero if this keyword is not provided. Retuns ------ sigPhiRotStar - The transformed standard error in the longitude-like angle (including cos(latitude) factor) sigThetaRot - The transformed standard error in the latitude-like angle. rhoPhiThetaRot - The transformed correlation coefficient.

Response:
def transformSkyCoordinateErrors(self, phi, theta, sigPhiStar, sigTheta, rhoPhiTheta=0):
        """
        Converts the sky coordinate errors from one reference system to another, including the covariance
        term. Equations (1.5.4) and (1.5.20) from section 1.5 in the Hipparcos Explanatory Volume 1 are used.

        Parameters
        ----------

        phi         - The longitude-like angle of the position of the source (radians).
        theta       - The latitude-like angle of the position of the source (radians).
        sigPhiStar  - Standard error in the longitude-like angle of the position of the source (radians or
                      sexagesimal units, including cos(latitude) term)
        sigTheta    - Standard error in the latitude-like angle of the position of the source (radians or
                      sexagesimal units)

        Keywords (optional)
        -------------------

        rhoPhiTheta - Correlation coefficient of the position errors. Set to zero if this keyword is not
                      provided.

        Retuns
        ------

        sigPhiRotStar  - The transformed standard error in the longitude-like angle (including
                         cos(latitude) factor)
        sigThetaRot    - The transformed standard error in the latitude-like angle.
        rhoPhiThetaRot - The transformed correlation coefficient.
        """
        if isscalar(rhoPhiTheta) and not isscalar(sigTheta):
            rhoPhiTheta=zeros_like(sigTheta)+rhoPhiTheta
        c, s = self._getJacobian(phi,theta)
        cSqr = c*c
        sSqr = s*s
        covar = sigPhiStar*sigTheta*rhoPhiTheta
        varPhiStar = sigPhiStar*sigPhiStar
        varTheta = sigTheta*sigTheta
        varPhiStarRot = cSqr*varPhiStar+sSqr*varTheta+2.0*covar*c*s
        varThetaRot = sSqr*varPhiStar+cSqr*varTheta-2.0*covar*c*s
        covarRot = (cSqr-sSqr)*covar+c*s*(varTheta-varPhiStar)
        return sqrt(varPhiStarRot), sqrt(varThetaRot), covarRot/sqrt(varPhiStarRot*varThetaRot)


Instruction:
Can you implement a function in Python 3 that
converts the proper motion errors from one reference system to another, including the covariance term. Equations (1.5.4) and (1.5.20) from section 1.5 in the Hipparcos Explanatory Volume 1 are used. Parameters ---------- phi - The longitude-like angle of the position of the source (radians). theta - The latitude-like angle of the position of the source (radians). sigMuPhiStar - Standard error in the proper motion in the longitude-like direction (including cos(latitude) factor). sigMuTheta - Standard error in the proper motion in the latitude-like direction. Keywords (optional) ------------------- rhoMuPhiMuTheta - Correlation coefficient of the proper motion errors. Set to zero if this keyword is not provided. Retuns ------ sigMuPhiRotStar - The transformed standard error in the proper motion in the longitude direction (including cos(latitude) factor). sigMuThetaRot - The transformed standard error in the proper motion in the longitude direction. rhoMuPhiMuThetaRot - The transformed correlation coefficient.

Response:
def transformProperMotionErrors(self, phi, theta, sigMuPhiStar, sigMuTheta, rhoMuPhiMuTheta=0):
        """
        Converts the proper motion errors from one reference system to another, including the covariance
        term. Equations (1.5.4) and (1.5.20) from section 1.5 in the Hipparcos Explanatory Volume 1 are used.

        Parameters
        ----------

        phi             - The longitude-like angle of the position of the source (radians).
        theta           - The latitude-like angle of the position of the source (radians).
        sigMuPhiStar    - Standard error in the proper motion in the longitude-like direction (including
        cos(latitude) factor).
        sigMuTheta      - Standard error in the proper motion in the latitude-like direction.

        Keywords (optional)
        -------------------

        rhoMuPhiMuTheta - Correlation coefficient of the proper motion errors. Set to zero if this
                          keyword is not provided.

        Retuns
        ------

        sigMuPhiRotStar    - The transformed standard error in the proper motion in the longitude direction
        (including cos(latitude) factor).
        sigMuThetaRot      - The transformed standard error in the proper motion in the longitude direction.
        rhoMuPhiMuThetaRot - The transformed correlation coefficient.
        """
        return self.transformSkyCoordinateErrors(phi, theta, sigMuPhiStar, sigMuTheta,
                rhoPhiTheta=rhoMuPhiMuTheta)


Instruction:
How would you code a function in Python 3 to
transform the astrometric covariance matrix to its representation in the new coordinate system.

Response:
def transformCovarianceMatrix(self, phi, theta, covmat):
        """
        Transform the astrometric covariance matrix to its representation in the new coordinate system.

        Parameters
        ----------

        phi       - The longitude-like angle of the position of the source (radians).
        theta     - The latitude-like angle of the position of the source (radians).
        covmat    - Covariance matrix (5x5) of the astrometric parameters.

        Returns
        -------

        covmat_rot - Covariance matrix in its representation in the new coordinate system.
        """

        c, s = self._getJacobian(phi,theta)
        jacobian = identity(5)
        jacobian[0][0]=c
        jacobian[1][1]=c
        jacobian[3][3]=c
        jacobian[4][4]=c
        jacobian[0][1]=s
        jacobian[1][0]=-s
        jacobian[3][4]=s
        jacobian[4][3]=-s

        return dot( dot(jacobian, covmat), jacobian.T )


Instruction:
Explain what the following Python 3 code does
def _getJacobian(self, phi, theta):

        p, q, r = normalTriad(phi, theta)

        # zRot = z-axis of new coordinate system expressed in terms of old system
        zRot = self.rotationMatrix[2,:]

        if (p.ndim == 2):
            zRotAll = tile(zRot, p.shape[1]).reshape(p.shape[1],3)
            pRot = cross(zRotAll, r.T)
            normPRot = norm(pRot,axis=1)
            for i in range(pRot.shape[0]):
                pRot[i] = pRot[i]/normPRot[i]
            c = zeros(pRot.shape[0])
            s = zeros(pRot.shape[0])
            for i in range(pRot.shape[0]):
                c[i] = dot(pRot[i], p.T[i])
                s[i] = dot(pRot[i], q.T[i])
            return c, s
        else:
            pRot = cross(zRot, r.T)
            pRot = pRot/norm(pRot)
            return dot(pRot,p), dot(pRot,q)

Response: Calculates the Jacobian for the transformation of the position errors and proper motion errors and desired coordinate system.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def propagate_astrometry(self, phi, theta, parallax, muphistar, mutheta, vrad, t0, t1):

        t = t1-t0
        p0, q0, r0 = normalTriad(phi, theta)

        # Convert input data to units of radians and Julian year. Use ICRS coordinate names internally to
        # avoid errors in translating the formulae to code.
        pmra0 = muphistar*self.mastorad
        pmdec0 = mutheta*self.mastorad
        plx0 = parallax*self.mastorad
        pmr0 = vrad*parallax/auKmYearPerSec*self.mastorad
        pmtot0sqr = (muphistar**2 + mutheta**2) * self.mastorad**2

        # Proper motion vector
        pmvec0 = pmra0*p0+pmdec0*q0

        f = (1 + 2*pmr0*t + (pmtot0sqr+pmr0**2)*t**2)**(-0.5)
        u = (r0*(1+pmr0*t) + pmvec0*t)*f

        _, phi1, theta1 = cartesianToSpherical(u[0], u[1], u[2])
        parallax1 = parallax*f
        pmr1 = (pmr0+(pmtot0sqr + pmr0**2)*t)*f**2
        pmvec1 = (pmvec0*(1+pmr0*t) - r0*pmr0**2*t)*f**3
        p1, q1, r1 = normalTriad(phi1, theta1)
        muphistar1 = sum(p1*pmvec1/self.mastorad, axis=0)
        mutheta1 = sum(q1*pmvec1/self.mastorad, axis =0)
        murad1 = pmr1/self.mastorad

        return phi1, theta1, parallax1, muphistar1, mutheta1, murad1

Response: Propagate the position of a source from the reference epoch t0 to the new epoch t1.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def propagate_pos(self, phi, theta, parallax, muphistar, mutheta, vrad, t0, t1):
        phi1, theta1, parallax1, muphistar1, mutheta1, vrad1 = self.epoch_prop_astrometry(phi, theta, parallax, muphistar, mutheta, vrad, t0, t1)
        return phi1, theta1

Response: Propagate the position of a source from the reference epoch t0 to the new epoch t1.


Instruction:
Given the following Python 3 function, write the documentation
def propagate_astrometry_and_covariance_matrix(self, a0, c0, t0, t1):

        zero, one, two, three = 0, 1, 2, 3
        tau = t1-t0

        # Calculate the normal triad [p0 q0 r0] at t0
        p0, q0, r0 = normalTriad(a0[0], a0[1])

        # Convert to internal units (radians, Julian year)
        par0 = a0[2]*self.mastorad
        pma0 = a0[3]*self.mastorad
        pmd0 = a0[4]*self.mastorad
        pmr0 = a0[5]*a0[2]/auKmYearPerSec*self.mastorad

        # Proper motion vector
        pmvec0 = pma0*p0+pmd0*q0

        # Auxiliary quantities
        tau2 = tau*tau
        pm02 = pma0**2 + pmd0**2
        w = one + pmr0*tau
        f2 = one/(one + two*pmr0*tau + (pm02+pmr0**2)*tau2)
        f = sqrt(f2)
        f3 = f2*f
        f4 = f2*f2

        # Position vector and parallax at t1
        u = (r0*w + pmvec0*tau)*f
        _, ra, dec = cartesianToSpherical(u[0], u[1], u[2])
        par = par0*f

        # Proper motion vector and radial proper motion at t1
        pmvec = (pmvec0*(one+pmr0*tau) - r0*pmr0**2*tau)*f3
        pmr = (pmr0+(pm02 + pmr0**2)*tau)*f2

        # Normal triad at t1
        p, q, r = normalTriad(ra, dec)

        # Convert parameters at t1 to external units (mas, Julian year)
        pma = sum(p*pmvec, axis=0)
        pmd = sum(q*pmvec, axis =0)

        a = zeros_like(a0)
        a[0] = ra
        a[1] = dec
        a[2] = par/self.mastorad
        a[3] = pma/self.mastorad
        a[4] = pmd/self.mastorad
        a[5] = pmr/self.mastorad

        # Auxiliary quantities for the partial derivatives

        pmz = pmvec0*f - three*pmvec*w
        pp0 = sum(p*p0, axis=0)
        pq0 = sum(p*q0, axis=0)
        pr0 = sum(p*r0, axis=0)
        qp0 = sum(q*p0, axis=0)
        qq0 = sum(q*q0, axis=0)
        qr0 = sum(q*r0, axis=0)
        ppmz = sum(p*pmz, axis=0)
        qpmz = sum(q*pmz, axis=0)

        J = zeros_like(c0)
        if (c0.ndim==2):
            J = J[newaxis,:,:]

        # Partial derivatives
        J[:,0,0] = pp0*w*f - pr0*pma0*tau*f
        J[:,0,1] = pq0*w*f - pr0*pmd0*tau*f
        J[:,0,2] = zero
        J[:,0,3] = pp0*tau*f
        J[:,0,4] = pq0*tau*f
        J[:,0,5] = -pma*tau2

        J[:,1,0] = qp0*w*f - qr0*pma0*tau*f
        J[:,1,1] = qq0*w*f - qr0*pmd0*tau*f
        J[:,1,2] = zero
        J[:,1,3] = qp0*tau*f
        J[:,1,4] = qq0*tau*f
        J[:,1,5] = -pmd*tau2

        J[:,2,0] = zero
        J[:,2,1] = zero
        J[:,2,2] = f
        J[:,2,3] = -par*pma0*tau2*f2
        J[:,2,4] = -par*pmd0*tau2*f2
        J[:,2,5] = -par*w*tau*f2

        J[:,3,0] = -pp0*pm02*tau*f3 - pr0*pma0*w*f3
        J[:,3,1] = -pq0*pm02*tau*f3 - pr0*pmd0*w*f3
        J[:,3,2] = zero
        J[:,3,3] = pp0*w*f3 - two*pr0*pma0*tau*f3 - three*pma*pma0*tau2*f2
        J[:,3,4] = pq0*w*f3 - two*pr0*pmd0*tau*f3 - three*pma*pmd0*tau2*f2
        J[:,3,5] = ppmz*tau*f2

        J[:,4,0] = -qp0*pm02*tau*f3 - qr0*pma0*w*f3
        J[:,4,1] = -qq0*pm02*tau*f3 - qr0*pmd0*w*f3
        J[:,4,2] = zero
        J[:,4,3] = qp0*w*f3 - two*qr0*pma0*tau*f3 - three*pmd*pma0*tau2*f2
        J[:,4,4] = qq0*w*f3 - two*qr0*pmd0*tau*f3 - three*pmd*pmd0*tau2*f2
        J[:,4,5] = qpmz*tau*f2

        J[:,5,0] = zero
        J[:,5,1] = zero
        J[:,5,2] = zero
        J[:,5,3] = two*pma0*w*tau*f4
        J[:,5,4] = two*pmd0*w*tau*f4
        J[:,5,5] = (w**2 - pm02*tau2)*f4

        JT = zeros_like(J)
        for i in range(J.shape[0]):
            JT[i] = J[i].T

        if (c0.ndim==2):
            c = matmul(J,matmul(c0[newaxis,:,:],JT))
        else:
            c = matmul(J,matmul(c0,JT))

        return a, squeeze(c)

Response: Propagate the astrometric parameters and radial proper motion of aCOOKIE into the new epoch t0 and t1.


Instruction:
Explain what the following Python 3 code does
def makePlot(args):
  distances = 10.0**np.linspace(1,6,10001)

  spts=['B0V', 'A0V', 'F0V', 'G0V', 'K0V', 'K4V', 'K1III']
  twokmsRV = []
  twokmsV = []
  vabsTwokms = []
  fivekmsRV = []
  fivekmsV = []
  vabsFivekms = []
  tenkmsRV = []
  tenkmsV = []
  vabsTenkms = []

  fig=plt.figure(figsize=(11,7.8))
  deltaHue = 240.0/(len(spts)-1)
  hues = (240.0-np.arange(len(spts))*deltaHue)/360.0
  hsv=np.zeros((1,1,3))
  hsv[0,0,1]=1.0
  hsv[0,0,2]=0.9
  for hue,spt in zip(hues, spts):
    hsv[0,0,0]=hue
    vmags = vabsFromSpt(spt)+5.0*np.log10(distances)-5.0
    vmini=vminiFromSpt(spt)
    grvsmags = vmags - vminGrvsFromVmini(vmini)
    rvError = vradErrorSkyAvg(vmags, spt)
    observed = (grvsmags>=5.7) & (grvsmags<=16.1)
    rvError = rvError[observed]
    # Identify the points where the relative parallax accuracy is 0.1, 1, or 10 per cent.
    if (rvError.min()<=2.0):
      index = len(rvError[rvError<=2.0])-1
      twokmsRV.append(distances[observed][index])
      twokmsV.append(vmags[observed][index])
      vabsTwokms.append(vabsFromSpt(spt))
    if (rvError.min()<=5.0):
      index = len(rvError[rvError<=5.0])-1
      fivekmsRV.append(distances[observed][index])
      fivekmsV.append(vmags[observed][index])
      vabsFivekms.append(vabsFromSpt(spt))
    if (rvError.min()<=10.0):
      index = len(rvError[rvError<=10.0])-1
      tenkmsRV.append(distances[observed][index])
      tenkmsV.append(vmags[observed][index])
      vabsTenkms.append(vabsFromSpt(spt))
    plt.semilogx(distances[observed], vmags[observed], '-', label=spt, color=hsv_to_rgb(hsv)[0,0,:])
    plt.text(distances[observed][-1], vmags[observed][-1], spt, horizontalalignment='center',
        verticalalignment='bottom', fontsize=14)

  # Draw the "contours" of constant radial velocity accuracy.
  twokmsRV = np.array(twokmsRV)
  twokmsV = np.array(twokmsV)
  indices = np.argsort(vabsTwokms)
  plt.semilogx(twokmsRV[indices],twokmsV[indices],'k--')
  plt.text(twokmsRV[indices][-1]*0.8,twokmsV[indices][-1],"$2$ km s$^{-1}$", ha='right', size=16,
      bbox=dict(boxstyle="round, pad=0.3", ec=(0.0, 0.0, 0.0), fc=(1.0, 1.0, 1.0),))

  fivekmsRV = np.array(fivekmsRV)
  fivekmsV = np.array(fivekmsV)
  indices = np.argsort(vabsFivekms)
  plt.semilogx(fivekmsRV[indices],fivekmsV[indices],'k--')
  plt.text(fivekmsRV[indices][-1]*0.8,fivekmsV[indices][-1],"$5$ km s$^{-1}$", ha='right', size=16,
      bbox=dict(boxstyle="round, pad=0.3", ec=(0.0, 0.0, 0.0), fc=(1.0, 1.0, 1.0),))

  tenkmsRV = np.array(tenkmsRV)
  tenkmsV = np.array(tenkmsV)
  indices = np.argsort(vabsTenkms)
  plt.semilogx(tenkmsRV[indices],tenkmsV[indices],'k--')
  plt.text(tenkmsRV[indices][-1]*0.8,tenkmsV[indices][-1]+0.5,"$10$ km s$^{-1}$", ha='right', size=16,
      bbox=dict(boxstyle="round, pad=0.3", ec=(0.0, 0.0, 0.0), fc=(1.0, 1.0, 1.0),))

  plt.title('Radial velocity accuracy horizons ($A_V=0$)')

  plt.xlabel('Distance [pc]')
  plt.ylabel('V')
  plt.grid()
  #leg=plt.legend(loc=4, fontsize=14, labelspacing=0.5)
  plt.ylim(5,20)

  basename='RadialVelocityHorizons'
  if (args['pdfOutput']):
    plt.savefig(basename+'.pdf')
  elif (args['pngOutput']):
    plt.savefig(basename+'.png')
  else:
    plt.show()

Response: A function to make a plot of the number of possible non - parallax horizons.


Instruction:
Write a Python 3 script for
returning the numerical factors to apply to the error of the given astrometric parameter.

Response:
def errorScalingFactor(observable, beta):
  """
  Look up the numerical factors to apply to the sky averaged parallax error in order to obtain error
  values for a given astrometric parameter, taking the Ecliptic latitude and the number of transits into
  account.

  Parameters
  ----------

  observable - Name of astrometric observable (one of: alphaStar, delta, parallax, muAlphaStar, muDelta)
  beta       - Values(s) of the Ecliptic latitude.

  Returns
  -------

  Numerical factors to apply to the errors of the given observable.
  """
  if isscalar(beta):
    index=int(floor(abs(sin(beta))*_numStepsSinBeta))
    if index == _numStepsSinBeta:
      return _astrometricErrorFactors[observable][_numStepsSinBeta-1]
    else:
      return _astrometricErrorFactors[observable][index]
  else:
    indices = array(floor(abs(sin(beta))*_numStepsSinBeta), dtype=int)
    indices[(indices==_numStepsSinBeta)] = _numStepsSinBeta-1
    return _astrometricErrorFactors[observable][indices]


Instruction:
Explain what the following Python 3 code does
def parallaxErrorSkyAvg(G, vmini, extension=0.0):
  factor = errorScalingMissionLength(extension, -0.5)
  z=calcZ(G)
  return sqrt(-1.631 + 680.766*z + 32.732*z*z)*(0.986 + (1.0 - 0.986)*vmini)*factor

Response: Calculate the parallax error from G and V - I.


Instruction:
Make a summary of the following Python 3 code
def parallaxMinError(G, vmini, extension=0.0):
  return _astrometricErrorFactors["parallax"].min()*parallaxErrorSkyAvg(G, vmini, extension=extension)

Response: Calculates the minimum parallax error from G and V - I.