Instruction:
Write a Python 3 script to
name _2g_bin_magic.py DESCRIPTION takes the binary 2g format magnetometer files and converts them to magic_measurements, er_samples.txt and er_sites.txt file SYNTAX 2g_bin_magic.py [command line options] OPTIONS -f FILE: specify input 2g (binary) file -F FILE: specify magic_measurements output file, default is: magic_measurements.txt -Fsa FILE: specify output file, default is: er_samples.txt -Fsi FILE: specify output file, default is: er_sites.txt -ncn NCON: specify naming convention: default is #2 below -ocn OCON: specify orientation convention, default is #5 below -mcd: specify sampling method codes as a colon delimited string: [default is: FS-FD:SO-POM] FS-FD field sampling done with a drill FS-H field sampling done with hand samples FS-LOC-GPS field location done with GPS FS-LOC-MAP field location done with map SO-POM a Pomeroy orientation device was used SO-ASC an ASC orientation device was used SO-MAG orientation with magnetic compass SO-SUN orientation with sun compass -loc: location name, default="unknown" -spc NUM : specify number of characters to designate a specimen, default = 0 -ins INST : specify instsrument name -a: average replicate measurements INPUT FORMAT Input files are horrible mag binary format (who knows why?) Orientation convention: [1] Lab arrow azimuth= mag_azimuth; Lab arrow dip=-field_dip i.e., field_dip is degrees from vertical down - the hade [default] [2] Lab arrow azimuth = mag_azimuth-90; Lab arrow dip = -field_dip i.e., mag_azimuth is strike and field_dip is hade [3] Lab arrow azimuth = mag_azimuth; Lab arrow dip = 90-field_dip i.e., lab arrow same as field arrow, but field_dip was a hade. [4] lab azimuth and dip are same as mag_azimuth, field_dip [5] lab azimuth is same as mag_azimuth,lab arrow dip=field_dip-90 [6] Lab arrow azimuth = mag_azimuth-90; Lab arrow dip = 90-field_dip [7] all others you will have to either customize your self or e-mail ltauxe@ucsd.edu for help. Magnetic declination convention: Az will use supplied declination to correct azimuth Sample naming convention: [1] XXXXY: where XXXX is an arbitrary length site designation and Y is the single character sample designation. e.g., TG001a is the first sample from site TG001. [default] [2] XXXX-YY: YY sample from site XXXX (XXX, YY of arbitary length) [3] XXXX.YY: YY sample from site XXXX (XXX, YY of arbitary length) [4-Z] XXXX[YYY]: YYY is sample designation with Z characters from site XXX [5] site name = sample name [6] site name entered in site_name column in the orient.txt format input file -- NOT CURRENTLY SUPPORTED [7-Z] [XXX]YYY: XXX is site designation with Z characters from samples XXXYYY NB: all others you will have to either customize your self or e-mail ltauxe@ucsd.edu for help. OUTPUT output saved in magic_measurements.txt & er_samples.txt formatted files will overwrite any existing files

Response:
def main(command_line=True, **kwargs):
    """
    NAME
        _2g_bin_magic.py

    DESCRIPTION
        takes the binary 2g format magnetometer files and converts them to magic_measurements, er_samples.txt and er_sites.txt file

    SYNTAX
        2g_bin_magic.py [command line options]

    OPTIONS
        -f FILE: specify input 2g (binary) file
        -F FILE: specify magic_measurements output file, default is: magic_measurements.txt
        -Fsa FILE: specify output file, default is: er_samples.txt
        -Fsi FILE: specify output file, default is: er_sites.txt
        -ncn NCON:  specify naming convention: default is #2 below
        -ocn OCON:  specify orientation convention, default is #5 below
        -mcd: specify sampling method codes as a colon delimited string:  [default is: FS-FD:SO-POM]
             FS-FD field sampling done with a drill
             FS-H field sampling done with hand samples
             FS-LOC-GPS  field location done with GPS
             FS-LOC-MAP  field location done with map
             SO-POM   a Pomeroy orientation device was used
             SO-ASC   an ASC orientation device was used
             SO-MAG   orientation with magnetic compass
             SO-SUN   orientation with sun compass
        -loc: location name, default="unknown"
        -spc NUM : specify number of characters to designate a  specimen, default = 0
        -ins INST : specify instsrument name
        -a: average replicate measurements

    INPUT FORMAT
        Input files are horrible mag binary format (who knows why?)
        Orientation convention:
            [1] Lab arrow azimuth= mag_azimuth; Lab arrow dip=-field_dip
                i.e., field_dip is degrees from vertical down - the hade [default]
            [2] Lab arrow azimuth = mag_azimuth-90; Lab arrow dip = -field_dip
                i.e., mag_azimuth is strike and field_dip is hade
            [3] Lab arrow azimuth = mag_azimuth; Lab arrow dip = 90-field_dip
                i.e.,  lab arrow same as field arrow, but field_dip was a hade.
            [4] lab azimuth and dip are same as mag_azimuth, field_dip
            [5] lab azimuth is same as mag_azimuth,lab arrow dip=field_dip-90
            [6] Lab arrow azimuth = mag_azimuth-90; Lab arrow dip = 90-field_dip
            [7] all others you will have to either customize your
                self or e-mail ltauxe@ucsd.edu for help.

         Magnetic declination convention:
             Az will use supplied declination to correct azimuth

       Sample naming convention:
        [1] XXXXY: where XXXX is an arbitrary length site designation and Y
            is the single character sample designation.  e.g., TG001a is the
            first sample from site TG001.    [default]
        [2] XXXX-YY: YY sample from site XXXX (XXX, YY of arbitary length)
        [3] XXXX.YY: YY sample from site XXXX (XXX, YY of arbitary length)
        [4-Z] XXXX[YYY]:  YYY is sample designation with Z characters from site XXX
        [5] site name = sample name
        [6] site name entered in site_name column in the orient.txt format input file  -- NOT CURRENTLY SUPPORTED
        [7-Z] [XXX]YYY:  XXX is site designation with Z characters from samples  XXXYYY
        NB: all others you will have to either customize your
            self or e-mail ltauxe@ucsd.edu for help.

    OUTPUT
            output saved in magic_measurements.txt & er_samples.txt formatted files
              will overwrite any existing files
    """
    #
    # initialize variables
    #
    mag_file = ''
    specnum = 0
    ub_file, samp_file, or_con, corr, meas_file = "", "er_samples.txt", "3", "1", "magic_measurements.txt"
    pos_file, site_file = "", "er_sites.txt"
    noave = 1
    args = sys.argv
    bed_dip, bed_dip_dir = "", ""
    samp_con, Z, average_bedding = "2", 1, "0"
    meths = 'FS-FD'
    sclass, lithology, _type = "", "", ""
    user, inst = "", ""
    DecCorr = 0.
    location_name = "unknown"
    months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
              'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
    gmeths = ""
    #
    #
    dir_path = '.'
    if command_line:
        if '-WD' in args:
            ind = args.index("-WD")
            dir_path = sys.argv[ind + 1]
        if "-h" in args:
            print(main.__doc__)
            return False
        if "-f" in args:
            ind = args.index("-f")
            mag_file = sys.argv[ind + 1]
        if "-fpos" in args:
            ind = args.index("-fpos")
            pos_file = sys.argv[ind + 1]
        if "-F" in args:
            ind = args.index("-F")
            meas_file = sys.argv[ind + 1]
        if "-Fsa" in args:
            ind = args.index("-Fsa")
            samp_file = sys.argv[ind + 1]
        if "-Fsi" in args:
            ind = args.index("-Fsi")
            site_file = sys.argv[ind + 1]
        if "-ocn" in args:
            ind = args.index("-ocn")
            or_con = sys.argv[ind + 1]
        if "-ncn" in args:
            ind = args.index("-ncn")
            samp_con = sys.argv[ind + 1]
        if "-mcd" in args:
            ind = args.index("-mcd")
            gmeths = (sys.argv[ind + 1])
        if "-loc" in args:
            ind = args.index("-loc")
            location_name = (sys.argv[ind + 1])
        if "-spc" in args:
            ind = args.index("-spc")
            specnum = int(args[ind + 1])

        if "-ins" in args:
            ind = args.index("-ins")
            inst = args[ind + 1]
        if "-a" in args:
            noave = 0
        #
        ID = False
        if '-ID' in args:
            ind = args.index('-ID')
            ID = args[ind + 1]
        #

    if not command_line:
        dir_path = kwargs.get('dir_path', '.')
        mag_file = kwargs.get('mag_file', '')
        pos_file = kwargs.get('pos_file', '')
        meas_file = kwargs.get('meas_file', 'magic_measurements.txt')
        samp_file = kwargs.get('samp_file', 'er_samples.txt')
        site_file = kwargs.get('site_file', 'er_sites.txt')
        or_con = kwargs.get('or_con', '3')
        samp_con = kwargs.get('samp_con', '2')
        corr = kwargs.get('corr', '1')
        gmeths = kwargs.get('gmeths', '')
        location_name = kwargs.get('location_name', '')
        specnum = int(kwargs.get('specnum', 0))
        inst = kwargs.get('inst', '')
        noave = kwargs.get('noave', 1)  # default is DO average
        ID = kwargs.get('ID', '')

    # format and fix variables acquired from command line args or input with
    # **kwargs
    if specnum != 0:
        specnum = -specnum

    if ID:
        input_dir_path = ID
    else:
        input_dir_path = dir_path

    if samp_con:
        if "4" in samp_con:
            if "-" not in samp_con:
                print("option [4] must be in form 4-Z where Z is an integer")
                return False, "option [4] must be in form 4-Z where Z is an integer"
            else:
                Z = samp_con.split("-")[1]
                samp_con = "4"
        if "7" in samp_con:
            if "-" not in samp_con:
                print("option [7] must be in form 7-Z where Z is an integer")
                return False, "option [7] must be in form 7-Z where Z is an integer"
            else:
                Z = samp_con.split("-")[1]
                samp_con = "7"
        if "6" in samp_con:
            print('Naming convention option [6] not currently supported')
            return False, 'Naming convention option [6] not currently supported'
            try:
                Samps, file_type = pmag.magic_read(
                    os.path.join(input_dir_path, 'er_samples.txt'))
            except:
                print(
                    "there is no er_samples.txt file in your input directory - you can't use naming convention #6")
                return False, "there is no er_samples.txt file in your input directory - you can't use naming convention #6"
            if file_type == 'bad_file':
                print(
                    "there is no er_samples.txt file in your input directory - you can't use naming convention #6")
                return False, "there is no er_samples.txt file in your input directory - you can't use naming convention #6"

    if not mag_file:
        print("mag file is required input")
        return False, "mag file is required input"
    output_dir_path = dir_path
    mag_file = os.path.join(input_dir_path, mag_file)
    samp_file = output_dir_path + '/' + samp_file
    site_file = output_dir_path + '/' + site_file
    meas_file = output_dir_path + '/' + meas_file
    samplist = []
    try:
        Samps, file_type = pmag.magic_read(samp_file)
        for samp in Samps:
            if samp['er_sample_name'] not in samplist:
                samplist.append(samp['er_sample_name'])
    except:
        Samps = []
    MagRecs = []
    try:
        f = open(mag_file, 'br')
        input = str(f.read()).strip("b '")
        f.close()
    except Exception as ex:
        print('ex', ex)
        print("bad mag file")
        return False, "bad mag file"
    firstline, date = 1, ""
    d = input.split('\\xcd')
    for line in d:
        rec = line.split('\\x00')
        if firstline == 1:
            firstline = 0
            spec, vol = "", 1
            el = 51
            while line[el:el + 1] != "\\":
                spec = spec + line[el]
                el += 1
            # check for bad sample name
            test = spec.split('.')
            date = ""
            if len(test) > 1:
                spec = test[0]
                kk = 24
                while line[kk] != '\\x01' and line[kk] != '\\x00':
                    kk += 1
                vcc = line[24:kk]
                el = 10
                while rec[el].strip() != '':
                    el += 1
                date, comments = rec[el + 7], []
            else:
                el = 9
                while rec[el] != '\\x01':
                    el += 1
                vcc, date, comments = rec[el - 3], rec[el + 7], []
            specname = spec.lower()
            print('importing ', specname)
            el += 8
            while rec[el].isdigit() == False:
                comments.append(rec[el])
                el += 1
            while rec[el] == "":
                el += 1
            az = float(rec[el])
            el += 1
            while rec[el] == "":
                el += 1
            pl = float(rec[el])
            el += 1
            while rec[el] == "":
                el += 1
            bed_dip_dir = float(rec[el])
            el += 1
            while rec[el] == "":
                el += 1
            bed_dip = float(rec[el])
            el += 1
            while rec[el] == "":
                el += 1
            if rec[el] == '\\x01':
                bed_dip = 180. - bed_dip
                el += 1
                while rec[el] == "":
                    el += 1
            fold_az = float(rec[el])
            el += 1
            while rec[el] == "":
                el += 1
            fold_pl = rec[el]
            el += 1
            while rec[el] == "":
                el += 1
            if rec[el] != "" and rec[el] != '\\x02' and rec[el] != '\\x01':
                deccorr = float(rec[el])
                az += deccorr
                bed_dip_dir += deccorr
                fold_az += deccorr
                if bed_dip_dir >= 360:
                    bed_dip_dir = bed_dip_dir - 360.
                if az >= 360.:
                    az = az - 360.
                if fold_az >= 360.:
                    fold_az = fold_az - 360.
            else:
                deccorr = 0
            if specnum != 0:
                sample = specname[:specnum]
            else:
                sample = specname
            SampRec = {}
            SampRec["er_sample_name"] = sample
            SampRec["er_location_name"] = location_name
            SampRec["er_citation_names"] = "This study"
            # convert to labaz, labpl
            labaz, labdip = pmag.orient(az, pl, or_con)
