def On_close_MagIC_dialog(self, dia):
        """
        Function called after save high level pmag table dialog. It
        calculates VGPs, high level means, and saves them the hard drive.

        Parameters
        ----------
        dia : save higher level pmag tables
        """

        def add_missing_ages(df):
            """
            Take a dataframe and add min/max age, age, age_sigma, age_units.
            Use values gained from dialog, but don't overwrite values already
            in the dataframe.
            """
            age_columns = df.columns[df.columns.str.startswith('age')]
            for col, value in {'age_high': max_age, 'age_low': min_age,
                            'age': age, 'age_sigma': age_sigma, 'age_unit': age_units}.items():
                if cb.not_null(value):
                    if col in age_columns:
                        df[col] = np.where(df[col].apply(cb.not_null), df[col], value)
                    else:
                        df[col] = value
            return df


        if dia.cb_acceptance_criteria.GetValue():
            use_criteria = 'existing'
        else:
            use_criteria = 'none'

        # -- coordinate system
        if dia.rb_spec_coor.GetValue():
            coord = "s"
        elif dia.rb_geo_coor.GetValue():
            coord = "g"
        elif dia.rb_tilt_coor.GetValue():
            coord = "t"
        elif dia.rb_geo_tilt_coor.GetValue():
            coord = "b"
        else:
            coord = "s"

        # -- default age options
        DefaultAge = ["none"]
        add_ages = dia.add_ages.GetValue()
        if add_ages:
            age_units = dia.default_age_unit.GetValue()
            min_age = dia.default_age_min.GetValue()
            max_age = dia.default_age_max.GetValue()
            age = dia.default_age.GetValue()
            age_sigma = dia.default_age_sigma.GetValue()
            if (min_age and max_age) or age:
                # enough age data provided
                pass
            else:
                go_on = self.user_warning("Not enough age data provided (you must provide lower and upper bound, or age).\nPress OK to skip ages for now, or cancel to end this process.")
                if not go_on:
                    self.user_warning("Aborting, please try again.", caption="Message")
                    return
                add_ages = False

            if min_age and max_age:
                DefaultAge = [min_age, max_age, age_units]

        # -- sample mean
        avg_directions_by_sample = False
        if dia.cb_sample_mean.GetValue():
            avg_directions_by_sample = True

        vgps_level = 'site'
        if dia.cb_sample_mean_VGP.GetValue():
            vgps_level = 'sample'

        # -- site mean

        if dia.cb_site_mean.GetValue():
            pass

        # -- location mean
        avg_by_polarity = False
        if dia.cb_location_mean.GetValue():
            avg_by_polarity = True

        if self.data_model == 3.0:
            # update or add age data to the sites table, but don't overwrite existing data
            if add_ages:
                site_df = self.con.tables['sites'].df
                self.con.tables['sites'].df = add_missing_ages(site_df)
                self.con.write_table_to_file("sites")

            # set some variables
            priorities = ['DA-AC-ARM', 'DA-AC-TRM']
            for p in priorities:
                if not p.startswith('DA-AC-'):
                    p = 'DA-AC-'+p
            # translate coord into coords
            if coord == 's':
                coords = ['-1']
            elif coord == 'g':
                coords = ['0']
            elif coord == 't':
                coords = ['100']
            elif coord == 'b':
                coords = ['0', '100']
            else:
                coords = ['-1']

            if vgps_level == 'sample':
                vgps = 1  # save sample level VGPS/VADMs
            else:
                vgps = 0  # site level

            nositeints = 0
            version_num = pmag.get_version()
            get_model_lat = 0  # skips VADM calculation entirely
            Dcrit, Icrit, nocrit = 0, 0, 0  # default criteria input

            # still broken (needs translation or determination of translation necessity)
            if use_criteria == 'none':
                Dcrit, Icrit, nocrit = 1, 1, 1  # no selection criteria
                crit_data = pmag.default_criteria(nocrit)
            elif use_criteria == 'existing':
                crit_data = self.read_criteria_file()
                if crit_data == None:
                    crit_data = pmag.default_criteria(nocrit)
                    print(
                        "No acceptance criteria found in criteria.txt defualt PmagPy criteria used instead")
                else:
                    print("Acceptance criteria from criteria.txt used")
            else:
                # use default criteria
                crit_data = pmag.default_criteria(nocrit)
                print("PmagPy default criteria used")

            accept = {}
            for critrec in crit_data:
                if type(critrec) != dict:
                    continue
                for key in list(critrec.keys()):
                    # need to migrate specimen_dang to specimen_int_dang for intensity data using old format
                    if 'IE-SPEC' in list(critrec.keys()) and 'specimen_dang' in list(critrec.keys()) and 'specimen_int_dang' not in list(critrec.keys()):
                        critrec['specimen_int_dang'] = critrec['specimen_dang']
                        del critrec['specimen_dang']
                    # need to get rid of ron shaars sample_int_sigma_uT
                    if 'sample_int_sigma_uT' in list(critrec.keys()):
                        critrec['sample_int_sigma'] = '%10.3e' % (
                            eval(critrec['sample_int_sigma_uT'])*1e-6)
                    if key not in list(accept.keys()) and critrec[key] != '':
                        accept[key] = critrec[key]

            if use_criteria == 'default':
                pmag.magic_write(critout, [accept], 'pmag_criteria')
                print("\n Pmag Criteria stored in ", critout, '\n')

            if 'specimens' not in self.con.tables:
                self.user_warning(
                    "No specimen interpretations found in the current contribution samples, sites, and locations cannot be exported, aborting")
                return
            spec_df = self.con.tables['specimens'].df
            if 'sites' not in self.con.tables:
                self.con.add_empty_magic_table('sites')
            site_df = self.con.tables['sites'].df
            SiteNFO = site_df.to_dict("records")
            Data = spec_df.to_dict("records")

            comment = ""
            orient = list(spec_df[spec_df['dir_tilt_correction'].notnull(
            )]['dir_tilt_correction'].drop_duplicates())
            samples = sorted(list(spec_df['sample'].dropna().drop_duplicates()))
            sites = sorted(list(spec_df['site'].dropna().drop_duplicates()))
            locations = sorted(list(spec_df['location'].dropna().drop_duplicates()))
            Comps = sorted(
                list(spec_df[spec_df['dir_comp'].notnull()]['dir_comp'].drop_duplicates()))
            Comps = [c for c in Comps if type(c) == str]
            # find all the sites with height info.
            height_info = pmag.get_dictitem(SiteNFO, 'height', '', 'F')

            nocorrection = ['DA-NL', 'DA-AC', 'DA-CR']
            SpecInts = []
            # retrieve specimens with intensity data
            IntData = pmag.get_dictitem(Data, 'int_abs', '', 'F')
            if nocrit == 0:  # use selection criteria
                for rec in IntData:  # do selection criteria
                    kill = pmag.grade(
                        rec, accept, 'specimen_int', data_model=3.0)
                    if len(kill) == 0:
                        # intensity record to be included in sample, site calculations
                        SpecInts.append(rec)
            else:
                # take everything - no selection criteria
                SpecInts = IntData[:]
            # check for required data adjustments
            if len(nocorrection) > 0 and len(SpecInts) > 0:
                for cor in nocorrection:
                    # exclude the corrections not specified for inclusion
                    SpecInts = pmag.get_dictitem(
                        SpecInts, 'method_codes', cor, 'not')
            # take top priority specimen of its name in remaining specimens (only one per customer)
            PrioritySpecInts = []
            # get list of uniq specimen names
            specimens = pmag.get_specs(SpecInts)
            for spec in specimens:
                # all the records for this specimen
                ThisSpecRecs = pmag.get_dictitem(
                    SpecInts, 'specimen', spec, 'T')
                if len(ThisSpecRecs) == 1:
                    PrioritySpecInts.append(ThisSpecRecs[0])
                elif len(ThisSpecRecs) > 1:  # more than one
                    prec = []
                    for p in priorities:
                        # all the records for this specimen
                        ThisSpecRecs = pmag.get_dictitem(
                            SpecInts, 'method_codes', p, 'has')
                        if len(ThisSpecRecs) > 0:
                            prec.append(ThisSpecRecs[0])
                            PrioritySpecInts.append(
                                prec[0])  # take the best one
            SpecInts = PrioritySpecInts  # this has the first specimen record

            # apply criteria to directional data
            # retrieve specimens with directed lines and planes and some measuremnt data
            Ns = spec_df[spec_df['dir_n_measurements']
                         != ''].to_dict("records")
            SpecDirs = []
            if nocrit != 1:  # use selection criteria
                for rec in Ns:  # look through everything with specimen_n for "good" data
                    kill = pmag.grade(
                        rec, accept, 'specimen_dir', data_model=3.0)
                    if len(kill) == 0:  # nothing killed it
                        SpecDirs.append(rec)
            else:  # no criteria
                SpecDirs = Ns[:]  # take them all

            # list of all sample data and list of those that pass the DE-SAMP criteria
            PmagSamps, SampDirs = [], []
            PmagSites = []  # list of all site data
            SampInts = []
            renamelnp = {'R': 'dir_r', 'n': 'dir_n_samples', 'n_total': 'dir_n_specimens', 'alpha95': 'dir_alpha95',
                         'n_lines': 'dir_n_specimens_lines', 'K': 'dir_k', 'dec': 'dir_dec', 'n_planes': 'dir_n_specimens_planes', 'inc': 'dir_inc'}
            for samp in samples:  # run through the sample names
                if not avg_directions_by_sample:
                    break
                # get all the directional data for this sample
                SampDir = pmag.get_dictitem(SpecDirs, 'sample', samp, 'T')
                if len(SampDir) <= 0:
                    continue  # if no directions
                for coord in coords:  # step through desired coordinate systems
                    # get all the directions for this sample
                    CoordDir = pmag.get_dictitem(
                        SampDir, 'dir_tilt_correction', coord, 'T')
                    if len(CoordDir) <= 0:
                        continue  # no data for this coordinate system
                    for comp in Comps:
                        # get all directions from this component
                        CompDir = pmag.get_dictitem(
                            CoordDir, 'dir_comp', comp, 'T')
                        CompDir = [
                            x for x in CompDir if 'result_quality' in x and x['result_quality'] == 'g']
                        if len(CompDir) <= 0:
                            continue  # no data for comp
                        PmagSampRec = pmag.dolnp3_0(CompDir)
                        for k, v in list(renamelnp.items()):
                            if k in PmagSampRec:
                                PmagSampRec[v] = PmagSampRec[k]
                                del PmagSampRec[k]
                        # decorate the sample record
                        PmagSampRec["location"] = CompDir[0]['location']
                        PmagSampRec["site"] = CompDir[0]['site']
                        PmagSampRec["sample"] = samp
                        PmagSampRec["citations"] = "This study"
                        PmagSampRec['software_packages'] = version_num + \
                            ': demag_gui.v.3.0'
                        if CompDir[0]['result_quality'] == 'g':
                            PmagSampRec['result_quality'] = 'g'
                        else:
                            PmagSampRec['result_quality'] = 'b'
                        if nocrit != 1:
                            PmagSampRec['criteria'] = "ACCEPT"
                        site_height = pmag.get_dictitem(
                            height_info, 'site', PmagSampRec['site'], 'T')
                        if len(site_height) > 0:
                            # add in height if available
                            PmagSampRec["height"] = site_height[0]['height']
                        PmagSampRec['dir_comp_name'] = comp
                        PmagSampRec['dir_tilt_correction'] = coord
                        specs = [d['specimen'] for d in CompDir]
                        if 'dir_n_specimens' not in PmagSampRec:
                            PmagSampRec['dir_n_specimens'] = len(specs)
                        # get a list of the specimen names used
                        PmagSampRec['specimens'] = reduce(
                            lambda x, y: str(x)+':'+str(y), specs)
                        # get old method codes
                        prev_meth_codes = self.con.tables['samples'].df.loc[samp]['method_codes']
                        # get a list of the methods used
                        new_meth_codes = pmag.get_list(CompDir, 'method_codes')
                        if isinstance(prev_meth_codes, Series):
                            merged_meths = self.merge_meth_codes(
                                prev_meth_codes.iloc[0], new_meth_codes)
                        else:
                            merged_meths = self.merge_meth_codes(
                                prev_meth_codes, new_meth_codes)
                        PmagSampRec['method_codes'] = merged_meths
                        if nocrit != 1:  # apply selection criteria
                            kill = pmag.grade(
                                PmagSampRec, accept, 'sample_dir', data_model=3.0)
                        else:
                            kill = []
                        if len(kill) > 0:
                            PmagSampRec['result_quality'] = 'b'
                        else:
                            SampDirs.append(PmagSampRec)
                        if vgps == 1:  # if sample level VGP info desired, do that now
                            try:
                                PmagResRec = pmag.getsampVGP(
                                    PmagSampRec, SiteNFO, data_model=self.data_model)
                            except KeyError:
                                print(
                                    ("no lat lon data for sample %s skipping VGP calculation" % samp))
                                PmagResRec = ""
                            if PmagResRec != "":
                                for k in ['vgp_dp', 'vgp_dm', 'vgp_lat', 'vgp_lon']:
                                    PmagSampRec[k] = PmagResRec[k]
                        PmagSamps.append(PmagSampRec)

            # removed average_all_components check because demag GUI never averages directional components
            # removed intensity average portion as demag GUI has no need of this also cause translating this is a bitch

            if len(PmagSamps) > 0:
                if 'samples' not in self.con.tables:
                    self.con.add_empty_magic_table('samples')
                for dc in ['magic_method_codes']:
                    if dc in self.con.tables['samples'].df:
                        del self.con.tables['samples'].df[dc]
                samps_df = DataFrame(PmagSamps)
                samps_df = samps_df.set_index('sample')
                samps_df['sample'] = samps_df.index
                nsdf = self.con.tables['samples'].merge_dfs(samps_df)
                if not vgps == 1:
                    nsdf.drop([col for col in nsdf.columns if type(
                        col) == str and col.startswith('vgp')], axis=1, inplace=True)
                nsdf = nsdf.reindex_axis(sorted(nsdf.columns), axis=1)
                self.con.tables['samples'].df = nsdf
                self.con.tables['samples'].write_magic_file(dir_path=self.WD)

            # create site averages from specimens or samples as specified
            for site in sites:
                for coord in coords:
                    if dia.combo_site_mean.GetValue() == 'samples' and avg_directions_by_sample:
                        # if sample averages at site level desired
                        key, comp_key, dirlist = 'sample', 'dir_comp_name', SampDirs
                    else:
                        # if specimen averages at site level desired
                        key, comp_key, dirlist = 'specimen', 'dir_comp', SpecDirs
                    # get all the sites with  directions
                    tmp = pmag.get_dictitem(dirlist, 'site', site, 'T')
                    tmp1 = pmag.get_dictitem(
                        tmp, 'dir_tilt_correction', coord, 'T', float_to_int=True)
                    # fish out site information (lat/lon, etc.)
                    sd = pmag.get_dictitem(SiteNFO, 'site', site, 'T')
                    if len(sd) <= 0:  # no data for this site
                        print(
                            ('site information not found in sites.txt for site, %s. skipping.' % site))
                        continue
                    for comp in Comps:
                        # get all components comp
                        siteD = pmag.get_dictitem(tmp1, comp_key, comp, 'T')
                        # remove bad data from means
                        siteD = [
                            x for x in siteD if 'result_quality' in x and x['result_quality'] == 'g']
                        if len(siteD) <= 0:
                            # print("no data for comp %s in site %s. skipping"%(comp,site))
                            continue
                        PmagSiteRec = PmagSampRec = pmag.dolnp3_0(
                            siteD)  # get an average for this site
                        for k, v in list(renamelnp.items()):
                            if k in PmagSiteRec:
                                PmagSiteRec[v] = PmagSiteRec[k]
                                del PmagSiteRec[k]
                        # decorate the site record
                        PmagSiteRec['dir_comp_name'] = comp
                        PmagSiteRec["location"] = siteD[0]['location']
                        PmagSiteRec["site"] = siteD[0]['site']
                        PmagSiteRec['dir_tilt_correction'] = coord
                        PmagSiteRec['samples'] = pmag.get_list(siteD, 'sample')
                        if dia.combo_site_mean.GetValue() == 'samples' and avg_directions_by_sample:
                            PmagSiteRec['specimens'] = pmag.get_list(
                                siteD, 'specimens')
                        else:
                            PmagSiteRec['specimens'] = pmag.get_list(
                                siteD, 'specimen')
                        if 'dir_n_samples' not in list(PmagSiteRec.keys()):
                            PmagSiteRec['dir_n_samples'] = len(
                                PmagSiteRec['samples'].split(':'))
                        if 'dir_n_specimens' not in list(PmagSiteRec.keys()):
                            PmagSiteRec['dir_n_specimens'] = len(
                                PmagSiteRec['specimens'].split(':'))
                        # determine the demagnetization code (DC3,4 or 5) for this site
                        AFnum = len(pmag.get_dictitem(
                            siteD, 'method_codes', 'LP-DIR-AF', 'has'))
                        Tnum = len(pmag.get_dictitem(
                            siteD, 'method_codes', 'LP-DIR-T', 'has'))
                        DC = 3
                        if AFnum > 0:
                            DC += 1
                        if Tnum > 0:
                            DC += 1
                        PmagSiteRec['method_codes'] = pmag.get_list(
                            siteD, 'method_codes')+':' + 'LP-DC'+str(DC)
                        PmagSiteRec['method_codes'].strip(":")

                        PmagSiteRec["citations"] = "This study"
                        PmagSiteRec['software_packages'] = version_num + \
                            ': demag_gui.v.3.0'

                        # here we need to grab ages from sites or ages
                        site_age_rec = Series()
                        if 'ages' in self.con.tables:
                            ages_df = self.con.tables['ages'].df
                            if 'site' in ages_df.columns:
                                site_age_records = ages_df[ages_df['site'] == site]
                                if len(site_age_records):
                                    if isinstance(site_age_records, Series):
                                        site_age_rec = site_age_records
                                    else:
                                        site_age_rec = site_age_records.iloc[0]
                        if not len(site_age_rec):
                            sites_df = self.con.tables['sites'].df
                            site_age_records = sites_df.loc[site]
                            if len(site_age_records):
                                if isinstance(site_age_records, Series):
                                    site_age_rec = site_age_records
                                else:
                                    site_age_rec = site_age_records.iloc[0]

                        PmagSiteRec['criteria'] = 'ACCEPT'
                        if 'dir_n_specimens_lines' in list(PmagSiteRec.keys()) and 'dir_n_specimens_planes' in list(PmagSiteRec.keys()) and PmagSiteRec['dir_n_specimens_lines'] != "" and PmagSiteRec['dir_n_specimens_planes'] != "":
                            if int(PmagSiteRec["dir_n_specimens_planes"]) > 0:
                                PmagSiteRec["method_codes"] = PmagSiteRec['method_codes']+":DE-FM-LP"
                            elif int(PmagSiteRec["dir_n_specimens_lines"]) > 2:
                                PmagSiteRec["method_codes"] = PmagSiteRec['method_codes']+":DE-FM"

                        site_height = pmag.get_dictitem(
                            height_info, 'site', site, 'T')
                        if len(site_height) > 0:
                            PmagSiteRec["height"] = site_height[0]['height']
                        if '0' in PmagSiteRec['dir_tilt_correction'] and "DA-DIR-GEO" not in PmagSiteRec['method_codes']:
                            PmagSiteRec['method_codes'] = PmagSiteRec['method_codes']+":DA-DIR-GEO"
                        if '100' in PmagSiteRec['dir_tilt_correction'] and "DA-DIR-TILT" not in PmagSiteRec['method_codes']:
                            PmagSiteRec['method_codes'] = PmagSiteRec['method_codes'] + \
                                ":DA-DIR-TILT"
                        PmagSiteRec['dir_polarity'] = ""
