Instruction:
How would you implement a function in Python 3 that
writes out a magic format record to ofile

Response:
def putout(ofile, keylist, Rec):
    """
    writes out a magic format record to ofile
    """
    pmag_out = open(ofile, 'a')
    outstring = ""
    for key in keylist:
        try:
            outstring = outstring + '\t' + str(Rec[key]).strip()
        except:
            print(key, Rec[key])
            # raw_input()
    outstring = outstring + '\n'
    pmag_out.write(outstring[1:])
    pmag_out.close()


Instruction:
Can you write a function in Python 3 where it
opens the file ofile as a magic template file with headers as the keys to Rec

Response:
def first_rec(ofile, Rec, file_type):
    """
    opens the file ofile as a magic template file with headers as the keys to Rec
    """
    keylist = []
    opened = False
    # sometimes Windows needs a little extra time to open a file
    # or else it throws an error
    while not opened:
        try:
            pmag_out = open(ofile, 'w')
            opened = True
        except IOError:
            time.sleep(1)
    outstring = "tab \t" + file_type + "\n"
    pmag_out.write(outstring)
    keystring = ""
    for key in list(Rec.keys()):
        keystring = keystring + '\t' + key.strip()
        keylist.append(key)
    keystring = keystring + '\n'
    pmag_out.write(keystring[1:])
    pmag_out.close()
    return keylist


Instruction:
How would you explain what the following Python 3 function does
def magic_write_old(ofile, Recs, file_type):
    if len(Recs) < 1:
        print ('nothing to write')
        return
    pmag_out = open(ofile, 'w')
    outstring = "tab \t" + file_type + "\n"
    pmag_out.write(outstring)
    keystring = ""
    keylist = []
    for key in list(Recs[0].keys()):
        keylist.append(key)
    keylist.sort()
    for key in keylist:
        keystring = keystring + '\t' + key.strip()
    keystring = keystring + '\n'
    pmag_out.write(keystring[1:])
    for Rec in Recs:
        outstring = ""
        for key in keylist:
            try:
                outstring = outstring + '\t' + str(Rec[key].strip())
            except:
                if 'er_specimen_name' in list(Rec.keys()):
                    print(Rec['er_specimen_name'])
                elif 'er_specimen_names' in list(Rec.keys()):
                    print(Rec['er_specimen_names'])
                print(key, Rec[key])
                # raw_input()
        outstring = outstring + '\n'
        pmag_out.write(outstring[1:])
    pmag_out.close()

Response: This function writes out a MagIC formatted file from a list of dictionaries in MagIC format


Instruction:
Here you have a function in Python 3, explain what it does
def dotilt(dec, inc, bed_az, bed_dip):
    rad = old_div(np.pi, 180.)  # converts from degrees to radians
    X = dir2cart([dec, inc, 1.])  # get cartesian coordinates of dec,inc
# get some sines and cosines of new coordinate system
    sa, ca = -np.sin(bed_az * rad), np.cos(bed_az * rad)
    cdp, sdp = np.cos(bed_dip * rad), np.sin(bed_dip * rad)
# do the rotation
    xc = X[0] * (sa * sa + ca * ca * cdp) + X[1] * \
        (ca * sa * (1. - cdp)) + X[2] * sdp * ca
    yc = X[0] * ca * sa * (1. - cdp) + X[1] * \
        (ca * ca + sa * sa * cdp) - X[2] * sa * sdp
    zc = X[0] * ca * sdp - X[1] * sdp * sa - X[2] * cdp
# convert back to direction:
    Dir = cart2dir([xc, yc, -zc])
    # return declination, inclination of rotated direction
    return Dir[0], Dir[1]

Response: Returns a tuple of declination inclination and rotation of a new tilt.


Instruction:
Here you have a function in Python 3, explain what it does
def dotilt_V(indat):
    indat = indat.transpose()
    # unpack input array into separate arrays
    dec, inc, bed_az, bed_dip = indat[0], indat[1], indat[2], indat[3]
    rad = old_div(np.pi, 180.)  # convert to radians
    Dir = np.array([dec, inc]).transpose()
    X = dir2cart(Dir).transpose()  # get cartesian coordinates
    N = np.size(dec)

# get some sines and cosines of new coordinate system
    sa, ca = -np.sin(bed_az * rad), np.cos(bed_az * rad)
    cdp, sdp = np.cos(bed_dip * rad), np.sin(bed_dip * rad)
# do the rotation
    xc = X[0] * (sa * sa + ca * ca * cdp) + X[1] * \
        (ca * sa * (1. - cdp)) + X[2] * sdp * ca
    yc = X[0] * ca * sa * (1. - cdp) + X[1] * \
        (ca * ca + sa * sa * cdp) - X[2] * sa * sdp
    zc = X[0] * ca * sdp - X[1] * sdp * sa - X[2] * cdp
# convert back to direction:
    cart = np.array([xc, yc, -zc]).transpose()
    Dir = cart2dir(cart).transpose()
    # return declination, inclination arrays of rotated direction
    return Dir[0], Dir[1]

Response: This function does a tilt correction on an array with rows of dec inc bed az direction and dip.


Instruction:
Can you implement a function in Python 3 that
rotates declination and inclination into geographic coordinates using the Z direction of the lab arrow of the X direction.

Response:
def dogeo(dec, inc, az, pl):
    """
    Rotates declination and inclination into geographic coordinates using the
    azimuth and plunge of the X direction (lab arrow) of a specimen.

    Parameters
    ----------
    dec : declination in specimen coordinates
    inc : inclination in specimen coordinates

    Returns
    -------
    rotated_direction : tuple of declination, inclination in geographic coordinates

    Examples
    --------
    >>> pmag.dogeo(0.0,90.0,0.0,45.5)
    (180.0, 44.5)
    """
    A1, A2, A3 = [], [], []  # set up lists for rotation vector
    # put dec inc in direction list and set  length to unity
    Dir = [dec, inc, 1.]
    X = dir2cart(Dir)  # get cartesian coordinates
#
#   set up rotation matrix
#
    A1 = dir2cart([az, pl, 1.])
    A2 = dir2cart([az + 90., 0, 1.])
    A3 = dir2cart([az - 180., 90. - pl, 1.])
#
# do rotation
#
    xp = A1[0] * X[0] + A2[0] * X[1] + A3[0] * X[2]
    yp = A1[1] * X[0] + A2[1] * X[1] + A3[1] * X[2]
    zp = A1[2] * X[0] + A2[2] * X[1] + A3[2] * X[2]
#
# transform back to dec,inc
#
    Dir_geo = cart2dir([xp, yp, zp])
    return Dir_geo[0], Dir_geo[1]


Instruction:
Can you tell what is the following Python 3 function doing
def dogeo_V(indat):
    indat = indat.transpose()
    # unpack input array into separate arrays
    dec, inc, az, pl = indat[0], indat[1], indat[2], indat[3]
    Dir = np.array([dec, inc]).transpose()
    X = dir2cart(Dir).transpose()  # get cartesian coordinates
    N = np.size(dec)
    A1 = dir2cart(np.array([az, pl, np.ones(N)]).transpose()).transpose()
    A2 = dir2cart(
        np.array([az + 90., np.zeros(N), np.ones(N)]).transpose()).transpose()
    A3 = dir2cart(
        np.array([az - 180., 90. - pl, np.ones(N)]).transpose()).transpose()

# do rotation
#
    xp = A1[0] * X[0] + A2[0] * X[1] + A3[0] * X[2]
    yp = A1[1] * X[0] + A2[1] * X[1] + A3[1] * X[2]
    zp = A1[2] * X[0] + A2[2] * X[1] + A3[2] * X[2]
    cart = np.array([xp, yp, zp]).transpose()
#
# transform back to dec,inc
#
    Dir_geo = cart2dir(cart).transpose()
    # send back declination and inclination arrays
    return Dir_geo[0], Dir_geo[1]

Response: This function takes a nested list of dec inc az and plunge and returns a list of arrays of dec inc az pl and X direction.


Instruction:
Write a Python 3 script to
rotate a single object in the order in which it is in the mean direction.

Response:
def dodirot(D, I, Dbar, Ibar):
    """
    Rotate a direction (declination, inclination) by the difference between
    dec=0 and inc = 90 and the provided desired mean direction

    Parameters
    ----------
    D : declination to be rotated
    I : inclination to be rotated
    Dbar : declination of desired mean
    Ibar : inclination of desired mean

    Returns
    ----------
    drot, irot : rotated declination and inclination
    """
    d, irot = dogeo(D, I, Dbar, 90. - Ibar)
    drot = d - 180.
    if drot < 360.:
        drot = drot + 360.
    if drot > 360.:
        drot = drot - 360.
    return drot, irot


Instruction:
Write a Python 3 function that can
rotate an array of dec and inc pairs to coordinate system with Dec Inc as 0 90

Response:
def dodirot_V(di_block, Dbar, Ibar):
    """
    Rotate an array of dec/inc pairs to coordinate system with Dec,Inc as 0,90

    Parameters
    ___________________
    di_block : array of [[Dec1,Inc1],[Dec2,Inc2],....]
    Dbar : declination of desired center
    Ibar : inclination of desired center

    Returns
    __________
    array of rotated decs and incs: [[rot_Dec1,rot_Inc1],[rot_Dec2,rot_Inc2],....]
    """
    N = di_block.shape[0]
    DipDir, Dip = np.ones(N, dtype=np.float).transpose(
    )*(Dbar-180.), np.ones(N, dtype=np.float).transpose()*(90.-Ibar)
    di_block = di_block.transpose()
    data = np.array([di_block[0], di_block[1], DipDir, Dip]).transpose()
    drot, irot = dotilt_V(data)
    drot = (drot-180.) % 360.  #
    return np.column_stack((drot, irot))


Instruction:
How would you implement a function in Python 3 that
finds the orientation info for a given samp

Response:
def find_samp_rec(s, data, az_type):
    """
    find the orientation info for samp s
    """
    datablock, or_error, bed_error = [], 0, 0
    orient = {}
    orient["sample_dip"] = ""
    orient["sample_azimuth"] = ""
    orient['sample_description'] = ""
    for rec in data:
        if rec["er_sample_name"].lower() == s.lower():
            if 'sample_orientation_flag' in list(rec.keys()) and rec['sample_orientation_flag'] == 'b':
                orient['sample_orientation_flag'] = 'b'
                return orient
            if "magic_method_codes" in list(rec.keys()) and az_type != "0":
                methods = rec["magic_method_codes"].replace(" ", "").split(":")
                if az_type in methods and "sample_azimuth" in list(rec.keys()) and rec["sample_azimuth"] != "":
                    orient["sample_azimuth"] = float(rec["sample_azimuth"])
                if "sample_dip" in list(rec.keys()) and rec["sample_dip"] != "":
                    orient["sample_dip"] = float(rec["sample_dip"])
                if "sample_bed_dip_direction" in list(rec.keys()) and rec["sample_bed_dip_direction"] != "":
                    orient["sample_bed_dip_direction"] = float(
                        rec["sample_bed_dip_direction"])
                if "sample_bed_dip" in list(rec.keys()) and rec["sample_bed_dip"] != "":
                    orient["sample_bed_dip"] = float(rec["sample_bed_dip"])
            else:
                if "sample_azimuth" in list(rec.keys()):
                    orient["sample_azimuth"] = float(rec["sample_azimuth"])
                if "sample_dip" in list(rec.keys()):
                    orient["sample_dip"] = float(rec["sample_dip"])
                if "sample_bed_dip_direction" in list(rec.keys()):
                    orient["sample_bed_dip_direction"] = float(
                        rec["sample_bed_dip_direction"])
                if "sample_bed_dip" in list(rec.keys()):
                    orient["sample_bed_dip"] = float(rec["sample_bed_dip"])
                if 'sample_description' in list(rec.keys()):
                    orient['sample_description'] = rec['sample_description']
        if orient["sample_azimuth"] != "":
            break
    return orient


Instruction:
Can you generate a brief explanation for the following Python 3 code
def Vdiff(D1, D2):
    A = dir2cart([D1[0], D1[1], 1.])
    B = dir2cart([D2[0], D2[1], 1.])
    C = []
    for i in range(3):
        C.append(A[i] - B[i])
    return cart2dir(C)

Response: returns the vector difference between two directions D1 D2


Instruction:
Can you tell what is the following Python 3 function doing
def cart2dir(cart):
    cart = np.array(cart)
    rad = old_div(np.pi, 180.)  # constant to convert degrees to radians
    if len(cart.shape) > 1:
        Xs, Ys, Zs = cart[:, 0], cart[:, 1], cart[:, 2]
    else:  # single vector
        Xs, Ys, Zs = cart[0], cart[1], cart[2]
    if np.iscomplexobj(Xs):
        Xs = Xs.real
    if np.iscomplexobj(Ys):
        Ys = Ys.real
    if np.iscomplexobj(Zs):
        Zs = Zs.real
    Rs = np.sqrt(Xs**2 + Ys**2 + Zs**2)  # calculate resultant vector length
    # calculate declination taking care of correct quadrants (arctan2) and
    # making modulo 360.
    Decs = (old_div(np.arctan2(Ys, Xs), rad)) % 360.
    try:
        # calculate inclination (converting to degrees) #
        Incs = old_div(np.arcsin(old_div(Zs, Rs)), rad)
    except:
        print('trouble in cart2dir')  # most likely division by zero somewhere
        return np.zeros(3)

    return np.array([Decs, Incs, Rs]).transpose()