#
# parse information common to all orientation methods
#
            SampRec["sample_bed_dip"] = '%7.1f' % (bed_dip)
            SampRec["sample_bed_dip_direction"] = '%7.1f' % (bed_dip_dir)
            SampRec["sample_dip"] = '%7.1f' % (labdip)
            SampRec["sample_azimuth"] = '%7.1f' % (labaz)
            if vcc.strip() != "":
                vol = float(vcc) * 1e-6  # convert to m^3 from cc
            SampRec["sample_volume"] = '%10.3e' % (vol)
            SampRec["sample_class"] = sclass
            SampRec["sample_lithology"] = lithology
            SampRec["sample_type"] = _type
            SampRec["sample_declination_correction"] = '%7.1f' % (deccorr)
            methods = gmeths.split(':')
            if deccorr != "0":
                if 'SO-MAG' in methods:
                    del methods[methods.index('SO-MAG')]
                methods.append('SO-CMD-NORTH')
            meths = ""
            for meth in methods:
                meths = meths + meth + ":"
            meths = meths[:-1]
            SampRec["magic_method_codes"] = meths
            if int(samp_con) < 6 or int(samp_con) == 7:
                # parse out the site name
                site = pmag.parse_site(SampRec["er_sample_name"], samp_con, Z)
                SampRec["er_site_name"] = site
            elif len(Samps) > 1:
                site, location = "", ""
                for samp in Samps:
                    if samp["er_sample_name"] == SampRec["er_sample_name"]:
                        site = samp["er_site_name"]
                        location = samp["er_location_name"]
                        break
                SampRec["er_location_name"] = samp["er_location_name"]
                SampRec["er_site_name"] = samp["er_site_name"]
            if sample not in samplist:
                samplist.append(sample)
                Samps.append(SampRec)
        else:
            MagRec = {}
            MagRec["treatment_temp"] = '%8.3e' % (273)  # room temp in kelvin
            MagRec["measurement_temp"] = '%8.3e' % (273)  # room temp in kelvin
            MagRec["treatment_ac_field"] = '0'
            MagRec["treatment_dc_field"] = '0'
            MagRec["treatment_dc_field_phi"] = '0'
            MagRec["treatment_dc_field_theta"] = '0'
            meas_type = "LT-NO"
            MagRec["measurement_flag"] = 'g'
            MagRec["measurement_standard"] = 'u'
            MagRec["measurement_number"] = '1'
            MagRec["er_specimen_name"] = specname
            MagRec["er_sample_name"] = SampRec['er_sample_name']
            MagRec["er_site_name"] = SampRec['er_site_name']
            MagRec["er_location_name"] = location_name
            el, demag = 1, ''
            treat = rec[el]
            if treat[-1] == 'C':
                demag = 'T'
            elif treat != 'NRM':
                demag = 'AF'
            el += 1
            while rec[el] == "":
                el += 1
            MagRec["measurement_dec"] = rec[el]
            cdec = float(rec[el])
            el += 1
            while rec[el] == "":
                el += 1
            MagRec["measurement_inc"] = rec[el]
            cinc = float(rec[el])
            el += 1
            while rec[el] == "":
                el += 1
            gdec = rec[el]
            el += 1
            while rec[el] == "":
                el += 1
            ginc = rec[el]
            el = skip(2, el, rec)  # skip bdec,binc
#                el=skip(4,el,rec) # skip gdec,ginc,bdec,binc
#                print 'moment emu: ',rec[el]
            MagRec["measurement_magn_moment"] = '%10.3e' % (
                float(rec[el]) * 1e-3)  # moment in Am^2 (from emu)
            MagRec["measurement_magn_volume"] = '%10.3e' % (
                float(rec[el]) * 1e-3 / vol)  # magnetization in A/m
            el = skip(2, el, rec)  # skip to xsig
            MagRec["measurement_sd_x"] = '%10.3e' % (
                float(rec[el]) * 1e-3)  # convert from emu
            el = skip(3, el, rec)  # skip to ysig
            MagRec["measurement_sd_y"] = '%10.3e' % (
                float(rec[el]) * 1e-3)  # convert from emu
            el = skip(3, el, rec)  # skip to zsig
            MagRec["measurement_sd_z"] = '%10.3e' % (
                float(rec[el]) * 1e-3)  # convert from emu
            el += 1  # skip to positions
            MagRec["measurement_positions"] = rec[el]
#                    el=skip(5,el,rec) # skip to date
#                    mm=str(months.index(date[0]))
#                    if len(mm)==1:
#                        mm='0'+str(mm)
#                    else:
#                        mm=str(mm)
#                    dstring=date[2]+':'+mm+':'+date[1]+":"+date[3]
#                    MagRec['measurement_date']=dstring
            MagRec["magic_instrument_codes"] = inst
            MagRec["er_analyst_mail_names"] = ""
            MagRec["er_citation_names"] = "This study"
            MagRec["magic_method_codes"] = meas_type
            if demag == "AF":
                MagRec["treatment_ac_field"] = '%8.3e' % (
                    float(treat[:-2]) * 1e-3)  # peak field in tesla
                meas_type = "LT-AF-Z"
                MagRec["treatment_dc_field"] = '0'
            elif demag == "T":
                MagRec["treatment_temp"] = '%8.3e' % (
                    float(treat[:-1]) + 273.)  # temp in kelvin
                meas_type = "LT-T-Z"
            MagRec['magic_method_codes'] = meas_type
            MagRecs.append(MagRec)
    MagOuts = pmag.measurements_methods(MagRecs, noave)
    MagOuts, keylist = pmag.fillkeys(MagOuts)
    pmag.magic_write(meas_file, MagOuts, 'magic_measurements')
    print("Measurements put in ", meas_file)
    SampsOut, sampkeys = pmag.fillkeys(Samps)
    pmag.magic_write(samp_file, SampsOut, "er_samples")
    Sites = []
    for samp in Samps:
        SiteRec = {}
        SiteRec['er_site_name'] = samp['er_site_name']
        SiteRec['er_location_name'] = samp['er_location_name']
        SiteRec['site_definition'] = 's'
        SiteRec['er_citation_names'] = 'This study'
        if 'sample_class' in list(samp.keys()):
            SiteRec['site_class'] = samp['sample_class']
        if 'sample_lithology' in list(samp.keys()):
            SiteRec['site_lithology'] = samp['sample_lithology']
        if 'sample_type' in list(samp.keys()):
            SiteRec['site_lithology'] = samp['sample_lithology']
        if 'sample_lat' in list(samp.keys()):
            SiteRec['site_lat'] = samp['sample_lat']
        else:
            SiteRec['site_lat'] = "-999"
        if 'sample_lon' in list(samp.keys()):
            SiteRec['site_lon'] = samp['sample_lon']
        else:
            SiteRec['site_lon'] = "-999"
        if 'sample_height' in list(samp.keys()):
            SiteRec['site_height'] = samp['sample_height']
        Sites.append(SiteRec)
    pmag.magic_write(site_file, Sites, 'er_sites')
    return True, meas_file


Instruction:
Create a Python 3 function to
name unsquish. py DESCRIPTIONtake dec and inc data and unsquishes with specified flattening factor flt takes dec and inc data and unsquishes with specified flattening factor flt uses formula tan (Io )=(1/flt)*tan(Io ) *= tan (Io ) *= tan (Io ) *= tan (Io ) *= tan (Io ) *= tan (Io ) *= tan (Io ) *= tan (Io )

Response:
def main():
    """
    NAME
        unsquish.py

    DESCRIPTION
      takes dec/inc data and "unsquishes" with specified flattening factor, flt
      using formula tan(If)=(1/flt)*tan(Io)

    INPUT
           declination inclination
    OUTPUT
           "unsquished" declincation inclination

    SYNTAX
        unsquish.py [command line options] [< filename]

    OPTIONS
        -h print help and quit
        -f FILE, input file
        -F FILE, output file
        -flt FLT, flattening factor [required]

    """
    ofile=""
    if '-h' in sys.argv:
        print(main.__doc__)
        sys.exit()
    if '-F' in sys.argv:
        ind=sys.argv.index('-F')
        ofile=sys.argv[ind+1]
        out=open(ofile,'w')
    if '-flt' in sys.argv:
        ind=sys.argv.index('-flt')
        flt=float(sys.argv[ind+1])
    else:
        print(main.__doc__)
        sys.exit()
    if '-f' in sys.argv:
        ind=sys.argv.index('-f')
        file=sys.argv[ind+1]
        input=numpy.loadtxt(file)
    else:
        input=numpy.loadtxt(sys.stdin,dtype=numpy.float)
# read in inclination data
    for line in input:
        dec=float(line[0])
        inc=float(line[1])*numpy.pi/180.
        tincnew=(old_div(1,flt))*numpy.tan(inc)
        incnew=numpy.arctan(tincnew)*180./numpy.pi
        if ofile=="":
            print('%7.1f %7.1f'% (dec,incnew))
        else:
            out.write('%7.1f %7.1f'% (dec,incnew)+'\n')


Instruction:
Write a Python 3 function for
naming iodp_jr6_magic.py DESCRIPTION converts shipboard .jr6 format files to magic_measurements format files SYNTAX iodp_jr6_magic.py [command line options] OPTIONS -h: prints the help message and quits. -f FILE: specify input file, or -F FILE: specify output file, default is magic_measurements.txt -fsa FILE: specify er_samples.txt file for sample name lookup , default is 'er_samples.txt' -loc HOLE : specify hole name (U1456A) -A: don't average replicate measurements INPUT JR6 .jr6 format file

Response:
def main(command_line=True, **kwargs):
    """
    NAME
        iodp_jr6_magic.py

    DESCRIPTION
        converts shipboard .jr6 format files to magic_measurements format files

    SYNTAX
        iodp_jr6_magic.py [command line options]

    OPTIONS
        -h: prints the help message and quits.
        -f FILE: specify  input file, or
        -F FILE: specify output file, default is magic_measurements.txt
        -fsa FILE: specify  er_samples.txt file for sample name lookup ,
           default is 'er_samples.txt'
        -loc HOLE : specify hole name (U1456A)
        -A: don't average replicate measurements

    INPUT
        JR6 .jr6 format file
    """

    def fix_separation(filename, new_filename):
        old_file = open(filename, 'r')
        data = old_file.readlines()
        new_data = []
        for line in data:
            new_line = line.replace('-', ' -')
            new_line = new_line.replace('  ', ' ')
            new_data.append(new_line)
        new_file = open(new_filename, 'w')
        for s in new_data:
            new_file.write(s)
        old_file.close()
        new_file.close()
        return new_filename

    def old_fix_separation(filename, new_filename):
        old_file = open(filename, 'r')
        data = old_file.readlines()
        new_data = []
        for line in data:
            new_line = []
            for i in line.split():
                if '-' in i[1:]:
                    lead_char = '-' if i[0] == '-' else ''
                    if lead_char:
                        v = i[1:].split('-')
                    else:
                        v = i.split('-')
                    new_line.append(lead_char + v[0])
                    new_line.append('-' + v[1])
                else:
                    new_line.append(i)
            new_line = (' '.join(new_line)) + '\n'
            new_data.append(new_line)
        new_file = open(new_filename, 'w')
        for s in new_data:
            new_file.write(s)
        new_file.close()
        old_file.close()
        return new_filename