# assign polarity based on angle of pole lat to spin axis - may want to re-think this sometime

                        if dia.cb_site_mean_VGP.GetValue():
                            dec = float(PmagSiteRec["dir_dec"])
                            inc = float(PmagSiteRec["dir_inc"])
                            if 'dir_alpha95' in list(PmagSiteRec.keys()) and PmagSiteRec['dir_alpha95'] != "":
                                a95 = float(PmagSiteRec["dir_alpha95"])
                            else:
                                a95 = 180.
                            # fish out site information (lat/lon, etc.)
                            sitedat = [x for x in pmag.get_dictitem(
                                SiteNFO, 'site', PmagSiteRec['site'], 'T') if x['lat'] != None and x['lon'] != None]
                            if len(sitedat) != 0:
                                sitedat = sitedat[0]
                            else:
                                sitedat = {}
                            try:
                                PmagSiteRec['lat'] = float(sitedat['lat'])
                                PmagSiteRec['lon'] = float(sitedat['lon'])
                                lat, lon = PmagSiteRec['lat'], PmagSiteRec['lon']
                                calculate = True
                            except (KeyError, ValueError, TypeError) as e:
                                calculate = False
                                ui_dialog = demag_dialogs.user_input(self, ['Latitude', 'Longitude'], parse_funcs=[
                                                                     float, float], heading="Missing Latitude or Longitude data for site: %s" % site)
                                self.show_dlg(ui_dialog)
                                ui_data = ui_dialog.get_values()
                                if ui_data[0]:
                                    PmagSiteRec['lat'] = ui_data[1]['Latitude']
                                    PmagSiteRec['lon'] = ui_data[1]['Longitude']
                                    lat, lon = PmagSiteRec['lat'], PmagSiteRec['lon']
                                    calculate = True
                                else:
                                    self.user_warning(
                                        "insuffecent data provided skipping VGP calculation for site %s and comp %s" % (site, comp))
                            if calculate:
                                plong, plat, dp, dm = pmag.dia_vgp(
                                    dec, inc, a95, lat, lon)  # get the VGP for this site
                                PmagSiteRec["vgp_lat"] = '%7.1f ' % (plat)
                                PmagSiteRec["vgp_lon"] = '%7.1f ' % (plong)
                                PmagSiteRec["vgp_dp"] = '%7.1f ' % (dp)
                                PmagSiteRec["vgp_dm"] = '%7.1f ' % (dm)

                                angle = pmag.angle([0, 0], [0, (90-plat)])
                                if angle <= 55.:
                                    PmagSiteRec["dir_polarity"] = 'n'
                                if angle > 55. and angle < 125.:
                                    PmagSiteRec["dir_polarity"] = 't'
                                if angle >= 125.:
                                    PmagSiteRec["dir_polarity"] = 'r'

                        kill = pmag.grade(PmagSiteRec, accept, 'site_dir')
                        if len(kill) > 0:
                            PmagSiteRec['result_quality'] = 'b'
                        else:
                            PmagSiteRec['result_quality'] = 'g'

                        # Carry over data from previous sites
                        prev_dat = pmag.get_dictitem(
                            SiteNFO, 'site', PmagSiteRec['site'], 'T')
                        if len(prev_dat) != 0:
                            for ndd in set(PmagSiteRec.keys()).symmetric_difference(set(prev_dat[0].keys())):
                                sitedat = [
                                    x for x in prev_dat if ndd in x and x[ndd] != None]
                                if len(sitedat) != 0:
                                    sitedat = sitedat[0]
                                else:
                                    continue
                                PmagSiteRec[ndd] = sitedat[ndd]

                        PmagSites.append(PmagSiteRec)

            if len(PmagSites) > 0:
                if 'sites' not in self.con.tables:
                    self.con.tables.add_empty_magic_table('sites')
                sites_df = DataFrame(PmagSites)
                if 'tilt_correction' in sites_df.columns:
                    sites_df.drop('tilt_correction', axis=1, inplace=True)
                sites_df = sites_df.set_index('site')
                sites_df['site'] = sites_df.index
                nsdf = self.con.tables['sites'].merge_dfs(sites_df)
                if not dia.cb_site_mean_VGP.GetValue():
                    nsdf.drop([col for col in nsdf.columns if type(
                        col) == str and col.startswith('vgp')], axis=1, inplace=True)
                nsdf = nsdf.reindex_axis(sorted(nsdf.columns), axis=1)
                self.con.tables['sites'].df = nsdf
                self.con.tables['sites'].write_magic_file(dir_path=self.WD)

            # location mean section
            PmagLocs = []
            for location in locations:
                if not avg_by_polarity:
                    break
                locrecs = pmag.get_dictitem(
                    PmagSites, 'location', location, 'T')
                if len(locrecs) < 2:
                    print(("no data for location %s" % location))
                    continue
                for coord in coords:
                    # find the tilt corrected data
                    coordrecs = pmag.get_dictitem(
                        locrecs, 'dir_tilt_correction', coord, 'T')
                    if len(coordrecs) < 2:
                        print(
                            ("not enough data of %s percent tilt corrected data in sites to calculate locations mean or vgp" % coord))
                        continue
                    for comp in Comps:
                        # fish out all of the component
                        crecs = pmag.get_dictitem(
                            coordrecs, 'dir_comp_name', comp, 'T')
                        if len(crecs) < 2:
                            print(
                                ("insuffecent data for comp %s when calculating location" % comp))
                            continue
                        precs = []
                        for rec in crecs:
                            prec = {'dec': rec['dir_dec'], 'inc': rec['dir_inc'],
                                    'name': rec['site'], 'loc': rec['location']}
                            prec = {k: v if v != None else 'None' for k,
                                    v in list(prec.items())}
                            precs.append(prec)
                        # calculate average by polarity
                        polpars = pmag.fisher_by_pol(precs)
                        # hunt through all the modes (normal=A, reverse=B, all=ALL)
                        for mode in list(polpars.keys()):
                            PolRes = {}
                            PolRes['citations'] = 'This study'
                            PolRes["result_name"] = "Polarity Average: Polarity "+mode
                            PolRes["pole_comp_name"] = comp+':'+mode
                            PolRes["dir_dec"] = '%7.1f' % (
                                polpars[mode]['dec'])
                            PolRes["dir_inc"] = '%7.1f' % (
                                polpars[mode]['inc'])
                            PolRes["dir_n_sites"] = '%i' % (polpars[mode]['n'])
                            PolRes["dir_r"] = '%5.4f' % (polpars[mode]['r'])
                            PolRes["dir_k"] = '%6.0f' % (polpars[mode]['k'])
                            PolRes["dir_alpha95"] = '%7.1f' % (
                                polpars[mode]['alpha95'])
                            PolRes['sites'] = polpars[mode]['sites']
                            sites_dat = self.con.tables['sites'].df
                            for e in ['samples', 'specimens']:
                                PolRes[e] = reduce(lambda x, y: x+':'+y, [sites_dat.loc[site][e].iloc[0] if isinstance(
                                    sites_dat.loc[site][e], Series) else sites_dat.loc[site][e] for site in PolRes['sites'].split(':')])
                            PolRes['dir_n_samples'] = len(
                                PolRes['samples'].split(':'))
                            PolRes['dir_n_specimens'] = len(
                                PolRes['specimens'].split(':'))
                            PolRes['location'] = polpars[mode]['locs']
                            PolRes['software_packages'] = version_num + \
                                ': demag_gui.v.3.0'
                            PolRes['dir_tilt_correction'] = coord
                            if add_ages:
                                loc_rec = {}
                                if 'locations' in self.con.tables:
                                    locs_df = self.con.tables['locations'].df
                                    self.con.tables['locations'].df = add_missing_ages(locs_df)
                                    loc_recs = locs_df.loc[location]
                                    if len(loc_recs):
                                        if isinstance(loc_recs, Series):
                                            loc_rec = loc_recs
                                        else:
                                            loc_rec = loc_recs.iloc[0]
                                PolRes['age_high'] = loc_rec.get('age_high', max_age)
                                PolRes['age_low'] = loc_rec.get('age_low', min_age)
                                PolRes['age'] = loc_rec.get('age', age)
                                PolRes['age_sigma'] = loc_rec.get('age_sigma', age_sigma)
                                PolRes['age_unit'] = loc_rec.get('age_unit', age_units)
                            if dia.cb_location_mean_VGP.GetValue():
                                sucess_lat_lon_info = True
                                if 'locations' in self.con.tables:
                                    locs_dat = self.con.tables['locations'].df
                                    if 'lat_n' in locs_dat.columns:
                                        lat = locs_dat['lat_n'][location].iloc[0] if isinstance(
                                            locs_dat['lat_n'][location], Series) else locs_dat['lat_n'][location]
                                    elif 'lat_s' in locs_dat.columns:
                                        lat = locs_dat['lat_s'][location].iloc[0] if isinstance(
                                            locs_dat['lat_s'][location], Series) else locs_dat['lat_s'][location]
                                    else:
                                        sucess_lat_lon_info = False
                                    if 'lon_e' in locs_dat.columns:
                                        lon = locs_dat['lon_e'][location].iloc[0] if isinstance(
                                            locs_dat['lon_e'][location], Series) else locs_dat['lon_e'][location]
                                    elif 'lon_w' in locs_dat.columns:
                                        lon = locs_dat['lon_w'][location].iloc[0] if isinstance(
                                            locs_dat['lon_w'][location], Series) else locs_dat['lon_w'][location]
                                    else:
                                        sucess_lat_lon_info = False
                                if not sucess_lat_lon_info:
                                    ui_dialog = demag_dialogs.user_input(self, ['North Boundary Latitude', 'South Boundary Latitude', 'East Boundary Longitude', 'West Boundary Longitude'], parse_funcs=[
                                                                         float, float, float, float], heading="Missing Latitude or Longitude data for location %s please define the boundary of this region so VGP calculations can be preformed" % location)
                                    ui_data = ui_dialog.get_values()
                                    if ui_data[0]:
                                        PolRes['lat_n'] = ui_data[1]['North Boundary Latitude']
                                        PolRes['lat_s'] = ui_data[1]['South Boundary Latitude']
                                        PolRes['lon_e'] = ui_data[1]['East Boundary Longitude']
                                        PolRes['lon_w'] = ui_data[1]['West Boundary Longitude']
                                        lat, lon = PolRes['lat_n'], PolRes['lon_e']
                                        sucess_lat_lon_info = True
                                    else:
                                        self.user_warning(
                                            "insuffecent data provided skipping VGP calculation for location %s" % location)
                                try:
                                    dec, inc, a95, lat, lon = float(polpars[mode]['dec']), float(
                                        polpars[mode]['inc']), float(polpars[mode]['alpha95']), float(lat), float(lon)
                                except (UnboundLocalError, TypeError):
                                    print(
                                        "unable to obtain all data needed for VGP calculation, skipping")
                                    sucess_lat_lon_info = False
                                if sucess_lat_lon_info:
                                    # get the VGP for this pole component
                                    plong, plat, dp, dm = pmag.dia_vgp(
                                        dec, inc, a95, lat, lon)
                                    PolRes["pole_lat"] = '%7.1f ' % (plat)
                                    PolRes["pole_lon"] = '%7.1f ' % (plong)
                                    PolRes["pole_dp"] = '%7.1f ' % (dp)
                                    PolRes["pole_dm"] = '%7.1f ' % (dm)
                                    PolRes["pole_alpha95"] = PolRes['dir_alpha95']
                                    PolRes["pole_r"] = PolRes['dir_r']
                                    PolRes["pole_k"] = PolRes['dir_k']
                                    angle = pmag.angle([0, 0], [0, (90-plat)])
                                    if angle <= 55.:
                                        PolRes["dir_polarity"] = 'n'
                                    if angle > 55. and angle < 125.:
                                        PolRes["dir_polarity"] = 't'
                                    if angle >= 125.:
                                        PolRes["dir_polarity"] = 'r'

                            # fix not duplicating data
                            prev_dat = pmag.get_dictitem(locs_dat.to_dict(
                                'records'), 'location', location, 'T')
                            # merge method codes
                            methods = []
                            for prd in prev_dat:
                                if 'method_codes' not in list(prd.keys()) or prd['method_codes'] == None:
                                    continue
                                for mc in prd['method_codes'].split(':'):
                                    if mc not in methods:
                                        methods.append(mc)
                            if len(methods) > 1:
                                PolRes['method_codes'] = reduce(
                                    lambda x, y: x+':'+y, methods)
                            elif len(methods) > 0:
                                PolRes['method_codes'] = methods[0]
                            else:
                                PolRes['method_codes'] = ''
                            if len(prev_dat) != 0:
                                for ndd in set(PolRes.keys()).symmetric_difference(set(prev_dat[0].keys())):
                                    dat = [
                                        x for x in prev_dat if ndd in x and x[ndd] != None]
                                    if len(dat) != 0:
                                        dat = dat[0]
                                    else:
                                        continue
                                    PolRes[ndd] = dat[ndd]

                            PmagLocs.append(PolRes)

            if len(PmagLocs) > 0:
                locs_df = DataFrame(PmagLocs)
                locs_df = locs_df.set_index('location')
                locs_df['location'] = locs_df.index
                nsdf = self.con.tables['locations'].merge_dfs(locs_df)
                if not dia.cb_location_mean_VGP.GetValue():
                    nsdf.drop([col for col in nsdf.columns if type(col) == str and col.startswith(
                        'pole') and col != 'pol_comp_name'], axis=1, inplace=True)
                nsdf = nsdf.reindex_axis(sorted(nsdf.columns), axis=1)
                self.con.tables['locations'].df = nsdf
                self.con.tables['locations'].write_magic_file(dir_path=self.WD)

        else:
            for FILE in ['pmag_samples.txt', 'pmag_sites.txt', 'pmag_results.txt']:
                self.PmagRecsOld[FILE] = []
                try:
                    meas_data, file_type = pmag.magic_read(
                        os.path.join(self.WD, FILE))
                    print(("-I- Read old magic file  %s" %
                           os.path.join(self.WD, FILE)))
                    if FILE != 'pmag_specimens.txt':
                        os.remove(os.path.join(self.WD, FILE))
                        print(("-I- Delete old magic file  %s" %
                               os.path.join(self.WD, FILE)))
                except:
                    continue

            for rec in meas_data:
                if "magic_method_codes" in list(rec.keys()):
                    if "LP-DIR" not in rec['magic_method_codes'] and "DE-" not in rec['magic_method_codes']:
                        self.PmagRecsOld[FILE].append(rec)

            print(('coord', coord, 'vgps_level', vgps_level, 'DefaultAge', DefaultAge, 'avg_directions_by_sample',
                   avg_directions_by_sample, 'avg_by_polarity', avg_by_polarity, 'use_criteria', use_criteria))
            prev_cwd = os.getcwd()
            os.chdir(self.WD)
            ipmag.specimens_results_magic(coord=coord, vgps_level=vgps_level, DefaultAge=DefaultAge,
                                          avg_directions_by_sample=avg_directions_by_sample, avg_by_polarity=avg_by_polarity, use_criteria=use_criteria)
            os.chdir(prev_cwd)

            # reads new pmag tables, and merge the old lines:
            for FILE in ['pmag_samples.txt', 'pmag_sites.txt', 'pmag_results.txt']:
                pmag_data = []
                try:
                    pmag_data, file_type = pmag.magic_read(
                        os.path.join(self.WD, FILE))
                except:
                    pass
                if FILE in list(self.PmagRecsOld.keys()):
                    for rec in self.PmagRecsOld[FILE]:
                        pmag_data.append(rec)
                if len(pmag_data) > 0:
                    pmag_data_fixed = self.merge_pmag_recs(pmag_data)
                    pmag.magic_write(os.path.join(self.WD, FILE),
                                     pmag_data_fixed, FILE.split(".")[0])
                    print(("write new interpretations in %s\n" %
                           (os.path.join(self.WD, FILE))))

            # make pmag_criteria.txt if it does not exist
            if not os.path.isfile(os.path.join(self.WD, "pmag_criteria.txt")):
                Fout = open(os.path.join(self.WD, "pmag_criteria.txt"), 'w')
                Fout.write("tab\tpmag_criteria\n")
                Fout.write("er_citation_names\tpmag_criteria_code\n")
                Fout.write("This study\tACCEPT\n")

            self.update_pmag_tables()
            self.update_selection()

        TEXT = "interpretations saved"
        self.saved_dlg(TEXT)
        self.close_warning = False
Function called after save high level pmag table dialog. It
        calculates VGPs, high level means, and saves them the hard drive.

        Parameters
        ----------
        dia : save higher level pmag tables