Instruction:
How would you explain what the following Python 3 function does
def InitLocCheck(self):
        self.panel = wx.Panel(self, style=wx.SIMPLE_BORDER)

        text = """Step 5:
Check that locations are correctly named.
Fill in any blank cells using controlled vocabularies.
(See Help button for details)

** Denotes controlled vocabulary"""
        label = wx.StaticText(self.panel, label=text)
        #self.Data_hierarchy = self.ErMagic.Data_hierarchy
        self.locations = self.er_magic_data.locations
        #
        if not self.er_magic_data.locations:
            msg = "You have no data in er_locations, so we are skipping step 5.\n Note that location names must be entered at the measurements level,so you may need to re-import your data, or you can add a location in step 3"
            dlg = wx.MessageDialog(None, caption="Message:", message=msg, style=wx.OK|wx.ICON_INFORMATION)
            dlg.ShowModal()
            dlg.Destroy()
            self.panel.Destroy()
            self.InitAgeCheck()
            return

        self.grid_builder = grid_frame2.GridBuilder(self.er_magic_data, 'location',
                                                   self.er_magic_data.headers, self.panel)
        self.loc_grid = self.grid_builder.make_grid(incl_pmag=False)
        self.loc_grid.InitUI()
        self.grid_builder.add_data_to_grid(self.loc_grid, 'location', incl_pmag=False)
        self.grid = self.loc_grid
        # initialize all needed drop-down menus
        self.drop_down_menu = drop_down_menus.Menus("location", self,
                                                     self.loc_grid, None)

        # need to find max/min lat/lon here IF they were added in the previous grid
        sites = self.er_magic_data.sites
        location_lat_lon = self.er_magic_data.get_min_max_lat_lon(self.er_magic_data.locations)

        col_names = ('location_begin_lat', 'location_end_lat', 'location_begin_lon', 'location_end_lon')
        col_inds = [self.grid.col_labels.index(name) for name in col_names]
        col_info = list(zip(col_names, col_inds))
        for loc in self.er_magic_data.locations:
            row_ind = self.grid.row_labels.index(loc.name)
            for col_name, col_ind in col_info:
                info = location_lat_lon[loc.name][col_name]
                self.grid.SetCellValue(row_ind, col_ind, str(info))

        ### Create Buttons ###
        hbox_one = wx.BoxSizer(wx.HORIZONTAL)
        self.helpButton = wx.Button(self.panel, label="Help")
        self.Bind(wx.EVT_BUTTON, lambda event: self.on_helpButton(event, "ErMagicLocationHelp.html"), self.helpButton)
        hbox_one.Add(self.helpButton)

        hboxok = wx.BoxSizer(wx.HORIZONTAL)
        self.saveButton = wx.Button(self.panel, id=-1, label='Save')
        self.Bind(wx.EVT_BUTTON, lambda event: self.on_saveButton(event, self.loc_grid), self.saveButton)
        self.cancelButton = wx.Button(self.panel, wx.ID_CANCEL, '&Cancel')
        self.Bind(wx.EVT_BUTTON, self.on_cancelButton, self.cancelButton)
        self.continueButton = wx.Button(self.panel, id=-1, label='Save and continue')
        self.Bind(wx.EVT_BUTTON, lambda event: self.on_continueButton(event, self.loc_grid, next_dia=self.InitAgeCheck), self.continueButton)
        self.backButton = wx.Button(self.panel, wx.ID_ANY, "&Back")
        previous_dia = self.InitSampCheck
        self.Bind(wx.EVT_BUTTON, lambda event: self.on_backButton(event, previous_dia, current_dia=self.InitLocCheck), self.backButton)

        hboxok.Add(self.saveButton, flag=wx.RIGHT, border=10)
        hboxok.Add(self.cancelButton, flag=wx.RIGHT, border=10)
        hboxok.Add(self.continueButton, flag=wx.RIGHT, border=10)
        hboxok.Add(self.backButton)

        #
        hboxgrid = pw.hbox_grid(self.panel, self.onDeleteRow, 'location', self.grid)
        self.deleteRowButton = hboxgrid.deleteRowButton

        self.Bind(wx.grid.EVT_GRID_LABEL_LEFT_CLICK, self.onLeftClickLabel, self.grid)

        ### Make Containers ###
        vbox = wx.BoxSizer(wx.VERTICAL)
        vbox.Add(label, flag=wx.ALIGN_CENTER|wx.TOP|wx.BOTTOM, border=20)
        vbox.Add(hbox_one, flag=wx.BOTTOM|wx.ALIGN_LEFT, border=10)
        vbox.Add(hboxok, flag=wx.BOTTOM|wx.ALIGN_LEFT, border=10)
        vbox.Add(hboxgrid, flag=wx.BOTTOM|wx.ALIGN_LEFT, border=10)
        vbox.Add(self.loc_grid, flag=wx.TOP|wx.BOTTOM, border=10)
        vbox.AddSpacer(20)

        self.hbox_all = wx.BoxSizer(wx.HORIZONTAL)
        self.hbox_all.AddSpacer(20)
        self.hbox_all.Add(vbox)
        self.hbox_all.AddSpacer(20)

        self.panel.SetSizer(self.hbox_all)
        #if sys.platform in ['win32', 'win64']:
        #    self.panel.SetScrollbars(20, 20, 50, 50)
        self.hbox_all.Fit(self)
        self.Centre()
        self.Show()
        self.Hide()
        self.Show()

Response: Initialize locations and locations grid


Instruction:
Make a summary of the following Python 3 code
def InitAgeCheck(self):
        self.panel = wx.Panel(self, style=wx.SIMPLE_BORDER)

        text = """Step 6:
Fill in or correct any cells with information about ages.
The column for magic_method_codes can take multiple values in the form of a colon-delimited list.
You may use the drop-down menus to add as many values as needed in these columns.
(See Help button for details)

**Denotes controlled vocabulary """
        label = wx.StaticText(self.panel, label=text)

        self.items = self.er_magic_data.data_lists[self.er_magic_data.age_type][0]

        self.grid_builder = grid_frame2.GridBuilder(self.er_magic_data, 'age',
                                                   self.er_magic_data.headers, self.panel, 'location')
        self.age_grid = self.grid_builder.make_grid(incl_pmag=False)
        self.age_grid.InitUI()
        self.grid_builder.add_data_to_grid(self.age_grid, 'age', incl_pmag=False)
        self.grid_builder.add_age_data_to_grid()

        self.grid = self.age_grid
        #
        # make it impossible to edit the 1st and 3rd columns
        for row in range(self.age_grid.GetNumberRows()):
            for col in (0, 2):
                self.age_grid.SetReadOnly(row, col, True)

        # initialize all needed drop-down menus
        self.drop_down_menu = drop_down_menus.Menus("age", self, self.age_grid, None)

        # re-set first column name
        self.age_grid.SetColLabelValue(0, 'er_site_name')

        ### Create Buttons ###
        hbox_one = wx.BoxSizer(wx.HORIZONTAL)
        self.helpButton = wx.Button(self.panel, label="Help")
        self.Bind(wx.EVT_BUTTON, lambda event: self.on_helpButton(event, "ErMagicAgeHelp.html"), self.helpButton)
        hbox_one.Add(self.helpButton)

        hboxok = wx.BoxSizer(wx.HORIZONTAL)
        self.saveButton = wx.Button(self.panel, id=-1, label='Save')
        self.Bind(wx.EVT_BUTTON, lambda event: self.on_saveButton(event, self.age_grid), self.saveButton)
        self.cancelButton = wx.Button(self.panel, wx.ID_CANCEL, '&Cancel')
        self.Bind(wx.EVT_BUTTON, self.on_cancelButton, self.cancelButton)
        self.continueButton = wx.Button(self.panel, id=-1, label='Save and continue')
        self.Bind(wx.EVT_BUTTON, lambda event: self.on_continueButton(event, self.age_grid, next_dia=None), self.continueButton)
        self.backButton = wx.Button(self.panel, wx.ID_ANY, "&Back")
        previous_dia = self.InitLocCheck
        self.Bind(wx.EVT_BUTTON, lambda event: self.on_backButton(event, previous_dia), self.backButton)

        self.panel.Bind(wx.grid.EVT_GRID_LABEL_LEFT_CLICK, self.onLeftClickLabel, self.grid)

        hboxok.Add(self.saveButton, flag=wx.RIGHT, border=10)
        hboxok.Add(self.cancelButton, flag=wx.RIGHT, border=10)
        hboxok.Add(self.continueButton, flag=wx.RIGHT, border=10)
        hboxok.Add(self.backButton)

        ### Make Containers ###
        vbox = wx.BoxSizer(wx.VERTICAL)
        vbox.Add(label, flag=wx.ALIGN_CENTER|wx.TOP|wx.BOTTOM, border=20)#, flag=wx.ALIGN_LEFT|wx.BOTTOM, border=20)
        vbox.Add(hbox_one, flag=wx.BOTTOM, border=10)
        vbox.Add(hboxok, flag=wx.BOTTOM, border=10)
        vbox.Add(self.age_grid, flag=wx.TOP|wx.BOTTOM, border=10) # EXPAND ??
        vbox.AddSpacer(20)

        self.hbox_all = wx.BoxSizer(wx.HORIZONTAL)
        self.hbox_all.AddSpacer(20)
        self.hbox_all.Add(vbox)
        self.hbox_all.AddSpacer(20)

        self.panel.SetSizer(self.hbox_all)
        #if sys.platform in ['win32', 'win64']:
        #    self.panel.SetScrollbars(20, 20, 50, 50)
        self.hbox_all.Fit(self)
        self.Centre()
        self.Show()
        self.Hide()
        self.Show()

Response: Initialize the age check dialog


Instruction:
Can you implement a function in Python 3 that
displays a tooltip over any cell in a certain column

Response:
def onMouseOver(self, event, grid):
        """
        Displays a tooltip over any cell in a certain column
        """
        x, y = grid.CalcUnscrolledPosition(event.GetX(), event.GetY())
        coords = grid.XYToCell(x, y)
        col = coords[1]
        row = coords[0]

        # creates tooltip message for cells with long values
        # note: this works with EPD for windows, and modern wxPython, but not with Canopy Python
        msg = grid.GetCellValue(row, col)
        if len(msg) > 15:
            event.GetEventObject().SetToolTipString(msg)
        else:
            event.GetEventObject().SetToolTipString('')


Instruction:
Can you tell what is the following Python 3 function doing
def on_helpButton(self, event, page=None):
        # for use on the command line:
        path = find_pmag_dir.get_pmag_dir()
        # for use with pyinstaller
        #path = self.main_frame.resource_dir
        help_page = os.path.join(path, 'dialogs', 'help_files', page)
        # if using with py2app, the directory structure is flat,
        # so check to see where the resource actually is
        if not os.path.exists(help_page):
            help_page = os.path.join(path, 'help_files', page)
        html_frame = pw.HtmlFrame(self, page=help_page)
        html_frame.Show()

Response: shows html help page


Instruction:
Write a Python 3 script for
pulling up next dialog, if there is one. gets any updated information from the current grid and runs ErMagicBuilder