# initialize some stuff
    noave=0
    volume=2.5**3 #default volume is a 2.5cm cube
    inst=""
    samp_con,Z='5',""
    missing=1
    demag="N"
    er_location_name="unknown"
    citation='This study'
    args=sys.argv
    meth_code="LP-NO"
    version_num=pmag.get_version()
    dir_path='.'
    MagRecs=[]
    samp_file = 'er_samples.txt'
    meas_file = 'magic_measurements.txt'
    mag_file = ''
    #
    # get command line arguments
    #
    if command_line:
        if '-WD' in sys.argv:
            ind = sys.argv.index('-WD')
            dir_path=sys.argv[ind+1]
        if '-ID' in sys.argv:
            ind = sys.argv.index('-ID')
            input_dir_path = sys.argv[ind+1]
        else:
            input_dir_path = dir_path
        output_dir_path = dir_path
        if "-h" in args:
            print(main.__doc__)
            return False
        if '-F' in args:
            ind=args.index("-F")
            meas_file = args[ind+1]
        if '-fsa' in args:
            ind = args.index("-fsa")
            samp_file = args[ind+1]
            if samp_file[0]!='/':
                samp_file = os.path.join(input_dir_path, samp_file)
            try:
                open(samp_file,'r')
                ErSamps,file_type=pmag.magic_read(samp_file)
            except:
                print(samp_file,' not found: ')
                print('   download csv file and import to MagIC with iodp_samples_magic.py')
        if '-f' in args:
            ind = args.index("-f")
            mag_file= args[ind+1]
        if "-loc" in args:
            ind=args.index("-loc")
            er_location_name=args[ind+1]
        if "-A" in args:
            noave=1
    if not command_line:
        dir_path = kwargs.get('dir_path', '.')
        input_dir_path = kwargs.get('input_dir_path', dir_path)
        output_dir_path = dir_path
        meas_file = kwargs.get('meas_file', 'magic_measurements.txt')
        mag_file = kwargs.get('mag_file', '')
        samp_file = kwargs.get('samp_file', 'er_samples.txt')
        specnum = kwargs.get('specnum', 1)
        samp_con = kwargs.get('samp_con', '1')
        if len(str(samp_con)) > 1:
            samp_con, Z = samp_con.split('-')
        else:
            Z = ''
        er_location_name = kwargs.get('er_location_name', '')
        noave = kwargs.get('noave', 0) # default (0) means DO average
        meth_code = kwargs.get('meth_code', "LP-NO")

    # format variables
    meth_code=meth_code+":FS-C-DRILL-IODP:SP-SS-C:SO-V"
    meth_code=meth_code.strip(":")
    if mag_file:
        mag_file = os.path.join(input_dir_path, mag_file)
    samp_file = os.path.join(input_dir_path, samp_file)
    meas_file = os.path.join(output_dir_path, meas_file)

    # validate variables
    if not mag_file:
        print("You must provide an IODP_jr6 format file")
        return False, "You must provide an IODP_jr6 format file"
    if not os.path.exists(mag_file):
        print('The input file you provided: {} does not exist.\nMake sure you have specified the correct filename AND correct input directory name.'.format(mag_file))
        return False, 'The input file you provided: {} does not exist.\nMake sure you have specified the correct filename AND correct input directory name.'.format(mag_file)
    if not os.path.exists(samp_file):
        print("Your input directory:\n{}\nmust contain an er_samples.txt file, or you must explicitly provide one".format(input_dir_path))
        return False, "Your input directory:\n{}\nmust contain an er_samples.txt file, or you must explicitly provide one".format(input_dir_path)

    # parse data
    temp = os.path.join(output_dir_path, 'temp.txt')
    fix_separation(mag_file, temp)
    samples, filetype = pmag.magic_read(samp_file)
    with open(temp, 'r') as finput:
        lines = finput.readlines()
    os.remove(temp)
    for line in lines:
        MagRec = {}
        line = line.split()
        spec_text_id = line[0].split('_')[1]
        SampRecs=pmag.get_dictitem(samples,'er_sample_alternatives',spec_text_id,'has')
        if len(SampRecs)>0: # found one
            MagRec['er_specimen_name']=SampRecs[0]['er_sample_name']
            MagRec['er_sample_name']=MagRec['er_specimen_name']
            MagRec['er_site_name']=MagRec['er_specimen_name']
            MagRec["er_citation_names"]="This study"
            MagRec['er_location_name']=er_location_name
            MagRec['magic_software_packages']=version_num
            MagRec["treatment_temp"]='%8.3e' % (273) # room temp in kelvin
            MagRec["measurement_temp"]='%8.3e' % (273) # room temp in kelvin
            MagRec["measurement_flag"]='g'
            MagRec["measurement_standard"]='u'
            MagRec["measurement_number"]='1'
            MagRec["treatment_ac_field"]='0'

            volume=float(SampRecs[0]['sample_volume'])
            x = float(line[4])
            y = float(line[3])
            negz = float(line[2])
            cart=np.array([x,y,-negz]).transpose()
            direction = pmag.cart2dir(cart).transpose()
            expon = float(line[5])
            magn_volume = direction[2] * (10.0**expon)
            moment = magn_volume * volume

            MagRec["measurement_magn_moment"]=str(moment)
            MagRec["measurement_magn_volume"]=str(magn_volume)#str(direction[2] * (10.0 ** expon))
            MagRec["measurement_dec"]='%7.1f'%(direction[0])
            MagRec["measurement_inc"]='%7.1f'%(direction[1])

            step = line[1]
            if step == 'NRM':
                meas_type="LT-NO"
            elif step[0:2] == 'AD':
                meas_type="LT-AF-Z"
                treat=float(step[2:])
                MagRec["treatment_ac_field"]='%8.3e' %(treat*1e-3) # convert from mT to tesla
            elif step[0:2] == 'TD':
                meas_type="LT-T-Z"
                treat=float(step[2:])
                MagRec["treatment_temp"]='%8.3e' % (treat+273.) # temp in kelvin
            elif step[0:3]=='ARM': #
                meas_type="LT-AF-I"
                treat=float(row['step'][3:])
                MagRec["treatment_ac_field"]='%8.3e' %(treat*1e-3) # convert from mT to tesla
                MagRec["treatment_dc_field"]='%8.3e' %(50e-6) # assume 50uT DC field
                MagRec["measurement_description"]='Assumed DC field - actual unknown'
            elif step[0:3]=='IRM': #
                meas_type="LT-IRM"
                treat=float(step[3:])
                MagRec["treatment_dc_field"]='%8.3e' %(treat*1e-3) # convert from mT to tesla
            else:
                print('unknown treatment type for ',row)
                return False, 'unknown treatment type for ',row

            MagRec['magic_method_codes']=meas_type
            MagRecs.append(MagRec.copy())

        else:
            print('sample name not found: ',row['specname'])
    MagOuts=pmag.measurements_methods(MagRecs,noave)
    file_created, error_message = pmag.magic_write(meas_file,MagOuts,'magic_measurements')
    if file_created:
        return True, meas_file
    else:
        return False, 'Results not written to file'


Instruction:
Can you tell what is the following Python 3 function doing
def get_n_ptrm(tmin, tmax, ptrm_temps, ptrm_starting_temps):
    # does not exclude ptrm checks that are less than tmin
    ptrm_checks_included_temps= []
    for num, check in enumerate(ptrm_temps):
        if check > tmax:
            pass
        elif ptrm_starting_temps[num] > tmax: # or ptrm_starting_temps[num] < tmin:
            pass
        else:
            ptrm_checks_included_temps.append(check)
    return len(ptrm_checks_included_temps), ptrm_checks_included_temps

Response: This function returns the number of ptrm checks included in best fit segment.


Instruction:
How would you explain what the following Python 3 function does
def get_max_ptrm_check(ptrm_checks_included_temps, ptrm_checks_all_temps, ptrm_x, t_Arai, x_Arai):
    if not ptrm_checks_included_temps:
        return [], float('nan'), float('nan'), float('nan'), float('nan')
    diffs = []
    abs_diffs = []
    x_Arai_compare = []
    ptrm_compare = []
    check_percents = []
    ptrm_checks_all_temps = list(ptrm_checks_all_temps)
    for check in ptrm_checks_included_temps: # goes through each included temperature step
        ptrm_ind = ptrm_checks_all_temps.index(check) # indexes the number of the check
        ptrm_check = ptrm_x[ptrm_ind] # x value at that temperature step
        ptrm_compare.append(ptrm_check) #
        arai_ind = t_Arai.index(check)
        ptrm_orig = x_Arai[arai_ind]
        x_Arai_compare.append(ptrm_orig)
        diff = ptrm_orig - ptrm_check
        diffs.append(diff)
        abs_diffs.append(abs(diff))
        if ptrm_orig == 0:
            check_percents.append(0)
        else:
            check_percents.append((old_div(abs(diff), ptrm_orig)) * 100)
    max_diff = max(abs_diffs)
    check_percent = max(check_percents)
    sum_diffs = abs(sum(diffs))
    sum_abs_diffs = sum(abs_diffs)
    return diffs, max_diff, sum_diffs, check_percent, sum_abs_diffs

Response: This function calculates the maximum ptrm check for a single element in the tree.


Instruction:
Implement a function in Python 3 to
input TRM length of best fit line (delta_x_prime), NRM length of best fit line, max_ptrm_check Output: DRAT (maximum difference produced by a ptrm check normed by best fit line), length best fit line

Response:
def get_DRAT(delta_x_prime, delta_y_prime, max_ptrm_check):
    """
    Input: TRM length of best fit line (delta_x_prime),
        NRM length of best fit line,
        max_ptrm_check
    Output: DRAT (maximum difference produced by a ptrm check normed by best fit line),
        length best fit line
    """
    L = numpy.sqrt(delta_x_prime**2 + delta_y_prime**2)
    DRAT = (old_div(max_ptrm_check, L)) * 100
    return DRAT, L


Instruction:
How would you explain what the following Python 3 function does
def get_CDRAT(L, sum_ptrm_checks, sum_abs_ptrm_checks):
    CDRAT = (old_div(sum_ptrm_checks, L)) * 100.
    CDRAT_prime = (old_div(sum_abs_ptrm_checks, L)) * 100.
    return CDRAT, CDRAT_prime

Response: get CDRAT and CDRAT_prime


Instruction:
Write a Python 3 function for
getting DRATS from sum of ptrm check diffs and sum of absolute value of ptrm check diffs

Response:
def get_DRATS(sum_ptrm_checks, sum_abs_ptrm_checks, x_Arai, end):
    """
    input: sum of ptrm check diffs, sum of absolute value of ptrm check diffs,
        x_Arai set of points, end.
    output: DRATS (uses sum of diffs), DRATS_prime (uses sum of absolute diffs)
    """
    DRATS = (old_div(sum_ptrm_checks, x_Arai[end])) * 100.
    DRATS_prime = (old_div(sum_abs_ptrm_checks, x_Arai[end])) * 100.
    return DRATS, DRATS_prime


Instruction:
Implement a Python 3 function for
inputting sum_ptrm_checks, sum_abs_ptrm_checks, n_pTRM, L output: mean DRAT (the average difference produced by a pTRM check, normalized by the length of the best-fit line)

Response:
def get_mean_DRAT(sum_ptrm_checks, sum_abs_ptrm_checks, n_pTRM, L):
    """
    input: sum_ptrm_checks, sum_abs_ptrm_checks, n_pTRM, L
    output: mean DRAT (the average difference produced by a pTRM check,
    normalized by the length of the best-fit line)
    """
    if not n_pTRM:
        return float('nan'), float('nan')
    mean_DRAT = ((old_div(1., n_pTRM)) * (old_div(sum_ptrm_checks, L))) * 100
    mean_DRAT_prime = ((old_div(1., n_pTRM)) * (old_div(sum_abs_ptrm_checks, L))) * 100
    return mean_DRAT, mean_DRAT_prime


Instruction:
Given the following Python 3 function, write the documentation
def get_mean_DEV(sum_ptrm_checks, sum_abs_ptrm_checks, n_pTRM, delta_x_prime):
    if not n_pTRM:
        return float('nan'), float('nan')
    mean_DEV = ((old_div(1., n_pTRM)) * (old_div(sum_ptrm_checks, delta_x_prime))) * 100
    mean_DEV_prime= ((old_div(1., n_pTRM)) * (old_div(sum_abs_ptrm_checks, delta_x_prime))) * 100
    return mean_DEV, mean_DEV_prime

Response: This function calculates the mean deviation of a checkon group