Response: Converts a direction in cartesian coordinates into declination inclination intensity


Instruction:
Can you implement a function in Python 3 that
returns the orientation matrix of the archive X

Response:
def Tmatrix(X):
    """
    gets the orientation matrix (T) from data in X
    """
    T = [[0., 0., 0.], [0., 0., 0.], [0., 0., 0.]]
    for row in X:
        for k in range(3):
            for l in range(3):
                T[k][l] += row[k] * row[l]
    return T


Instruction:
Write a Python 3 script for
converting a list or array of vector directions in degrees ( declination inclination ) to an array of the direction in cartesian coordinates x y z

Response:
def dir2cart(d):
    """
    Converts a list or array of vector directions in degrees (declination,
    inclination) to an array of the direction in cartesian coordinates (x,y,z)

    Parameters
    ----------
    d : list or array of [dec,inc] or [dec,inc,intensity]

    Returns
    -------
    cart : array of [x,y,z]

    Examples
    --------
    >>> pmag.dir2cart([200,40,1])
    array([-0.71984631, -0.26200263,  0.64278761])
    """
    ints = np.ones(len(d)).transpose(
    )  # get an array of ones to plug into dec,inc pairs
    d = np.array(d)
    rad = np.pi/180.
    if len(d.shape) > 1:  # array of vectors
        decs, incs = d[:, 0] * rad, d[:, 1] * rad
        if d.shape[1] == 3:
            ints = d[:, 2]  # take the given lengths
    else:  # single vector
        decs, incs = np.array(float(d[0])) * rad, np.array(float(d[1])) * rad
        if len(d) == 3:
            ints = np.array(d[2])
        else:
            ints = np.array([1.])
    cart = np.array([ints * np.cos(decs) * np.cos(incs), ints *
                     np.sin(decs) * np.cos(incs), ints * np.sin(incs)]).transpose()
    return cart


Instruction:
Can you generate the documentation for the following Python 3 function
def findrec(s, data):
    datablock = []
    for rec in data:
        if s == rec[0]:
            datablock.append([rec[1], rec[2], rec[3], rec[4]])
    return datablock

Response: finds all the records belonging to s in data


Instruction:
Can you write a function in Python 3 where it
gets average direction using Fisher or principal component analysis

Response:
def domean(data, start, end, calculation_type):
    """
    Gets average direction using Fisher or principal component analysis (line
    or plane) methods

    Parameters
    ----------
    data : nest list of data: [[treatment,dec,inc,int,quality],...]
    start : step being used as start of fit (often temperature minimum)
    end : step being used as end of fit (often temperature maximum)
    calculation_type : string describing type of calculation to be made
    'DE-BFL' (line), 'DE-BFL-A' (line-anchored), 'DE-BFL-O' (line-with-origin),
    'DE-BFP' (plane), 'DE-FM' (Fisher mean)

    Returns
    -------
    mpars : dictionary with the keys "specimen_n","measurement_step_min",
    "measurement_step_max","specimen_mad","specimen_dec","specimen_inc"
    """
    mpars = {}
    datablock = []
    start0, end0 = start, end
    # indata = [rec.append('g') if len(rec)<6 else rec for rec in indata] #
    # this statement doesn't work!
    indata = []
    for rec in data:
        if len(rec) < 6:
            rec.append('g')
        indata.append(rec)
    if indata[start0][5] == 'b':
        print("Can't select 'bad' point as start for PCA")
    flags = [x[5] for x in indata]
    bad_before_start = flags[:start0].count('b')
    bad_in_mean = flags[start0:end0 + 1].count('b')
    start = start0 - bad_before_start
    end = end0 - bad_before_start - bad_in_mean
    datablock = [x for x in indata if x[5] == 'g']
    if indata[start0] != datablock[start]:
        print('problem removing bad data in pmag.domean start of datablock shifted:\norigional: %d\nafter removal: %d' % (
            start0, indata.index(datablock[start])))
    if indata[end0] != datablock[end]:
        print('problem removing bad data in pmag.domean end of datablock shifted:\norigional: %d\nafter removal: %d' % (
            end0, indata.index(datablock[end])))
    mpars["calculation_type"] = calculation_type
    rad = old_div(np.pi, 180.)
    if end > len(datablock) - 1 or end < start:
        end = len(datablock) - 1
    control, data, X, Nrec = [], [], [], float(end - start + 1)
    cm = [0., 0., 0.]
#
#  get cartesian coordinates
#
    fdata = []
    for k in range(start, end + 1):
        if calculation_type == 'DE-BFL' or calculation_type == 'DE-BFL-A' or calculation_type == 'DE-BFL-O':  # best-fit line
            data = [datablock[k][1], datablock[k][2], datablock[k][3]]
        else:
            data = [datablock[k][1], datablock[k][2], 1.0]  # unit weight
        fdata.append(data)
        cart = dir2cart(data)
        X.append(cart)
    if calculation_type == 'DE-BFL-O':  # include origin as point
        X.append([0., 0., 0.])
        # pass
    if calculation_type == 'DE-FM':  # for fisher means
        fpars = fisher_mean(fdata)
        mpars["specimen_direction_type"] = 'l'
        mpars["specimen_dec"] = fpars["dec"]
        mpars["specimen_inc"] = fpars["inc"]
        mpars["specimen_alpha95"] = fpars["alpha95"]
        mpars["specimen_n"] = fpars["n"]
        mpars["specimen_r"] = fpars["r"]
        mpars["measurement_step_min"] = indata[start0][0]
        mpars["measurement_step_max"] = indata[end0][0]
        mpars["center_of_mass"] = cm
        mpars["specimen_dang"] = -1
        return mpars
#
#   get center of mass for principal components (DE-BFL or DE-BFP)
#
    for cart in X:
        for l in range(3):
            cm[l] += old_div(cart[l], Nrec)
    mpars["center_of_mass"] = cm

#
#   transform to center of mass (if best-fit line)
#
    if calculation_type != 'DE-BFP':
        mpars["specimen_direction_type"] = 'l'
    if calculation_type == 'DE-BFL' or calculation_type == 'DE-BFL-O':  # not for planes or anchored lines
        for k in range(len(X)):
            for l in range(3):
                X[k][l] = X[k][l] - cm[l]
    else:
        mpars["specimen_direction_type"] = 'p'

#
#   put in T matrix
#
    T = np.array(Tmatrix(X))
#
#   get sorted evals/evects
#
    t, V = tauV(T)
    if t == []:
        mpars["specimen_direction_type"] = "Error"
        print("Error in calculation")
        return mpars
    v1, v3 = V[0], V[2]
    if t[2] < 0:
        t[2] = 0  # make positive
    if calculation_type == 'DE-BFL-A':
        Dir, R = vector_mean(fdata)
        mpars["specimen_direction_type"] = 'l'
        mpars["specimen_dec"] = Dir[0]
        mpars["specimen_inc"] = Dir[1]
        mpars["specimen_n"] = len(fdata)
        mpars["measurement_step_min"] = indata[start0][0]
        mpars["measurement_step_max"] = indata[end0][0]
        mpars["center_of_mass"] = cm
        s1 = np.sqrt(t[0])
        MAD = old_div(np.arctan(old_div(np.sqrt(t[1] + t[2]), s1)), rad)
        if np.iscomplexobj(MAD):
            MAD = MAD.real
        # I think this is how it is done - i never anchor the "PCA" - check
        mpars["specimen_mad"] = MAD
        return mpars
    if calculation_type != 'DE-BFP':
        #
        #   get control vector for principal component direction
        #
        rec = [datablock[start][1], datablock[start][2], datablock[start][3]]
        P1 = dir2cart(rec)
        rec = [datablock[end][1], datablock[end][2], datablock[end][3]]
        P2 = dir2cart(rec)
#
#   get right direction along principal component
##
        for k in range(3):
            control.append(P1[k] - P2[k])
        # changed by rshaar
        # control is taken as the center of mass
        # control=cm

        dot = 0
        for k in range(3):
            dot += v1[k] * control[k]
        if dot < -1:
            dot = -1
        if dot > 1:
            dot = 1
        if np.arccos(dot) > old_div(np.pi, 2.):
            for k in range(3):
                v1[k] = -v1[k]
#   get right direction along principal component
#
        s1 = np.sqrt(t[0])
        Dir = cart2dir(v1)
        MAD = old_div(np.arctan(old_div(np.sqrt(t[1] + t[2]), s1)), rad)
        if np.iscomplexobj(MAD):
            MAD = MAD.real
    if calculation_type == "DE-BFP":
        Dir = cart2dir(v3)
        MAD = old_div(
            np.arctan(np.sqrt(old_div(t[2], t[1]) + old_div(t[2], t[0]))), rad)
        if np.iscomplexobj(MAD):
            MAD = MAD.real
#
#   get angle with  center of mass
#
    CMdir = cart2dir(cm)
    Dirp = [Dir[0], Dir[1], 1.]
    dang = angle(CMdir, Dirp)
    mpars["specimen_dec"] = Dir[0]
    mpars["specimen_inc"] = Dir[1]
    mpars["specimen_mad"] = MAD
    # mpars["specimen_n"]=int(Nrec)
    mpars["specimen_n"] = len(X)
    mpars["specimen_dang"] = dang[0]
    mpars["measurement_step_min"] = indata[start0][0]
    mpars["measurement_step_max"] = indata[end0][0]
    return mpars


Instruction:
Create a Python 3 function to
function to calculate points on a circle about dec dip with angle alpha