Response:
def on_continueButton(self, event, grid, next_dia=None):
        """
        pulls up next dialog, if there is one.
        gets any updated information from the current grid and runs ErMagicBuilder
        """
        #wait = wx.BusyInfo("Please wait, working...")
        # unhighlight selected columns, etc.
        if self.drop_down_menu:
            self.drop_down_menu.clean_up()

        # remove '**' from col names
        #self.remove_starred_labels(grid)
        grid.remove_starred_labels()

        grid.SaveEditControlValue() # locks in value in cell currently edited
        grid_name = str(grid.GetName())

        # check that all required data are present
        validation_errors = self.validate(grid)
        if validation_errors:
            result = pw.warning_with_override("You are missing required data in these columns: {}\nAre you sure you want to continue without these data?".format(', '.join(validation_errors)))
            if result == wx.ID_YES:
                pass
            else:
                return False

        if grid.changes:
            self.onSave(grid)

        self.deleteRowButton = None
        #self.panel.Destroy()  # calling Destroy here breaks with Anaconda Python (segfault)

        # make sure that specimens get propagated with
        # any default sample info
        if next_dia == self.InitLocCheck:
            if self.er_magic_data.specimens:
                for spec in self.er_magic_data.specimens:
                    spec.propagate_data()

        if next_dia:
            wait = wx.BusyInfo("Please wait, working...")
            wx.SafeYield()
            wx.CallAfter(self.panel.Destroy) # no segfault here!
            next_dia()
            # need to wait to process the resize:
            event = wx.PyCommandEvent(wx.EVT_SIZE.typeId, self.GetId())
            wx.CallAfter(self.GetEventHandler().ProcessEvent, event)
            del wait
        else:
            wait = wx.BusyInfo("Please wait, writing data to files...")
            wx.SafeYield()
            # actually write data:
            self.er_magic_data.write_files()
            self.Destroy()
            del wait


Instruction:
Write a Python 3 function for
deleting the selected object from both the data model and the grid.

Response:
def onDeleteRow(self, event, data_type):
        """
        On button click, remove relevant object from both the data model and the grid.
        """
        ancestry = self.er_magic_data.ancestry
        child_type = ancestry[ancestry.index(data_type) - 1]
        names = [self.grid.GetCellValue(row, 0) for row in self.selected_rows]
        if data_type == 'site':
            how_to_fix = 'Make sure to select a new site for each orphaned sample in the next step'
        else:
            how_to_fix = 'Go back a step and select a new {} for each orphaned {}'.format(data_type, child_type)

        orphans = []
        for name in names:
            row = self.grid.row_labels.index(name)
            orphan = self.er_magic_data.delete_methods[data_type](name)
            if orphan:
                orphans.extend(orphan)
            self.grid.remove_row(row)
        if orphans:
            orphan_names = self.er_magic_data.make_name_list(orphans)
            pw.simple_warning('You have deleted:\n\n  {}\n\nthe parent(s) of {}(s):\n\n  {}\n\n{}'.format(', '.join(names), child_type, ', '.join(orphan_names), how_to_fix))

        self.selected_rows = set()

        # update grid and data model
        self.update_grid(self.grid)#, grids[grid_name])

        self.grid.Refresh()


Instruction:
Create a Python 3 function for
highlighting or unhighlight a row for possible deletion.

Response:
def onSelectRow(self, event):
        """
        Highlight or unhighlight a row for possible deletion.
        """
        grid = self.grid
        row = event.Row
        default = (255, 255, 255, 255)
        highlight = (191, 216, 216, 255)
        cell_color = grid.GetCellBackgroundColour(row, 0)
        attr = wx.grid.GridCellAttr()
        if cell_color == default:
            attr.SetBackgroundColour(highlight)
            self.selected_rows.add(row)
        else:
            attr.SetBackgroundColour(default)
            try:
                self.selected_rows.remove(row)
            except KeyError:
                pass
        if self.selected_rows and self.deleteRowButton:
            self.deleteRowButton.Enable()
        else:
            self.deleteRowButton.Disable()
        grid.SetRowAttr(row, attr)
        grid.Refresh()


Instruction:
Create a Python 3 function to
update the internal data structures of the current level of the grid

Response:
def update_grid(self, grid):
        """
        takes in wxPython grid and ErMagic data object to be updated
        """
        data_methods = {'specimen': self.er_magic_data.change_specimen,
                        'sample': self.er_magic_data.change_sample,
                        'site': self.er_magic_data.change_site,
                        'location': self.er_magic_data.change_location,
                        'age': self.er_magic_data.change_age}

        grid_name = str(grid.GetName())

        cols = list(range(grid.GetNumberCols()))

        col_labels = []
        for col in cols:
            col_labels.append(grid.GetColLabelValue(col))

        for row in grid.changes: # go through changes and update data structures
            if row == -1:
                continue
            else:
                data_dict = {}
                for num, label in enumerate(col_labels):
                    if label:
                        data_dict[str(label)] = str(grid.GetCellValue(row, num))
                new_name = str(grid.GetCellValue(row, 0))
                old_name = self.temp_data[grid_name][row]
                data_methods[grid_name](new_name, old_name, data_dict)

        grid.changes = False


Instruction:
Here you have a function in Python 3, explain what it does
def onSave(self, grid):#, age_data_type='site'):
        # deselect column, including remove 'EDIT ALL' label
        if self.drop_down_menu:
            self.drop_down_menu.clean_up()

        # save all changes to er_magic data object
        self.grid_builder.save_grid_data()

        # don't actually write data in this step (time-consuming)
        # instead, write to files when user is done editing
        #self.er_magic_data.write_files()

        wx.MessageBox('Saved!', 'Info',
                      style=wx.OK | wx.ICON_INFORMATION)

Response: Save the data in the object


Instruction:
Can you tell what is the following Python 3 function doing
def main():
    dir_path='.'
    meas_file='magic_measurements.txt'
    samp_file="er_samples.txt"
    out_file='magic_measurements.txt'
    if '-h' in sys.argv:
        print(main.__doc__)
        sys.exit()
    if '-WD' in sys.argv:
        ind = sys.argv.index('-WD')
        dir_path=sys.argv[ind+1]
    if '-f' in sys.argv:
        ind = sys.argv.index('-f')
        meas_file=sys.argv[ind+1]
    if '-fsa' in sys.argv:
        ind = sys.argv.index('-fsa')
        samp_file=sys.argv[ind+1]
    if '-F' in sys.argv:
        ind = sys.argv.index('-F')
        out_file=sys.argv[ind+1]
    # read in measurements file
    meas_file=dir_path+'/'+meas_file
    out_file=dir_path+'/'+out_file
    samp_file=dir_path+'/'+samp_file
    data,file_type=pmag.magic_read(meas_file)
    samps,file_type=pmag.magic_read(samp_file)
    MeasRecs=[]
    sampnames,sflag=[],0
    for rec in data:
        for samp in  samps:
            if samp['er_sample_name'].lower()==rec['er_sample_name'].lower():
                if samp['er_sample_name'] not in sampnames:sampnames.append(samp['er_sample_name'].lower())
                rec['er_site_name']=samp['er_site_name']
                rec['er_location_name']=samp['er_location_name']
                MeasRecs.append(rec)
                break
        if rec['er_sample_name'].lower() not in sampnames:
            sampnames.append(rec['er_sample_name'].lower())
            sflag=1
            SampRec={}
            for key in list(samps[0].keys()):SampRec[key]=""
            SampRec['er_sample_name']=rec['er_sample_name']
            SampRec['er_citation_names']="This study"
            SampRec['er_site_name']='MISSING'
            SampRec['er_location_name']='MISSING'
            SampRec['sample_desription']='recorded added by update_measurements - edit as needed'
            samps.append(SampRec)
            print(rec['er_sample_name'],' missing from er_samples.txt file - edit orient.txt file and re-import')
            rec['er_site_name']='MISSING'
            rec['er_location_name']='MISSING'
            MeasRecs.append(rec)
    pmag.magic_write(out_file,MeasRecs,'magic_measurements')
    print("updated measurements file stored in ", out_file)
    if sflag==1:
         pmag.magic_write(samp_file,samps,'er_samples')
         print("updated sample file stored in ", samp_file)

Response: NAME update_measurements. py is the entry point for the update_measurements module.


Instruction:
Implement a Python 3 function for
naming ldeo_magic.py DESCRIPTION converts LDEO format files to magic_measurements format files SYNTAX ldeo_magic.py [command line options] OPTIONS -h: prints the help message and quits. -usr USER: identify user, default is "" -f FILE: specify .ldeo format input file, required -F FILE: specify output file, default is magic_measurements.txt -Fsy: specify er_synthetics file, default is er_sythetics.txt -LP [colon delimited list of protocols, include all that apply] AF: af demag T: thermal including thellier but not trm acquisition S: Shaw method I: IRM (acquisition) N: NRM only TRM: trm acquisition ANI: anisotropy experiment D: double AF demag G: triple AF demag (GRM protocol) -V [1,2,3] units of IRM field in volts using ASC coil #1,2 or 3 -spc NUM : specify number of characters to designate a specimen, default = 0 -loc LOCNAME : specify location/study name, must have either LOCNAME or SAMPFILE or be a synthetic -syn INST TYPE: sets these specimens as synthetics created at institution INST and of type TYPE -ins INST : specify which demag instrument was used (e.g, SIO-Suzy or SIO-Odette),default is "" -dc B PHI THETA: dc lab field (in micro tesla) and phi,theta, default is none NB: use PHI, THETA = -1 -1 to signal that it changes, i.e. in anisotropy experiment -ac B : peak AF field (in mT) for ARM acquisition, default is none -ARM_dc # default value is 50e-6 -ARM_temp # default is 600c -ncn NCON: specify naming convention: default is #1 below -A: don't average replicate measurements 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 same as sample [6] site is entered under a separate column -- NOT CURRENTLY SUPPORTED [7-Z] [XXXX]YYY: XXXX is site designation with Z characters with sample name XXXXYYYY NB: all others you will have to customize your self or e-mail ltauxe@ucsd.edu for help. [8] synthetic - has no site name INPUT Best to put separate experiments (all AF, thermal, thellier, trm aquisition, Shaw, etc.) in seperate .mag files (eg. af.mag, thermal.mag, etc.) Format of LDEO files: isaf2.fix LAT: .00 LON: .00 ID TREAT I CD J CDECL CINCL GDECL GINCL BDECL BINCL SUSC M/V ________________________________________________________________________________ is031c2 .0 SD 0 461.600 163.9 17.5 337.1 74.5 319.1 74.4 .0 .0 ID: specimen name TREAT: treatment step I: Instrument CD: Circular standard devation J: intensity. assumed to be total moment in 10^-4 (emu) CDECL: Declination in specimen coordinate system CINCL: Declination in specimen coordinate system GDECL: Declination in geographic coordinate system GINCL: Declination in geographic coordinate system BDECL: Declination in bedding adjusted coordinate system BINCL: Declination in bedding adjusted coordinate system SUSC: magnetic susceptibility (in micro SI)a M/V: mass or volume for nomalizing (0 won't normalize)

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

    DESCRIPTION
        converts LDEO  format files to magic_measurements format files

    SYNTAX
        ldeo_magic.py [command line options]

    OPTIONS
        -h: prints the help message and quits.
        -usr USER:   identify user, default is ""
        -f FILE: specify .ldeo format input file, required
        -F FILE: specify output file, default is magic_measurements.txt
        -Fsy: specify er_synthetics file, default is er_sythetics.txt
        -LP [colon delimited list of protocols, include all that apply]
            AF:  af demag
            T: thermal including thellier but not trm acquisition
            S: Shaw method
            I: IRM (acquisition)
            N: NRM only
            TRM: trm acquisition
            ANI: anisotropy experiment
            D: double AF demag
            G: triple AF demag (GRM protocol)
        -V [1,2,3] units of IRM field in volts using ASC coil #1,2 or 3
        -spc NUM : specify number of characters to designate a  specimen, default = 0
        -loc LOCNAME : specify location/study name, must have either LOCNAME or SAMPFILE or be a synthetic
        -syn INST TYPE:  sets these specimens as synthetics created at institution INST and of type TYPE
        -ins INST : specify which demag instrument was used (e.g, SIO-Suzy or SIO-Odette),default is ""
        -dc B PHI THETA: dc lab field (in micro tesla) and phi,theta, default is none
              NB: use PHI, THETA = -1 -1 to signal that it changes, i.e. in anisotropy experiment
        -ac B : peak AF field (in mT) for ARM acquisition, default is none

        -ARM_dc # default value is 50e-6
        -ARM_temp # default is 600c

        -ncn NCON:  specify naming convention: default is #1 below
        -A: don't average replicate measurements
       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 same as sample
            [6] site is entered under a separate column -- NOT CURRENTLY SUPPORTED
            [7-Z] [XXXX]YYY:  XXXX is site designation with Z characters with sample name XXXXYYYY
            NB: all others you will have to customize your self
                 or e-mail ltauxe@ucsd.edu for help.

            [8] synthetic - has no site name
    INPUT
        Best to put separate experiments (all AF, thermal, thellier, trm aquisition, Shaw, etc.) in
           seperate .mag files (eg. af.mag, thermal.mag, etc.)

        Format of LDEO files:
isaf2.fix
LAT:   .00  LON:    .00
    ID     TREAT  I  CD    J    CDECL CINCL  GDECL GINCL  BDECL BINCL  SUSC  M/V
________________________________________________________________________________
is031c2       .0  SD  0 461.600 163.9  17.5  337.1  74.5  319.1  74.4    .0   .0

        ID: specimen name
        TREAT:  treatment step
        I:  Instrument
        CD:  Circular standard devation
        J: intensity.  assumed to be total moment in 10^-4 (emu)
        CDECL:  Declination in specimen coordinate system
        CINCL:  Declination in specimen coordinate system
        GDECL:  Declination in geographic coordinate system
        GINCL:  Declination in geographic coordinate system
        BDECL:  Declination in bedding adjusted coordinate system
        BINCL:  Declination in bedding adjusted coordinate system
        SUSC:  magnetic susceptibility (in micro SI)a
        M/V: mass or volume for nomalizing (0 won't normalize)

    """
# initialize some stuff
    noave=0
    codelist = ''
    methcode,inst="LP-NO",""
    phi,theta,peakfield,labfield=0,0,0,0
    pTRM,MD,samp_con,Z=0,0,'1',1
    dec=[315,225,180,135,45,90,270,270,270,90,180,180,0,0,0]
    inc=[0,0,0,0,0,-45,-45,0,45,45,45,-45,-90,-45,45]
    tdec=[0,90,0,180,270,0,0,90,0]
    tinc=[0,0,90,0,0,-90,0,0,90]
    missing=1
    demag="N"
    er_location_name=""
    citation='This study'
    args=sys.argv
    fmt='old'
    syn=0
    synfile='er_synthetics.txt'
    magfile = ''
    trm=0
    irm=0
    specnum=0
    coil=""
    arm_labfield = 50e-6
    trm_peakT = 600+273
    #
    # get command line arguments
    #

    meas_file="magic_measurements.txt"
    user=""
    if command_line:
        if "-h" in args:
            print(main.__doc__)
            return False
        if "-usr" in args:
            ind=args.index("-usr")
            user=args[ind+1]
        if '-F' in args:
            ind=args.index("-F")
            meas_file=args[ind+1]
        if '-Fsy' in args:
            ind=args.index("-Fsy")
            synfile=args[ind+1]
        if '-f' in args:
            ind=args.index("-f")
            magfile=args[ind+1]
        if "-dc" in args:
            ind=args.index("-dc")
            labfield=float(args[ind+1])*1e-6
            phi=float(args[ind+2])
            theta=float(args[ind+3])
        if "-ac" in args:
            ind=args.index("-ac")
            peakfield=float(args[ind+1])*1e-3
        if "-spc" in args:
            ind=args.index("-spc")
            specnum=int(args[ind+1])
        if "-loc" in args:
            ind=args.index("-loc")
            er_location_name=args[ind+1]
        if '-syn' in args:
            syn=1
            ind=args.index("-syn")
            institution=args[ind+1]
            syntype=args[ind+2]
            if '-fsy' in args:
                ind=args.index("-fsy")
                synfile=args[ind+1]
        if "-ins" in args:
            ind=args.index("-ins")
            inst=args[ind+1]
        if "-A" in args: noave=1
        if "-ncn" in args:
            ind=args.index("-ncn")
            samp_con=sys.argv[ind+1]
        if '-LP' in args:
            ind=args.index("-LP")
            codelist=args[ind+1]
        if "-V" in args:
            ind=args.index("-V")
            coil=args[ind+1]
        if '-ARM_dc' in args:
            ind = args.index("-ARM_dc")
            arm_labfield = args[ind+1]
        if '-ARM_temp' in args:
            ind = args.index('-ARM_temp')
            trm_peakT = args[ind+1]

    if not command_line:
        user = kwargs.get('user', '')
        meas_file = kwargs.get('meas_file', 'magic_measurements.txt')
        synfile = kwargs.get('synfile', 'er_synthetics.txt')
        # rm samp_file = kwargs.get('samp_file', '')
        magfile = kwargs.get('magfile', '')
        labfield = int(kwargs.get('labfield', 0)) *1e-6
        phi = int(kwargs.get('phi', 0))
        theta = int(kwargs.get('theta', 0))
        peakfield = int(kwargs.get('peakfield', 0))*1e-3
        specnum = int(kwargs.get('specnum', 0))
        er_location_name = kwargs.get('er_location_name', '')
        # rm samp_infile = kwargs.get('samp_infile', '')
        syn = kwargs.get('syn', 0)
        institution = kwargs.get('institution', '')
        syntype = kwargs.get('syntype', '')
        inst = kwargs.get('inst', '')
        noave = kwargs.get('noave', 0) # 0 means "do average", is default
        samp_con = kwargs.get('samp_con', '1')
        codelist = kwargs.get('codelist', '')
        coil = kwargs.get('coil', '')
        arm_labfield = kwargs.get('arm_labfield', 50e-6)
        trm_peakT = kwargs.get('trm_peakT', 600+273)

    # format/organize variables
    if magfile:
        try:
            input=open(magfile,'r')
        except:
            print("bad mag file name")
            return False, "bad mag file name"
    else:
        print("mag_file field is required option")
        print(main.__doc__)
        return False, "mag_file field is required option"

    if specnum!=0:specnum=-specnum

    if "4" in samp_con:
        if "-" not in samp_con:
            print("naming convention option [4] must be in form 4-Z where Z is an integer")
            return False, "naming convention 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("naming convention option [7] must be in form 7-Z where Z is an integer")
            return False, "naming convention option [7] must be in form 7-Z where Z is an integer"
        else:
            Z=samp_con.split("-")[1]
            samp_con="4"

    codes=codelist.split(':')
    if "AF" in codes:
        demag='AF'
        if not labfield: methcode="LT-AF-Z"
        if labfield: methcode="LT-AF-I"
    if "T" in codes:
        demag="T"
        if not labfield: methcode="LT-T-Z"
        if labfield: methcode="LT-T-I"
    if "I" in codes:
        methcode="LP-IRM"
        irmunits="mT"
    if "S" in codes:
        demag="S"
        methcode="LP-PI-TRM:LP-PI-ALT-AFARM"
        trm_labfield=labfield
        # should use arm_labfield and trm_peakT as well, but these values are currently never asked for
    if "G" in codes: methcode="LT-AF-G"
    if "D" in codes: methcode="LT-AF-D"
    if "TRM" in codes:
        demag="T"
        trm=1

    if coil:
        methcode="LP-IRM"
        irmunits="V"
        if coil not in ["1","2","3"]:
            print(main.__doc__)
            print('not a valid coil specification')
            return False, 'not a valid coil specification'

    if demag=="T" and "ANI" in codes:
        methcode="LP-AN-TRM"
    if demag=="AF" and "ANI" in codes:
        methcode="LP-AN-ARM"
        if labfield==0: labfield=50e-6
        if peakfield==0: peakfield=.180
    SynRecs,MagRecs=[],[]
    version_num=pmag.get_version()
    if 1: # ldeo file format
#
# find start of data:
#
        DIspec=[]
        Data,k=input.readlines(),0
        for k in range(len(Data)):
            rec=Data[k].split()
            if rec[0][0]=="_" or rec[0][0:2]=="!_":
                break
        start=k+1
        for k in range(start,len(Data)):
          rec=Data[k].split()
          if len(rec)>0:
            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"]=rec[0]
            if specnum!=0:
                MagRec["er_sample_name"]=rec[0][:specnum]
            else:
                MagRec["er_sample_name"]=rec[0]
            site=pmag.parse_site(MagRec['er_sample_name'],samp_con,Z)
            MagRec["er_site_name"]=site
            MagRec["er_location_name"]=er_location_name
            MagRec["measurement_csd"]=rec[3]
            MagRec["measurement_magn_moment"]='%10.3e'% (float(rec[4])*1e-7) # moment in Am^2 (from 10^-4 emu)
#
            #if samp_file!="" and MagRec["er_sample_name"] not in Samps:        # create er_samples.txt file with these data
            #    cdec,cinc=float(rec[5]),float(rec[6])
            #    gdec,ginc=float(rec[7]),float(rec[8])
            #    az,pl=pmag.get_azpl(cdec,cinc,gdec,ginc)
            #    bdec,binc=float(rec[9]),float(rec[10])
            #    if rec[7]!=rec[9] and rec[6]!=rec[8]:
            #        dipdir,dip=pmag.get_tilt(gdec,ginc,bdec,binc)
            #    else:
            #        dipdir,dip=0,0
            #    ErSampRec={}
            #    ErSampRec['er_location_name']=MagRec['er_location_name']
            #    ErSampRec['er_sample_name']=MagRec['er_sample_name']
            #    ErSampRec['er_site_name']=MagRec['er_site_name']
            #    ErSampRec['sample_azimuth']='%7.1f'%(az)
            #    ErSampRec['sample_dip']='%7.1f'%(pl)
            #    ErSampRec['sample_bed_dip_direction']='%7.1f'%(dipdir)
            #    ErSampRec['sample_bed_dip']='%7.1f'%(dip)
            #    ErSampRec['sample_description']='az,pl,dip_dir and dip recalculated from [c,g,b][dec,inc] in ldeo file'
            #    ErSampRec['magic_method_codes']='SO-REC'
            #    ErSamps.append(ErSampRec)
            #    Samps.append(ErSampRec['er_sample_name'])
            MagRec["measurement_dec"]=rec[5]
            MagRec["measurement_inc"]=rec[6]
            MagRec["measurement_chi"]='%10.3e'%(float(rec[11])*1e-5)#convert to SI (assume Bartington, 10-5 SI)
            #MagRec["magic_instrument_codes"]=rec[2]
            #MagRec["er_analyst_mail_names"]=""
            MagRec["er_citation_names"]="This study"
            MagRec["magic_method_codes"]=meas_type
            if demag=="AF":
                if methcode != "LP-AN-ARM":
                    MagRec["treatment_ac_field"]='%8.3e' %(float(rec[1])*1e-3) # peak field in tesla
                    meas_type="LT-AF-Z"
                    MagRec["treatment_dc_field"]='0'
                else: # AARM experiment
                    if treat[1][0]=='0':
                        meas_type="LT-AF-Z"
                        MagRec["treatment_ac_field"]='%8.3e' %(peakfield) # peak field in tesla
                    else:
                        meas_type="LT-AF-I"
                        ipos=int(treat[0])-1
                        MagRec["treatment_dc_field_phi"]='%7.1f' %(dec[ipos])
                        MagRec["treatment_dc_field_theta"]='%7.1f'% (inc[ipos])
                        MagRec["treatment_dc_field"]='%8.3e'%(labfield)
                        MagRec["treatment_ac_field"]='%8.3e' %(peakfield) # peak field in tesla
            elif demag=="T":
                if rec[1][0]==".":rec[1]="0"+rec[1]
                treat=rec[1].split('.')
                if len(treat)==1:treat.append('0')
                MagRec["treatment_temp"]='%8.3e' % (float(rec[1])+273.) # temp in kelvin
                meas_type="LT-T-Z"
                MagRec["treatment_temp"]='%8.3e' % (float(treat[0])+273.) # temp in kelvin
                if trm==0:  # demag=T and not trmaq
                    if treat[1][0]=='0':
                        meas_type="LT-T-Z"
                    else:
                        MagRec["treatment_dc_field"]='%8.3e' % (labfield) # labfield in tesla (convert from microT)
                        MagRec["treatment_dc_field_phi"]='%7.1f' % (phi) # labfield phi
                        MagRec["treatment_dc_field_theta"]='%7.1f' % (theta) # labfield theta
                        if treat[1][0]=='1':meas_type="LT-T-I" # in-field thermal step
                        if treat[1][0]=='2':
                            meas_type="LT-PTRM-I" # pTRM check
                            pTRM=1
                        if treat[1][0]=='3':
                            MagRec["treatment_dc_field"]='0'  # this is a zero field step
                            meas_type="LT-PTRM-MD" # pTRM tail check
                else:
                    meas_type="LT-T-I" # trm acquisition experiment
            MagRec['magic_method_codes']=meas_type
            MagRecs.append(MagRec)
    MagOuts=pmag.measurements_methods(MagRecs,noave)
    pmag.magic_write(meas_file,MagOuts,'magic_measurements')
    print("results put in ",meas_file)
    if len(SynRecs)>0:
        pmag.magic_write(synfile,SynRecs,'er_synthetics')
        print("synthetics put in ",synfile)
    return True, meas_file


Instruction:
How would you implement a function in Python 3 that
names odp_dcs_magic.py DESCRIPTION converts ODP discrete sample format files to magic_measurements format files SYNTAX odp_dsc_magic.py [command line options] OPTIONS -h: prints the help message and quits. -F FILE: specify output measurements file, default is magic_measurements.txt -Fsp FILE: specify output er_specimens.txt file, default is er_specimens.txt -Fsa FILE: specify output er_samples.txt file for appending, default is er_samples.txt -Fsi FILE: specify output er_sites.txt file, default is er_sites.txt -dc B PHI THETA: dc lab field (in micro tesla) and phi,theta, default is none NB: use PHI, THETA = -1 -1 to signal that it changes, i.e. in anisotropy experiment -ac B : peak AF field (in mT) for ARM acquisition, default is none -A : don't average replicate measurements INPUT Put data from separate experiments (all AF, thermal, thellier, trm aquisition, Shaw, etc.) in separate directory

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

    DESCRIPTION
        converts ODP discrete sample format files to magic_measurements format files

    SYNTAX
        odp_dsc_magic.py [command line options]

    OPTIONS
        -h: prints the help message and quits.
        -F FILE: specify output  measurements file, default is magic_measurements.txt
        -Fsp FILE: specify output er_specimens.txt file, default is er_specimens.txt
        -Fsa FILE: specify output er_samples.txt file for appending, default is er_samples.txt
        -Fsi FILE: specify output er_sites.txt file, default is er_sites.txt
        -dc B PHI THETA: dc lab field (in micro tesla) and phi,theta, default is none
              NB: use PHI, THETA = -1 -1 to signal that it changes, i.e. in anisotropy experiment
        -ac B : peak AF field (in mT) for ARM acquisition, default is none
        -A : don't average replicate measurements
    INPUT
        Put data from separate experiments (all AF, thermal, thellier, trm aquisition, Shaw, etc.)  in separate directory

    """
#
#
    version_num=pmag.get_version()
    meas_file='magic_measurements.txt'
    spec_file='er_specimens.txt'
    samp_file='er_samples.txt'
    site_file='er_sites.txt'
    ErSpecs,ErSamps,ErSites,ErLocs,ErCits=[],[],[],[],[]
    MagRecs=[]
    citation="This study"
    dir_path,demag='.','NRM'
    args=sys.argv
    noave=0
    if '-WD' in args:
        ind=args.index("-WD")
        dir_path=args[ind+1]
    if "-h" in args:
        print(main.__doc__)
        sys.exit()
    if "-A" in args: noave=1
    if '-F' in args:
        ind=args.index("-F")
        meas_file=args[ind+1]
    if '-Fsp' in args:
        ind=args.index("-Fsp")
        spec_file=args[ind+1]
    if '-Fsa' in args:
        ind=args.index("-Fsa")
        samp_file=dir_path+'/'+args[ind+1]
        ErSamps,file_type=pmag.magic_read(samp_file)
    else:
        samp_file=dir_path+'/'+samp_file
    if '-LP' in args:
        ind=args.index("-LP")
        codelist=args[ind+1]
        codes=codelist.split(':')
        if "AF" in codes:
            demag='AF'
            if'-dc' not in args: methcode="LT-AF-Z"
            if'-dc' in args: methcode="LT-AF-I"
        if "T" in codes:
            demag="T"
            if '-dc' not in args: methcode="LT-T-Z"
            if '-dc' in args: methcode="LT-T-I"
        if "I" in codes:
            methcode="LP-IRM"
        if "S" in codes:
            demag="S"
            methcode="LP-PI-TRM:LP-PI-ALT-AFARM"
            trm_labfield=labfield
            ans=input("DC lab field for ARM step: [50uT] ")
            if ans=="":
                arm_labfield=50e-6
            else:
                arm_labfield=float(ans)*1e-6
            ans=input("temperature for total trm step: [600 C] ")
            if ans=="":
                trm_peakT=600+273 # convert to kelvin
            else:
                trm_peakT=float(ans)+273 # convert to kelvin
        if "G" in codes: methcode="LT-AF-G"
    if "D" in codes: methcode="LT-AF-D"
    if "TRM" in codes:
        demag="T"
        trm=1
    if demag=="T" and "ANI" in codes:
        methcode="LP-AN-TRM"
    if demag=="AF" and "ANI" in codes:
        methcode="LP-AN-ARM"
        if labfield==0: labfield=50e-6
        if peakfield==0: peakfield=.180
    spec_file=dir_path+'/'+spec_file
    site_file=dir_path+'/'+site_file
    meas_file=dir_path+'/'+meas_file
    filelist=os.listdir(dir_path) # read in list of files to import
    specimens,samples,sites=[],[],[]
    MagRecs,SpecRecs,SampRecs=[],[],[]
    for samp in ErSamps:
        if samp['er_sample_name'] not in samples:
            samples.append(samp['er_sample_name'])
            SampRecs.append(samp)
    for file in filelist: # parse each file
        if file[-3:].lower()=='dsc':
            print('processing: ',file)
            MagRec,SpecRec,SampRec={},{},{}
            treatment_type,treatment_value,user="","",""
            inst="ODP-SRM"
            input=open(dir_path+'/'+file,'r').readlines()
            IDs=file.split('_') # splits on underscores
            pieces=IDs[0].split('-')
            expedition=pieces[0]
            location=pieces[1]
            if file[0]!='_':
                while len(pieces[2])<4:pieces[2]='0'+pieces[2] # pad core to be 3 characters
                specimen=""
            else:
                specimen="test"
            for piece in pieces:
                specimen=specimen+piece+'-'
            specimen=specimen[:-1]
            alt_spec=IDs[1] # alternate specimen is second field in field name
# set up specimen record for Er_specimens table
            SpecRec['er_expedition_name']=expedition
            SpecRec['er_location_name']=location
            SpecRec['er_site_name']=specimen
            SpecRec['er_sample_name']=specimen
            SpecRec['er_citation_names']=citation
            for key in list(SpecRec.keys()):SampRec[key]=SpecRec[key]
            SampRec['sample_azimuth']='0'
            SampRec['sample_dip']='0'
            SampRec['magic_method_codes']='FS-C-DRILL-IODP:SP-SS-C:SO-V'
            SpecRec['er_specimen_name']=specimen
            SampRec['er_specimen_names']=specimen
            for key in list(SpecRec.keys()):MagRec[key]=SpecRec[key]
# set up measurement record - default is NRM
            MagRec['er_analyst_mail_names']=user
            MagRec['magic_method_codes']='LT-NO'
            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["treatment_ac_field"]=0.
            MagRec["treatment_dc_field"]='0'
            MagRec["treatment_dc_field_phi"]='0'
            MagRec["treatment_dc_field_theta"]='0'
            MagRec["measurement_flag"]='g' # assume all data are "good"
            MagRec["measurement_standard"]='u' # assume all data are "good"
            MagRec["measurement_csd"]='' # set csd to blank
            SpecRec['er_specimen_alternatives']=alt_spec
            vol=7e-6 # assume 7 cc samples
            datestamp=input[1].split() # date time is second line of file
            mmddyy=datestamp[0].split('/') # break into month day year
            date=mmddyy[2]+':'+mmddyy[0]+":"+mmddyy[1] +':' +datestamp[1]
            MagRec["measurement_date"]=date
            for k in range(len(input)):
                fields= input[k].split("=")
                if 'treatment_type' in fields[0]:
                    if "Alternating Frequency Demagnetization" in fields[1]:
                        MagRec['magic_method_codes'] = 'LT-AF-Z'
                        inst=inst+':ODP-DTECH' # measured on shipboard AF DTECH D2000
                        treatment_type="AF"
                    if "Anhysteretic Remanent Magnetization" in fields[1]:
                        MagRec['magic_method_codes'] = 'LT-AF-I'
                        inst=inst+':ODP-DTECH' # measured on shipboard AF DTECH D2000
                        treatment_type="ARM"
                    if "Isothermal Remanent Magnetization" in fields[1]:
                        MagRec['magic_method_codes'] = 'LT-IRM'
                        inst=inst+':ODP-IMP' # measured on shipboard ASC IMPULSE magnetizer
                        treatment_type="IRM"
                if "treatment_value" in fields[0]:
                    values=fields[1].split(',')
                    value=values[0]
                    if value!=" \n":
                        if treatment_type=="AF":
                            treatment_value=float(value)*1e-3
                            MagRec["treatment_ac_field"]=treatment_value # AF demag in treat mT => T
                        elif treatment_type=="IRM":
                            treatment_value=float(value)*1e-3
                            MagRec["treatment_dc_field"]='%8.3e'%(treatment_value) # IRM treat mT => T
                        if treatment_type=="ARM":
                            treatment_value=float(value)*1e-3
                            dc_value=float(values[1])*1e-3
                            MagRec["treatment_ac_field"]=treatment_value # AF demag in treat mT => T
                            MagRec["treatment_dc_field"]='%8.3e'%(dc_value) # DC mT => T
                if 'user' in fields[0]:
                    user=fields[-1]
                    MagRec["er_analyst_mail_names"]=user
                if 'sample_orientation' in fields[0]:
                    MagRec["measurement_description"]=fields[-1]
                MagRec["measurement_standard"]='u' # assume all data are "good"
                if 'sample_area' in fields[0]:  vol=float(fields[1])*1e-6 # takes volume (cc) and converts to m^3
                if 'run_number' in fields[0]:
                    MagRec['external_database_ids']=fields[1] # run number is the LIMS measurement number
                    MagRec['external_database_names']='LIMS'
                if input[k][0:7]=='<MULTI>':
                    rec=input[k+1].split(',') # list of data
                    for item in rec:
                        items=item.split('=')
                        if items[0].strip()=='demag_level' and  treatment_value=="" :
                            treat= float(items[1])
                            if treat!=0:
                                MagRec['magic_method_codes']='LT-AF-Z'
                                inst=inst+':ODP-SRM-AF'
                                MagRec["treatment_ac_field"]=treat*1e-3 # AF demag in treat mT => T
                        if items[0].strip()=='inclination_w_tray_w_bkgrd': MagRec['measurement_inc']=items[1]
                        if items[0].strip()=='declination_w_tray_w_bkgrd': MagRec['measurement_dec']=items[1]
                        if items[0].strip()=='intensity_w_tray_w_bkgrd': MagRec['measurement_magn_moment']='%8.3e'%(float(items[1])*vol) # convert intensity from A/m to Am^2 using vol
                        if items[0].strip()=='x_stdev':MagRec['measurement_x_sd']=items[1]
                        if items[0].strip()=='y_stdev':MagRec['measurement_y_sd']=items[1]
                        if items[0].strip()=='z_stdev':MagRec['measurement_sd_z']=items[1]
                        MagRec['magic_instrument_codes']=inst
                        MagRec['measurement_number']='1'
                        MagRec['measurement_positions']=''
            MagRecs.append(MagRec)
            if specimen not in specimens:
                specimens.append(specimen)
                SpecRecs.append(SpecRec)
            if MagRec['er_sample_name'] not in samples:
                samples.append(MagRec['er_sample_name'])
                SampRecs.append(SampRec)
    MagOuts=pmag.sort_diclist(MagRecs,'treatment_ac_field')
    for MagRec in MagOuts:
        MagRec["treatment_ac_field"]='%8.3e'%(MagRec["treatment_ac_field"]) # convert to string
    pmag.magic_write(spec_file,SpecRecs,'er_specimens')
    if len(SampRecs)>0:
        SampOut,keys=pmag.fillkeys(SampRecs)
        pmag.magic_write(samp_file,SampOut,'er_samples')
        print('samples stored in ',samp_file)
    pmag.magic_write(samp_file,SampRecs,'er_samples')
    print('specimens stored in ',spec_file)

    Fixed=pmag.measurements_methods(MagOuts,noave)
    pmag.magic_write(meas_file,Fixed,'magic_measurements')
    print('data stored in ',meas_file)


Instruction:
Can you generate a brief explanation for the following Python 3 code
def main():
    N,kappa,D,I=100,20.,0.,90.
    if len(sys.argv)!=0 and  '-h' in sys.argv:
        print(main.__doc__)
        sys.exit()
    elif '-i' in sys.argv:
        ans=input('    Kappa: ')
        kappa=float(ans)
        ans=input('    N: ')
        N=int(ans)
        ans=input('    Mean Dec: ')
        D=float(ans)
        ans=input('    Mean Inc: ')
        I=float(ans)
    else:
        if '-k' in sys.argv:
            ind=sys.argv.index('-k')
            kappa=float(sys.argv[ind+1])
        if '-n' in sys.argv:
            ind=sys.argv.index('-n')
            N=int(sys.argv[ind+1])
        if '-D' in sys.argv:
            ind=sys.argv.index('-D')
            D=float(sys.argv[ind+1])
        if '-I' in sys.argv:
            ind=sys.argv.index('-I')
            I=float(sys.argv[ind+1])
    for k in range(N):
        dec,inc= pmag.fshdev(kappa)  # send kappa to fshdev
        drot,irot=pmag.dodirot(dec,inc,D,I)
        print('%7.1f %7.1f ' % (drot,irot))

Response:
NAME fishrot. py
Taxonomy DESCRIPTION get a set of Fisher distributed data from a single Fisher Distribution


Instruction:
Explain what the following Python 3 code does
def main():
    if "-h" in sys.argv:
        print(main.__doc__)
        sys.exit()

    dataframe = extractor.command_line_dataframe([['WD', False, '.'], ['ID', False, '.'], ['f', True, ''], ['Fsa', False, 'samples.txt'], ['DM', False, 3]])
    args = sys.argv
    checked_args = extractor.extract_and_check_args(args, dataframe)
    samp_file, output_samp_file, output_dir_path, input_dir_path, data_model_num = extractor.get_vars(['f', 'Fsa', 'WD', 'ID', 'DM'], checked_args)
    data_model_num = int(float(data_model_num))
    if '-Fsa' not in args and data_model_num == 2:
        output_samp_file = "er_samples.txt"
    ran, error = convert.iodp_samples(samp_file, output_samp_file, output_dir_path,
                                      input_dir_path, data_model_num=data_model_num)
    if not ran:
        print("-W- " + error)

Response:
iodp_samples_magic.py
    OPTIONS:
        -f FILE, input csv file
        -Fsa FILE, output samples file for updating, default is to overwrite existing samples file


Instruction:
Can you write a function in Python 3 where it
converts a cartesian coordinates to a direction vector

Response:
def cart2dir(self,cart):
        """
        converts a direction to cartesian coordinates
        """
#        print "calling cart2dir(), not in anything"
        cart=numpy.array(cart)
        rad=old_div(numpy.pi,180.) # constant to convert degrees to radians
        if len(cart.shape)>1:
            Xs,Ys,Zs=cart[:,0],cart[:,1],cart[:,2]
        else: #single vector
            Xs,Ys,Zs=cart[0],cart[1],cart[2]
        Rs=numpy.sqrt(Xs**2+Ys**2+Zs**2) # calculate resultant vector length
        Decs=(old_div(numpy.arctan2(Ys,Xs),rad))%360. # calculate declination taking care of correct quadrants (arctan2) and making modulo 360.
        try:
            Incs=old_div(numpy.arcsin(old_div(Zs,Rs)),rad) # calculate inclination (converting to degrees) #
        except:
            print('trouble in cart2dir') # most likely division by zero somewhere
            return numpy.zeros(3)

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


Instruction:
Can you tell what is the following Python 3 function doing
def magic_read(self,infile):
#        print "calling magic_read(self, infile)", infile
        hold,magic_data,magic_record,magic_keys=[],[],{},[]
        try:
            f=open(infile,"r")
        except:
            return [],'bad_file'
        d = f.readline()[:-1].strip('\n')
        if d[0]=="s" or d[1]=="s":
            delim='space'
        elif d[0]=="t" or d[1]=="t":
            delim='tab'
        else:
            print('error reading ', infile)
            sys.exit()
        if delim=='space':file_type=d.split()[1]
        if delim=='tab':file_type=d.split('\t')[1]
        if file_type=='delimited':
            if delim=='space':file_type=d.split()[2]
            if delim=='tab':file_type=d.split('\t')[2]
        if delim=='space':line =f.readline()[:-1].split()
        if delim=='tab':line =f.readline()[:-1].split('\t')
        for key in line:
            magic_keys.append(key)
        lines=f.readlines()
        for line in lines[:-1]:
            line.replace('\n','')
            if delim=='space':rec=line[:-1].split()
            if delim=='tab':rec=line[:-1].split('\t')
            hold.append(rec)
        line = lines[-1].replace('\n','')
        if delim=='space':rec=line[:-1].split()
        if delim=='tab':rec=line.split('\t')
        hold.append(rec)
        for rec in hold:
            magic_record={}
            if len(magic_keys) != len(rec):

                print("Warning: Uneven record lengths detected: ")
                #print magic_keys
                #print rec
            for k in range(len(rec)):
               magic_record[magic_keys[k]]=rec[k].strip('\n')
            magic_data.append(magic_record)
        magictype=file_type.lower().split("_")
        Types=['er','magic','pmag','rmag']
        if magictype in Types:file_type=file_type.lower()
#        print "magic data from magic_read:"
#        print str(magic_data)[:500] + "..."
#        print "file_type", file_type
        return magic_data,file_type

Response: reads a Magic template file puts data in a list of dictionaries


Instruction:
Create a Python 3 function for
taking a magic format file and returns a list of unique specimen names

Response:
def get_specs(self,data):
        """
         takes a magic format file and returns a list of unique specimen names
        """
    # sort the specimen names
    #
#        print "calling get_specs()"
        speclist=[]
        for rec in data:
          spec=rec["er_specimen_name"]
          if spec not in speclist:speclist.append(spec)
        speclist.sort()
        #print speclist
        return speclist


Instruction:
Write a Python 3 script to
sort the data block in to first_Z first_I first_I... Zdiff is the number of times the data block is in.

Response:
def sortarai(self,datablock,s,Zdiff):
        """
         sorts data block in to first_Z, first_I, etc.
        """
#        print "calling sortarai()"
        first_Z,first_I,zptrm_check,ptrm_check,ptrm_tail=[],[],[],[],[]
        field,phi,theta="","",""
        starthere=0
        Treat_I,Treat_Z,Treat_PZ,Treat_PI,Treat_M,Treat_AC=[],[],[],[],[],[]
        ISteps,ZSteps,PISteps,PZSteps,MSteps,ACSteps=[],[],[],[],[],[]
        GammaChecks=[] # comparison of pTRM direction acquired and lab field
        Mkeys=['measurement_magn_moment','measurement_magn_volume','measurement_magn_mass','measurement_magnitude']
        rec=datablock[0]  # finds which type of magnetic measurement is present in magic_measurements.txt, then assigns momkey to that value
        for key in Mkeys:
            if key in list(rec.keys()) and rec[key]!="":
                momkey=key
                break
    # first find all the steps
        for k in range(len(datablock)):  # iterates through records.
            rec=datablock[k]
            if "treatment_temp" in list(rec.keys()):
                temp=float(rec["treatment_temp"])
            elif "treatment_mw_power" in list(rec.keys()):
                temp=float(rec["treatment_mw_power"])

            methcodes=[]
            tmp=rec["magic_method_codes"].split(":")
            for meth in tmp:
                methcodes.append(meth.strip())
                # methchodes contains all codes for a particular record
            # for thellier-thellier
            if 'LT-T-I' in methcodes and 'LP-PI-TRM' in methcodes and 'LP-TRM' not in methcodes :
                # IF specimen cooling AND using a laboratory trm AND NOT trm acquisition
                Treat_I.append(temp)
                ISteps.append(k)
                if field=="":field=float(rec["treatment_dc_field"])
                if phi=="":
                    phi=float(rec['treatment_dc_field_phi'])
                    theta=float(rec['treatment_dc_field_theta'])

            # for Microwave
            if 'LT-M-I' in methcodes and 'LP-PI-M' in methcodes :
                # if using microwave radiation in lab field AND using microwave demagnetisation
                Treat_I.append(temp)
                ISteps.append(k)
                if field=="":field=float(rec["treatment_dc_field"])
                if phi=="":
                    phi=float(rec['treatment_dc_field_phi'])
                    theta=float(rec['treatment_dc_field_theta'])

    # stick  first zero field stuff into first_Z
            if 'LT-NO' in methcodes:
                # if no treatments applied before measurements
                Treat_Z.append(temp)
                ZSteps.append(k)
            if 'LT-T-Z' in methcodes or 'LT-M-Z' in methcodes:
                # if specimen cooling in zero field OR using microwave radiation: In zero field
                Treat_Z.append(temp)
                ZSteps.append(k)
            if 'LT-PTRM-Z' : # maybe this should be in methcodes ??  note I no longer understand
                # if pTRM tail check
                Treat_PZ.append(temp)
                PZSteps.append(k)
            if 'LT-PTRM-I' in methcodes or 'LT-PMRM-I' in methcodes:
                # if pTRM check
                Treat_PI.append(temp)
                PISteps.append(k)
            if 'LT-PTRM-MD' in methcodes:
                # if pTRM tail check
                Treat_M.append(temp)
                MSteps.append(k)
            if 'LT-PTRM-AC' in methcodes or 'LT-PMRM-AC' in methcodes:
                Treat_AC.append(temp)
                ACSteps.append(k)
            if 'LT-NO' in methcodes:
                # if no treatments applied before measurement
                dec=float(rec["measurement_dec"])
                inc=float(rec["measurement_inc"])
                str=float(rec[momkey])
                if 'LP-PI-M'  not in methcodes:
                    # if not using microwave demagnetisation
                    first_I.append([273,0.,0.,0.,1])
                    first_Z.append([273,dec,inc,str,1])  # NRM step
                else:
                    first_I.append([0,0.,0.,0.,1])
                    first_Z.append([0,dec,inc,str,1])  # NRM step

                    # the block above seems to be sorting out into wheter it is Treat_Z (zero field), Treat_I (infield), a ptrm check, or a ptrm tail check. so, each record has been appended to whichever of those it belongs in.
        #---------------------
        # find  IZ and ZI
        #---------------------

        for temp in Treat_I: # look through infield steps and find matching Z step
            if temp in Treat_Z: # found a match
                istep=ISteps[Treat_I.index(temp)]
                irec=datablock[istep]
                methcodes=[]
                tmp=irec["magic_method_codes"].split(":")
                for meth in tmp: methcodes.append(meth.strip())
                brec=datablock[istep-1] # take last record as baseline to subtract
                zstep=ZSteps[Treat_Z.index(temp)]
                zrec=datablock[zstep]
        # sort out first_Z records
                if "LP-PI-TRM-IZ" in methcodes or "LP-PI-M-IZ" in methcodes:
                    ZI=0
                else:
                    ZI=1
                dec=float(zrec["measurement_dec"])
                inc=float(zrec["measurement_inc"])
                str=float(zrec[momkey])
                first_Z.append([temp,dec,inc,str,ZI])
        # sort out first_I records
                #print 'irec', irec # full data set for infield measurement
                #print 'zrec', zrec # coresponding zerofield measurement
                idec=float(irec["measurement_dec"])
                iinc=float(irec["measurement_inc"])
                istr=float(irec[momkey])
                X=self.dir2cart([idec,iinc,istr])
                BL=self.dir2cart([dec,inc,str])
                I=[]
                for c in range(3):
                    I.append((X[c]-BL[c]))
                iDir=self.cart2dir(I)
                first_I.append([temp,iDir[0],iDir[1],iDir[2],ZI])
                now_ignore = """
                #if I[2]!=0: # lj PUT THIS BACK
                if True:
                    iDir=self.cart2dir(I)
                    if Zdiff==0:
                        print "Zdiff == 0, appending to first_I" #lj
                        print [temp,iDir[0],iDir[1],iDir[2],ZI] #lj
                        first_I.append([temp,iDir[0],iDir[1],iDir[2],ZI])
                    else:
                        print "Zdiff != 0, appending to first_I" #lj
                        print [temp,0.,0.,I[2],ZI]  #lj
                        first_I.append([temp,0.,0.,I[2],ZI])
##                    gamma=angle([iDir[0],iDir[1]],[phi,theta])
                else:
                    print "0,0,0 appending to first_I"
                    print [temp,0.,0.,0.,ZI]
                    first_I.append([temp,0.,0.,0.,ZI])
##                    gamma=0.0
##    # put in Gamma check (infield trm versus lab field)
##                if 180.-gamma<gamma:
##                    gamma=180.-gamma
##                GammaChecks.append([temp-273.,gamma])
                 """

        #---------------------
        # find Thellier Thellier protocol
        #---------------------
        if 'LP-PI-II'in methcodes or 'LP-PI-T-II' in methcodes or 'LP-PI-M-II' in methcodes:
            for i in range(1,len(Treat_I)): # look through infield steps and find matching Z step
                if Treat_I[i] == Treat_I[i-1]:
                    # ignore, if there are more than
                    temp= Treat_I[i]
                    irec1=datablock[ISteps[i-1]]
                    dec1=float(irec1["measurement_dec"])
                    inc1=float(irec1["measurement_inc"])
                    moment1=float(irec1["measurement_magn_moment"])
                    if len(first_I)<2:
                        dec_initial=dec1;inc_initial=inc1
                    cart1=numpy.array(self.dir2cart([dec1,inc1,moment1]))
                    irec2=datablock[ISteps[i]]
                    dec2=float(irec2["measurement_dec"])
                    inc2=float(irec2["measurement_inc"])
                    moment2=float(irec2["measurement_magn_moment"])
                    cart2=numpy.array(self.dir2cart([dec2,inc2,moment2]))

                    # check if its in the same treatment
                    if Treat_I[i] == Treat_I[i-2] and dec2!=dec_initial and inc2!=inc_initial:
                        continue
                    if dec1!=dec2 and inc1!=inc2:
                        zerofield=old_div((cart2+cart1),2)
                        infield=old_div((cart2-cart1),2)

                        DIR_zerofield=self.cart2dir(zerofield)
                        DIR_infield=self.cart2dir(infield)

                        first_Z.append([temp,DIR_zerofield[0],DIR_zerofield[1],DIR_zerofield[2],0])
                        print("appending to first_I") # LJ remove this
                        print([temp,DIR_infield[0],DIR_infield[1],DIR_infield[2],0]) # LJ remove this
                        first_I.append([temp,DIR_infield[0],DIR_infield[1],DIR_infield[2],0])

        #---------------------
        # find  pTRM checks
        #---------------------

        for temp in Treat_PI: # look through infield steps and find matching Z step
            if 'LP-PI-II' not in methcodes:
                step=PISteps[Treat_PI.index(temp)]
                rec=datablock[step]
                dec=float(rec["measurement_dec"])
                inc=float(rec["measurement_inc"])
                str=float(rec[momkey])
                brec=datablock[step-1] # take last record as baseline to subtract
                pdec=float(brec["measurement_dec"])
                pinc=float(brec["measurement_inc"])
                pint=float(brec[momkey])
                X=self.dir2cart([dec,inc,str])
                prevX=self.dir2cart([pdec,pinc,pint])
                I=[]
                for c in range(3): I.append(X[c]-prevX[c])
                dir1=self.cart2dir(I)
                if Zdiff==0:
                    ptrm_check.append([temp,dir1[0],dir1[1],dir1[2]])
                else:
                    ptrm_check.append([temp,0.,0.,I[2]])
            else:
                step=PISteps[Treat_PI.index(temp)]
                rec=datablock[step]
                dec=float(rec["measurement_dec"])
                inc=float(rec["measurement_inc"])
                moment=float(rec["measurement_magn_moment"])
                for zerofield in first_Z:
                    if zerofield[0]==temp:
                        M1=numpy.array(self.dir2cart([dec,inc,moment]))
                        M2=numpy.array(self.dir2cart([zerofield[1],zerofield[2],zerofield[3]]))
                        diff=M1-M2
                        diff_cart=self.cart2dir(diff)
                        ptrm_check.append([temp,diff_cart[0],diff_cart[1],diff_cart[2]])

    # in case there are zero-field pTRM checks (not the SIO way)
        for temp in Treat_PZ:
            step=PZSteps[Treat_PZ.index(temp)]
            rec=datablock[step]
            dec=float(rec["measurement_dec"])
            inc=float(rec["measurement_inc"])
            str=float(rec[momkey])
            brec=datablock[step-1]
            pdec=float(brec["measurement_dec"])
            pinc=float(brec["measurement_inc"])
            pint=float(brec[momkey])
            X=self.dir2cart([dec,inc,str])
            prevX=self.dir2cart([pdec,pinc,pint])
            I=[]
            for c in range(3): I.append(X[c]-prevX[c])
            dir2=self.cart2dir(I)
            zptrm_check.append([temp,dir2[0],dir2[1],dir2[2]])
        ## get pTRM tail checks together -
        for temp in Treat_M:
            step=MSteps[Treat_M.index(temp)] # tail check step - just do a difference in magnitude!
            rec=datablock[step]
            str=float(rec[momkey])
            if temp in Treat_Z:
                step=ZSteps[Treat_Z.index(temp)]
                brec=datablock[step]
                pint=float(brec[momkey])
                ptrm_tail.append([temp,0,0,str-pint])  # difference - if negative, negative tail!
            else:
                print(s, '  has a tail check with no first zero field step - check input file! for step',temp-273.)
    #
    # final check
    #
        if len(first_Z)!=len(first_I):
                   print(len(first_Z),len(first_I))
                   print(" Something wrong with this specimen! Better fix it or delete it ")
                   input(" press return to acknowledge message")

       #---------------------
        # find  Additivity (patch by rshaar)
        #---------------------

        additivity_check=[]
        for i in range(len(Treat_AC)):
            step_0=ACSteps[i]
            temp=Treat_AC[i]
            dec0=float(datablock[step_0]["measurement_dec"])
            inc0=float(datablock[step_0]["measurement_inc"])
            moment0=float(datablock[step_0]['measurement_magn_moment'])
            V0=self.dir2cart([dec0,inc0,moment0])

            # find the infield step that comes before the additivity check
            foundit=False
            for j in range(step_0,1,-1):
                if "LT-T-I" in datablock[j]['magic_method_codes']:
                  foundit=True ; break
            if foundit:
                dec1=float(datablock[j]["measurement_dec"])
                inc1=float(datablock[j]["measurement_inc"])
                moment1=float(datablock[j]['measurement_magn_moment'])
                #lj
                start_temp=float(datablock[j]['treatment_temp']);
                #lj
                V1=self.dir2cart([dec1,inc1,moment1])

                I=[]
                #print "temp (K)", temp - 273
                #print "start_temp (K)", start_temp - 273
                #print "dec0: {}, inc0: {}, moment0: {}".format(dec0, inc0, moment0)
                #print "V0: ", V0
                #print "dec1: {}, inc1: {}, moment1: {}".format(dec1, inc1,moment1)
                #print "V1: ", V1
                #print "---"
                for c in range(3): I.append(V1[c]-V0[c])
                dir1=self.cart2dir(I)
                additivity_check.append([temp,dir1[0],dir1[1],dir1[2]])

        araiblock=(first_Z,first_I,ptrm_check,ptrm_tail,zptrm_check,GammaChecks,additivity_check)

#        print "done with sortarai()"
#        print "araiblock[0] (first_Z) "
        #  [[273, 277.5, 79.6, 1.66e-09, 1], .....]
#        print araiblock[0]
#        print "araiblock[0][0]:"
#        print araiblock[0][0]
#        print "araiblock[1] (first_I)"
#        print araiblock[1]
#        print "araiblock[2] (ptrm_check)"
#        print araiblock[2]
#        print "araiblock[3] (ptrm_tail)"
#        print araiblock[3]
#        print "araiblock[4] (zptrm_check)"
#        print araiblock[4]
#        print "araiblock[5] (GammaChecks) "
#        print araiblock[5]
#        print "field ", field
        return araiblock,field


Instruction:
Create a Python 3 function to
name base. py for the main function of the vgpmap_magic. py script

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

    DESCRIPTION
        makes a map of vgps and a95/dp,dm for site means in a sites table

    SYNTAX
        vgpmap_magic.py [command line options]

    OPTIONS
        -h prints help and quits
        -eye  ELAT ELON [specify eyeball location], default is 90., 0.
        -f FILE sites format file, [default is sites.txt]
        -res [c,l,i,h] specify resolution (crude, low, intermediate, high]
        -etp plot the etopo20 topographpy data (requires high resolution data set)
        -prj PROJ,  specify one of the following:
             ortho = orthographic
             lcc = lambert conformal
             moll = molweide
             merc = mercator
        -sym SYM SIZE: choose a symbol and size, examples:
            ro 5 : small red circles
            bs 10 : intermediate blue squares
            g^ 20 : large green triangles
        -ell  plot dp/dm or a95 ellipses
        -rev RSYM RSIZE : flip reverse poles to normal antipode
        -S:  plot antipodes of all poles
        -age : plot the ages next to the poles
        -crd [g,t] : choose coordinate system, default is to plot all site VGPs
        -fmt [pdf, png, eps...] specify output format, default is pdf
        -sav  save and quit
    DEFAULTS
        FILE: sites.txt
        res:  c
        prj: ortho
        ELAT,ELON = 0,0
        SYM SIZE: ro 8
        RSYM RSIZE: g^ 8

    """
    if '-h' in sys.argv:
        print(main.__doc__)
        sys.exit()
    dir_path = pmag.get_named_arg("-WD", ".")
    # plot: default is 0, if -sav in sys.argv should be 1
    interactive = True
    save_plots = pmag.get_flag_arg_from_sys("-sav", true=1, false=0)
    if save_plots:
        interactive = False
    fmt = pmag.get_named_arg("-fmt", "pdf")
    res = pmag.get_named_arg("-res", "c")
    proj = pmag.get_named_arg("-prj", "ortho")
    anti = pmag.get_flag_arg_from_sys("-S", true=1, false=0)
    fancy = pmag.get_flag_arg_from_sys("-etp", true=1, false=0)
    ell = pmag.get_flag_arg_from_sys("-ell", true=1, false=0)
    ages = pmag.get_flag_arg_from_sys("-age", true=1, false=0)
    if '-rev' in sys.argv:
        flip = 1
        ind = sys.argv.index('-rev')
        rsym = (sys.argv[ind + 1])
        rsize = int(sys.argv[ind + 2])
    else:
        flip, rsym, rsize = 0, "g^", 8
    if '-sym' in sys.argv:
        ind = sys.argv.index('-sym')
        sym = (sys.argv[ind + 1])
        size = int(sys.argv[ind + 2])
    else:
        sym, size = 'ro', 8
    if '-eye' in sys.argv:
        ind = sys.argv.index('-eye')
        lat_0 = float(sys.argv[ind + 1])
        lon_0 = float(sys.argv[ind + 2])
    else:
        lat_0, lon_0 = 90., 0.
    crd = pmag.get_named_arg("-crd", "")
    results_file = pmag.get_named_arg("-f", "sites.txt")
    ipmag.vgpmap_magic(dir_path, results_file, crd, sym, size, rsym, rsize,
                       fmt, res, proj, flip, anti, fancy, ell, ages, lat_0, lon_0,
                       save_plots, interactive)


Instruction:
Can you tell what is the following Python 3 function doing
def main():
    args = sys.argv
    hyst_file, rem_file = "rmag_hysteresis.txt", "rmag_remanence.txt"
    dir_path = '.'
    verbose = pmagplotlib.verbose
    fmt = 'svg'  # default file format
    if '-WD' in args:
        ind = args.index('-WD')
        dir_path = args[ind+1]
    if "-h" in args:
        print(main.__doc__)
        sys.exit()
    if '-f' in args:
        ind = args.index("-f")
        hyst_file = args[ind+1]
    if '-fr' in args:
        ind = args.index("-fr")
        rem_file = args[ind+1]
    if '-fmt' in sys.argv:
        ind = sys.argv.index("-fmt")
        fmt = sys.argv[ind+1]
    if '-sav' in sys.argv:
        plots = 1
        verbose = 0
    else:
        plots = 0
    if '-n' in sys.argv:
        label = 1
    else:
        label = 0
    hyst_file = os.path.realpath(os.path.join(dir_path, hyst_file))
    rem_file = os.path.realpath(os.path.join(dir_path, rem_file))
    #
    # initialize some variables
    # define figure numbers for Day,S-Bc,S-Bcr
    DSC = {}
    DSC['day'], DSC['S-Bc'], DSC['S-Bcr'], DSC['bcr1-bcr2'] = 1, 2, 3, 4
    pmagplotlib.plot_init(DSC['day'], 5, 5)
    pmagplotlib.plot_init(DSC['S-Bc'], 5, 5)
    pmagplotlib.plot_init(DSC['S-Bcr'], 5, 5)
    pmagplotlib.plot_init(DSC['bcr1-bcr2'], 5, 5)
    #
    #
    hyst_data, file_type = pmag.magic_read(hyst_file)
    rem_data, file_type = pmag.magic_read(rem_file)
    #
    S, BcrBc, Bcr2, Bc, hsids, Bcr = [], [], [], [], [], []
    Ms, Bcr1, Bcr1Bc, S1 = [], [], [], []
    names = []
    locations = ''
    for rec in hyst_data:
        if 'er_location_name' in rec.keys() and rec['er_location_name'] not in locations:
            locations = locations+rec['er_location_name']+'_'
        if rec['hysteresis_bcr'] != "" and rec['hysteresis_mr_moment'] != "":
            S.append(float(rec['hysteresis_mr_moment']) /
                     float(rec['hysteresis_ms_moment']))
            Bcr.append(float(rec['hysteresis_bcr']))
            Bc.append(float(rec['hysteresis_bc']))
            BcrBc.append(Bcr[-1]/Bc[-1])
            if 'er_synthetic_name' in rec.keys() and rec['er_synthetic_name'] != "":
                rec['er_specimen_name'] = rec['er_synthetic_name']
            hsids.append(rec['er_specimen_name'])
            names.append(rec['er_specimen_name'])
    if len(rem_data) > 0:
        for rec in rem_data:
            if rec['remanence_bcr'] != "" and float(rec['remanence_bcr']) > 0:
                try:
                    ind = hsids.index(rec['er_specimen_name'])
                    Bcr1.append(float(rec['remanence_bcr']))
                    Bcr1Bc.append(Bcr1[-1]/Bc[ind])
                    S1.append(S[ind])
                    Bcr2.append(Bcr[ind])
                except ValueError:
                    if verbose:
                        print('hysteresis data for ',
                              rec['er_specimen_name'], ' not found')
    #
    # now plot the day and S-Bc, S-Bcr plots
    #
    leglist = []
    if label == 0:
        names = []
    if len(Bcr1) > 0:
        pmagplotlib.plot_day(DSC['day'], Bcr1Bc, S1, 'ro', names=names)
        pmagplotlib.plot_s_bcr(DSC['S-Bcr'], Bcr1, S1, 'ro')
        pmagplotlib.plot_init(DSC['bcr1-bcr2'], 5, 5)
        pmagplotlib.plot_bcr(DSC['bcr1-bcr2'], Bcr1, Bcr2)
    else:
        del DSC['bcr1-bcr2']
    pmagplotlib.plot_day(DSC['day'], BcrBc, S, 'bs', names=names)
    pmagplotlib.plot_s_bcr(DSC['S-Bcr'], Bcr, S, 'bs')
    pmagplotlib.plot_s_bc(DSC['S-Bc'], Bc, S, 'bs')
    files = {}
    if len(locations) > 0:
        locations = locations[:-1]
    for key in DSC.keys():
        if pmagplotlib.isServer:  # use server plot naming convention
            files[key] = 'LO:_'+locations+'_' + \
                'SI:__SA:__SP:__TY:_'+key+'_.'+fmt
        else:  # use more readable plot naming convention
            files[key] = '{}_{}.{}'.format(locations, key, fmt)
    if verbose:
        pmagplotlib.draw_figs(DSC)
        ans = raw_input(" S[a]ve to save plots, return to quit:  ")
        if ans == "a":
            pmagplotlib.save_plots(DSC, files)
        else:
            sys.exit()
    if plots:
        pmagplotlib.save_plots(DSC, files)

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 rmag_hysteresis.txt
        -fr: specify input remanence file, default is rmag_remanence.txt
        -fmt [svg,png,jpg] format for output plots
        -sav saves plots and quits quietly
        -n label specimen names


Instruction:
Can you implement a function in Python 3 that
names orientation_magic.py DESCRIPTION takes tab delimited field notebook information and converts to MagIC formatted tables SYNTAX orientation_magic.py [command line options] OPTIONS -f FILE: specify input file, default is: orient.txt -Fsa FILE: specify output file, default is: er_samples.txt -Fsi FILE: specify output site location file, default is: er_sites.txt -app append/update these data in existing er_samples.txt, er_sites.txt files -ocn OCON: specify orientation convention, default is #1 below -dcn DCON [DEC]: specify declination convention, default is #1 below if DCON = 2, you must supply the declination correction -BCN don't correct bedding_dip_dir for magnetic declination -already corrected -ncn NCON: specify naming convention: default is #1 below -a: averages all bedding poles and uses average for all samples: default is NO -gmt HRS: specify hours to subtract from local time to get GMT: default is 0 -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 -DM: specify data model (2 or 3). Default: 3. Will output to the appropriate format. Orientation convention: Samples are oriented in the field with a "field arrow" and measured in the laboratory with a "lab arrow". The lab arrow is the positive X direction of the right handed coordinate system of the specimen measurements. The lab and field arrows may not be the same. In the MagIC database, we require the orientation (azimuth and plunge) of the X direction of the measurements (lab arrow). Here are some popular conventions that convert the field arrow azimuth (mag_azimuth in the orient.txt file) and dip (field_dip in orient.txt) to the azimuth and plunge of the laboratory arrow (sample_azimuth and sample_dip in er_samples.txt). The two angles, mag_azimuth and field_dip are explained below. [1] Standard Pomeroy convention of azimuth and hade (degrees from vertical down) of the drill direction (field arrow). lab arrow azimuth= sample_azimuth = mag_azimuth; lab arrow dip = sample_dip =-field_dip. i.e. the lab arrow dip is minus the hade. [2] Field arrow is the strike of the plane orthogonal to the drill direction, Field dip is the hade of the drill direction. Lab arrow azimuth = mag_azimuth-90 Lab arrow dip = -field_dip [3] Lab arrow is the same as the drill direction; hade was measured in the field. Lab arrow azimuth = mag_azimuth; Lab arrow dip = 90-field_dip [4] lab azimuth and dip are same as mag_azimuth, field_dip : use this for unoriented samples too [5] Same as AZDIP convention explained below - azimuth and inclination of the drill direction are mag_azimuth and field_dip; lab arrow is as in [1] above. 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: [1] Use the IGRF value at the lat/long and date supplied [default] [2] Will supply declination correction [3] mag_az is already corrected in file [4] Correct mag_az but not bedding_dip_dir 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 [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 er_samples.txt and er_sites.txt (or samples.txt and sites.txt if using data model 3.0) - this will overwrite any existing files

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

    DESCRIPTION
        takes tab delimited field notebook information and converts to MagIC formatted tables

    SYNTAX
        orientation_magic.py [command line options]

    OPTIONS
        -f FILE: specify input file, default is: orient.txt
        -Fsa FILE: specify output file, default is: er_samples.txt
        -Fsi FILE: specify output site location file, default is: er_sites.txt
        -app  append/update these data in existing er_samples.txt, er_sites.txt files
        -ocn OCON:  specify orientation convention, default is #1 below
        -dcn DCON [DEC]: specify declination convention, default is #1 below
            if DCON = 2, you must supply the declination correction
        -BCN don't correct bedding_dip_dir for magnetic declination -already corrected
        -ncn NCON:  specify naming convention: default is #1 below
        -a: averages all bedding poles and uses average for all samples: default is NO
        -gmt HRS:  specify hours to subtract from local time to get GMT: default is 0
        -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
        -DM: specify data model (2 or 3).  Default: 3.  Will output to the appropriate format.

        Orientation convention:
            Samples are oriented in the field with a "field arrow" and measured in the laboratory with a "lab arrow". The lab arrow is the positive X direction of the right handed coordinate system of the specimen measurements. The lab and field arrows may  not be the same. In the MagIC database, we require the orientation (azimuth and plunge) of the X direction of the measurements (lab arrow). Here are some popular conventions that convert the field arrow azimuth (mag_azimuth in the orient.txt file) and dip (field_dip in orient.txt) to the azimuth and plunge  of the laboratory arrow (sample_azimuth and sample_dip in er_samples.txt). The two angles, mag_azimuth and field_dip are explained below.

            [1] Standard Pomeroy convention of azimuth and hade (degrees from vertical down)
                 of the drill direction (field arrow).  lab arrow azimuth= sample_azimuth = mag_azimuth;
                 lab arrow dip = sample_dip =-field_dip. i.e. the lab arrow dip is minus the hade.
            [2] Field arrow is the strike  of the plane orthogonal to the drill direction,
                 Field dip is the hade of the drill direction.  Lab arrow azimuth = mag_azimuth-90
                 Lab arrow dip = -field_dip
            [3] Lab arrow is the same as the drill direction;
                 hade was measured in the field.
                 Lab arrow azimuth = mag_azimuth; Lab arrow dip = 90-field_dip
            [4] lab azimuth and dip are same as mag_azimuth, field_dip : use this for unoriented samples too
            [5] Same as AZDIP convention explained below -
                azimuth and inclination of the drill direction are mag_azimuth and field_dip;
                lab arrow is as in [1] above.
                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:
            [1] Use the IGRF value at the lat/long and date supplied [default]
            [2] Will supply declination correction
            [3] mag_az is already corrected in file
            [4] Correct mag_az but not bedding_dip_dir

         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
            [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 er_samples.txt and er_sites.txt (or samples.txt and sites.txt if using data model 3.0)
            - this will overwrite any existing files
    """
    args = sys.argv
    if "-h" in args:
        print(main.__doc__)
        sys.exit()
    else:
        info = [['WD', False, '.'], ['ID', False, ''], ['f', False, 'orient.txt'],
                ['app', False, False], ['ocn', False, 1], ['dcn', False, 1],
                ['BCN', False, True], ['ncn', False, '1'], ['gmt', False, 0],
                ['mcd', False, ''], ['a', False, False], ['DM', False, 3]]

        #output_dir_path, input_dir_path, orient_file, append, or_con, dec_correction_con, samp_con, hours_from_gmt, method_codes, average_bedding
        # leave off -Fsa, -Fsi b/c defaults in command_line_extractor
        dataframe = extractor.command_line_dataframe(info)
        checked_args = extractor.extract_and_check_args(args, dataframe)
        output_dir_path, input_dir_path, orient_file, append, or_con, dec_correction_con, bed_correction, samp_con, hours_from_gmt, method_codes, average_bedding, samp_file, site_file, data_model = extractor.get_vars(['WD', 'ID', 'f', 'app', 'ocn', 'dcn', 'BCN', 'ncn', 'gmt', 'mcd', 'a', 'Fsa', 'Fsi', 'DM'], checked_args)
        if input_dir_path == '.':
            input_dir_path = output_dir_path

        if not isinstance(dec_correction_con, int):
            if len(dec_correction_con) > 1:
                dec_correction = int(dec_correction_con.split()[1])
                dec_correction_con = int(dec_correction_con.split()[0])
            else:
                dec_correction = 0
        else:
            dec_correction = 0

        ipmag.orientation_magic(or_con, dec_correction_con, dec_correction, bed_correction, samp_con, hours_from_gmt, method_codes, average_bedding, orient_file, samp_file, site_file, output_dir_path, input_dir_path, append, data_model)


Instruction:
Write a Python 3 script to
add items and or update existing items in grid

Response:
def add_items(self, items_list, incl_pmag=True, incl_parents=True):
        """
        Add items and/or update existing items in grid
        """
        num_rows = self.GetNumberRows()
        current_grid_rows = [self.GetCellValue(num, 0) for num in range(num_rows)]
        er_data = {item.name: item.er_data for item in items_list}
        pmag_data = {item.name: item.pmag_data for item in items_list}
        items_list = sorted(items_list, key=lambda item: item.name)
        for item in items_list[:]:
            if item.name in current_grid_rows:
                pass
            else:
                self.add_row(item.name, item)
        self.add_data(er_data)#, pmag=False)
        if incl_pmag:
            self.add_data(pmag_data, pmag=True)
        if incl_parents:
            self.add_parents()


Instruction:
Create a Python 3 function to
add a row to the grid

Response:
def add_row(self, label='', item=''):
        """
        Add a row to the grid
        """
        self.AppendRows(1)
        last_row = self.GetNumberRows() - 1
        self.SetCellValue(last_row, 0, str(label))
        self.row_labels.append(label)
        self.row_items.append(item)


Instruction:
Write a Python 3 function for
removing a row from the grid.

Response:
def remove_row(self, row_num=None):
        """
        Remove a row from the grid
        """
        #DeleteRows(self, pos, numRows, updateLabel
        if not row_num and row_num != 0:
            row_num = self.GetNumberRows() - 1
        label = self.GetCellValue(row_num, 0)
        self.DeleteRows(pos=row_num, numRows=1, updateLabels=True)

        # remove label from row_labels
        try:
            self.row_labels.remove(label)
        except ValueError:
            # if label name hasn't been saved yet, simply truncate row_labels
            self.row_labels = self.row_labels[:-1]
        self.row_items.pop(row_num)
        if not self.changes:
            self.changes = set()
        self.changes.add(-1)
        # fix #s for rows edited:
        self.update_changes_after_row_delete(row_num)


Instruction:
Can you create a Python 3 function that
adds a correctly formatted drop - down menu for given col_label.

Response:
def add_drop_down(self, col_number, col_label):
        """
        Add a correctly formatted drop-down-menu for given col_label, if required.
        Otherwise do nothing.
        """
        if col_label in ['magic_method_codes', 'magic_method_codes++']:
            self.add_method_drop_down(col_number, col_label)
        if col_label in vocab.possible_vocabularies:
            if col_number not in list(self.choices.keys()): # if not already assigned above
                self.grid.SetColLabelValue(col_number, col_label + "**") # mark it as using a controlled vocabulary
                url = 'http://api.earthref.org/MagIC/vocabularies/{}.json'.format(col_label)
                controlled_vocabulary = pd.io.json.read_json(url)
                stripped_list = []
                for item in controlled_vocabulary[col_label][0]:
                    try:
                        stripped_list.append(str(item['item']))
                    except UnicodeEncodeError:
                        # skips items with non ASCII characters
                        pass
                #stripped_list = [item['item'] for item in controlled_vocabulary[label][0]]

                if len(stripped_list) > 100:
                # split out the list alphabetically, into a dict of lists {'A': ['alpha', 'artist'], 'B': ['beta', 'beggar']...}
                    dictionary = {}
                    for item in stripped_list:
                        letter = item[0].upper()
                        if letter not in list(dictionary.keys()):
                            dictionary[letter] = []
                        dictionary[letter].append(item)

                    stripped_list = dictionary

                two_tiered = True if isinstance(stripped_list, dict) else False
                self.choices[col_number] = (stripped_list, two_tiered)


Instruction:
Write a Python 3 function for
adding drop - down - menu options for magic_method_codes columns

Response:
def add_method_drop_down(self, col_number, col_label):
        """
        Add drop-down-menu options for magic_method_codes columns
        """
        if self.data_type == 'age':
            method_list = vocab.age_methods
        elif '++' in col_label:
            method_list = vocab.pmag_methods
        elif self.data_type == 'result':
            method_list = vocab.pmag_methods
        else:
            method_list = vocab.er_methods
        self.choices[col_number] = (method_list, True)


Instruction:
Can you implement a function in Python 3 that
creates a popup menu when user clicks on the column.

Response:
def on_left_click(self, event, grid, choices):
        """
        creates popup menu when user clicks on the column
        if that column is in the list of choices that get a drop-down menu.
        allows user to edit the column, but only from available values
        """
        color = self.grid.GetCellBackgroundColour(event.GetRow(), event.GetCol())
        # allow user to cherry-pick cells for editing.  gets selection of meta key for mac, ctrl key for pc
        if event.ControlDown() or event.MetaDown():
            row, col = event.GetRow(), event.GetCol()
            if (row, col) not in self.dispersed_selection:
                self.dispersed_selection.append((row, col))
                self.grid.SetCellBackgroundColour(row, col, 'light blue')
            else:
                self.dispersed_selection.remove((row, col))
                self.grid.SetCellBackgroundColour(row, col, color)# 'white'
            self.grid.ForceRefresh()
            return
        if event.ShiftDown(): # allow user to highlight multiple consecutive cells in a column
            previous_col = self.grid.GetGridCursorCol()
            previous_row = self.grid.GetGridCursorRow()
            col = event.GetCol()
            row = event.GetRow()
            if col != previous_col:
                return
            else:
                if row > previous_row:
                    row_range = list(range(previous_row, row+1))
                else:
                    row_range = list(range(row, previous_row+1))
            for r in row_range:
                self.grid.SetCellBackgroundColour(r, col, 'light blue')
                self.selection.append((r, col))
            self.grid.ForceRefresh()
            return

        selection = False

        if self.dispersed_selection:
            is_dispersed = True
            selection = self.dispersed_selection

        if self.selection:
            is_dispersed = False
            selection = self.selection

        try:
            col = event.GetCol()
            row = event.GetRow()
        except AttributeError:
            row, col = selection[0][0], selection[0][1]

        self.grid.SetGridCursor(row, col)

        if col in list(choices.keys()): # column should have a pop-up menu
            menu = wx.Menu()
            two_tiered = choices[col][1]
            choices = choices[col][0]
            if not two_tiered: # menu is one tiered
                if 'CLEAR cell of all values' not in choices:
                    choices.insert(0, 'CLEAR cell of all values')
                for choice in choices:
                    if not choice:
                        choice = " " # prevents error if choice is an empty string
                    menuitem = menu.Append(wx.ID_ANY, str(choice))
                    self.window.Bind(wx.EVT_MENU, lambda event: self.on_select_menuitem(event, grid, row, col, selection), menuitem)
                self.show_menu(event, menu)
            else: # menu is two_tiered
                clear = menu.Append(-1, 'CLEAR cell of all values')
                self.window.Bind(wx.EVT_MENU, lambda event: self.on_select_menuitem(event, grid, row, col, selection), clear)
                for choice in sorted(choices.items()):
                    submenu = wx.Menu()
                    for item in choice[1]:
                        menuitem = submenu.Append(-1, str(item))
                        self.window.Bind(wx.EVT_MENU, lambda event: self.on_select_menuitem(event, grid, row, col, selection), menuitem)
                    menu.Append(-1, choice[0], submenu)
                self.show_menu(event, menu)

        if selection:
            # re-whiten the cells that were previously highlighted
            for row, col in selection:
                self.grid.SetCellBackgroundColour(row, col, self.col_color)
            self.dispersed_selection = []
            self.selection = []
            self.grid.ForceRefresh()