Instruction:
Can you create a Python 3 function that
returns the delta PTRM and PTRM_Checks vectors in vector form.

Response:
def get_delta_pal_vectors(PTRMS, PTRM_Checks, NRM):
    """ takes in PTRM data in this format: [temp, dec, inc, moment, ZI or IZ] -- and PTRM_check data in this format: [temp, dec, inc, moment].  Returns them in vector form (cartesian). """
    PTRMS = numpy.array(PTRMS)
    PTRM_Checks = numpy.array(PTRM_Checks)
    TRM_1 = lib_direct.dir2cart(PTRMS[0,1:3])
    PTRMS_cart = []
    Checks_cart = []
    for num, ptrm in enumerate(PTRMS):
        ptrm_cart = lib_direct.dir2cart([PTRMS[num][1], PTRMS[num][2], old_div(PTRMS[num][3], NRM)])
        PTRMS_cart.append(ptrm_cart)
    for num, check in enumerate(PTRM_Checks):
        check_cart = lib_direct.dir2cart([PTRM_Checks[num][1], PTRM_Checks[num][2], old_div(PTRM_Checks[num][3], NRM)])
        Checks_cart.append(check_cart)
    return PTRMS_cart, Checks_cart, TRM_1


Instruction:
Can you tell what is the following Python 3 function doing
def get_diffs(ptrms_vectors, ptrm_checks_vectors, ptrms_orig, checks_orig):
    ptrm_temps = numpy.array(ptrms_orig)[:,0]
    check_temps = numpy.array(checks_orig)[:,0]
    index = numpy.zeros(len(ptrm_temps))
    for num, temp in enumerate(ptrm_temps):
        if len(numpy.where(check_temps == temp)[0]):
            index[num] = numpy.where(check_temps == temp)[0][0]
        else:
            index[num] = float('nan')
    diffs = numpy.zeros((len(ptrms_vectors), 3))
    for num, ptrm in enumerate(ptrms_vectors):
        if numpy.isnan(index[num]):
            diffs[num] = numpy.array([0,0,0])
        else:
            diffs[num] = ptrm_checks_vectors[int(index[num])] - ptrm
    C = numpy.cumsum(diffs, 0)
    #print "diffs (should be same as to_sum"
    #print diffs
    #print "C (should be same as dpal_sum)"
    #print C
    return diffs, C

Response: get the vector diffs between original and ptrm check


Instruction:
Create a Python 3 function for
getting TRM star from ptrms_vectors start and end

Response:
def get_TRM_star(C, ptrms_vectors, start, end):
    """
    input: C, ptrms_vectors, start, end
    output: TRM_star, x_star (for delta_pal statistic)
    """
    TRM_star = numpy.zeros([len(ptrms_vectors), 3])
    TRM_star[0] = [0., 0., 0.]
    x_star = numpy.zeros(len(ptrms_vectors))
    for num, vec in enumerate(ptrms_vectors[1:]):
        TRM_star[num+1] = vec + C[num]
       # print 'vec', vec
       # print 'C', C[num]
    for num, trm in enumerate(TRM_star):
        x_star[num] = numpy.linalg.norm(trm)
    #print "x_star (should match corr_TRM / NRM)"
    #print x_star[start:end+1]
    return TRM_star[start:end+1], x_star[start:end+1]


Instruction:
Can you generate a brief explanation for the following Python 3 code
def get_b_star(x_star, y_err, y_mean, y_segment):
    #print "x_star, should be same as Xcorr / NRM"
    #print x_star
    x_star_mean = numpy.mean(x_star)
    x_err = x_star - x_star_mean
    b_star = -1* numpy.sqrt( old_div(sum(numpy.array(y_err)**2), sum(numpy.array(x_err)**2)) )  # averaged slope
    #print "y_segment", y_segment
    b_star = numpy.sign(sum(x_err * y_err)) * numpy.std(y_segment, ddof=1) / numpy.std(x_star, ddof=1)
    #print "b_star (should be same as corr_slope)"
    #print b_star
    return b_star

Response: get b_star from x_star y_err y_mean y_segment


Instruction:
Write a Python 3 script to
calculate delta_pal from b_star and b

Response:
def get_delta_pal(b, b_star):
    """
    input: b, b_star (actual and corrected slope)
    output: delta_pal
    """
    delta_pal = numpy.abs(old_div((b - b_star), b)) * 100
    return delta_pal


Instruction:
Can you generate a brief explanation for the following Python 3 code
def get_full_delta_pal(PTRMS, PTRM_Checks, NRM, y_err, y_mean, b, start, end, y_segment):
    #print "-------"
    #print "calling get_full_delta_pal in lib"
#    return 0
    PTRMS_cart, checks, TRM_1 = get_delta_pal_vectors(PTRMS, PTRM_Checks, NRM)
#    print "PTRMS_Cart", PTRMS_cart
    diffs, C = get_diffs(PTRMS_cart, checks, PTRMS, PTRM_Checks)
#    print "C", C
    TRM_star, x_star = get_TRM_star(C, PTRMS_cart, start, end)
#    print "x_star", x_star
#    print type(x_star)
    b_star = get_b_star(x_star, y_err, y_mean, y_segment)
    delta_pal = get_delta_pal(b, b_star)
    return delta_pal

Response:
input: PTRMS, PTRM_Checks, NRM, y_err, y_mean, b, start, end, y_segment
    runs full sequence necessary to get delta_pal


Instruction:
Can you tell what is the following Python 3 function doing
def get_segments(ptrms, ptrm_checks, tmax):
    ptrms_included = []
    checks_included = []
    ptrms = numpy.array(ptrms)
    for ptrm in ptrms:
        if ptrm[0] <= tmax:
            ptrms_included.append(ptrm)
    for check in ptrm_checks:
        if check[0] <= tmax:
            checks_included.append(check)
    #print "checks", ptrm_checks
    #print "checks_included", checks_included
    return ptrms_included, checks_included

Response: get_segments - returns a list of all the segments in the order of the given ptrms and ptrm_checks


Instruction:
Create a Python 3 function to
select the current fit on the GUI that is the parent of this one.

Response:
def select(self):
        """
        Makes this fit the selected fit on the GUI that is it's parent
        (Note: may be moved into GUI soon)
        """
        if self.GUI==None: return
        self.GUI.current_fit = self
        if self.tmax != None and self.tmin != None:
            self.GUI.update_bounds_boxes()
        if self.PCA_type != None:
            self.GUI.update_PCA_box()
        try: self.GUI.zijplot
        except AttributeError: self.GUI.draw_figure(self.GUI.s)
        self.GUI.fit_box.SetStringSelection(self.name)
        self.GUI.get_new_PCA_parameters(-1)


Instruction:
How would you implement a function in Python 3 that
returns the pmagpy paramters dictionary associated with this fit and the given coordinate system

Response:
def get(self,coordinate_system):
        """
        Return the pmagpy paramters dictionary associated with this fit and the given
        coordinate system
        @param: coordinate_system -> the coordinate system who's parameters to return
        """
        if coordinate_system == 'DA-DIR' or coordinate_system == 'specimen':
            return self.pars
        elif coordinate_system == 'DA-DIR-GEO' or coordinate_system == 'geographic':
            return self.geopars
        elif coordinate_system == 'DA-DIR-TILT' or coordinate_system == 'tilt-corrected':
            return self.tiltpars
        else:
            print("-E- no such parameters to fetch for " + coordinate_system + " in fit: " + self.name)
            return None


Instruction:
How would you code a function in Python 3 to
give a coordinate system and a new parameters dictionary that follows pmagpy convention given by the pmag.py/domean function it alters this fit's bounds and parameters such that it matches the new data. @param: specimen -> None if fit is for a site or a sample or a valid specimen from self.GUI @param: coordinate_system -> the coordinate system to alter @param: new_pars -> the new paramters to change your fit to @alters: tmin, tmax, pars, geopars, tiltpars, PCA_type

Response:
def put(self,specimen,coordinate_system,new_pars):
        """
        Given a coordinate system and a new parameters dictionary that follows pmagpy
        convention given by the pmag.py/domean function it alters this fit's bounds and
        parameters such that it matches the new data.
        @param: specimen -> None if fit is for a site or a sample or a valid specimen from self.GUI
        @param: coordinate_system -> the coordinate system to alter
        @param: new_pars -> the new paramters to change your fit to
        @alters: tmin, tmax, pars, geopars, tiltpars, PCA_type
        """

        if specimen != None:
            if type(new_pars)==dict:
                if 'er_specimen_name' not in list(new_pars.keys()): new_pars['er_specimen_name'] = specimen
                if 'specimen_comp_name' not in list(new_pars.keys()): new_pars['specimen_comp_name'] = self.name
            if type(new_pars) != dict or 'measurement_step_min' not in list(new_pars.keys()) or 'measurement_step_max' not in list(new_pars.keys()) or 'calculation_type' not in list(new_pars.keys()):
                print("-E- invalid parameters cannot assign to fit %s for specimen %s - was given:\n%s"%(self.name,specimen,str(new_pars)))
                return self.get(coordinate_system)

            self.tmin = new_pars['measurement_step_min']
            self.tmax = new_pars['measurement_step_max']
            self.PCA_type = new_pars['calculation_type']

            if self.GUI!=None:
                steps = self.GUI.Data[specimen]['zijdblock_steps']
                tl = [self.tmin,self.tmax]
                for i,t in enumerate(tl):
                    if str(t) in steps: tl[i] = str(t)
                    elif str(int(t)) in steps: tl[i] = str(int(t))
                    elif "%.1fmT"%t in steps: tl[i] = "%.1fmT"%t
                    elif "%.0fC"%t in steps: tl[i] = "%.0fC"%t
                    else:
                        print("-E- Step " + str(tl[i]) + " does not exsist (func: Fit.put)")
                        tl[i] = str(t)
                self.tmin,self.tmax = tl
            elif meas_data != None:
                steps = meas_data[specimen]['zijdblock_steps']
                tl = [self.tmin,self.tmax]
                for i,t in enumerate(tl):
                    if str(t) in steps: tl[i] = str(t)
                    elif str(int(t)) in steps: tl[i] = str(int(t))
                    elif "%.1fmT"%t in steps: tl[i] = "%.1fmT"%t
                    elif "%.0fC"%t in steps: tl[i] = "%.0fC"%t
                    else:
                        print("-E- Step " + str(tl[i]) + " does not exsist (func: Fit.put)")
                        tl[i] = str(t)
                self.tmin,self.tmax = tl
            else: self.tmin,self.tmax = list(map(str, tl))

        if coordinate_system == 'DA-DIR' or coordinate_system == 'specimen':
            self.pars = new_pars
        elif coordinate_system == 'DA-DIR-GEO' or coordinate_system == 'geographic':
            self.geopars = new_pars
        elif coordinate_system == 'DA-DIR-TILT' or coordinate_system == 'tilt-corrected':
            self.tiltpars = new_pars
        else:
            print('-E- no such coordinate system could not assign those parameters to fit')


Instruction:
Can you tell what is the following Python 3 function doing
def has_values(self, name, tmin, tmax):
        return str(self.name) == str(name) and str(self.tmin) == str(tmin) and str(self.tmax) == str(tmax)

Response: A basic fit equality checker compares name and bounds of 2 fits


Instruction:
Write a Python 3 script for
determining number of included tail checks in best fit segment

Response:
def get_n_tail(tmax, tail_temps):
    """determines number of included tail checks in best fit segment"""
    #print "tail_temps: {0}, tmax: {0}".format(tail_temps, tmax)
    t_index = 0
    adj_tmax = 0
    if tmax < tail_temps[0]:
        return 0
    try:
        t_index = list(tail_temps).index(tmax)
    except: # finds correct tmax if there was no tail check performed at tmax
        for temp in tail_temps:
            if temp <= tmax:
                adj_tmax = temp
        t_index = list(tail_temps).index(adj_tmax)
    incl_temps = tail_temps[0:t_index+1] # b/c not inclusive
    return len(incl_temps)


Instruction:
Write a Python 3 function that can
function to get the max tail check for a single Arai

Response:
def get_max_tail_check(y_Arai, y_tail, t_Arai, tail_temps, n_tail):
    """
    input: y_Arai, y_tail, t_Arai, tail_temps, n_tail
    output: max_check, diffs
    """
    if not n_tail:
        return float('nan'), []
    tail_compare = []
    y_Arai_compare = []
    for temp in tail_temps[:n_tail]:
        tail_index = list(tail_temps).index(temp)
        tail_check = y_tail[tail_index]
        tail_compare.append(tail_check)
        arai_index = list(t_Arai).index(temp)
        nrm_orig = y_Arai[arai_index]
        y_Arai_compare.append(nrm_orig)
    diffs = numpy.array(y_Arai_compare) - numpy.array(tail_compare)
    abs_diffs = abs(diffs)
    max_check = max(abs_diffs)
    return max_check, diffs