Response:
def circ(dec, dip, alpha):
    """
    function to calculate points on an circle about dec,dip with angle alpha
    """
    rad = old_div(np.pi, 180.)
    D_out, I_out = [], []
    dec, dip, alpha = dec * rad, dip * rad, alpha * rad
    dec1 = dec + old_div(np.pi, 2.)
    isign = 1
    if dip != 0:
        isign = (old_div(abs(dip), dip))
    dip1 = (dip - isign * (old_div(np.pi, 2.)))
    t = [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
    v = [0, 0, 0]
    t[0][2] = np.cos(dec) * np.cos(dip)
    t[1][2] = np.sin(dec) * np.cos(dip)
    t[2][2] = np.sin(dip)
    t[0][1] = np.cos(dec) * np.cos(dip1)
    t[1][1] = np.sin(dec) * np.cos(dip1)
    t[2][1] = np.sin(dip1)
    t[0][0] = np.cos(dec1)
    t[1][0] = np.sin(dec1)
    t[2][0] = 0
    for i in range(101):
        psi = float(i) * np.pi / 50.
        v[0] = np.sin(alpha) * np.cos(psi)
        v[1] = np.sin(alpha) * np.sin(psi)
        v[2] = np.sqrt(abs(1. - v[0]**2 - v[1]**2))
        elli = [0, 0, 0]
        for j in range(3):
            for k in range(3):
                elli[j] = elli[j] + t[j][k] * v[k]
        Dir = cart2dir(elli)
        D_out.append(Dir[0])
        I_out.append(Dir[1])
    return D_out, I_out


Instruction:
Write a Python 3 script for
calculating the paleointensity magic parameters

Response:
def PintPars(datablock, araiblock, zijdblock, start, end, accept, **kwargs):
    """
     calculate the paleointensity magic parameters  make some definitions
    """
    if 'version' in list(kwargs.keys()) and kwargs['version'] == 3:
        meth_key = 'method_codes'
        beta_key = 'int_b_beta'
        temp_key, min_key, max_key = 'treat_temp', 'meas_step_min', 'meas_step_max'
        dc_theta_key, dc_phi_key = 'treat_dc_field_theta', 'treat_dc_field_phi'
        # convert dataframe to list of dictionaries
        datablock = datablock.to_dict('records')
        z_key = 'int_z'
        drats_key = 'int_drats'
        drat_key = 'int_drat'
        md_key = 'int_md'
        dec_key = 'dir_dec'
        inc_key = 'dir_inc'
        mad_key = 'int_mad_free'
        dang_key = 'int_dang'
        ptrm_key = 'int_n_ptrm'
        theta_key = 'int_theta'
        gamma_key = 'int_gamma'
        delta_key = 'int_delta'
        frac_key = 'int_frac'
        gmax_key = 'int_gmax'
        scat_key = 'int_scat'
    else:
        beta_key = 'specimen_b_beta'
        meth_key = 'magic_method_codes'
        temp_key, min_key, max_key = 'treatment_temp', 'measurement_step_min', 'measurement_step_max'
        z_key = 'specimen_z'
        drats_key = 'specimen_drats'
        drat_key = 'specimen_drat'
        md_key = 'specimen_md'
        dec_key = 'specimen_dec'
        inc_key = 'specimen_inc'
        mad_key = 'specimen_int_mad'
        dang_key = 'specimen_dang'
        ptrm_key = 'specimen_int_ptrm_n'
        theta_key = 'specimen_theta'
        gamma_key = 'specimen_gamma'
        delta_key = 'specimen_delta'
        frac_key = 'specimen_frac'
        gmax_key = 'specimen_gmax'
        scat_key = 'specimen_scat'

    first_Z, first_I, zptrm_check, ptrm_check, ptrm_tail = [], [], [], [], []
    methcode, ThetaChecks, DeltaChecks, GammaChecks = "", "", "", ""
    zptrm_check = []
    first_Z, first_I, ptrm_check, ptrm_tail, zptrm_check, GammaChecks = araiblock[
        0], araiblock[1], araiblock[2], araiblock[3], araiblock[4], araiblock[5]
    if len(araiblock) > 6:
        # used only for perpendicular method of paleointensity
        ThetaChecks = araiblock[6]
        # used only for perpendicular  method of paleointensity
        DeltaChecks = araiblock[7]
    xi, yi, diffcum = [], [], 0
    xiz, xzi, yiz, yzi = [], [], [], []
    Nptrm, dmax = 0, -1e-22
# check if even zero and infield steps
    if len(first_Z) > len(first_I):
        maxe = len(first_I) - 1
    else:
        maxe = len(first_Z) - 1
    if end == 0 or end > maxe:
        end = maxe
# get the MAD, DANG, etc. for directional data
    bstep = araiblock[0][start][0]
    estep = araiblock[0][end][0]
    zstart, zend = 0, len(zijdblock)
    for k in range(len(zijdblock)):
        zrec = zijdblock[k]
        if zrec[0] == bstep:
            zstart = k
        if zrec[0] == estep:
            zend = k
    PCA = domean(zijdblock, zstart, zend, 'DE-BFL')
    D, Diz, Dzi, Du = [], [], [], []  # list of NRM vectors, and separated by zi and iz
    for rec in zijdblock:
        D.append((rec[1], rec[2], rec[3]))
        Du.append((rec[1], rec[2]))
        if rec[4] == 1:
            Dzi.append((rec[1], rec[2]))  # if this is ZI step
        else:
            Diz.append((rec[1], rec[2]))  # if this is IZ step
# calculate the vector difference sum
    vds = dovds(D)
    b_zi, b_iz = [], []
# collect data included in ZigZag calculation
    if end + 1 >= len(first_Z):
        stop = end - 1
    else:
        stop = end
    for k in range(start, end + 1):
        for l in range(len(first_I)):
            irec = first_I[l]
            if irec[0] == first_Z[k][0]:
                xi.append(irec[3])
                yi.append(first_Z[k][3])
    pars, errcode = int_pars(xi, yi, vds)
    if errcode == 1:
        return pars, errcode
#    for k in range(start,end+1):
    for k in range(len(first_Z) - 1):
        for l in range(k):
            # only go down to 10% of NRM.....
            if old_div(first_Z[k][3], vds) > 0.1:
                irec = first_I[l]
                if irec[4] == 1 and first_I[l + 1][4] == 0:  # a ZI step
                    xzi = irec[3]
                    yzi = first_Z[k][3]
                    xiz = first_I[l + 1][3]
                    yiz = first_Z[k + 1][3]
                    slope = np.arctan2((yzi - yiz), (xiz - xzi))
                    r = np.sqrt((yzi - yiz)**2 + (xiz - xzi)**2)
                    if r > .1 * vds:
                        b_zi.append(slope)  # suppress noise
                elif irec[4] == 0 and first_I[l + 1][4] == 1:  # an IZ step
                    xiz = irec[3]
                    yiz = first_Z[k][3]
                    xzi = first_I[l + 1][3]
                    yzi = first_Z[k + 1][3]
                    slope = np.arctan2((yiz - yzi), (xzi - xiz))
                    r = np.sqrt((yiz - yzi)**2 + (xzi - xiz)**2)
                    if r > .1 * vds:
                        b_iz.append(slope)  # suppress noise
#
    ZigZag, Frat, Trat = -1, 0, 0
    if len(Diz) > 2 and len(Dzi) > 2:
        ZigZag = 0
        dizp = fisher_mean(Diz)  # get Fisher stats on IZ steps
        dzip = fisher_mean(Dzi)  # get Fisher stats on ZI steps
        dup = fisher_mean(Du)  # get Fisher stats on all steps
#
# if directions are TOO well grouped, can get false positive for ftest, so
# angles must be > 3 degrees apart.
#
        if angle([dizp['dec'], dizp['inc']], [dzip['dec'], dzip['inc']]) > 3.:
            F = (dup['n'] - 2.) * (dzip['r'] + dizp['r'] - dup['r']) / \
                (dup['n'] - dzip['r'] - dizp['r']
                 )  # Watson test for common mean
            nf = 2. * (dup['n'] - 2.)  # number of degees of freedom
            ftest = fcalc(2, nf)
            Frat = old_div(F, ftest)
            if Frat > 1.:
                ZigZag = Frat  # fails zigzag on directions
                methcode = "SM-FTEST"
# now do slopes
    if len(b_zi) > 2 and len(b_iz) > 2:
        bzi_m, bzi_sig = gausspars(b_zi)  # mean, std dev
        biz_m, biz_sig = gausspars(b_iz)
        n_zi = float(len(b_zi))
        n_iz = float(len(b_iz))
        b_diff = abs(bzi_m - biz_m)  # difference in means
#
# avoid false positives - set 3 degree slope difference here too
        if b_diff > 3 * np.pi / 180.:
            nf = n_zi + n_iz - 2.  # degrees of freedom
            svar = old_div(((n_zi - 1.) * bzi_sig**2 +
                            (n_iz - 1.) * biz_sig**2), nf)
            T = old_div((b_diff), np.sqrt(
                svar * (old_div(1.0, n_zi) + old_div(1.0, n_iz))))  # student's t
            ttest = tcalc(nf, .05)  # t-test at 95% conf.
            Trat = old_div(T, ttest)
            if Trat > 1 and Trat > Frat:
                ZigZag = Trat  # fails zigzag on directions
                methcode = "SM-TTEST"
    pars[z_key] = ZigZag
    pars[meth_key] = methcode
# do drats
    if len(ptrm_check) != 0:
        diffcum, drat_max = 0, 0
        for prec in ptrm_check:
            step = prec[0]
            endbak = end
            zend = end
            while zend > len(zijdblock) - 1:
                zend = zend - 2  # don't count alteration that happens after this step
            if step < zijdblock[zend][0]:
                Nptrm += 1
                for irec in first_I:
                    if irec[0] == step:
                        break
                diffcum += prec[3] - irec[3]
                if abs(prec[3] - irec[3]) > drat_max:
                    drat_max = abs(prec[3] - irec[3])
        pars[drats_key] = (100 * abs(diffcum) / first_I[zend][3])
        pars[drat_key] = (100 * abs(drat_max) / first_I[zend][3])
    elif len(zptrm_check) != 0:
        diffcum = 0
        for prec in zptrm_check:
            step = prec[0]
            endbak = end
            zend = end
            while zend > len(zijdblock) - 1:
                zend = zend - 1
            if step < zijdblock[zend][0]:
                Nptrm += 1
                for irec in first_I:
                    if irec[0] == step:
                        break
                diffcum += prec[3] - irec[3]
        pars[drats_key] = (100 * abs(diffcum) / first_I[zend][3])
    else:
        pars[drats_key] = -1
        pars[drat_key] = -1
# and the pTRM tails
    if len(ptrm_tail) != 0:
        for trec in ptrm_tail:
            step = trec[0]
            for irec in first_I:
                if irec[0] == step:
                    break
            if abs(trec[3]) > dmax:
                dmax = abs(trec[3])
        pars[md_key] = (100 * dmax / vds)
    else:
        pars[md_key] = -1
    pars[min_key] = bstep
    pars[max_key] = estep
    pars[dec_key] = PCA["specimen_dec"]
    pars[inc_key] = PCA["specimen_inc"]
    pars[mad_key] = PCA["specimen_mad"]
    pars[dang_key] = PCA["specimen_dang"]
    pars[ptrm_key] = Nptrm
# and the ThetaChecks
    if ThetaChecks != "":
        t = 0
        for theta in ThetaChecks:
            if theta[0] >= bstep and theta[0] <= estep and theta[1] > t:
                t = theta[1]
        pars[theta_key] = t
    else:
        pars[theta_key] = -1
# and the DeltaChecks
    if DeltaChecks != "":
        d = 0
        for delta in DeltaChecks:
            if delta[0] >= bstep and delta[0] <= estep and delta[1] > d:
                d = delta[1]
        pars[delta_key]
    else:
        pars[delta_key] = -1
    pars[gamma_key] = -1
    if GammaChecks != "":
        for gamma in GammaChecks:
            if gamma[0] <= estep:
                pars['specimen_gamma'] = gamma[1]

    # --------------------------------------------------------------
    # From here added By Ron Shaar 11-Dec 2012
    # New parameters defined in Shaar and Tauxe (2012):
    # FRAC (specimen_frac) - ranges from 0. to 1.
    # SCAT (specimen_scat) - takes 1/0
    # gap_max (specimen_gmax) - ranges from 0. to 1.
    # --------------------------------------------------------------

    # --------------------------------------------------------------
    # FRAC is similar to Fvds, but the numerator is the vds fraction:
    # FRAC= [ vds (start,end)] / total vds ]
    # gap_max= max [ (vector difference) /  vds (start,end)]
    # --------------------------------------------------------------

    # collect all zijderveld data to arrays and calculate VDS

    z_temperatures = [row[0] for row in zijdblock]
    zdata = []                # array of zero-fields measurements in Cartezian coordinates
    # array of vector differences (for vds calculation)
    vector_diffs = []
    NRM = zijdblock[0][3]     # NRM

    for k in range(len(zijdblock)):
        DIR = [zijdblock[k][1], zijdblock[k][2], old_div(zijdblock[k][3], NRM)]
        cart = dir2cart(DIR)
        zdata.append(np.array([cart[0], cart[1], cart[2]]))
        if k > 0:
            vector_diffs.append(
                np.sqrt(sum((np.array(zdata[-2]) - np.array(zdata[-1]))**2)))
    # last vector difference: from the last point to the origin.
    vector_diffs.append(np.sqrt(sum(np.array(zdata[-1])**2)))
    vds = sum(vector_diffs)  # vds calculation
    zdata = np.array(zdata)
    vector_diffs = np.array(vector_diffs)

    # calculate the vds within the chosen segment
    vector_diffs_segment = vector_diffs[zstart:zend]
    # FRAC calculation
    FRAC = old_div(sum(vector_diffs_segment), vds)
    pars[frac_key] = FRAC

    # gap_max calculation
    max_FRAC_gap = max(
        old_div(vector_diffs_segment, sum(vector_diffs_segment)))
    pars[gmax_key] = max_FRAC_gap

    # ---------------------------------------------------------------------
    # Calculate the "scat box"
    # all data-points, pTRM checks, and tail-checks, should be inside a "scat box"
    # ---------------------------------------------------------------------

    # intialization
    # fail scat due to arai plot data points
    pars["fail_arai_beta_box_scatter"] = False
    pars["fail_ptrm_beta_box_scatter"] = False  # fail scat due to pTRM checks
    pars["fail_tail_beta_box_scatter"] = False  # fail scat due to tail checks
    pars[scat_key] = "t"  # Pass by default

    # --------------------------------------------------------------
    # collect all Arai plot data points in arrays

    x_Arai, y_Arai, t_Arai, steps_Arai = [], [], [], []
    NRMs = araiblock[0]
    PTRMs = araiblock[1]
    ptrm_checks = araiblock[2]
    ptrm_tail = araiblock[3]

    PTRMs_temperatures = [row[0] for row in PTRMs]
    NRMs_temperatures = [row[0] for row in NRMs]
    NRM = NRMs[0][3]

    for k in range(len(NRMs)):
        index_pTRMs = PTRMs_temperatures.index(NRMs[k][0])
        x_Arai.append(old_div(PTRMs[index_pTRMs][3], NRM))
        y_Arai.append(old_div(NRMs[k][3], NRM))
        t_Arai.append(NRMs[k][0])
        if NRMs[k][4] == 1:
            steps_Arai.append('ZI')
        else:
            steps_Arai.append('IZ')
    x_Arai = np.array(x_Arai)
    y_Arai = np.array(y_Arai)

    # --------------------------------------------------------------
    # collect all pTRM check to arrays

    x_ptrm_check, y_ptrm_check, ptrm_checks_temperatures, = [], [], []
    x_ptrm_check_starting_point, y_ptrm_check_starting_point, ptrm_checks_starting_temperatures = [], [], []

    for k in range(len(ptrm_checks)):
        if ptrm_checks[k][0] in NRMs_temperatures:
            # find the starting point of the pTRM check:
            for i in range(len(datablock)):
                rec = datablock[i]
                if "LT-PTRM-I" in rec[meth_key] and float(rec[temp_key]) == ptrm_checks[k][0]:
                    starting_temperature = (float(datablock[i - 1][temp_key]))
                    try:
                        index = t_Arai.index(starting_temperature)
                        x_ptrm_check_starting_point.append(x_Arai[index])
                        y_ptrm_check_starting_point.append(y_Arai[index])
                        ptrm_checks_starting_temperatures.append(
                            starting_temperature)

                        index_zerofield = zerofield_temperatures.index(
                            ptrm_checks[k][0])
                        x_ptrm_check.append(old_div(ptrm_checks[k][3], NRM))
                        y_ptrm_check.append(
                            old_div(zerofields[index_zerofield][3], NRM))
                        ptrm_checks_temperatures.append(ptrm_checks[k][0])

                        break
                    except:
                        pass

    x_ptrm_check_starting_point = np.array(x_ptrm_check_starting_point)
    y_ptrm_check_starting_point = np.array(y_ptrm_check_starting_point)
    ptrm_checks_starting_temperatures = np.array(
        ptrm_checks_starting_temperatures)
    x_ptrm_check = np.array(x_ptrm_check)
    y_ptrm_check = np.array(y_ptrm_check)
    ptrm_checks_temperatures = np.array(ptrm_checks_temperatures)

    # --------------------------------------------------------------
    # collect tail checks to arrays

    x_tail_check, y_tail_check, tail_check_temperatures = [], [], []
    x_tail_check_starting_point, y_tail_check_starting_point, tail_checks_starting_temperatures = [], [], []

    for k in range(len(ptrm_tail)):
        if ptrm_tail[k][0] in NRMs_temperatures:

            # find the starting point of the pTRM check:
            for i in range(len(datablock)):
                rec = datablock[i]
                if "LT-PTRM-MD" in rec[meth_key] and float(rec[temp_key]) == ptrm_tail[k][0]:
                    starting_temperature = (float(datablock[i - 1][temp_key]))
                    try:

                        index = t_Arai.index(starting_temperature)
                        x_tail_check_starting_point.append(x_Arai[index])
                        y_tail_check_starting_point.append(y_Arai[index])
                        tail_checks_starting_temperatures.append(
                            starting_temperature)

                        index_infield = infield_temperatures.index(
                            ptrm_tail[k][0])
                        x_tail_check.append(
                            old_div(infields[index_infield][3], NRM))
                        y_tail_check.append(
                            old_div(ptrm_tail[k][3], NRM) + old_div(zerofields[index_infield][3], NRM))
                        tail_check_temperatures.append(ptrm_tail[k][0])

                        break
                    except:
                        pass

    x_tail_check = np.array(x_tail_check)
    y_tail_check = np.array(y_tail_check)
    tail_check_temperatures = np.array(tail_check_temperatures)
    x_tail_check_starting_point = np.array(x_tail_check_starting_point)
    y_tail_check_starting_point = np.array(y_tail_check_starting_point)
    tail_checks_starting_temperatures = np.array(
        tail_checks_starting_temperatures)

    # --------------------------------------------------------------
    # collect the chosen segment in the Arai plot to arrays

    x_Arai_segment = x_Arai[start:end + 1]  # chosen segent in the Arai plot
    y_Arai_segment = y_Arai[start:end + 1]  # chosen segent in the Arai plot

    # --------------------------------------------------------------
    # collect pTRM checks in segment to arrays
    # notice, this is different than the conventional DRATS.
    # for scat calculation we take only the pTRM checks which were carried out
    # before reaching the highest temperature in the chosen segment

    x_ptrm_check_for_SCAT, y_ptrm_check_for_SCAT = [], []
    for k in range(len(ptrm_checks_temperatures)):
        if ptrm_checks_temperatures[k] >= pars[min_key] and ptrm_checks_starting_temperatures <= pars[max_key]:
            x_ptrm_check_for_SCAT.append(x_ptrm_check[k])
            y_ptrm_check_for_SCAT.append(y_ptrm_check[k])

    x_ptrm_check_for_SCAT = np.array(x_ptrm_check_for_SCAT)
    y_ptrm_check_for_SCAT = np.array(y_ptrm_check_for_SCAT)

    # --------------------------------------------------------------
    # collect Tail checks in segment to arrays
    # for scat calculation we take only the tail checks which were carried out
    # before reaching the highest temperature in the chosen segment

    x_tail_check_for_SCAT, y_tail_check_for_SCAT = [], []

    for k in range(len(tail_check_temperatures)):
        if tail_check_temperatures[k] >= pars[min_key] and tail_checks_starting_temperatures[k] <= pars[max_key]:
            x_tail_check_for_SCAT.append(x_tail_check[k])
            y_tail_check_for_SCAT.append(y_tail_check[k])

    x_tail_check_for_SCAT = np.array(x_tail_check_for_SCAT)
    y_tail_check_for_SCAT = np.array(y_tail_check_for_SCAT)

    # --------------------------------------------------------------
    # calculate the lines that define the scat box:

    # if threshold value for beta is not defined, then scat cannot be calculated (pass)
    # in this case, scat pass
    if beta_key in list(accept.keys()) and accept[beta_key] != "":
        b_beta_threshold = float(accept[beta_key])
        b = pars[b_key]             # best fit line
        cm_x = np.mean(np.array(x_Arai_segment))  # x center of mass
        cm_y = np.mean(np.array(y_Arai_segment))  # y center of mass
        a = cm_y - b * cm_x

        # lines with slope = slope +/- 2*(specimen_b_beta)

        two_sigma_beta_threshold = 2 * b_beta_threshold
        two_sigma_slope_threshold = abs(two_sigma_beta_threshold * b)

        # a line with a  shallower  slope  (b + 2*beta*b) passing through the center of mass
        # y=a1+b1x
        b1 = b + two_sigma_slope_threshold
        a1 = cm_y - b1 * cm_x

        # bounding line with steeper  slope (b - 2*beta*b) passing through the center of mass
        # y=a2+b2x
        b2 = b - two_sigma_slope_threshold
        a2 = cm_y - b2 * cm_x

        # lower bounding line of the 'beta box'
        # y=intercept1+slop1x
        slop1 = old_div(a1, ((old_div(a2, b2))))
        intercept1 = a1

        # higher bounding line of the 'beta box'
        # y=intercept2+slop2x

        slop2 = old_div(a2, ((old_div(a1, b1))))
        intercept2 = a2

        pars['specimen_scat_bounding_line_high'] = [intercept2, slop2]
        pars['specimen_scat_bounding_line_low'] = [intercept1, slop1]

        # --------------------------------------------------------------
        # check if the Arai data points are in the 'box'

        # the two bounding lines
        ymin = intercept1 + x_Arai_segment * slop1
        ymax = intercept2 + x_Arai_segment * slop2

        # arrays of "True" or "False"
        check_1 = y_Arai_segment > ymax
        check_2 = y_Arai_segment < ymin

        # check if at least one "True"
        if (sum(check_1) + sum(check_2)) > 0:
            pars["fail_arai_beta_box_scatter"] = True

        # --------------------------------------------------------------
        # check if the pTRM checks data points are in the 'box'

        if len(x_ptrm_check_for_SCAT) > 0:

            # the two bounding lines
            ymin = intercept1 + x_ptrm_check_for_SCAT * slop1
            ymax = intercept2 + x_ptrm_check_for_SCAT * slop2

            # arrays of "True" or "False"
            check_1 = y_ptrm_check_for_SCAT > ymax
            check_2 = y_ptrm_check_for_SCAT < ymin

            # check if at least one "True"
            if (sum(check_1) + sum(check_2)) > 0:
                pars["fail_ptrm_beta_box_scatter"] = True

        # --------------------------------------------------------------
        # check if the tail checks data points are in the 'box'

        if len(x_tail_check_for_SCAT) > 0:

            # the two bounding lines
            ymin = intercept1 + x_tail_check_for_SCAT * slop1
            ymax = intercept2 + x_tail_check_for_SCAT * slop2

            # arrays of "True" or "False"
            check_1 = y_tail_check_for_SCAT > ymax
            check_2 = y_tail_check_for_SCAT < ymin

            # check if at least one "True"
            if (sum(check_1) + sum(check_2)) > 0:
                pars["fail_tail_beta_box_scatter"] = True

        # --------------------------------------------------------------
        # check if specimen_scat is PASS or FAIL:

        if pars["fail_tail_beta_box_scatter"] or pars["fail_ptrm_beta_box_scatter"] or pars["fail_arai_beta_box_scatter"]:
            pars[scat_key] = 'f'
        else:
            pars[scat_key] = 't'

    return pars, 0


Instruction:
Can you create a Python 3 function that
customizes by commenting out unwanted keys

Response:
def getkeys(table):
    """
    customize by commenting out unwanted keys
    """
    keys = []
    if table == "ER_expedition":
        pass
    if table == "ER_citations":
        keys.append("er_citation_name")
        keys.append("long_authors")
        keys.append("year")
        keys.append("title")
        keys.append("citation_type")
        keys.append("doi")
        keys.append("journal")
        keys.append("volume")
        keys.append("pages")
        keys.append("book_title")
        keys.append("book_editors")
        keys.append("publisher")
        keys.append("city")
    if table == "ER_locations":
        keys.append("er_location_name")
        keys.append("er_scientist_mail_names")
#        keys.append("er_location_alternatives" )
        keys.append("location_type")
        keys.append("location_begin_lat")
        keys.append("location_begin_lon")
#        keys.append("location_begin_elevation" )
        keys.append("location_end_lat")
        keys.append("location_end_lon")
#        keys.append("location_end_elevation" )
        keys.append("continent_ocean")
        keys.append("country")
        keys.append("region")
        keys.append("plate_block")
        keys.append("terrane")
        keys.append("tectonic_setting")
#        keys.append("er_citation_names")
    if table == "ER_Formations":
        keys.append("er_formation_name")
        keys.append("formation_class")
        keys.append("formation_lithology")
        keys.append("formation_paleo_environment")
        keys.append("formation_thickness")
        keys.append("formation_description")
    if table == "ER_sections":
        keys.append("er_section_name")
        keys.append("er_section_alternatives")
        keys.append("er_expedition_name")
        keys.append("er_location_name")
        keys.append("er_formation_name")
        keys.append("er_member_name")
        keys.append("section_definition")
        keys.append("section_class")
        keys.append("section_lithology")
        keys.append("section_type")
        keys.append("section_n")
        keys.append("section_begin_lat")
        keys.append("section_begin_lon")
        keys.append("section_begin_elevation")
        keys.append("section_begin_height")
        keys.append("section_begin_drill_depth")
        keys.append("section_begin_composite_depth")
        keys.append("section_end_lat")
        keys.append("section_end_lon")
        keys.append("section_end_elevation")
        keys.append("section_end_height")
        keys.append("section_end_drill_depth")
        keys.append("section_end_composite_depth")
        keys.append("section_azimuth")
        keys.append("section_dip")
        keys.append("section_description")
        keys.append("er_scientist_mail_names")
        keys.append("er_citation_names")
    if table == "ER_sites":
        keys.append("er_location_name")
        keys.append("er_site_name")
#        keys.append("er_site_alternatives")
#        keys.append("er_formation_name")
#        keys.append("er_member_name")
#        keys.append("er_section_name")
        keys.append("er_scientist_mail_names")
        keys.append("site_class")
#        keys.append("site_type")
#        keys.append("site_lithology")
#        keys.append("site_height")
#        keys.append("site_drill_depth")
#        keys.append("site_composite_depth")
#        keys.append("site_lithology")
#        keys.append("site_description")
        keys.append("site_lat")
        keys.append("site_lon")
#        keys.append("site_location_precision")
#        keys.append("site_elevation")
    if table == "ER_samples":
        keys.append("er_location_name")
        keys.append("er_site_name")
#       keys.append("er_sample_alternatives")
        keys.append("sample_azimuth")
        keys.append("sample_dip")
        keys.append("sample_bed_dip")
        keys.append("sample_bed_dip_direction")
#       keys.append("sample_cooling_rate")
#       keys.append("sample_type")
#       keys.append("sample_lat")
#       keys.append("sample_lon")
        keys.append("magic_method_codes")
    if table == "ER_ages":
        #       keys.append("er_location_name")
        #       keys.append("er_site_name")
        #       keys.append("er_section_name")
        #       keys.append("er_formation_name")
        #       keys.append("er_member_name")
        #       keys.append("er_site_name")
        #       keys.append("er_sample_name")
        #       keys.append("er_specimen_name")
        #       keys.append("er_fossil_name")
        #       keys.append("er_mineral_name")
        #       keys.append("tiepoint_name")
        keys.append("age")
        keys.append("age_sigma")
        keys.append("age_unit")
        keys.append("age_range_low")
        keys.append("age_range_hi")
        keys.append("timescale_eon")
        keys.append("timescale_era")
        keys.append("timescale_period")
        keys.append("timescale_epoch")
        keys.append("timescale_stage")
        keys.append("biostrat_zone")
        keys.append("conodont_zone")
        keys.append("magnetic_reversal_chron")
        keys.append("astronomical_stage")
#       keys.append("age_description")
#       keys.append("magic_method_codes")
#       keys.append("er_timescale_citation_names")
#       keys.append("er_citation_names")
    if table == "MAGIC_measurements":
        keys.append("er_location_name")
        keys.append("er_site_name")
        keys.append("er_sample_name")
        keys.append("er_specimen_name")
        keys.append("measurement_positions")
        keys.append("treatment_temp")
        keys.append("treatment_ac_field")
        keys.append("treatment_dc_field")
        keys.append("treatment_dc_field_phi")
        keys.append("treatment_dc_field_theta")
        keys.append("magic_experiment_name")
        keys.append("magic_instrument_codes")
        keys.append("measurement_temp")
        keys.append("magic_method_codes")
        keys.append("measurement_inc")
        keys.append("measurement_dec")
        keys.append("measurement_magn_moment")
        keys.append("measurement_csd")
    return keys


Instruction:
Can you implement a function in Python 3 that
returns a help message for a give magic keyhelp

Response:
def magic_help(keyhelp):
    """
    returns a help message for a give magic key
    """
    helpme = {}
    helpme["er_location_name"] = "Name for location or drill site"
    helpme["er_location_alternatives"] = "Colon-delimited list of alternative names and abbreviations"
    helpme["location_type"] = "Location type"
    helpme["location_begin_lat"] = "Begin of section or core or outcrop -- latitude"
    helpme["location_begin_lon"] = "Begin of section or core or outcrop -- longitude"
    helpme["location_begin_elevation"] = "Begin of section or core or outcrop -- elevation relative to sealevel"
    helpme["location_end_lat"] = "Ending of section or core -- latitude "
    helpme["location_end_lon"] = "Ending of section or core -- longitude "
    helpme["location_end_elevation"] = "Ending of section or core -- elevation relative to sealevel"
    helpme["location_geoid"] = "Geoid used in determination of latitude and longitude:  WGS84, GEOID03, USGG2003, GEOID99, G99SSS , G99BM, DEFLEC99 "
    helpme["continent_ocean"] = "Name for continent or ocean island region"
    helpme["ocean_sea"] = "Name for location in an ocean or sea"
    helpme["country"] = "Country name"
    helpme["region"] = "Region name"
    helpme["plate_block"] = "Plate or tectonic block name"
    helpme["terrane"] = "Terrane name"
    helpme["tectonic_setting"] = "Tectonic setting"
    helpme["location_description"] = "Detailed description"
    helpme["location_url"] = "Website URL for the location explicitly"
    helpme["er_scientist_mail_names"] = "Colon-delimited list of names for scientists who described location"
    helpme["er_citation_names"] = "Colon-delimited list of citations"
    helpme["er_formation_name"] = "Name for formation"
    helpme["er_formation_alternatives"] = "Colon-delimited list of alternative names and abbreviations"
    helpme["formation_class"] = "General lithology class: igneous, metamorphic or sedimentary"
    helpme["formation_lithology"] = "Lithology: e.g., basalt, sandstone, etc."
    helpme["formation_paleo_enviroment"] = "Depositional environment"
    helpme["formation_thickness"] = "Formation thickness"
    helpme["er_member_name"] = "Name for member"
    helpme["er_member_alternatives"] = "Colon-delimited list of alternative names and abbreviations"
    helpme["er_formation_name"] = "Name for formation"
    helpme["member_class"] = "General lithology type"
    helpme["member_lithology"] = "Lithology"
    helpme["member_paleo_environment"] = "Depositional environment"
    helpme["member_thickness"] = "Member thickness"
    helpme["member_description"] = "Detailed description"
    helpme["er_section_name"] = "Name for section or core"
    helpme["er_section_alternatives"] = "Colon-delimited list of alternative names and abbreviations"
    helpme["er_expedition_name"] = "Name for seagoing or land expedition"
    helpme["er_location_name"] = "Name for location or drill site"
    helpme["er_formation_name"] = "Name for formation"
    helpme["er_member_name"] = "Name for member"
    helpme["section_definition"] = "General definition of section"
    helpme["section_class"] = "General lithology type"
    helpme["section_lithology"] = "Section lithology or archeological classification"
    helpme["section_type"] = "Section type"
    helpme["section_n"] = "Number of subsections included composite (stacked) section"
    helpme["section_begin_lat"] = "Begin of section or core -- latitude"
    helpme["section_begin_lon"] = "Begin of section or core -- longitude"
    helpme["section_begin_elevation"] = "Begin of section or core -- elevation relative to sealevel"
    helpme["section_begin_height"] = "Begin of section or core -- stratigraphic height"
    helpme["section_begin_drill_depth"] = "Begin of section or core -- depth in MBSF as used by ODP"
    helpme["section_begin_composite_depth"] = "Begin of section or core -- composite depth in MBSF as used by ODP"
    helpme["section_end_lat"] = "End of section or core -- latitude "
    helpme["section_end_lon"] = "End of section or core -- longitude "
    helpme["section_end_elevation"] = "End of section or core -- elevation relative to sealevel"
    helpme["section_end_height"] = "End of section or core -- stratigraphic height"
    helpme["section_end_drill_depth"] = "End of section or core -- depth in MBSF as used by ODP"
    helpme["section_end_composite_depth"] = "End of section or core -- composite depth in MBSF as used by ODP"
    helpme["section_azimuth"] = "Section azimuth as measured clockwise from the north"
    helpme["section_dip"] = "Section dip as measured into the outcrop"
    helpme["section_description"] = "Detailed description"
    helpme["er_site_name"] = "Name for site"
    helpme["er_site_alternatives"] = "Colon-delimited list of alternative names and abbreviations"
    helpme["er_expedition_name"] = "Name for seagoing or land expedition"
    helpme["er_location_name"] = "Name for location or drill site"
    helpme["er_section_name"] = "Name for section or core"
    helpme["er_formation_name"] = "Name for formation"
    helpme["er_member_name"] = "Name for member"
    helpme["site_definition"] = "General definition of site"
    helpme["site_class"] = "[A]rchaeologic,[E]xtrusive,[I]ntrusive,[M]etamorphic,[S]edimentary"
    helpme["site_lithology"] = "Site lithology or archeological classification"
    helpme["site_type"] = "Site type: slag, lava flow, sediment layer, etc."
    helpme["site_lat"] = "Site location -- latitude"
    helpme["site_lon"] = "Site location -- longitude"
    helpme["site_location_precision"] = "Site location -- precision in latitude and longitude"
    helpme["site_elevation"] = "Site location -- elevation relative to sealevel"
    helpme["site_height"] = "Site location -- stratigraphic height"
    helpme["site_drill_depth"] = "Site location -- depth in MBSF as used by ODP"
    helpme["site_composite_depth"] = "Site location -- composite depth in MBSF as used by ODP"
    helpme["site_description"] = "Detailed description"
    helpme["magic_method_codes"] = "Colon-delimited list of method codes"
    helpme["er_sample_name"] = "Name for sample"
    helpme["er_sample_alternatives"] = "Colon-delimited list of alternative names and abbreviations"
    helpme["er_expedition_name"] = "Name for seagoing or land expedition"
    helpme["er_location_name"] = "Name for location or drill site"
    helpme["er_section_name"] = "Name for section or core"
    helpme["er_formation_name"] = "Name for formation"
    helpme["er_member_name"] = "Name for member"
    helpme["er_site_name"] = "Name for site"
    helpme["sample_class"] = "General lithology type"
    helpme["sample_lithology"] = "Sample lithology or archeological classification"
    helpme["sample_type"] = "Sample type"
    helpme["sample_texture"] = "Sample texture"
    helpme["sample_alteration"] = "Sample alteration grade"
    helpme["sample_alteration_type"] = "Sample alteration type"
    helpme["sample_lat"] = "Sample location -- latitude"
    helpme["sample_lon"] = "Sample location -- longitude"
    helpme["sample_location_precision"] = "Sample location -- precision in latitude and longitude"
    helpme["sample_elevation"] = "Sample location -- elevation relative to sealevel"
    helpme["sample_height"] = "Sample location -- stratigraphic height"
    helpme["sample_drill_depth"] = "Sample location -- depth in MBSF as used by ODP"
    helpme["sample_composite_depth"] = "Sample location -- composite depth in MBSF as used by ODP"
    helpme["sample_date"] = "Sampling date"
    helpme["sample_time_zone"] = "Sampling time zone"
    helpme["sample_azimuth"] = "Sample azimuth as measured clockwise from the north"
    helpme["sample_dip"] = "Sample dip as measured into the outcrop"
    helpme["sample_bed_dip_direction"] = "Direction of the dip of a paleo-horizontal plane in the bedding"
    helpme["sample_bed_dip"] = "Dip of the bedding as measured to the right of strike direction"
    helpme["sample_cooling_rate"] = "Estimated ancient in-situ cooling rate per Ma"
    helpme["er_specimen_name"] = "Name for specimen"
    helpme["er_specimen_alternatives"] = "Colon-delimited list of alternative names and abbreviations"
    helpme["er_expedition_name"] = "Name for seagoing or land expedition"
    helpme["er_location_name"] = "Name for location or drill site"
    helpme["er_section_name"] = "Name for section or core"
    helpme["er_formation_name"] = "Name for formation"
    helpme["er_member_name"] = "Name for member"
    helpme["er_site_name"] = "Name for site"
    helpme["er_sample_name"] = "Name for sample"
    helpme["specimen_class"] = "General lithology type"
    helpme["specimen_lithology"] = "Specimen lithology or archeological classification"
    helpme["specimen_type"] = "Specimen type"
    helpme["specimen_texture"] = "Specimen texture"
    helpme["specimen_alteration"] = "Specimen alteration grade"
    helpme["specimen_alteration_type"] = "Specimen alteration type"
    helpme["specimen_elevation"] = "Specimen location -- elevation relative to sealevel"
    helpme["specimen_height"] = "Specimen location -- stratigraphic height"
    helpme["specimen_drill_depth"] = "Specimen location -- depth in MBSF as used by ODP"
    helpme["specimen_composite_depth"] = "Specimen location -- composite depth in MBSF as used by ODP"
    helpme["specimen_azimuth"] = "Specimen azimuth as measured clockwise from the north"
    helpme["specimen_dip"] = "Specimen dip as measured into the outcrop"
    helpme["specimen_volume"] = "Specimen volume"
    helpme["specimen_weight"] = "Specimen weight"
    helpme["specimen_density"] = "Specimen density"
    helpme["specimen_size"] = "Specimen grain size fraction"
    helpme["er_expedition_name"] = "Name for seagoing or land expedition"
    helpme["er_location_name"] = "Name for location or drill site"
    helpme["er_formation_name"] = "Name for formation"
    helpme["er_member_name"] = "Name for member"
    helpme["er_site_name"] = "Name for site"
    helpme["er_sample_name"] = "Name for sample"
    helpme["er_specimen_name"] = "Name for specimen"
    helpme["er_fossil_name"] = "Name for fossil"
    helpme["er_mineral_name"] = "Name for mineral"
    helpme["GM-ALPHA"] = "Age determination by using alpha counting"
    helpme["GM-ARAR"] = "40Ar/39Ar age determination"
    helpme["GM-ARAR-AP"] = "40Ar/39Ar age determination: Age plateau"
    helpme["GM-ARAR-II"] = "40Ar/39Ar age determination: Inverse isochron"
    helpme["GM-ARAR-NI"] = "40Ar/39Ar age determination: Normal isochron"
    helpme["GM-ARAR-TF"] = "40Ar/39Ar age determination: Total fusion or recombined age"
    helpme["GM-C14"] = "Radiocarbon age determination"
    helpme["GM-C14-AMS"] = "Radiocarbon age determination: AMS"
    helpme["GM-C14-BETA"] = "Radiocarbon age determination: Beta decay counting"
    helpme["GM-C14-CAL"] = "Radiocarbon age determination: Calibrated"
    helpme["GM-CC"] = "Correlation chronology"
    helpme["GM-CC-ARCH"] = "Correlation chronology: Archeology"
    helpme["GM-CC-ARM"] = "Correlation chronology: ARM"
    helpme["GM-CC-ASTRO"] = "Correlation chronology: Astronomical"
    helpme["GM-CC-CACO3"] = "Correlation chronology: Calcium carbonate"
    helpme["GM-CC-COLOR"] = "Correlation chronology: Color or reflectance"
    helpme["GM-CC-GRAPE"] = "Correlation chronology: Gamma Ray Polarimeter Experiment"
    helpme["GM-CC-IRM"] = "Correlation chronology: IRM"
    helpme["GM-CC-ISO"] = "Correlation chronology: Stable isotopes"
    helpme["GM-CC-REL"] = "Correlation chronology: Relative chronology other than stratigraphic successions"
    helpme["GM-CC-STRAT"] = "Correlation chronology: Stratigraphic succession"
    helpme["GM-CC-TECT"] = "Correlation chronology: Tectites and microtectites"
    helpme["GM-CC-TEPH"] = "Correlation chronology: Tephrochronology"
    helpme["GM-CC-X"] = "Correlation chronology: Susceptibility"
    helpme["GM-CHEM"] = "Chemical chronology"
    helpme["GM-CHEM-AAR"] = "Chemical chronology: Amino acid racemization"
    helpme["GM-CHEM-OH"] = "Chemical chronology: Obsidian hydration"
    helpme["GM-CHEM-SC"] = "Chemical chronology: Stoan coatings CaCO3"
    helpme["GM-CHEM-TH"] = "Chemical chronology: Tephra hydration"
    helpme["GM-COSMO"] = "Cosmogenic age determination"
    helpme["GM-COSMO-AL26"] = "Cosmogenic age determination: 26Al"
    helpme["GM-COSMO-AR39"] = "Cosmogenic age determination: 39Ar"
    helpme["GM-COSMO-BE10"] = "Cosmogenic age determination: 10Be"
    helpme["GM-COSMO-C14"] = "Cosmogenic age determination: 14C"
    helpme["GM-COSMO-CL36"] = "Cosmogenic age determination: 36Cl"
    helpme["GM-COSMO-HE3"] = "Cosmogenic age determination: 3He"
    helpme["GM-COSMO-KR81"] = "Cosmogenic age determination: 81Kr"
    helpme["GM-COSMO-NE21"] = "Cosmogenic age determination: 21Ne"
    helpme["GM-COSMO-NI59"] = "Cosmogenic age determination: 59Ni"
    helpme["GM-COSMO-SI32"] = "Cosmogenic age determination: 32Si"
    helpme["GM-DENDRO"] = "Dendrochronology"
    helpme["GM-ESR"] = "Electron Spin Resonance"
    helpme["GM-FOSSIL"] = "Age determined from fossil record"
    helpme["GM-FT"] = "Fission track age determination"
    helpme["GM-HIST"] = "Historically recorded geological event"
    helpme["GM-INT"] = "Age determination through interpolation between at least two geological units of known age"
    helpme["GM-INT-L"] = "Age determination through interpolation between at least two geological units of known age: Linear"
    helpme["GM-INT-S"] = "Age determination through interpolation between at least two geological units of known age: Cubic spline"
    helpme["GM-ISO"] = "Age determined by isotopic dating, but no further details available"
    helpme["GM-KAR"] = "40K-40Ar age determination"
    helpme["GM-KAR-I"] = "40K-40Ar age determination: Isochron"
    helpme["GM-KAR-MA"] = "40K-40Ar age determination: Model age"
    helpme["GM-KCA"] = "40K-40Ca age determination"
    helpme["GM-KCA-I"] = "40K-40Ca age determination: Isochron"
    helpme["GM-KCA-MA"] = "40K-40Ca age determination: Model age"
    helpme["GM-LABA"] = "138La-138Ba age determination"
    helpme["GM-LABA-I"] = "138La-138Ba age determination: Isochron"
    helpme["GM-LABA-MA"] = "138La-138Ba age determination: Model age"
    helpme["GM-LACE"] = "138La-138Ce age determination"
    helpme["GM-LACE-I"] = "138La-138Ce age determination: Isochron"
    helpme["GM-LACE-MA"] = "138La-138Ce age determination: Model age"
    helpme["GM-LICHE"] = "Lichenometry"
    helpme["GM-LUHF"] = "176Lu-176Hf age determination"
    helpme["GM-LUHF-I"] = "176Lu-176Hf age determination: Isochron"
    helpme["GM-LUHF-MA"] = "176Lu-176Hf age determination: Model age"
    helpme["GM-LUM"] = "Luminescence"
    helpme["GM-LUM-IRS"] = "Luminescence: Infrared stimulated luminescence"
    helpme["GM-LUM-OS"] = "Luminescence: Optically stimulated luminescence"
    helpme["GM-LUM-TH"] = "Luminescence: Thermoluminescence"
    helpme["GM-MOD"] = "Model curve fit to available age dates"
    helpme["GM-MOD-L"] = "Model curve fit to available age dates: Linear"
    helpme["GM-MOD-S"] = "Model curve fit to available age dates: Cubic spline"
    helpme["GM-MORPH"] = "Geomorphic chronology"
    helpme["GM-MORPH-DEF"] = "Geomorphic chronology: Rate of deformation"
    helpme["GM-MORPH-DEP"] = "Geomorphic chronology: Rate of deposition"
    helpme["GM-MORPH-POS"] = "Geomorphic chronology: Geomorphology position"
    helpme["GM-MORPH-WEATH"] = "Geomorphic chronology: Rock and mineral weathering"
    helpme["GM-NO"] = "Unknown geochronology method"
    helpme["GM-O18"] = "Oxygen isotope dating"
    helpme["GM-PBPB"] = "207Pb-206Pb age determination"
    helpme["GM-PBPB-C"] = "207Pb-206Pb age determination: Common Pb"
    helpme["GM-PBPB-I"] = "207Pb-206Pb age determination: Isochron"
    helpme["GM-PLEO"] = "Pleochroic haloes"
    helpme["GM-PMAG-ANOM"] = "Paleomagnetic age determination: Magnetic anomaly identification"
    helpme["GM-PMAG-APWP"] = "Paleomagnetic age determination: Comparing paleomagnetic data to APWP"
    helpme["GM-PMAG-ARCH"] = "Paleomagnetic age determination: Archeomagnetism"
    helpme["GM-PMAG-DIR"] = "Paleomagnetic age determination: Directions"
    helpme["GM-PMAG-POL"] = "Paleomagnetic age determination: Polarities"
    helpme["GM-PMAG-REGSV"] = "Paleomagnetic age determination: Correlation to a regional secular variation curve"
    helpme["GM-PMAG-RPI"] = "Paleomagnetic age determination: Relative paleointensity"
    helpme["GM-PMAG-VEC"] = "Paleomagnetic age determination: Full vector"
    helpme["GM-RATH"] = "226Ra-230Th age determination"
    helpme["GM-RBSR"] = "87Rb-87Sr age determination"
    helpme["GM-RBSR-I"] = "87Rb-87Sr age determination: Isochron"
    helpme["GM-RBSR-MA"] = "87Rb-87Sr age determination: Model age"
    helpme["GM-REOS"] = "187Re-187Os age determination"
    helpme["GM-REOS-I"] = "187Re-187Os age determination: Isochron"
    helpme["GM-REOS-MA"] = "187Re-187Os age determination: Model age"
    helpme["GM-REOS-PT"] = "187Re-187Os age determination: Pt normalization of 186Os"
    helpme["GM-SCLERO"] = "Screlochronology"
    helpme["GM-SHRIMP"] = "SHRIMP age dating"
    helpme["GM-SMND"] = "147Sm-143Nd age determination"
    helpme["GM-SMND-I"] = "147Sm-143Nd age determination: Isochron"
    helpme["GM-SMND-MA"] = "147Sm-143Nd age determination: Model age"
    helpme["GM-THPB"] = "232Th-208Pb age determination"
    helpme["GM-THPB-I"] = "232Th-208Pb age determination: Isochron"
    helpme["GM-THPB-MA"] = "232Th-208Pb age determination: Model age"
    helpme["GM-UPA"] = "235U-231Pa age determination"
    helpme["GM-UPB"] = "U-Pb age determination"
    helpme["GM-UPB-CC-T0"] = "U-Pb age determination: Concordia diagram age, upper intersection"
    helpme["GM-UPB-CC-T1"] = "U-Pb age determination: Concordia diagram age, lower intersection"
    helpme["GM-UPB-I-206"] = "U-Pb age determination: 238U-206Pb isochron"
    helpme["GM-UPB-I-207"] = "U-Pb age determination: 235U-207Pb isochron"
    helpme["GM-UPB-MA-206"] = "U-Pb age determination: 238U-206Pb model age"
    helpme["GM-UPB-MA-207"] = "U-Pb age determination: 235U-207Pb model age"
    helpme["GM-USD"] = "Uranium series disequilibrium age determination"
    helpme["GM-USD-PA231-TH230"] = "Uranium series disequilibrium age determination: 231Pa-230Th"
    helpme["GM-USD-PA231-U235"] = "Uranium series disequilibrium age determination: 231Pa-235U"
    helpme["GM-USD-PB210"] = "Uranium series disequilibrium age determination: 210Pb"
    helpme["GM-USD-RA226-TH230"] = "Uranium series disequilibrium age determination: 226Ra-230Th"
    helpme["GM-USD-RA228-TH232"] = "Uranium series disequilibrium age determination: 228Ra-232Th"
    helpme["GM-USD-TH228-TH232"] = "Uranium series disequilibrium age determination: 228Th-232Th"
    helpme["GM-USD-TH230"] = "Uranium series disequilibrium age determination: 230Th"
    helpme["GM-USD-TH230-TH232"] = "Uranium series disequilibrium age determination: 230Th-232Th"
    helpme["GM-USD-TH230-U234"] = "Uranium series disequilibrium age determination: 230Th-234U"
    helpme["GM-USD-TH230-U238"] = "Uranium series disequilibrium age determination: 230Th-238U"
    helpme["GM-USD-U234-U238"] = "Uranium series disequilibrium age determination: 234U-238U"
    helpme["GM-UTH"] = "238U-230Th age determination"
    helpme["GM-UTHHE"] = "U-Th-He age determination"
    helpme["GM-UTHPB"] = "U-Th-Pb age determination"
    helpme["GM-UTHPB-CC-T0"] = "U-Th-Pb age determination: Concordia diagram intersection age, upper intercept"
    helpme["GM-UTHPB-CC-T1"] = "U-Th-Pb age determination: Concordia diagram intersection age, lower intercept"
    helpme["GM-VARVE"] = "Age determined by varve counting"
    helpme["tiepoint_name"] = "Name for tiepoint horizon"
    helpme["tiepoint_alternatives"] = "Colon-delimited list of alternative names and abbreviations"
    helpme["tiepoint_height"] = "Tiepoint stratigraphic height relative to reference tiepoint"
    helpme["tiepoint_height_sigma"] = "Tiepoint stratigraphic height uncertainty"
    helpme["tiepoint_elevation"] = "Tiepoint elevation relative to sealevel"
    helpme["tiepoint_type"] = "Tiepoint type"
    helpme["age"] = "Age"
    helpme["age_sigma"] = "Age -- uncertainty"
    helpme["age_range_low"] = "Age -- low range"
    helpme["age_range_high"] = "Age -- high range"
    helpme["age_unit"] = "Age -- unit"
    helpme["timescale_eon"] = "Timescale eon"
    helpme["timescale_era"] = "Timescale era"
    helpme["timescale_period"] = "Timescale period"
    helpme["timescale_epoch"] = "Timescale epoch"
    helpme["timescale_stage"] = "Timescale stage"
    helpme["biostrat_zone"] = "Biostratigraphic zone"
    helpme["conodont_zone"] = "Conodont zone"
    helpme["magnetic_reversal_chron"] = "Magnetic reversal chron"
    helpme["astronomical_stage"] = "Astronomical stage name"
    helpme["oxygen_stage"] = "Oxygen stage name"
    helpme["age_culture_name"] = "Age culture name"
    return helpme[keyhelp]


Instruction:
Create a Python 3 function to
return the declination for a given set of suncompass data Parameters __________ sundata : dictionary with these keys: date: time string with the format 'yyyy:mm:dd:hr:min' delta_u: time to SUBTRACT from local time for Universal time lat: latitude of location (negative for south) lon: longitude of location (negative for west) shadow_angle: shadow angle of the desired direction with respect to the sun. Returns ________ sunaz : the declination of the desired direction wrt true north.

Response:
def dosundec(sundata):
    """
    returns the declination for a given set of suncompass data
    Parameters
    __________
      sundata : dictionary with these keys:
          date: time string with the format 'yyyy:mm:dd:hr:min'
          delta_u: time to SUBTRACT from local time for Universal time
          lat: latitude of location (negative for south)
          lon: longitude of location (negative for west)
          shadow_angle: shadow angle of the desired direction with respect to the sun.
    Returns
    ________
       sunaz : the declination of the desired direction wrt true north.
    """
    iday = 0
    timedate = sundata["date"]
    timedate = timedate.split(":")
    year = int(timedate[0])
    mon = int(timedate[1])
    day = int(timedate[2])
    hours = float(timedate[3])
    min = float(timedate[4])
    du = int(sundata["delta_u"])
    hrs = hours - du
    if hrs > 24:
        day += 1
        hrs = hrs - 24
    if hrs < 0:
        day = day - 1
        hrs = hrs + 24
    julian_day = julian(mon, day, year)
    utd = old_div((hrs + old_div(min, 60.)), 24.)
    greenwich_hour_angle, delta = gha(julian_day, utd)
    H = greenwich_hour_angle + float(sundata["lon"])
    if H > 360:
        H = H - 360
    lat = float(sundata["lat"])
    if H > 90 and H < 270:
        lat = -lat
# now do spherical trig to get azimuth to sun
    lat = np.radians(lat)
    delta = np.radians(delta)
    H = np.radians(H)
    ctheta = np.sin(lat) * np.sin(delta) + np.cos(lat) * \
        np.cos(delta) * np.cos(H)
    theta = np.arccos(ctheta)
    beta = np.cos(delta) * np.sin(H) / np.sin(theta)
#
#       check which beta
#
    beta = np.degrees(np.arcsin(beta))
    if delta < lat:
        beta = 180 - beta
    sunaz = 180 - beta
    sunaz = (sunaz + float(sundata["shadow_angle"])) % 360.  # mod 360
    return sunaz


Instruction:
Can you create a Python 3 function that
returns greenwich hour angle

Response:
def gha(julian_day, f):
    """
    returns greenwich hour angle
    """
    rad = old_div(np.pi, 180.)
    d = julian_day - 2451545.0 + f
    L = 280.460 + 0.9856474 * d
    g = 357.528 + 0.9856003 * d
    L = L % 360.
    g = g % 360.
# ecliptic longitude
    lamb = L + 1.915 * np.sin(g * rad) + .02 * np.sin(2 * g * rad)
# obliquity of ecliptic
    epsilon = 23.439 - 0.0000004 * d
# right ascension (in same quadrant as lambda)
    t = (np.tan(old_div((epsilon * rad), 2)))**2
    r = old_div(1, rad)
    rl = lamb * rad
    alpha = lamb - r * t * np.sin(2 * rl) + \
        (old_div(r, 2)) * t * t * np.sin(4 * rl)
#       alpha=mod(alpha,360.0)
# declination
    delta = np.sin(epsilon * rad) * np.sin(lamb * rad)
    delta = old_div(np.arcsin(delta), rad)
# equation of time
    eqt = (L - alpha)
#
    utm = f * 24 * 60
    H = old_div(utm, 4) + eqt + 180
    H = H % 360.0
    return H, delta


Instruction:
Write a Python 3 function for
filling the keys of dictionaries within Recs

Response:
def fillkeys(Recs):
    """
    reconciles keys of dictionaries within Recs.
    """
    keylist, OutRecs = [], []
    for rec in Recs:
        for key in list(rec.keys()):
            if key not in keylist:
                keylist.append(key)
    for rec in Recs:
        for key in keylist:
            if key not in list(rec.keys()):
                rec[key] = ""
        OutRecs.append(rec)
    return OutRecs, keylist


Instruction:
Write a Python 3 function for
calculating the Fisher mean and associated parameter from a nested list of data points.

Response:
def fisher_mean(data):
    """
    Calculates the Fisher mean and associated parameter from a di_block

    Parameters
    ----------
    di_block : a nested list of [dec,inc] or [dec,inc,intensity]

    Returns
    -------
    fpars : dictionary containing the Fisher mean and statistics
        dec : mean declination
        inc : mean inclination
        r : resultant vector length
        n : number of data points
        k : Fisher k value
        csd : Fisher circular standard deviation
        alpha95 : Fisher circle of 95% confidence
    """
    R, Xbar, X, fpars = 0, [0, 0, 0], [], {}
    N = len(data)
    if N < 2:
        return fpars
    X = dir2cart(data)
    for i in range(len(X)):
        for c in range(3):
            Xbar[c] += X[i][c]
    for c in range(3):
        R += Xbar[c]**2
    R = np.sqrt(R)
    for c in range(3):
        Xbar[c] = Xbar[c]/R
    dir = cart2dir(Xbar)
    fpars["dec"] = dir[0]
    fpars["inc"] = dir[1]
    fpars["n"] = N
    fpars["r"] = R
    if N != R:
        k = (N - 1.) / (N - R)
        fpars["k"] = k
        csd = 81./np.sqrt(k)
    else:
        fpars['k'] = 'inf'
        csd = 0.
    b = 20.**(1./(N - 1.)) - 1
    a = 1 - b * (N - R) / R
    if a < -1:
        a = -1
    a95 = np.degrees(np.arccos(a))
    fpars["alpha95"] = a95
    fpars["csd"] = csd
    if a < 0:
        fpars["alpha95"] = 180.0
    return fpars


Instruction:
Implement a function in Python 3 to
calculate gaussian statistics for data

Response:
def gausspars(data):
    """
    calculates gaussian statistics for data
    """
    N, mean, d = len(data), 0., 0.
    if N < 1:
        return "", ""
    if N == 1:
        return data[0], 0
    for j in range(N):
        mean += old_div(data[j], float(N))
    for j in range(N):
        d += (data[j] - mean)**2
    stdev = np.sqrt(d * (1./(float(N - 1))))
    return mean, stdev


Instruction:
Given the following Python 3 function, write the documentation
def weighted_mean(data):
    W, N, mean, d = 0, len(data), 0, 0
    if N < 1:
        return "", ""
    if N == 1:
        return data[0][0], 0
    for x in data:
        W += x[1]  # sum of the weights
    for x in data:
        mean += old_div((float(x[1]) * float(x[0])), float(W))
    for x in data:
        d += (old_div(float(x[1]), float(W))) * (float(x[0]) - mean)**2
    stdev = np.sqrt(d * (old_div(1., (float(N - 1)))))
    return mean, stdev

Response: Calculates weighted mean of data


Instruction:
How would you code a function in Python 3 to
function to calculate fisher mean of a single set of data in a single set of polarity domains

Response:
def fisher_by_pol(data):
    """
    input:    as in dolnp (list of dictionaries with 'dec' and 'inc')
    description: do fisher mean after splitting data into two polarity domains.
    output: three dictionaries:
        'A'= polarity 'A'
        'B = polarity 'B'
        'ALL'= switching polarity of 'B' directions, and calculate fisher mean of all data
    code modified from eqarea_ell.py b rshaar 1/23/2014
    """
    FisherByPoles = {}
    DIblock, nameblock, locblock = [], [], []
    for rec in data:
        if 'dec' in list(rec.keys()) and 'inc' in list(rec.keys()):
            # collect data for fisher calculation
            DIblock.append([float(rec["dec"]), float(rec["inc"])])
        else:
            continue
        if 'name' in list(rec.keys()):
            nameblock.append(rec['name'])
        else:
            nameblock.append("")
        if 'loc' in list(rec.keys()):
            locblock.append(rec['loc'])
        else:
            locblock.append("")

    ppars = doprinc(np.array(DIblock))  # get principal directions
    # choose the northerly declination principe component ("normal")
    reference_DI = [ppars['dec'], ppars['inc']]
    # make reference direction in northern hemisphere
    if reference_DI[0] > 90 and reference_DI[0] < 270:
        reference_DI[0] = (reference_DI[0] + 180.) % 360
        reference_DI[1] = reference_DI[1] * -1.
    nDIs, rDIs, all_DI, npars, rpars = [], [], [], [], []
    nlist, rlist, alllist = "", "", ""
    nloclist, rloclist, allloclist = "", "", ""
    for k in range(len(DIblock)):
        if angle([DIblock[k][0], DIblock[k][1]], reference_DI) > 90.:
            rDIs.append(DIblock[k])
            rlist = rlist + ":" + nameblock[k]
            if locblock[k] not in rloclist:
                rloclist = rloclist + ":" + locblock[k]
            all_DI.append([(DIblock[k][0] + 180.) % 360., -1. * DIblock[k][1]])
            alllist = alllist + ":" + nameblock[k]
            if locblock[k] not in allloclist:
                allloclist = allloclist + ":" + locblock[k]
        else:
            nDIs.append(DIblock[k])
            nlist = nlist + ":" + nameblock[k]
            if locblock[k] not in nloclist:
                nloclist = nloclist + ":" + locblock[k]
            all_DI.append(DIblock[k])
            alllist = alllist + ":" + nameblock[k]
            if locblock[k] not in allloclist:
                allloclist = allloclist + ":" + locblock[k]

    for mode in ['A', 'B', 'All']:
        if mode == 'A' and len(nDIs) > 2:
            fpars = fisher_mean(nDIs)
            fpars['sites'] = nlist.strip(':')
            fpars['locs'] = nloclist.strip(':')
            FisherByPoles[mode] = fpars
        elif mode == 'B' and len(rDIs) > 2:
            fpars = fisher_mean(rDIs)
            fpars['sites'] = rlist.strip(':')
            fpars['locs'] = rloclist.strip(':')
            FisherByPoles[mode] = fpars
        elif mode == 'All' and len(all_DI) > 2:
            fpars = fisher_mean(all_DI)
            fpars['sites'] = alllist.strip(':')
            fpars['locs'] = allloclist.strip(':')
            FisherByPoles[mode] = fpars
    return FisherByPoles


Instruction:
Given the following Python 3 function, write the documentation
def dolnp3_0(Data):
    if len(Data) == 0:
        print("This function requires input Data have at least 1 entry")
        return {}
    if len(Data) == 1:
        ReturnData = {}
        ReturnData["dec"] = Data[0]['dir_dec']
        ReturnData["inc"] = Data[0]['dir_inc']
        ReturnData["n_total"] = '1'
        if "DE-BFP" in Data[0]['method_codes']:
            ReturnData["n_lines"] = '0'
            ReturnData["n_planes"] = '1'
        else:
            ReturnData["n_planes"] = '0'
            ReturnData["n_lines"] = '1'
        ReturnData["alpha95"] = ""
        ReturnData["R"] = ""
        ReturnData["K"] = ""
        return ReturnData
    else:
        LnpData = []
        for n, d in enumerate(Data):
            LnpData.append({})
            LnpData[n]['dec'] = d['dir_dec']
            LnpData[n]['inc'] = d['dir_inc']
            LnpData[n]['tilt_correction'] = d['dir_tilt_correction']
            if 'method_codes' in list(d.keys()):
                if "DE-BFP" in d['method_codes']:
                    LnpData[n]['dir_type'] = 'p'
                else:
                    LnpData[n]['dir_type'] = 'l'
        # get a sample average from all specimens
        ReturnData = dolnp(LnpData, 'dir_type')
        return ReturnData

Response: This function takes a list of dicts with the controlled vocabulary of 3_0 and calls dolnp on them.


Instruction:
Can you write a function in Python 3 where it
returns fisher mean, a95 for data using method of Mcfadden and Mcelhinny '88 for lines and planes Parameters __________ Data : nested list of dictionaries with keys Data model 3.0: dir_dec dir_inc dir_tilt_correction method_codes Data model 2.5: dec inc tilt_correction magic_method_codes direction_type_key : ['specimen_direction_type'] Returns ------- ReturnData : dictionary with keys dec : fisher mean dec of data in Data inc : fisher mean inc of data in Data n_lines : number of directed lines [method_code = DE-BFL or DE-FM] n_planes : number of best fit planes [method_code = DE-BFP] alpha95 : fisher confidence circle from Data R : fisher R value of Data K : fisher k value of Data Effects prints to screen in case of no data

Response:
def dolnp(data, direction_type_key):
    """
    Returns fisher mean, a95 for data  using method of Mcfadden and Mcelhinny '88 for lines and planes

    Parameters
    __________
    Data : nested list of dictionaries with keys
        Data model 3.0:
            dir_dec
            dir_inc
            dir_tilt_correction
            method_codes
        Data model 2.5:
            dec
            inc
            tilt_correction
            magic_method_codes
         direction_type_key :  ['specimen_direction_type']
    Returns
    -------
        ReturnData : dictionary with keys
            dec : fisher mean dec of data in Data
            inc : fisher mean inc of data in Data
            n_lines : number of directed lines [method_code = DE-BFL or DE-FM]
            n_planes : number of best fit planes [method_code = DE-BFP]
            alpha95  : fisher confidence circle from Data
            R : fisher R value of Data
            K : fisher k value of Data
    Effects
        prints to screen in case of no data
    """

    if 'dir_dec' in data[0].keys():
        tilt_key = 'dir_tilt_correction'  # this is data model 3.0
    else:
        tilt_key = 'tilt_correction'  # this is data model 3.0
    if tilt_key in list(data[0].keys()):
        tc = str(data[0][tilt_key])
    else:
        tc = '-1'
    dirV = [0, 0, 0]
    fpars = {}

    # sort data  into lines and planes and collect cartesian coordinates
    fdata, n_lines, L, n_planes, E = process_data_for_mean(
        data, direction_type_key)
# set up initial points on the great circles
    V, XV = [], []
    if n_planes != 0:
        if n_lines == 0:
            # set the initial direction arbitrarily
            V = dir2cart([180., -45., 1.])
        else:
            R = np.sqrt(E[0]**2 + E[1]**2 + E[2]**2)
            for c in E:
                # set initial direction as mean of lines
                V.append(old_div(c, R))
        XV = calculate_best_fit_vectors(L, E, V, n_planes)
# calculating overall mean direction and R
        U = E[:]
        for dir in XV:
            for c in range(3):
                U[c] = U[c] + dir[c]
        R = np.sqrt(U[0]**2 + U[1]**2 + U[2]**2)
        for c in range(3):
            U[c] = old_div(U[c], R)
# get dec and inc of solution points on gt circles
        dirV = cart2dir(U)
# calculate modified Fisher stats fo fit
        n_total = n_lines + n_planes
        NP = n_lines + 0.5 * n_planes
        if NP < 1.1:
            NP = 1.1
        if n_total - R != 0:
            K = old_div((NP - 1.), (n_total - R))
            fac = (20.**(old_div(1., (NP - 1.))) - 1.)
            fac = fac * (NP - 1.) / K
            a = 1. - old_div(fac, R)
            a95 = a
            if abs(a) > 1.0:
                a95 = 1.
            if a < 0:
                a95 = -a95
            a95 = np.arccos(a95) * 180. / np.pi
        else:
            a95 = 0.
            K = 'inf'
    else:
        fdir = fisher_mean(fdata)
        n_total, R, K, a95 = fdir["n"], fdir["r"], fdir["k"], fdir["alpha95"]
        dirV[0], dirV[1] = fdir["dec"], fdir["inc"]
    fpars["tilt_correction"] = tc
    fpars["n_total"] = '%i ' % (n_total)
    fpars["n_lines"] = '%i ' % (n_lines)
    fpars["n_planes"] = '%i ' % (n_planes)
    fpars["R"] = '%5.4f ' % (R)
    if K != 'inf':
        fpars["K"] = '%6.0f ' % (K)
    else:
        fpars["K"] = K
    fpars["alpha95"] = '%7.1f ' % (a95)
    fpars["dec"] = '%7.1f ' % (dirV[0])
    fpars["inc"] = '%7.1f ' % (dirV[1])
    return fpars


Instruction:
Make a summary of the following Python 3 code
def vclose(L, V):
    lam, X = 0, []
    for k in range(3):
        lam = lam + V[k] * L[k]
    beta = np.sqrt(1. - lam**2)
    for k in range(3):
        X.append((old_div((V[k] - lam * L[k]), beta)))
    return X

Response: returns the closest vector in the tree


Instruction:
Write a Python 3 function that can
calculate the best fit vectors for a set of plane interpretations used in fisher mean calculations.

Response:
def calculate_best_fit_vectors(L, E, V, n_planes):
    """
    Calculates the best fit vectors for a set of plane interpretations used in fisher mean calculations
    @param: L - a list of the "EL, EM, EN" array of MM88 or the cartisian form of dec and inc of the plane interpretation
    @param: E - the sum of the cartisian coordinates of all the line fits to be used in the mean
    @param: V - inital direction to start iterating from to get plane best fits
    @returns: nested list of n_plane by 3 dimension where the 3 are the cartisian dimension of the best fit vector
    """

    U, XV = E[:], []  # make a copy of E to prevent mutation
    for pole in L:
        XV.append(vclose(pole, V))  # get some points on the great circle
        for c in range(3):
            U[c] = U[c] + XV[-1][c]
# iterate to find best agreement
    angle_tol = 1.
    while angle_tol > 0.1:
        angles = []
        for k in range(n_planes):
            for c in range(3):
                U[c] = U[c] - XV[k][c]
            R = np.sqrt(U[0]**2 + U[1]**2 + U[2]**2)
            for c in range(3):
                V[c] = old_div(U[c], R)
            XX = vclose(L[k], V)
            ang = XX[0] * XV[k][0] + XX[1] * XV[k][1] + XX[2] * XV[k][2]
            angles.append(np.arccos(ang) * 180. / np.pi)
            for c in range(3):
                XV[k][c] = XX[c]
                U[c] = U[c] + XX[c]
            amax = -1
            for ang in angles:
                if ang > amax:
                    amax = ang
            angle_tol = amax

    return XV


Instruction:
Explain what the following Python 3 code does
def process_data_for_mean(data, direction_type_key):
    dec_key, inc_key, meth_key = 'dec', 'inc', 'magic_method_codes'  # data model 2.5
    if 'dir_dec' in data[0].keys():  # this is data model 3.0
        dec_key, inc_key, meth_key = 'dir_dec', 'dir_inc', 'method_codes'

    n_lines, n_planes = 0, 0
    L, fdata = [], []
    E = [0, 0, 0]

    # sort data  into lines and planes and collect cartesian coordinates
    for rec in data:
        cart = dir2cart([float(rec[dec_key]), float(rec[inc_key])])[0]
        if direction_type_key in list(rec.keys()):
            if rec[direction_type_key] == 'p':  # this is a pole to a plane
                n_planes += 1
                L.append(cart)  # this is the "EL, EM, EN" array of MM88
            else:  # this is a line
                n_lines += 1
                # collect data for fisher calculation
                fdata.append([float(rec[dec_key]), float(rec[inc_key]), 1.])
                E[0] += cart[0]
                E[1] += cart[1]
                E[2] += cart[2]
        elif 'method_codes' in list(rec.keys()):
            if "DE-BFP" in rec[meth_key]:  # this is a pole to a plane
                n_planes += 1
                L.append(cart)  # this is the "EL, EM, EN" array of MM88
            else:  # this is a line
                n_lines += 1
                # collect data for fisher calculation
                fdata.append([rec[dec_key], rec[inc_key], 1.])
                E[0] += cart[0]
                E[1] += cart[1]
                E[2] += cart[2]
        elif meth_key in list(rec.keys()):
            if "DE-BFP" in rec[meth_key]:  # this is a pole to a plane
                n_planes += 1
                L.append(cart)  # this is the "EL, EM, EN" array of MM88
            else:  # this is a line
                n_lines += 1
                # collect data for fisher calculation
                fdata.append([rec[dec_key], rec[inc_key], 1.])
                E[0] += cart[0]
                E[1] += cart[1]
                E[2] += cart[2]
        else:
                # EVERYTHING IS A LINE!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
            n_lines += 1
            # collect data for fisher calculation
            fdata.append([rec[dec_key], rec[inc_key], 1.])
            E[0] += cart[0]
            E[1] += cart[1]
            E[2] += cart[2]

    return fdata, n_lines, L, n_planes, E

Response: process data for fisher means


Instruction:
Make a summary of the following Python 3 code
def scoreit(pars, PmagSpecRec, accept, text, verbose):
    s = PmagSpecRec["er_specimen_name"]
    PmagSpecRec["measurement_step_min"] = '%8.3e' % (
        pars["measurement_step_min"])
    PmagSpecRec["measurement_step_max"] = '%8.3e' % (
        pars["measurement_step_max"])
    PmagSpecRec["measurement_step_unit"] = pars["measurement_step_unit"]
    PmagSpecRec["specimen_int_n"] = '%i' % (pars["specimen_int_n"])
    PmagSpecRec["specimen_lab_field_dc"] = '%8.3e' % (
        pars["specimen_lab_field_dc"])
    PmagSpecRec["specimen_int"] = '%8.3e ' % (pars["specimen_int"])
    PmagSpecRec["specimen_b"] = '%5.3f ' % (pars["specimen_b"])
    PmagSpecRec["specimen_q"] = '%5.1f ' % (pars["specimen_q"])
    PmagSpecRec["specimen_f"] = '%5.3f ' % (pars["specimen_f"])
    PmagSpecRec["specimen_fvds"] = '%5.3f' % (pars["specimen_fvds"])
    PmagSpecRec["specimen_b_beta"] = '%5.3f' % (pars["specimen_b_beta"])
    PmagSpecRec["specimen_int_mad"] = '%7.1f' % (pars["specimen_int_mad"])
    PmagSpecRec["specimen_dec"] = '%7.1f' % (pars["specimen_dec"])
    PmagSpecRec["specimen_inc"] = '%7.1f' % (pars["specimen_inc"])
    PmagSpecRec["specimen_int_dang"] = '%7.1f ' % (pars["specimen_int_dang"])
    PmagSpecRec["specimen_drats"] = '%7.1f ' % (pars["specimen_drats"])
    PmagSpecRec["specimen_int_ptrm_n"] = '%i ' % (pars["specimen_int_ptrm_n"])
    PmagSpecRec["specimen_rsc"] = '%6.4f ' % (pars["specimen_rsc"])
    PmagSpecRec["specimen_md"] = '%i ' % (int(pars["specimen_md"]))
    PmagSpecRec["specimen_b_sigma"] = '%5.3f ' % (pars["specimen_b_sigma"])
    if 'specimen_scat' in list(pars.keys()):
        PmagSpecRec['specimen_scat'] = pars['specimen_scat']
    if 'specimen_gmax' in list(pars.keys()):
        PmagSpecRec['specimen_gmax'] = '%5.3f' % (pars['specimen_gmax'])
    if 'specimen_frac' in list(pars.keys()):
        PmagSpecRec['specimen_frac'] = '%5.3f' % (pars['specimen_frac'])
    # PmagSpecRec["specimen_Z"]='%7.1f'%(pars["specimen_Z"])
  # check score
    #
    kill = grade(PmagSpecRec, accept, 'specimen_int')
    Grade = ""
    if len(kill) == 0:
        Grade = 'A'
    else:
        Grade = 'F'
    pars["specimen_grade"] = Grade
    if verbose == 0:
        return pars, kill
    diffcum = 0
    if pars['measurement_step_unit'] == 'K':
        outstr = "specimen     Tmin  Tmax  N  lab_field  B_anc  b  q  f(coe)  Fvds  beta  MAD  Dang  Drats  Nptrm  Grade  R  MD%  sigma  Gamma_max \n"
        pars_out = (s, (pars["measurement_step_min"] - 273), (pars["measurement_step_max"] - 273), (pars["specimen_int_n"]), 1e6 * (pars["specimen_lab_field_dc"]), 1e6 * (pars["specimen_int"]), pars["specimen_b"], pars["specimen_q"], pars["specimen_f"], pars["specimen_fvds"],
                    pars["specimen_b_beta"], pars["specimen_int_mad"], pars["specimen_int_dang"], pars["specimen_drats"], pars["specimen_int_ptrm_n"], pars["specimen_grade"], np.sqrt(pars["specimen_rsc"]), int(pars["specimen_md"]), pars["specimen_b_sigma"], pars['specimen_gamma'])
        outstring = '%s %4.0f %4.0f %i %4.1f %4.1f %5.3f %5.1f %5.3f %5.3f %5.3f  %7.1f %7.1f %7.1f %s %s %6.3f %i %5.3f %7.1f' % pars_out + '\n'
    elif pars['measurement_step_unit'] == 'J':
        outstr = "specimen     Wmin  Wmax  N  lab_field  B_anc  b  q  f(coe)  Fvds  beta  MAD  Dang  Drats  Nptrm  Grade  R  MD%  sigma  ThetaMax DeltaMax GammaMax\n"
        pars_out = (s, (pars["measurement_step_min"]), (pars["measurement_step_max"]), (pars["specimen_int_n"]), 1e6 * (pars["specimen_lab_field_dc"]), 1e6 * (pars["specimen_int"]), pars["specimen_b"], pars["specimen_q"], pars["specimen_f"], pars["specimen_fvds"], pars["specimen_b_beta"],
                    pars["specimen_int_mad"], pars["specimen_int_dang"], pars["specimen_drats"], pars["specimen_int_ptrm_n"], pars["specimen_grade"], np.sqrt(pars["specimen_rsc"]), int(pars["specimen_md"]), pars["specimen_b_sigma"], pars["specimen_theta"], pars["specimen_delta"], pars["specimen_gamma"])
        outstring = '%s %4.0f %4.0f %i %4.1f %4.1f %5.3f %5.1f %5.3f %5.3f %5.3f  %7.1f %7.1f %7.1f %s %s %6.3f %i %5.3f %7.1f %7.1f %7.1f' % pars_out + '\n'
    if pars["specimen_grade"] != "A":
        print('\n killed by:')
        for k in kill:
            print(k, ':, criterion set to: ',
                  accept[k], ', specimen value: ', pars[k])
        print('\n')
    print(outstr)
    print(outstring)
    return pars, kill

Response: This function generates a scoreit formula for a given set of data and returns a new set of data.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def b_vdm(B, lat):
    # changed radius of the earth from 3.367e6 3/12/2010
    fact = ((6.371e6)**3) * 1e7
    colat = np.radians(90. - lat)
    return fact * B / (np.sqrt(1 + 3 * (np.cos(colat)**2)))

Response: Converts a magnetic field value to a virtual dipole moment or a virtual axial dipole moment.


Instruction:
Can you generate the documentation for the following Python 3 function
def vdm_b(vdm, lat):
    rad = old_div(np.pi, 180.)
    # changed radius of the earth from 3.367e6 3/12/2010
    fact = ((6.371e6)**3) * 1e7
    colat = (90. - lat) * rad
    return vdm * (np.sqrt(1 + 3 * (np.cos(colat)**2))) / fact

Response: Converts a virtual dipole moment or a virtual axial dipole moment to a local magnetic field value in tesla.