Instruction:
Can you implement a function in Python 3 that
gets DRAT tail of a node

Response:
def get_DRAT_tail(max_check, L):
    """
    input: tail_check_max, best fit line length
    output: DRAT_tail
    """
    if max_check == 0:
        return float('nan')
    DRAT_tail = (old_div(max_check, L)) * 100.
    return DRAT_tail


Instruction:
How would you explain what the following Python 3 function does
def get_delta_TR(tail_check_max, y_int):
    if tail_check_max == 0 or numpy.isnan(tail_check_max):
        return float('nan')
    delta_TR = (old_div(tail_check_max, abs(y_int))) * 100.
    return delta_TR

Response: calculate delta TR from tail_check_max y_int


Instruction:
Can you generate the documentation for the following Python 3 function
def get_MD_VDS(tail_check_max, vds):
    if tail_check_max == 0 or numpy.isnan(tail_check_max):
        return float('nan')
    MD_VDS = (old_div(tail_check_max, vds)) * 100
    return MD_VDS

Response: calculate MD VDS from vector difference sum


Instruction:
How would you explain what the following Python 3 function does
def set_dm(self, num):
        #enable or disable self.btn1a
        if self.data_model_num == 3:
            self.btn1a.Enable()
        else:
            self.btn1a.Disable()
        #
        # set pmag_gui_dialogs
        global pmag_gui_dialogs
        if self.data_model_num == 2:
            pmag_gui_dialogs = pgd2
            wx.CallAfter(self.get_wd_data2)
        elif self.data_model_num == 3:
            pmag_gui_dialogs = pgd3
            wx.CallAfter(self.get_wd_data)

        # do / re-do menubar
        menubar = pmag_gui_menu.MagICMenu(self, data_model_num=self.data_model_num)
        self.SetMenuBar(menubar)
        self.menubar = menubar

Response: Set the data model num and set the GUI to show it.


Instruction:
How would you explain what the following Python 3 function does
def get_wd_data(self):
        wait = wx.BusyInfo('Reading in data from current working directory, please wait...')
        #wx.Yield()
        print('-I- Read in any available data from working directory')
        self.contribution = cb.Contribution(self.WD, dmodel=self.data_model)
        del wait

Response:
Show dialog to get user input for which directory
        to set as working directory.


Instruction:
Create a Python 3 function for
getting 2. 5 data from self. WD and put it into ErMagicBuilder object.

Response:
def get_wd_data2(self):
        """
        Get 2.5 data from self.WD and put it into
        ErMagicBuilder object.
        Called by get_dm_and_wd
        """
        wait = wx.BusyInfo('Reading in data from current working directory, please wait...')
        #wx.Yield()
        print('-I- Read in any available data from working directory (data model 2)')

        self.er_magic = builder.ErMagicBuilder(self.WD,
                                               data_model=self.data_model)
        del wait


Instruction:
Can you generate a brief explanation for the following Python 3 code
def get_dir(self):
        if "-WD" in sys.argv and self.FIRST_RUN:
            ind = sys.argv.index('-WD')
            self.WD = os.path.abspath(sys.argv[ind+1])
            os.chdir(self.WD)
            self.WD = os.getcwd()
            self.dir_path.SetValue(self.WD)
        else:
            self.on_change_dir_button(None)
            #self.WD = os.getcwd()

        self.FIRST_RUN = False

Response: Choose a working directory dialog.


Instruction:
Create a Python 3 function to
open dialog for rough conversion of 2.5 files to 3.0 files. Offer link to earthref for proper upgrade.

Response:
def on_btn_convert_3(self, event):
        """
        Open dialog for rough conversion of
        2.5 files to 3.0 files.
        Offer link to earthref for proper upgrade.
        """
        dia = pw.UpgradeDialog(None)
        dia.Center()
        res = dia.ShowModal()
        if res == wx.ID_CANCEL:
            webbrowser.open("https://www2.earthref.org/MagIC/upgrade", new=2)
            return
        ## more nicely styled way, but doesn't link to earthref
        #msg = "This tool is meant for relatively simple upgrades (for instance, a measurement file, a sample file, and a criteria file).\nIf you have a more complex contribution to upgrade, and you want maximum accuracy, use the upgrade tool at https://www2.earthref.org/MagIC/upgrade.\n\nDo you want to continue?"
        #result = pw.warning_with_override(msg)
        #if result == wx.ID_NO:
            #webbrowser.open("https://www2.earthref.org/MagIC/upgrade", new=2)
            #return
        # turn files from 2.5 --> 3.0 (rough translation)
        meas, upgraded, no_upgrade = pmag.convert_directory_2_to_3('magic_measurements.txt',
                                                                   input_dir=self.WD, output_dir=self.WD,
                                                                   data_model=self.contribution.data_model)
        if not meas:
            wx.MessageBox('2.5 --> 3.0 failed. Do you have a magic_measurements.txt file in your working directory?',
                          'Info', wx.OK | wx.ICON_INFORMATION)
            return

        # create a contribution
        self.contribution = cb.Contribution(self.WD)
        # make skeleton files with specimen, sample, site, location data
        self.contribution.propagate_measurement_info()
        # pop up
        upgraded_string = ", ".join(upgraded)
        if no_upgrade:
            no_upgrade_string = ", ".join(no_upgrade)
            msg = '2.5 --> 3.0 translation completed!\n\nThese 3.0 format files were created: {}.\n\nHowever, these 2.5 format files could not be upgraded: {}.\n\nTo convert all 2.5 files, use the MagIC upgrade tool: https://www2.earthref.org/MagIC/upgrade\n'.format(upgraded_string, no_upgrade_string)
            if 'criteria.txt' in upgraded:
                msg += '\nNote: Please check your criteria file for completeness and accuracy, as not all 2.5 files will be fully upgraded.'
            if 'pmag_criteria.txt' in no_upgrade:
                msg += '\nNote: Not all criteria files can be upgraded, even on the MagIC site.  You may need to recreate an old pmag_criteria file from scratch in Thellier GUI or Demag GUI.'
            wx.MessageBox(msg, 'Warning', wx.OK | wx.ICON_INFORMATION)
        else:
            msg = '2.5 --> 3.0 translation completed!\nThese files were converted: {}'.format(upgraded_string)
            wx.MessageBox(msg, 'Info', wx.OK | wx.ICON_INFORMATION)


Instruction:
How would you explain what the following Python 3 function does
def on_btn_metadata(self, event):
        # make sure we have a measurements file
        if not self.check_for_meas_file():
            return
        # make sure all files of the same type have been combined
        if not self.check_for_uncombined_files():
            return
        if self.data_model_num == 2:
            wait = wx.BusyInfo('Compiling required data, please wait...')
            wx.SafeYield()
            self.ErMagic_frame = ErMagicBuilder.MagIC_model_builder(self.WD, self, self.er_magic)
        elif self.data_model_num == 3:
            wait = wx.BusyInfo('Compiling required data, please wait...')
            wx.SafeYield()
            self.ErMagic_frame = ErMagicBuilder.MagIC_model_builder3(self.WD, self, self.contribution)
        #
        self.ErMagic_frame.Show()
        self.ErMagic_frame.Center()
        # gets total available screen space - 10%
        size = wx.DisplaySize()
        size = (size[0] - 0.3 * size[0], size[1] - 0.3 * size[1])
        self.ErMagic_frame.Raise()
        del wait

Response: Initiate the series of windows to add metadata to the contribution.


Instruction:
Can you create a Python 3 function that
initiates the object that will control steps 1 - 6 of checking headers filling in cell values etc.

Response:
def init_check_window2(self):
        """
        initiates the object that will control steps 1-6
        of checking headers, filling in cell values, etc.
        """
        self.check_dia = pmag_er_magic_dialogs.ErMagicCheckFrame(self, 'Check Data',
                                                                 self.WD, self.er_magic)


Instruction:
Implement a function in Python 3 to
initiate the object that will control steps 1 - 6 of checking headers filling in cell values etc.

Response:
def init_check_window(self):
        """
        initiates the object that will control steps 1-6
        of checking headers, filling in cell values, etc.
        """
        self.check_dia = pmag_er_magic_dialogs.ErMagicCheckFrame3(self, 'Check Data',
                                                                  self.WD, self.contribution)


Instruction:
Implement a Python 3 function for
creating and fill wxPython grid for entering the current ISO - 8601 data.

Response:
def on_btn_orientation(self, event):
        """
        Create and fill wxPython grid for entering
        orientation data.
        """
        wait = wx.BusyInfo('Compiling required data, please wait...')
        wx.SafeYield()
        #dw, dh = wx.DisplaySize()
        size = wx.DisplaySize()
        size = (size[0]-0.1 * size[0], size[1]-0.1 * size[1])
        if self.data_model_num == 3:
            frame = pmag_gui_dialogs.OrientFrameGrid3(self, -1, 'demag_orient.txt',
                                                        self.WD, self.contribution,
                                                        size)
        else:
            frame = pmag_gui_dialogs.OrientFrameGrid(self, -1, 'demag_orient.txt',
                                                        self.WD, self.er_magic, size)
        frame.Show(True)
        frame.Centre()
        self.Hide()
        del wait


Instruction:
Can you tell what is the following Python 3 function doing
def on_btn_unpack(self, event):
        dlg = wx.FileDialog(
            None, message = "choose txt file to unpack",
            defaultDir=self.WD,
            defaultFile="",
            style=wx.FD_OPEN #| wx.FD_CHANGE_DIR
            )
        if dlg.ShowModal() == wx.ID_OK:
            FILE = dlg.GetPath()
            input_dir, f = os.path.split(FILE)
        else:
            return False

        outstring="download_magic.py -f {} -WD {} -ID {} -DM {}".format(f, self.WD, input_dir, self.data_model_num)

        # run as module:
        print("-I- running python script:\n %s"%(outstring))
        wait = wx.BusyInfo("Please wait, working...")
        wx.SafeYield()
        ex = None
        try:
            if ipmag.download_magic(f, self.WD, input_dir, overwrite=True, data_model=self.data_model):
                text = "Successfully ran download_magic.py program.\nMagIC files were saved in your working directory.\nSee Terminal/message window for details."
            else:
                text = "Something went wrong.  Make sure you chose a valid file downloaded from the MagIC database and try again."

        except Exception as ex:
            text = "Something went wrong.  Make sure you chose a valid file downloaded from the MagIC database and try again."
            del wait
            dlg = wx.MessageDialog(self, caption="Saved", message=text, style=wx.OK)
            result = dlg.ShowModal()
            if result == wx.ID_OK:
                dlg.Destroy()
            if ex:
                raise(ex)
        self.contribution = cb.Contribution(self.WD)

Response: Create dialog to choose a file to unpack and create a contribution.


Instruction:
Here you have a function in Python 3, explain what it does
def on_btn_upload(self, event):
        if not self.check_for_uncombined_files():
            return
        outstring="upload_magic.py"
        print("-I- running python script:\n %s"%(outstring))
        wait = wx.BusyInfo("Please wait, working...")
        wx.SafeYield()
        self.contribution.tables['measurements'].add_measurement_names()
        if self.data_model_num == 3:
            res, error_message, has_problems, all_failing_items = ipmag.upload_magic(concat=False, dir_path=self.WD,
                                                                                vocab=self.contribution.vocab,
                                                                                contribution=self.contribution)
        if self.data_model_num == 2:
            res, error_message, errors = ipmag.upload_magic2(dir_path=self.WD, data_model=self.er_magic.data_model)
            del wait

        if res:
            text = "You are ready to upload!\n{} was generated in {}".format(os.path.split(res)[1], os.path.split(res)[0])
            dlg = pw.ChooseOne(self, "Go to MagIC for uploading", "Not ready yet", text, "Saved")
            del wait
            #dlg = wx.MessageDialog(self, caption="Saved", message=text, style=wx.OK)
        else:
            text = "There were some problems with the creation of your upload file.\nError message: {}\nSee Terminal/message window for details".format(error_message)
            dlg = wx.MessageDialog(self, caption="Error", message=text, style=wx.OK)

        dlg.Centre()
        result = dlg.ShowModal()
        if result == wx.ID_OK:
            dlg.Destroy()
        if result == wx.ID_YES:
            pw.on_database_upload(None)

        if self.data_model_num == 3:
            if not res:
                from programs import magic_gui
                self.Disable()
                self.Hide()
                self.magic_gui_frame = magic_gui.MainFrame(self.WD,
                                                           dmodel=self.data_model,
                                                           title="Validations",
                                                           contribution=self.contribution)

                self.magic_gui_frame.validation_mode = ['specimens']
                self.magic_gui_frame.failing_items = all_failing_items
                self.magic_gui_frame.change_dir_button.Disable()
                self.magic_gui_frame.Centre()
                self.magic_gui_frame.Show()
                self.magic_gui_frame.highlight_problems(has_problems)
                #
                # change name of upload button to 'exit validation mode'
                self.magic_gui_frame.bSizer2.GetStaticBox().SetLabel('return to main GUI')
                self.magic_gui_frame.btn_upload.SetLabel("exit validation mode")
                # bind that button to quitting magic gui and re-enabling Pmag GUI
                self.magic_gui_frame.Bind(wx.EVT_BUTTON, self.on_end_validation, self.magic_gui_frame.btn_upload)
                # do binding so that closing/quitting re-opens the main frame
                self.magic_gui_frame.Bind(wx.EVT_CLOSE, self.on_end_validation)
                # this makes it work with only the validation window open
                self.magic_gui_frame.Bind(wx.EVT_MENU,
                                          lambda event: self.menubar.on_quit(event, self.magic_gui_frame),
                                          self.magic_gui_frame.menubar.file_quit)
                # this makes it work if an additional grid is open
                self.Bind(wx.EVT_MENU,
                          lambda event: self.menubar.on_quit(event, self.magic_gui_frame),
                          self.magic_gui_frame.menubar.file_quit)

Response: Upload a new MagIC file to MagIC


Instruction:
Can you tell what is the following Python 3 function doing
def on_end_validation(self, event):
        self.Enable()
        self.Show()
        self.magic_gui_frame.Destroy()

Response: Switch back from validation mode to main Pmag GUI mode and show main frame and hide validation frame and show main frame.


Instruction:
Can you generate the documentation for the following Python 3 function
def check_for_uncombined_files(self):
        wd_files = os.listdir(self.WD)
        if self.data_model_num == 2:
            ftypes = ['er_specimens.txt', 'er_samples.txt', 'er_sites.txt', 'er_locations.txt', 'pmag_specimens.txt', 'pmag_samples.txt', 'pmag_sites.txt', 'rmag_specimens.txt', 'rmag_results.txt', 'rmag_anisotropy.txt']
        else:
            ftypes = ['specimens.txt', 'samples.txt', 'sites.txt', 'locations.txt']
        uncombined = set()
        for ftype in ftypes:
            if ftype not in wd_files:
                for f in wd_files:
                    if f.endswith('_' + ftype):
                        uncombined.add(ftype)
        if uncombined:
            msg = 'It looks like you may have uncombined files of type(s) {} in your working directory.\nYou may want to go back to Step 1 and finish combining all files.\nIf you continue, the program will try to extract as much information as possible from your measurement file.'.format(", ".join(list(uncombined)))
            dlg = pw.ChooseOne(self, 'Continue anyway', 'Go back', msg, title="Warning!")
            res = dlg.ShowModal()
            if res == wx.ID_NO:
                return
        return True

Response: Check if uncombined files are found in the working directory and if not continue to extract as much information as possible.


Instruction:
Explain what the following Python 3 code does
def check_for_meas_file(self):
        if self.data_model_num == 2:
            meas_file_name = "magic_measurements.txt"
            dm = "2.5"
        else:
            meas_file_name = "measurements.txt"
            dm = "3.0"
        if not os.path.isfile(os.path.join(self.WD, meas_file_name)):
            pw.simple_warning("Your working directory must have a {} format {} file to run this step.  Make sure you have fully completed step 1 (import magnetometer file) and ALSO converted to 3.0., if necessary), then try again.\n\nIf you are trying to look at data downloaded from MagIC, you must unpack the txt file first. Some contributions do not contain measurement data, in which case you won't be able to use this function.".format(dm, meas_file_name))
            return False
        return True

Response: Check the working directory for a measurement file.


Instruction:
Can you tell what is the following Python 3 function doing
def main():
    args = sys.argv
    if "-h" in args:
        print(main.__doc__)
        sys.exit()
    dir_path = pmag.get_named_arg('-WD', '.')
    fmt = pmag.get_named_arg('-fmt', 'svg')
    save_plots = False
    interactive = True
    if '-sav' in sys.argv:
        save_plots = True
        interactive = False
    infile = pmag.get_named_arg("-f", "specimens.txt")
    ipmag.dayplot_magic(dir_path, infile, save=save_plots,
                        fmt=fmt, interactive=interactive)

Response:
NAME
        dayplot_magic.py

    DESCRIPTION
        makes 'day plots' (Day et al. 1977) and squareness/coercivity,
        plots 'linear mixing' curve from Dunlop and Carter-Stiglitz (2006).
          squareness coercivity of remanence (Neel, 1955) plots after
          Tauxe et al. (2002)

    SYNTAX
        dayplot_magic.py [command line options]

    OPTIONS
        -h prints help message and quits
        -f: specify input hysteresis file, default is specimens.txt
        -fmt [svg,png,jpg] format for output plots, default svg
        -sav saves plots and quits quietly


Instruction:
How would you explain what the following Python 3 function does
def on_import1(self, event):
        pmag_menu_dialogs.MoveFileIntoWD(self.parent, self.parent.WD)

Response: initialize window to import an arbitrary file into the working directory


Instruction:
Here you have a function in Python 3, explain what it does
def orient_import2(self, event):
        pmag_menu_dialogs.ImportAzDipFile(self.parent, self.parent.WD)

Response: initialize window to import an AzDip format file into the working directory


Instruction:
Can you write a function in Python 3 where it
names plot_map_pts.py DESCRIPTION plots points on map SYNTAX plot_map_pts.py [command line options] OPTIONS -h prints help and quits -sym [ro, bs, g^, r., b-, etc.] [1,5,10] symbol and size for points colors are r=red,b=blue,g=green, etc. symbols are '.' for points, ^, for triangle, s for square, etc. -, for lines, -- for dotted lines, see matplotlib online documentation for plot() -eye ELAT ELON [specify eyeball location] -etp put on topography -cmap color map [default is jet] -f FILE, specify input file -o color ocean blue/land green (default is not) -res [c,l,i,h] specify resolution (crude, low, intermediate, high] -fmt [pdf,eps, png] specify output format (default is pdf) -R don't plot details of rivers -B don't plot national/state boundaries, etc. -pad [LAT LON] pad bounding box by LAT/LON (default is not) -grd SPACE specify grid spacing -sav save plot and quit -prj PROJ, specify one of the supported projections: pc = Plate Carree aea = Albers Equal Area aeqd = Azimuthal Equidistant lcc = Lambert Conformal lcyl = Lambert Cylindrical merc = Mercator mill = Miller Cylindrical moll = Mollweide [default] ortho = Orthographic robin = Robinson sinu = Sinusoidal stere = Stereographic tmerc = Transverse Mercator utm = UTM laea = Lambert Azimuthal Equal Area geos = Geostationary npstere = North-Polar Stereographic spstere = South-Polar Stereographic Special codes for MagIC formatted input files: -n -l INPUTS space or tab delimited LON LAT data OR: standard MagIC formatted er_sites or pmag_results table DEFAULTS res: c prj: mollweide; lcc for MagIC format files ELAT,ELON = 0,0 pad LAT,LON=0,0 NB: high resolution or lines can be very slow

Response:
def main():
    """
    NAME
        plot_map_pts.py

    DESCRIPTION
        plots points on map

    SYNTAX
        plot_map_pts.py [command line options]

    OPTIONS
        -h prints help and quits
        -sym [ro, bs, g^, r., b-, etc.] [1,5,10] symbol and size for points
           colors are r=red,b=blue,g=green, etc.
           symbols are '.' for points, ^, for triangle, s for square, etc.
            -, for lines, -- for dotted lines, see matplotlib online documentation for plot()
        -eye  ELAT ELON [specify eyeball location]
        -etp  put on topography
        -cmap color map [default is jet]
        -f FILE, specify input file
        -o color ocean blue/land green (default is not)
        -res [c,l,i,h] specify resolution (crude, low, intermediate, high]
        -fmt [pdf,eps, png] specify output format (default is pdf)
        -R don't plot details of rivers
        -B don't plot national/state boundaries, etc.
        -pad [LAT LON] pad bounding box by LAT/LON (default is not)
        -grd SPACE specify grid spacing
        -sav  save plot and quit
        -prj PROJ,  specify one of the supported projections:
            pc = Plate Carree
            aea = Albers Equal Area
            aeqd = Azimuthal Equidistant
            lcc = Lambert Conformal
            lcyl = Lambert Cylindrical
            merc = Mercator
            mill = Miller Cylindrical
            moll = Mollweide [default]
            ortho = Orthographic
            robin = Robinson
            sinu = Sinusoidal
            stere = Stereographic
            tmerc = Transverse Mercator
            utm = UTM
            laea = Lambert Azimuthal Equal Area
            geos = Geostationary
            npstere = North-Polar Stereographic
            spstere = South-Polar Stereographic
        Special codes for MagIC formatted input files:
            -n
            -l

    INPUTS
        space or tab delimited LON LAT data
        OR:
           standard MagIC formatted er_sites or pmag_results table
    DEFAULTS
        res:  c
        prj: mollweide;  lcc for MagIC format files
        ELAT,ELON = 0,0
        pad LAT,LON=0,0
        NB: high resolution or lines can be very slow

    """
    dir_path='.'
    plot=0
    ocean=0
    res='c'
    proj='moll'
    Lats,Lons=[],[]
    fmt='pdf'
    sym='ro'
    symsize=5
    fancy=0
    rivers,boundaries,ocean=1,1,0
    latmin,latmax,lonmin,lonmax,lat_0,lon_0=-90,90,0.,360.,0.,0.
    padlat,padlon,gridspace=0,0,30
    lat_0,lon_0="",""
    basemap=1
    prn_name,prn_loc,names,locs=0,0,[],[]
    if '-WD' in sys.argv:
        ind = sys.argv.index('-WD')
        dir_path=sys.argv[ind+1]
    if '-h' in sys.argv:
        print(main.__doc__)
        sys.exit()
    if '-fmt' in sys.argv:
        ind = sys.argv.index('-fmt')
        fmt=sys.argv[ind+1]
    if '-res' in sys.argv:
        ind = sys.argv.index('-res')
        res=sys.argv[ind+1]
        if res!= 'c' and res!='l':
            print('this resolution will take a while - be patient')
    if '-etp' in sys.argv:
        fancy=1
        print ('-W- plotting will require patience!')
    if '-ctp' in sys.argv: basemap=0
    if '-sav' in sys.argv: plot=1
    if '-R' in sys.argv:rivers=0
    if '-B' in sys.argv:boundaries=0
    if '-o' in sys.argv:ocean=1
    if '-cmap' in sys.argv:
        ind = sys.argv.index('-cmap')
        cmap=float(sys.argv[ind+1])
    else:
        cmap='jet'
    if '-grd' in sys.argv:
        ind = sys.argv.index('-grd')
        gridspace=float(sys.argv[ind+1])
    if '-eye' in sys.argv:
        ind = sys.argv.index('-eye')
        lat_0=float(sys.argv[ind+1])
        lon_0=float(sys.argv[ind+2])
    if '-sym' in sys.argv:
        ind = sys.argv.index('-sym')
        sym=sys.argv[ind+1]
        symsize=int(sys.argv[ind+2])
    if '-pad' in sys.argv:
        ind = sys.argv.index('-pad')
        padlat=float(sys.argv[ind+1])
        padlon=float(sys.argv[ind+2])
    if '-f' in sys.argv:
        ind = sys.argv.index('-f')
        file=dir_path+'/'+sys.argv[ind+1]
        header=open(file,'r').readlines()[0].split('\t')
        if 'tab' in header[0]:
            proj='lcc'
            if 'sites' in header[1]:
                latkey='lat'
                lonkey='lon'
                namekey='site'
                lockey=''
            else:
                print('file type not supported')
                print(main.__doc__)
                sys.exit()
            Sites,file_type=pmag.magic_read(file)
            Lats=pmag.get_dictkey(Sites,latkey,'f')
            Lons=pmag.get_dictkey(Sites,lonkey,'f')
            if prn_name==1:names=pmag.get_dictkey(Sites,namekey,'')
            if prn_loc==1:names=pmag.get_dictkey(Sites,lockey,'')
        else:
            ptdata=numpy.loadtxt(file)
            Lons=ptdata.transpose()[0]
            Lats=ptdata.transpose()[1]
        latmin=numpy.min(Lats)-padlat
        lonmin=numpy.min(Lons)-padlon
        latmax=numpy.max(Lats)+padlat
        lonmax=numpy.max(Lons)+padlon
        if lon_0=="":
            lon_0=0.5*(lonmin+lonmax)
            lat_0=0.5*(latmin+latmax)
    else:
        print("input file must be specified")
        sys.exit()
    if '-prj' in sys.argv:
        ind = sys.argv.index('-prj')
        proj=sys.argv[ind+1]
    FIG={'map':1}
    pmagplotlib.plot_init(FIG['map'],6,6)
    cnt=0
    Opts={'latmin':latmin,'latmax':latmax,'lonmin':lonmin,'lonmax':lonmax,'lat_0':lat_0,'lon_0':lon_0,'proj':proj,'sym':sym,'symsize':3,'pltgrid':1,'res':res,'boundinglat':0.,'padlon':padlon,'padlat':padlat,'gridspace':gridspace,'cmap':cmap}
    Opts['details']={}
    Opts['details']['coasts']=1
    Opts['details']['rivers']=rivers
    Opts['details']['states']=boundaries
    Opts['details']['countries']=boundaries
    Opts['details']['ocean']=ocean
    Opts['details']['fancy']=fancy
    if len(names)>0:Opts['names']=names
    if len(locs)>0:Opts['loc_name']=locs
    if proj=='merc':
        Opts['latmin']=-70
        Opts['latmax']=70
        Opts['lonmin']=-180
        Opts['lonmax']=180
    print('please wait to draw points')
    Opts['sym']=sym
    Opts['symsize']=symsize
    if basemap:
        pmagplotlib.plot_map(FIG['map'],Lats,Lons,Opts)
    else:
        pmagplotlib.plot_map(FIG['map'],Lats,Lons,Opts)
    files={}
    titles={}
    titles['map']='PT Map'
    for key in list(FIG.keys()):
        files[key]='map_pts'+'.'+fmt
    if pmagplotlib.isServer:
        black     = '#000000'
        purple    = '#800080'
        FIG = pmagplotlib.add_borders(FIG,titles,black,purple)
        pmagplotlib.save_plots(FIG,files)
    if plot==1:
        pmagplotlib.save_plots(FIG,files)
    else:
        pmagplotlib.draw_figs(FIG)
        ans=input(" S[a]ve to save plot, Return to quit:  ")
        if ans=="a": pmagplotlib.save_plots(FIG,files)


Instruction:
Create a Python 3 function to
name n_h is the main function of the pmag. dohext function.

Response:
def main():
    """
    NAME
        s_hext.py

    DESCRIPTION
     calculates Hext statistics for tensor data

    SYNTAX
        s_hext.py [-h][-i][-f file] [<filename]

    OPTIONS
        -h prints help message and quits
        -f file specifies filename on command line
        -l NMEAS do line by line instead of whole file, use number of measurements NMEAS for degrees of freedom
        < filename, reads from standard input (Unix like operating systems only)

    INPUT
        x11,x22,x33,x12,x23,x13,sigma [sigma only if line by line]

    OUTPUT
       F  F12  F23  sigma
       and three sets of:
        tau dec inc Eij dec inc Eik dec inc

    DEFAULT
       average whole file
    """
    ave=1
    if '-h' in sys.argv:
        print(main.__doc__)
        sys.exit()
    if '-l' in sys.argv:
        ind=sys.argv.index('-l')
        npts=int(sys.argv[ind+1])
        ave=0
    if '-f' in sys.argv:
        ind=sys.argv.index('-f')
        file=sys.argv[ind+1]
        f=open(file,'r')
        data=f.readlines()
        f.close()
    else:
        data=sys.stdin.readlines()
    Ss=[]
    for line in data:
        s=[]
        rec=line.split()
        for i in range(6):
            s.append(float(rec[i]))
        if ave==0:
            sig=float(rec[6])
            hpars=pmag.dohext(npts-6,sig,s)
            print('%s %4.2f %s %4.2f %s %4.2f'%('F = ',hpars['F'],'F12 = ',hpars['F12'],'F23 = ',hpars['F23']))
            print('%s %i %s %14.12f'%('Nmeas = ',npts,' sigma = ',sig))
            print('%7.5f %7.1f %7.1f %7.1f %7.1f %7.1f %7.1f %7.1f %7.1f'%(hpars["t1"],hpars["v1_dec"],hpars["v1_inc"],hpars["e12"],hpars["v2_dec"],hpars["v2_inc"],hpars["e13"],hpars["v3_dec"],hpars["v3_inc"] ))
            print('%7.5f %7.1f %7.1f %7.1f %7.1f %7.1f %7.1f %7.1f %7.1f'%(hpars["t2"],hpars["v2_dec"],hpars["v2_inc"],hpars["e23"],hpars["v3_dec"],hpars["v3_inc"],hpars["e12"],hpars["v1_dec"],hpars["v1_inc"] ))
            print('%7.5f %7.1f %7.1f %7.1f %7.1f %7.1f %7.1f %7.1f %7.1f'%(hpars["t3"],hpars["v3_dec"],hpars["v3_inc"],hpars["e13"],hpars["v1_dec"],hpars["v1_inc"],hpars["e23"],hpars["v2_dec"],hpars["v2_inc"] ))
        else:
            Ss.append(s)
    if ave==1:
        npts=len(Ss)
        nf,sigma,avs=pmag.sbar(Ss)
        hpars=pmag.dohext(nf,sigma,avs)
        print('%s %4.2f %s %4.2f %s %4.2f'%('F = ',hpars['F'],'F12 = ',hpars['F12'],'F23 = ',hpars['F23']))
        print('%s %i %s %14.12f'%('N = ',npts,' sigma = ',sigma))
        print('%7.5f %7.1f %7.1f %7.1f %7.1f %7.1f %7.1f %7.1f %7.1f'%(hpars["t1"],hpars["v1_dec"],hpars["v1_inc"],hpars["e12"],hpars["v2_dec"],hpars["v2_inc"],hpars["e13"],hpars["v3_dec"],hpars["v3_inc"] ))
        print('%7.5f %7.1f %7.1f %7.1f %7.1f %7.1f %7.1f %7.1f %7.1f'%(hpars["t2"],hpars["v2_dec"],hpars["v2_inc"],hpars["e23"],hpars["v3_dec"],hpars["v3_inc"],hpars["e12"],hpars["v1_dec"],hpars["v1_inc"] ))
        print('%7.5f %7.1f %7.1f %7.1f %7.1f %7.1f %7.1f %7.1f %7.1f'%(hpars["t3"],hpars["v3_dec"],hpars["v3_inc"],hpars["e13"],hpars["v1_dec"],hpars["v1_inc"],hpars["e23"],hpars["v2_dec"],hpars["v2_inc"] ))


Instruction:
Here you have a function in Python 3, explain what it does
def _UTMLetterDesignator(Lat):

        if   84 >= Lat >= 72: return 'X'
        elif 72 >  Lat >= 64: return 'W'
        elif 64 >  Lat >= 56: return 'V'
        elif 56 >  Lat >= 48: return 'U'
        elif 48 >  Lat >= 40: return 'T'
        elif 40 >  Lat >= 32: return 'S'
        elif 32 >  Lat >= 24: return 'R'
        elif 24 >  Lat >= 16: return 'Q'
        elif 16 >  Lat >= 8:  return 'P'
        elif  8 >  Lat >= 0:  return 'N'
        elif  0 >  Lat >=-8:  return 'M'
        elif -8 >  Lat >=-16: return 'L'
        elif -16 > Lat >=-24: return 'K'
        elif -24 > Lat >=-32: return 'J'
        elif -32 > Lat >=-40: return 'H'
        elif -40 > Lat >=-48: return 'G'
        elif -48 > Lat >=-56: return 'F'
        elif -56 > Lat >=-64: return 'E'
        elif -64 > Lat >=-72: return 'D'
        elif -72 > Lat >=-80: return 'C'
        else:                 return 'Z'

Response: This routine determines the correct UTM letter designator for the given latitude.


Instruction:
Create a Python 3 function for
converting UTM coordinates to Lat Long.

Response:
def UTMtoLL(ReferenceEllipsoid, easting, northing, zone):
        """
        converts UTM coords to lat/long.  Equations from USGS Bulletin 1532
        East Longitudes are positive, West longitudes are negative.
        North latitudes are positive, South latitudes are negative
        Lat and Long are in decimal degrees.
        Written by Chuck Gantz- chuck.gantz@globalstar.com
        Converted to Python by Russ Nelson <nelson@crynwr.com>
        """

        k0 = 0.9996
        a = _ellipsoid[ReferenceEllipsoid][_EquatorialRadius]
        eccSquared = _ellipsoid[ReferenceEllipsoid][_eccentricitySquared]
        e1 = old_div((1-sqrt(1-eccSquared)),(1+sqrt(1-eccSquared)))
        #NorthernHemisphere; //1 for northern hemispher, 0 for southern

        x = easting-500000.0 #remove 500,000 meter offset for longitude
        y = northing

        ZoneLetter = zone[-1]
        if ZoneLetter == 'Z':
                raise Exception("Latitude is outside the UTM limits")

        ZoneNumber = int(zone[:-1])
        if ZoneLetter >= 'N':
                NorthernHemisphere = 1  # point is in northern hemisphere
        else:
                NorthernHemisphere = 0  # point is in southern hemisphere
                y-= 10000000.0          # remove 10,000,000 meter offset used for southern hemisphere

        LongOrigin = (ZoneNumber-1)*6-180+3  # +3 puts origin in middle of zone

        eccPrimeSquared = old_div((eccSquared),(1-eccSquared))

        M = old_div(y, k0)
        mu = old_div(M,(a*(1-old_div(eccSquared,4)-3*eccSquared*eccSquared/64-5*eccSquared*eccSquared*eccSquared/256)))

        phi1Rad = (mu+(3*e1/2-27*e1*e1*e1/32)*sin(2*mu)
                  +(21*e1*e1/16-55*e1*e1*e1*e1/32)*sin(4*mu)
                  +(151*e1*e1*e1/96)*sin(6*mu))
        phi1 = degrees(phi1Rad);

        N1 = old_div(a,sqrt(1-eccSquared*sin(phi1Rad)*sin(phi1Rad)))
        T1 = tan(phi1Rad)*tan(phi1Rad)
        C1 = eccPrimeSquared*cos(phi1Rad)*cos(phi1Rad)
        R1 = a*(1-eccSquared)/pow(1-eccSquared*sin(phi1Rad)*sin(phi1Rad), 1.5)
        D = old_div(x,(N1*k0))

        Lat = phi1Rad-(N1*tan(phi1Rad)/R1)*(D*D/2-(5+3*T1+10*C1-4*C1*C1-9*eccPrimeSquared)*D*D*D*D/24
                     +(61+90*T1+298*C1+45*T1*T1-252*eccPrimeSquared-3*C1*C1)*D*D*D*D*D*D/720)
        Lat = degrees(Lat)

        Long = old_div((D-(1+2*T1+C1)*D*D*D/6+(5-2*C1+28*T1-3*C1*C1+8*eccPrimeSquared+24*T1*T1)*D*D*D*D*D/120),cos(phi1Rad))
        Long = LongOrigin+degrees(Long)
        return (Long, Lat)


Instruction:
How would you code a function in Python 3 to
initialize the main user interface.

Response:
def InitUI(self):
        """
        Make main user interface
        """
        bSizer0 = wx.StaticBoxSizer(
            wx.StaticBox(self.panel, wx.ID_ANY, "Choose MagIC project directory", name='bSizer0'), wx.HORIZONTAL
        )
        self.dir_path = wx.TextCtrl(self.panel, id=-1, size=(600, 25), style=wx.TE_READONLY)
        self.dir_path.SetValue(self.WD)
        self.change_dir_button = buttons.GenButton(
            self.panel, id=-1, label="change directory", size=(-1, -1), name='change_dir_btn'
        )
        self.change_dir_button.SetBackgroundColour("#F8F8FF")
        self.change_dir_button.InitColours()
        self.Bind(wx.EVT_BUTTON, self.on_change_dir_button, self.change_dir_button)
        bSizer0.Add(self.change_dir_button, wx.ALIGN_LEFT)
        bSizer0.AddSpacer(40)
        bSizer0.Add(self.dir_path, wx.ALIGN_CENTER_VERTICAL)

        self.bSizer_msg = wx.StaticBoxSizer(wx.StaticBox(
            self.panel, wx.ID_ANY, "Message", name='bsizer_msg'),
                                            wx.HORIZONTAL)
        self.message = wx.StaticText(self.panel, -1,
                                     label="Some text will be here",
                                     name='messages')
        self.bSizer_msg.Add(self.message)

        #---sizer 1 ----
        bSizer1 = wx.StaticBoxSizer(wx.StaticBox(
            self.panel, wx.ID_ANY, "Add information to the data model", name='bSizer1'),
                                    wx.HORIZONTAL)

        text = "1. add location data"
        self.btn1 = buttons.GenButton(self.panel, id=-1, label=text,
                                      size=(300, 50), name='locations_btn')
        self.btn1.SetBackgroundColour("#FDC68A")
        self.btn1.InitColours()
        self.Bind(wx.EVT_BUTTON, self.make_grid_frame, self.btn1)

        text = "2. add site data"
        self.btn2 = buttons.GenButton(self.panel, id=-1, label=text,
                                      size=(300, 50), name='sites_btn')
        self.btn2.SetBackgroundColour("#6ECFF6")
        self.btn2.InitColours()
        self.Bind(wx.EVT_BUTTON, self.make_grid_frame, self.btn2)

        text = "3. add sample data"
        self.btn3 = buttons.GenButton(self.panel, id=-1, label=text,
                                      size=(300, 50), name='samples_btn')
        self.btn3.SetBackgroundColour("#C4DF9B")
        self.btn3.InitColours()
        self.Bind(wx.EVT_BUTTON, self.make_grid_frame, self.btn3)

        text = "4. add specimen data"
        self.btn4 = buttons.GenButton(self.panel, id=-1,
                                      label=text, size=(300, 50), name='specimens_btn')
        self.btn4.SetBackgroundColour("#FDC68A")
        self.btn4.InitColours()
        self.Bind(wx.EVT_BUTTON, self.make_grid_frame, self.btn4)

        text = "5. add age data"
        self.btn5 = buttons.GenButton(self.panel, id=-1, label=text,
                                      size=(300, 50), name='ages_btn')
        self.btn5.SetBackgroundColour("#6ECFF6")
        self.btn5.InitColours()
        self.Bind(wx.EVT_BUTTON, self.make_grid_frame, self.btn5)

        text = "6. add measurements data"
        self.btn6 = buttons.GenButton(self.panel, id=-1, label=text,
                                      size=(300, 50), name='measurements_btn')
        self.btn6.SetBackgroundColour("#C4DF9B")
        self.btn6.InitColours()
        self.Bind(wx.EVT_BUTTON, self.make_grid_frame, self.btn6)

        bsizer1a = wx.BoxSizer(wx.VERTICAL)
        bsizer1a.AddSpacer(20)
        bsizer1a.Add(self.btn1, wx.ALIGN_TOP)
        bsizer1a.AddSpacer(20)
        bsizer1a.Add(self.btn2, wx.ALIGN_TOP)
        bsizer1a.AddSpacer(20)
        bsizer1a.Add(self.btn3, wx.ALIGN_TOP)
        bsizer1a.AddSpacer(20)

        bSizer1.Add(bsizer1a, wx.ALIGN_CENTER, wx.EXPAND)
        bSizer1.AddSpacer(20)

        #bSizer1.Add(OR, 0, wx.ALIGN_CENTER, 0)
        bSizer1.AddSpacer(20)
        bsizer1b = wx.BoxSizer(wx.VERTICAL)
        #__init__(self, parent, id, label, pos, size, style, validator, name
        bsizer1b.Add(self.btn4, flag=wx.ALIGN_CENTER|wx.BOTTOM, border=20)
        bsizer1b.Add(self.btn5, 0, flag=wx.ALIGN_CENTER|wx.BOTTOM, border=20)
        bsizer1b.Add(self.btn6, 0, wx.ALIGN_CENTER, 0)
        bSizer1.Add(bsizer1b, 0, wx.ALIGN_CENTER, 0)
        bSizer1.AddSpacer(20)

        #---sizer 2 ----

        self.bSizer2 = wx.StaticBoxSizer(wx.StaticBox(self.panel, wx.ID_ANY, "Create file for upload to MagIC database", name='bSizer2'), wx.HORIZONTAL)

        text = "prepare upload txt file"
        self.btn_upload = buttons.GenButton(self.panel, id=-1, label=text,
                                            size=(300, 50), name='upload_btn')
        self.btn_upload.SetBackgroundColour("#C4DF9B")
        self.btn_upload.InitColours()
        self.Bind(wx.EVT_BUTTON, self.on_upload_file, self.btn_upload)

        self.bSizer2.AddSpacer(20)
        self.bSizer2.Add(self.btn_upload, 0, wx.ALIGN_CENTER, 0)
        self.bSizer2.AddSpacer(20)
        #self.Bind(wx.EVT_BUTTON, self.on_btn_upload, self.btn_upload)

        #---arrange sizers ----

        self.hbox = wx.BoxSizer(wx.HORIZONTAL)
        vbox = wx.BoxSizer(wx.VERTICAL)
        vbox.AddSpacer(5)
        #vbox.Add(self.logo,0,wx.ALIGN_CENTER,0)
        vbox.AddSpacer(5)
        vbox.Add(bSizer0, 0, wx.ALIGN_CENTER, 0)
        vbox.AddSpacer(10)
        #vbox.Add(bSizer0_1, 0, wx.ALIGN_CENTER, 0)
        #vbox.AddSpacer(10)
        vbox.Add(self.bSizer_msg, 0, wx.ALIGN_CENTER, 0)
        self.bSizer_msg.ShowItems(False)
        vbox.Add(bSizer1, 0, wx.ALIGN_CENTER, 0)
        vbox.AddSpacer(10)
        vbox.AddSpacer(10)
        self.hbox.AddSpacer(10)
        vbox.Add(self.bSizer2, 0, wx.ALIGN_CENTER, 0)
        vbox.AddSpacer(10)

        self.hbox.Add(vbox, 0, wx.ALIGN_CENTER, 0)
        self.hbox.AddSpacer(5)

        self.panel.SetSizer(self.hbox)
        self.hbox.Fit(self)

        # do menu
        print("-I- Initializing menu")
        menubar = MagICMenu(self)
        self.SetMenuBar(menubar)
        self.menubar = menubar


Instruction:
Make a summary of the following Python 3 code
def on_change_dir_button(self, event=None):
        currentDirectory = self.WD #os.getcwd()
        change_dir_dialog = wx.DirDialog(self.panel,
                                         "Choose your working directory to create or edit a MagIC contribution:",
                                         defaultPath=currentDirectory,
                                         style=wx.DD_DEFAULT_STYLE | wx.DD_NEW_DIR_BUTTON | wx.DD_CHANGE_DIR)
        result = change_dir_dialog.ShowModal()
        if result == wx.ID_CANCEL:
            return
        if result == wx.ID_OK:
            self.WD = change_dir_dialog.GetPath()
            self.dir_path.SetValue(self.WD)
        change_dir_dialog.Destroy()
        self.get_wd_data()

Response: create change directory frame


Instruction:
Here you have a function in Python 3, explain what it does
def make_grid_frame(self, event):
        if self.grid_frame:
            print('-I- You already have a grid frame open')
            pw.simple_warning("You already have a grid open")
            return

        try:
            grid_type = event.GetButtonObj().Name[:-4] # remove '_btn'
        except AttributeError:
            grid_type = self.FindWindowById(event.Id).Name[:-4] # remove ('_btn')
        wait = wx.BusyInfo('Making {} grid, please wait...'.format(grid_type))
        wx.SafeYield()
        # propagate site lat/lon info into locations if necessary
        if grid_type == 'locations' and 'sites' in self.contribution.tables:
            self.contribution.get_min_max_lat_lon()
            self.contribution.propagate_cols_up(['lithologies',
                                                 'geologic_classes'],
                                                'locations', 'sites')
        # propagate lithologies/type/class information from sites to samples/specimens
        if grid_type in ['specimens', 'samples']:
            self.contribution.propagate_lithology_cols()
        # propagate average lat/lon info from samples table if
        # available in samples and missing in sites
        if grid_type == 'sites':
            self.contribution.propagate_average_up(cols=['lat', 'lon', 'height'],
                                           target_df_name='sites',
                                           source_df_name='samples')
            self.contribution.propagate_lithology_cols()
        # hide mainframe
        self.on_open_grid_frame()
        # choose appropriate size for grid
        if grid_type == 'measurements':
            huge = True
        else:
            huge = False
        # make grid frame
        self.grid_frame = grid_frame.GridFrame(self.contribution, self.WD,
                                               grid_type, grid_type,
                                               self.panel, huge=huge)
        row_string = ""
        # paint validations if appropriate
        if self.validation_mode:
            if grid_type in self.validation_mode:
                if grid_type == 'measurements':
                    skip_cell_render = True
                else:
                    skip_cell_render = False
                self.grid_frame.toggle_help(None, "open")
                row_problems = self.failing_items[grid_type]["rows"]
                missing_columns = self.failing_items[grid_type]["missing_columns"]
                missing_groups = self.failing_items[grid_type]["missing_groups"]
                #all_cols = row_problems.columns
                #col_nums = range(len(all_cols))
                #col_pos = dict(zip(all_cols, col_nums))
                if len(row_problems):
                    row_string = "Columns and rows with problem data have been highlighted in blue.\n"
                    if not skip_cell_render:
                        row_string += "Cells with problem data are highlighted according to the type of problem.\nRed: incorrect data\n"
                    row_string += "For full error messages, see {}.".format(grid_type + "_errors.txt")
                    # reset codes button to show error file instead
                    self.grid_frame.toggle_codes_btn.SetLabel("Show errors")
                    self.grid_frame.Bind(wx.EVT_BUTTON, self.grid_frame.show_errors,
                                         self.grid_frame.toggle_codes_btn)
                    # paint cells
                    for row in row_problems['num']:
                        self.grid_frame.grid.paint_invalid_row(row)
                        mask = row_problems["num"] == row
                        items = row_problems[mask]
                        cols = items.dropna(how="all", axis=1).drop(["num", "issues"], axis=1)
                        for col in cols:
                            pre, col_name = val_up3.extract_col_name(col)
                            col_ind = self.grid_frame.grid.col_labels.index(col_name)
                            self.grid_frame.grid.paint_invalid_cell(row, col_ind,
                                                                    skip_cell=skip_cell_render)
                current_label = self.grid_frame.msg_text.GetLabel()
                if len(missing_columns):
                    col_string = "You are missing the following required columns: {}\n\n".format(", ".join(missing_columns))
                else:
                    col_string = ""
                if len(missing_groups):
                    group_string = "You must have at least one column from each of the following groups: {}\n\n".format(", ".join(missing_groups))
                else:
                    group_string = ""
                #
                add_text = """{}{}{}""".format(col_string, group_string, row_string)
                self.grid_frame.msg_text.SetLabel(add_text)
        #self.on_finish_change_dir(self.change_dir_dialog)
        self.grid_frame.do_fit(None)
        del wait

Response: Create a grid frame for the current event


Instruction:
How would you implement a function in Python 3 that
highlights grids in red if they have validation errors

Response:
def highlight_problems(self, has_problems):
        """
        Outline grid buttons in red if they have validation errors
        """
        if has_problems:
            self.validation_mode = set(has_problems)
            # highlighting doesn't work with Windows
            if sys.platform in ['win32', 'win62']:
                self.message.SetLabel('The following grid(s) have incorrect or incomplete data:\n{}'.format(', '.join(self.validation_mode)))
            # highlighting does work with OSX
            else:
                for dtype in ["specimens", "samples", "sites", "locations", "ages", "measurements"]:
                    wind = self.FindWindowByName(dtype + '_btn')
                    if dtype not in has_problems:
                        wind.Unbind(wx.EVT_PAINT, handler=self.highlight_button)
                    else:
                        wind.Bind(wx.EVT_PAINT, self.highlight_button)
                self.Refresh()
                self.message.SetLabel('Highlighted grids have incorrect or incomplete data')
            self.bSizer_msg.ShowItems(True)
            # manually fire a paint event to make sure all buttons
            # are highlighted/unhighlighted appropriately
            paintEvent = wx.CommandEvent(wx.wxEVT_PAINT,
                                         self.GetId())
            self.GetEventHandler().ProcessEvent(paintEvent)

        else:
            self.message.SetLabel("Validated!")
            self.bSizer_msg.ShowItems(True)
        self.hbox.Fit(self)