docs: def on_menu_prepare_magic_results_tables(self, event):
          """
          Menubar --> File --> Save MagIC tables
          """
          # write a redo file
          try:
              self.on_menu_save_interpretation(None)
          except Exception as ex:
              print('-W-', ex)
              pass
          if self.data_model != 3:  # data model 3 data already read in to contribution
              #------------------
              # read existing pmag results data and sort out the directional data.
              # The directional data will be merged to one combined pmag table.
              # these data will be merged later
              #-----------------------.
  
              PmagRecsOld = {}
              for FILE in ['pmag_specimens.txt', 'pmag_samples.txt', 'pmag_sites.txt', 'pmag_results.txt']:
                  PmagRecsOld[FILE], meas_data = [], []
                  try:
                      meas_data, file_type = pmag.magic_read(
                          os.path.join(self.WD, FILE))
                      self.GUI_log.write(
                          "-I- Read existing magic file  %s\n" % (os.path.join(self.WD, FILE)))
                      # if FILE !='pmag_specimens.txt':
                      os.rename(os.path.join(self.WD, FILE),
                                os.path.join(self.WD, FILE + ".backup"))
                      self.GUI_log.write(
                          "-I- rename old magic file  %s.backup\n" % (os.path.join(self.WD, FILE)))
                  except:
                      self.GUI_log.write(
                          "-I- Can't read existing magic file  %s\n" % (os.path.join(self.WD, FILE)))
                      continue
                  for rec in meas_data:
                      if "magic_method_codes" in list(rec.keys()):
                          if "LP-PI" not in rec['magic_method_codes'] and "IE-" not in rec['magic_method_codes']:
                              PmagRecsOld[FILE].append(rec)
  
          pmag_specimens_header_1 = [
              "er_location_name", "er_site_name", "er_sample_name", "er_specimen_name"]
          pmag_specimens_header_2 = [
              'measurement_step_min', 'measurement_step_max', 'specimen_int']
          pmag_specimens_header_3 = ["specimen_correction", "specimen_int_corr_anisotropy",
                                     "specimen_int_corr_nlt", "specimen_int_corr_cooling_rate"]
          pmag_specimens_header_4 = []
          for short_stat in self.preferences['show_statistics_on_gui']:
              stat = "specimen_" + short_stat
              pmag_specimens_header_4.append(stat)
          pmag_specimens_header_5 = [
              "magic_experiment_names", "magic_method_codes", "measurement_step_unit", "specimen_lab_field_dc"]
          pmag_specimens_header_6 = ["er_citation_names"]
  
          specimens_list = []
          for specimen in list(self.Data.keys()):
              if 'pars' in list(self.Data[specimen].keys()):
                  if 'saved' in self.Data[specimen]['pars'] and self.Data[specimen]['pars']['saved']:
                      specimens_list.append(specimen)
                  elif 'deleted' in self.Data[specimen]['pars'] and self.Data[specimen]['pars']['deleted']:
                      specimens_list.append(specimen)
  
          # Empty pmag tables:
          MagIC_results_data = {}
          MagIC_results_data['pmag_specimens'] = {}
          MagIC_results_data['pmag_samples_or_sites'] = {}
          MagIC_results_data['pmag_results'] = {}
  
          # write down pmag_specimens.txt
          specimens_list.sort()
          for specimen in specimens_list:
              if 'pars' in self.Data[specimen] and 'deleted' in self.Data[specimen]['pars'] and self.Data[specimen]['pars']['deleted']:
                  print('-I- Deleting interpretation for {}'.format(specimen))
                  this_spec_data = self.spec_data.loc[specimen]
                  # there are multiple rows for this specimen
                  if isinstance(this_spec_data, pd.DataFrame):
                      # delete the intensity rows for specimen
                      cond1 = self.spec_container.df.specimen == specimen
                      cond2 = self.spec_container.df.int_abs.notnull()
                      cond = cond1 & cond2
                      self.spec_container.df = self.spec_container.df[-cond]
                  # there is only one record for this specimen
                  else:
                      # delete all intensity data for that specimen
                      columns = list(self.contribution.data_model.get_group_headers('specimens', 'Paleointensity'))
                      columns.extend(list(self.contribution.data_model.get_group_headers('specimens', 'Paleointensity pTRM Check Statistics')))
                      columns.extend(list(self.contribution.data_model.get_group_headers('specimens', 'Paleointensity pTRM Tail Check Statistics')))
                      columns.extend(list(self.contribution.data_model.get_group_headers('specimens', 'Paleointensity pTRM Additivity Check Statistics')))
                      columns.extend(list(self.contribution.data_model.get_group_headers('specimens', 'Paleointensity Arai Statistics')))
                      columns.extend(list(self.contribution.data_model.get_group_headers('specimens', 'Paleointensity Directional Statistics')))
                      int_columns = set(columns).intersection(self.spec_data.columns)
                      int_columns.update(['method_codes', 'result_quality', 'meas_step_max', 'meas_step_min', 'software_packages', 'meas_step_unit', 'experiments'])
                      new_data = {col: "" for col in int_columns}
                      cond1 = self.spec_container.df.specimen == specimen
                      for col in int_columns:
                          self.spec_container.df.loc[specimen, col] = ""
  
              elif 'pars' in self.Data[specimen] and 'saved' in self.Data[specimen]['pars'] and self.Data[specimen]['pars']['saved']:
                  sample_name = self.Data_hierarchy['specimens'][specimen]
                  site_name = thellier_gui_lib.get_site_from_hierarchy(
                      sample_name, self.Data_hierarchy)
                  location_name = thellier_gui_lib.get_location_from_hierarchy(
                      site_name, self.Data_hierarchy)
  
                  MagIC_results_data['pmag_specimens'][specimen] = {}
                  if version != "unknown":
                      MagIC_results_data['pmag_specimens'][specimen]['magic_software_packages'] = version
                  MagIC_results_data['pmag_specimens'][specimen]['er_citation_names'] = "This study"
                  # MagIC_results_data['pmag_specimens'][specimen]['er_analyst_mail_names']="unknown"
  
                  MagIC_results_data['pmag_specimens'][specimen]['er_specimen_name'] = specimen
                  MagIC_results_data['pmag_specimens'][specimen]['er_sample_name'] = sample_name
                  MagIC_results_data['pmag_specimens'][specimen]['er_site_name'] = site_name
                  MagIC_results_data['pmag_specimens'][specimen]['er_location_name'] = location_name
                  MagIC_results_data['pmag_specimens'][specimen]['magic_method_codes'] = self.Data[
                      specimen]['pars']['magic_method_codes'] + ":IE-TT"
                  tmp = MagIC_results_data['pmag_specimens'][specimen]['magic_method_codes'].split(
                      ":")
                  # magic_experiment_names=specimen
                  magic_experiment_names = ""
                  # for m in tmp: # this is incorrect - it should be a concatenated list of the experiment names from the measurement table.
                  #    if "LP-" in m:
                  #        magic_experiment_names=magic_experiment_names+":" + m
                  MagIC_results_data['pmag_specimens'][specimen]['magic_experiment_names'] = magic_experiment_names
                  MagIC_results_data['pmag_specimens'][specimen]['measurement_step_unit'] = 'K'
                  MagIC_results_data['pmag_specimens'][specimen]['specimen_lab_field_dc'] = "%.2e" % (
                      self.Data[specimen]['pars']['lab_dc_field'])
                  MagIC_results_data['pmag_specimens'][specimen]['specimen_correction'] = self.Data[specimen]['pars']['specimen_correction']
                  for key in pmag_specimens_header_4:
                      if key in ['specimen_int_ptrm_n', 'specimen_int_n']:
                          MagIC_results_data['pmag_specimens'][specimen][key] = "%i" % (
                              self.Data[specimen]['pars'][key])
                      elif key in ['specimen_scat'] and self.Data[specimen]['pars'][key] in ["Fail", 'f']:
                          MagIC_results_data['pmag_specimens'][specimen][key] = "f"
                      elif key in ['specimen_scat'] and self.Data[specimen]['pars'][key] in ["Pass", 't']:
                          MagIC_results_data['pmag_specimens'][specimen][key] = "t"
                      else:
                          MagIC_results_data['pmag_specimens'][specimen][key] = "%.2f" % (
                              self.Data[specimen]['pars'][key])
  
                  MagIC_results_data['pmag_specimens'][specimen]['specimen_int'] = "%.2e" % (
                      self.Data[specimen]['pars']['specimen_int'])
                  MagIC_results_data['pmag_specimens'][specimen]['measurement_step_min'] = "%i" % (
                      self.Data[specimen]['pars']['measurement_step_min'])
                  MagIC_results_data['pmag_specimens'][specimen]['measurement_step_max'] = "%i" % (
                      self.Data[specimen]['pars']['measurement_step_max'])
                  if "specimen_int_corr_anisotropy" in list(self.Data[specimen]['pars'].keys()):
                      MagIC_results_data['pmag_specimens'][specimen]['specimen_int_corr_anisotropy'] = "%.2f" % (
                          self.Data[specimen]['pars']['specimen_int_corr_anisotropy'])
                  else:
                      MagIC_results_data['pmag_specimens'][specimen]['specimen_int_corr_anisotropy'] = ""
                  if "specimen_int_corr_nlt" in list(self.Data[specimen]['pars'].keys()):
                      MagIC_results_data['pmag_specimens'][specimen]['specimen_int_corr_nlt'] = "%.2f" % (
                          self.Data[specimen]['pars']['specimen_int_corr_nlt'])
                  else:
                      MagIC_results_data['pmag_specimens'][specimen]['specimen_int_corr_nlt'] = ""
                  if "specimen_int_corr_cooling_rate" in list(self.Data[specimen]['pars'].keys()) and self.Data[specimen]['pars']['specimen_int_corr_cooling_rate'] != -999:
                      MagIC_results_data['pmag_specimens'][specimen]['specimen_int_corr_cooling_rate'] = "%.2f" % (
                          self.Data[specimen]['pars']['specimen_int_corr_cooling_rate'])
                  else:
                      MagIC_results_data['pmag_specimens'][specimen]['specimen_int_corr_cooling_rate'] = ""
                  MagIC_results_data['pmag_specimens'][specimen]['criteria'] = "IE-SPEC"
  
                  if self.data_model == 3:   # convert pmag_specimen format to data model 3 and replace existing specimen record or add new & delete blank records
                      new_spec_data = MagIC_results_data['pmag_specimens'][specimen]
                      # turn new_specimen data to 3.0
                      new_data = map_magic.convert_spec('magic3', new_spec_data)
                      # check if interpretation passes criteria and set flag
                      spec_pars = thellier_gui_lib.check_specimen_PI_criteria(
                          self.Data[specimen]['pars'], self.acceptance_criteria)
                      if len(spec_pars['specimen_fail_criteria']) > 0:
                          new_data['result_quality'] = 'b'
                      else:
                          new_data['result_quality'] = 'g'
                      # reformat all the keys
                      cond1 = self.spec_container.df['specimen'].str.contains(
                          specimen + "$") == True
                      if 'int_abs' not in self.spec_container.df.columns:
                          self.spec_container.df['int_abs'] = None
                          print("-W- No intensity data found for specimens")
                      cond2 = self.spec_container.df['int_abs'].apply(lambda x: cb.not_null(x, False)) #notnull() == True
                      condition = (cond1 & cond2)
                      # update intensity records
                      self.spec_data = self.spec_container.update_record(
                          specimen, new_data, condition)
                      ## delete essentially blank records
                      #condition = self.spec_data['method_codes'].isnull().astype(
                      #bool)  # find the blank records
                      #info_str = "specimen rows with blank method codes"
                      #self.spec_data = self.spec_container.delete_rows(
                      #    condition, info_str)  # delete them
  
          if self.data_model != 3:  # write out pmag_specimens.txt file
              fout = open(os.path.join(self.WD, "pmag_specimens.txt"), 'w')
              fout.write("tab\tpmag_specimens\n")
              headers = pmag_specimens_header_1 + pmag_specimens_header_2 + pmag_specimens_header_3 + \
                  pmag_specimens_header_4 + pmag_specimens_header_5 + pmag_specimens_header_6
              String = ""
              for key in headers:
                  String = String + key + "\t"
              fout.write(String[:-1] + "\n")
              for specimen in specimens_list:
                  String = ""
                  for key in headers:
                      String = String + \
                          MagIC_results_data['pmag_specimens'][specimen][key] + "\t"
                  fout.write(String[:-1] + "\n")
              fout.close()
              # merge with non-intensity data
              # read the new pmag_specimens.txt
              meas_data, file_type = pmag.magic_read(
                  os.path.join(self.WD, "pmag_specimens.txt"))
              # add the old non-PI lines from pmag_specimens.txt
              for rec in PmagRecsOld["pmag_specimens.txt"]:
                  meas_data.append(rec)
              # fix headers, so all headers in all lines
              meas_data = self.converge_pmag_rec_headers(meas_data)
              # write the combined pmag_specimens.txt
              pmag.magic_write(os.path.join(
                  self.WD, "pmag_specimens.txt"), meas_data, 'pmag_specimens')
              try:
                  os.remove(os.path.join(self.WD, "pmag_specimens.txt.backup"))
              except:
                  pass
  
              #-------------
              # message dialog
              #-------------
              TEXT = "specimens interpretations are saved in pmag_specimens.txt.\nPress OK for pmag_samples/pmag_sites/pmag_results tables."
          else:  # data model 3, so merge with spec_data  and save as specimens.txt file
              # remove unwanted columns (site, location).
              for col in ['site', 'location']:
                  if col in self.spec_data.columns:
                      del self.spec_data[col]
  
              self.spec_container.drop_duplicate_rows()
              #  write out the data
              self.spec_container.write_magic_file(dir_path=self.WD)
              TEXT = "specimens interpretations are saved in specimens.txt.\nPress OK for samples/sites tables."
  
          dlg = wx.MessageDialog(self, caption="Saved",
                                 message=TEXT, style=wx.OK | wx.CANCEL)
          result = self.show_dlg(dlg)
          if result == wx.ID_OK:
              dlg.Destroy()
          if result == wx.ID_CANCEL:
              dlg.Destroy()
              return()
          #-------------
          # pmag_samples.txt or pmag_sites.txt
          #-------------
          if self.acceptance_criteria['average_by_sample_or_site']['value'] == 'sample':
              BY_SITES = False
              BY_SAMPLES = True
          else:
              BY_SITES = True
              BY_SAMPLES = False
  
          pmag_samples_header_1 = ["er_location_name", "er_site_name"]
          if BY_SAMPLES:
              pmag_samples_header_1.append("er_sample_name")
          if BY_SAMPLES:
              pmag_samples_header_2 = ["er_specimen_names", "sample_int", "sample_int_n",
                                       "sample_int_sigma", "sample_int_sigma_perc", "sample_description"]
          else:
              pmag_samples_header_2 = ["er_specimen_names", "site_int", "site_int_n",
                                       "site_int_sigma", "site_int_sigma_perc", "site_description"]
          pmag_samples_header_3 = [
              "magic_method_codes", "magic_software_packages"]
          pmag_samples_header_4 = ["er_citation_names"]
  
          pmag_samples_or_sites_list = []
  
          if BY_SAMPLES:
              samples_or_sites = list(self.Data_samples.keys())
              Data_samples_or_sites = copy.deepcopy(self.Data_samples)
          else:
              samples_or_sites = list(self.Data_sites.keys())
              Data_samples_or_sites = copy.deepcopy(self.Data_sites)
          samples_or_sites.sort()
          for sample_or_site in samples_or_sites:
              if True:
                  specimens_names = ""
                  B = []
                  specimens_LP_codes = []
                  for specimen in list(Data_samples_or_sites[sample_or_site].keys()):
                      B.append(Data_samples_or_sites[sample_or_site][specimen])
                      if specimen not in MagIC_results_data['pmag_specimens']:
                          continue
                      magic_codes = MagIC_results_data['pmag_specimens'][specimen]['magic_method_codes']
                      codes = magic_codes.replace(" ", "").split(":")
                      for code in codes:
                          if "LP-" in code and code not in specimens_LP_codes:
                              specimens_LP_codes.append(code)
  
                      specimens_names = specimens_names + specimen + ":"
                  magic_codes = ":".join(specimens_LP_codes) + ":IE-TT"
                  specimens_names = specimens_names[:-1]
                  if specimens_names != "":
  
                      # sample_pass_criteria=False
                      sample_or_site_pars = self.calculate_sample_mean(
                          Data_samples_or_sites[sample_or_site])
                      if sample_or_site_pars['pass_or_fail'] == 'fail':
                          continue
                      N = sample_or_site_pars['N']
                      B_uT = sample_or_site_pars['B_uT']
                      B_std_uT = sample_or_site_pars['B_std_uT']
                      B_std_perc = sample_or_site_pars['B_std_perc']
                      pmag_samples_or_sites_list.append(sample_or_site)
                      MagIC_results_data['pmag_samples_or_sites'][sample_or_site] = {
                      }
                      MagIC_results_data['pmag_samples_or_sites'][sample_or_site]['er_specimen_names'] = specimens_names
                      if BY_SAMPLES:
                          name = "sample_"
                      else:
                          name = "site_"
                      MagIC_results_data['pmag_samples_or_sites'][sample_or_site][name +
                                                                                  'int'] = "%.2e" % (B_uT * 1e-6)
                      MagIC_results_data['pmag_samples_or_sites'][sample_or_site][name +
                                                                                  'int_n'] = "%i" % (N)
                      MagIC_results_data['pmag_samples_or_sites'][sample_or_site][name +
                                                                                  'int_sigma'] = "%.2e" % (B_std_uT * 1e-6)
                      MagIC_results_data['pmag_samples_or_sites'][sample_or_site][name +
                                                                                  'int_sigma_perc'] = "%.2f" % (B_std_perc)
                      MagIC_results_data['pmag_samples_or_sites'][sample_or_site][name +
                                                                                  'description'] = "paleointensity mean"
                      if BY_SAMPLES:
                          sample_name = sample_or_site
                          site_name = thellier_gui_lib.get_site_from_hierarchy(
                              sample_name, self.Data_hierarchy)
                          location_name = thellier_gui_lib.get_location_from_hierarchy(
                              site_name, self.Data_hierarchy)
                          MagIC_results_data['pmag_samples_or_sites'][sample_or_site]['er_sample_name'] = sample_name
  
                      if BY_SITES:
                          site_name = sample_or_site
                          location_name = thellier_gui_lib.get_location_from_hierarchy(
                              site_name, self.Data_hierarchy)
  
                      MagIC_results_data['pmag_samples_or_sites'][sample_or_site]['er_site_name'] = site_name
                      MagIC_results_data['pmag_samples_or_sites'][sample_or_site]['er_location_name'] = location_name
                      MagIC_results_data['pmag_samples_or_sites'][sample_or_site]["pmag_criteria_codes"] = ""
                      MagIC_results_data['pmag_samples_or_sites'][sample_or_site]['magic_method_codes'] = magic_codes
                      MagIC_results_data['pmag_samples_or_sites'][sample_or_site]["magic_software_packages"] = version
  
                      MagIC_results_data['pmag_samples_or_sites'][sample_or_site]["er_citation_names"] = "This study"
  
          # prepare pmag_samples.txt
          pmag_samples_or_sites_list.sort()
          if self.data_model != 3:  # save 2.5 way
              if BY_SAMPLES:
                  fout = open(os.path.join(self.WD, "pmag_samples.txt"), 'w')
                  fout.write("tab\tpmag_samples\n")
              else:
                  fout = open(os.path.join(self.WD, "pmag_sites.txt"), 'w')
                  fout.write("tab\tpmag_sites\n")
  
              headers = pmag_samples_header_1 + pmag_samples_header_2 + \
                  pmag_samples_header_3 + pmag_samples_header_4
              String = ""
              for key in headers:
                  String = String + key + "\t"
              fout.write(String[:-1] + "\n")
  
              for sample_or_site in pmag_samples_or_sites_list:
                  String = ""
                  for key in headers:
                      String = String + \
                          MagIC_results_data['pmag_samples_or_sites'][sample_or_site][key] + "\t"
                  fout.write(String[:-1] + "\n")
              fout.close()
  
          # merge with non-intensity data
              if BY_SAMPLES:
                  meas_data, file_type = pmag.magic_read(
                      os.path.join(self.WD, "pmag_samples.txt"))
                  for rec in PmagRecsOld["pmag_samples.txt"]:
                      meas_data.append(rec)
                  meas_data = self.converge_pmag_rec_headers(meas_data)
                  pmag.magic_write(os.path.join(
                      self.WD, "pmag_samples.txt"), meas_data, 'pmag_samples')
                  try:
                      os.remove(os.path.join(self.WD, "pmag_samples.txt.backup"))
                  except:
                      pass
                  pmag.magic_write(os.path.join(
                      self.WD, "pmag_sites.txt"), PmagRecsOld["pmag_sites.txt"], 'pmag_sites')
                  try:
                      os.remove(os.path.join(self.WD, "pmag_sites.txt.backup"))
                  except:
                      pass
  
              else:
                  meas_data, file_type = pmag.magic_read(
                      os.path.join(self.WD, "pmag_sites.txt"))
                  for rec in PmagRecsOld["pmag_sites.txt"]:
                      meas_data.append(rec)
                  meas_data = self.converge_pmag_rec_headers(meas_data)
                  pmag.magic_write(os.path.join(
                      self.WD, "pmag_sites.txt"), meas_data, 'pmag_sites')
                  try:
                      os.remove(os.path.join(self.WD, "pmag_sites.txt.backup"))
                  except:
                      pass
                  pmag.magic_write(os.path.join(
                      self.WD, "pmag_samples.txt"), PmagRecsOld["pmag_samples.txt"], 'pmag_samples')
                  try:
                      os.remove(os.path.join(self.WD, "pmag_samples.txt.backup"))
                  except:
                      pass
  
          else:  # don't do anything yet = need vdm data
              pass
  
          #-------------
          # pmag_results.txt
          #-------------
  
          pmag_results_header_1 = ["er_location_names", "er_site_names"]
          if BY_SAMPLES:
              pmag_results_header_1.append("er_sample_names")
          pmag_results_header_1.append("er_specimen_names")
  
          pmag_results_header_2 = ["average_lat", "average_lon", ]
          pmag_results_header_3 = [
              "average_int_n", "average_int", "average_int_sigma", "average_int_sigma_perc"]
          if self.preferences['VDM_or_VADM'] == "VDM":
              pmag_results_header_4 = ["vdm", "vdm_sigma"]
          else:
              pmag_results_header_4 = ["vadm", "vadm_sigma"]
          pmag_results_header_5 = ["data_type", "pmag_result_name", "magic_method_codes",
                                   "result_description", "er_citation_names", "magic_software_packages", "pmag_criteria_codes"]
  
          for sample_or_site in pmag_samples_or_sites_list:
              if sample_or_site is None:
                  continue
              if isinstance(sample_or_site, type(np.nan)):
                  continue
              MagIC_results_data['pmag_results'][sample_or_site] = {}
              if self.data_model == 3:
                  if BY_SAMPLES:
                      if len(self.test_for_criteria()):
                          MagIC_results_data['pmag_results'][sample_or_site]['pmag_criteria_codes'] = "IE-SPEC:IE-SAMP"
                  if BY_SITES:
                      if len(self.test_for_criteria()):
                          MagIC_results_data['pmag_results'][sample_or_site]['pmag_criteria_codes'] = "IE-SPEC:IE-SITE"
              else:
                  MagIC_results_data['pmag_results'][sample_or_site]['pmag_criteria_codes'] = "ACCEPT"
              MagIC_results_data['pmag_results'][sample_or_site]["er_location_names"] = MagIC_results_data[
                  'pmag_samples_or_sites'][sample_or_site]['er_location_name']
              MagIC_results_data['pmag_results'][sample_or_site]["er_site_names"] = MagIC_results_data[
                  'pmag_samples_or_sites'][sample_or_site]['er_site_name']
              MagIC_results_data['pmag_results'][sample_or_site]["er_specimen_names"] = MagIC_results_data[
                  'pmag_samples_or_sites'][sample_or_site]['er_specimen_names']
  
              if BY_SAMPLES:
                  MagIC_results_data['pmag_results'][sample_or_site]["er_sample_names"] = MagIC_results_data[
                      'pmag_samples_or_sites'][sample_or_site]['er_sample_name']
  
              site = MagIC_results_data['pmag_results'][sample_or_site]["er_site_names"]
              lat, lon = "", ""
              if site in list(self.Data_info["er_sites"].keys()) and "site_lat" in list(self.Data_info["er_sites"][site].keys()):
                  # MagIC_results_data['pmag_results'][sample_or_site]["average_lat"]=self.Data_info["er_sites"][site]["site_lat"]
                  lat = self.Data_info["er_sites"][site]["site_lat"]
  
              if site in list(self.Data_info["er_sites"].keys()) and "site_lon" in list(self.Data_info["er_sites"][site].keys()):
                  # MagIC_results_data['pmag_results'][sample_or_site]["average_lon"]=self.Data_info["er_sites"][site]["site_lon"]
                  lon = self.Data_info["er_sites"][site]["site_lon"]
              MagIC_results_data['pmag_results'][sample_or_site]["average_lat"] = lat
              MagIC_results_data['pmag_results'][sample_or_site]["average_lon"] = lon
              if BY_SAMPLES:
                  name = 'sample'
              else:
                  name = 'site'
  
              MagIC_results_data['pmag_results'][sample_or_site]["average_int_n"] = MagIC_results_data[
                  'pmag_samples_or_sites'][sample_or_site][name + '_int_n']
              MagIC_results_data['pmag_results'][sample_or_site]["average_int"] = MagIC_results_data[
                  'pmag_samples_or_sites'][sample_or_site][name + '_int']
              MagIC_results_data['pmag_results'][sample_or_site]["average_int_sigma"] = MagIC_results_data[
                  'pmag_samples_or_sites'][sample_or_site][name + '_int_sigma']
              MagIC_results_data['pmag_results'][sample_or_site]["average_int_sigma_perc"] = MagIC_results_data[
                  'pmag_samples_or_sites'][sample_or_site][name + '_int_sigma_perc']
  
              if self.preferences['VDM_or_VADM'] == "VDM":
                  pass
                  # to be done
              else:
                  if lat != "":
                      lat = float(lat)
                      # B=float(MagIC_results_data['pmag_samples_or_sites'][sample_or_site]['sample_int'])
                      B = float(
                          MagIC_results_data['pmag_results'][sample_or_site]["average_int"])
                      # B_sigma=float(MagIC_results_data['pmag_samples_or_sites'][sample_or_site]['sample_int_sigma'])
                      B_sigma = float(
                          MagIC_results_data['pmag_results'][sample_or_site]["average_int_sigma"])
                      VADM = pmag.b_vdm(B, lat)
                      VADM_plus = pmag.b_vdm(B + B_sigma, lat)
                      VADM_minus = pmag.b_vdm(B - B_sigma, lat)
                      VADM_sigma = (VADM_plus - VADM_minus) / 2
                      MagIC_results_data['pmag_results'][sample_or_site]["vadm"] = "%.2e" % VADM
                      MagIC_results_data['pmag_results'][sample_or_site]["vadm_sigma"] = "%.2e" % VADM_sigma
                      if self.data_model == 3:  # stick vadm into site_or_sample record
                          MagIC_results_data['pmag_samples_or_sites'][sample_or_site]["vadm"] = "%.2e" % VADM
                          MagIC_results_data['pmag_samples_or_sites'][sample_or_site]["vadm_sigma"] = "%.2e" % VADM_sigma
                  else:
                      MagIC_results_data['pmag_results'][sample_or_site]["vadm"] = ""
                      MagIC_results_data['pmag_results'][sample_or_site]["vadm_sigma"] = ""
                      if self.data_model == 3:  # stick vadm into site_or_sample record
                          MagIC_results_data['pmag_samples_or_sites'][sample_or_site]["vadm"] = ""
                          MagIC_results_data['pmag_samples_or_sites'][sample_or_site]["vadm_sigma"] = ""
              if MagIC_results_data['pmag_results'][sample_or_site]["vadm"] != "":
                  MagIC_results_data['pmag_results'][sample_or_site]["pmag_result_name"] = "Paleointensity;V[A]DM;" + sample_or_site
                  MagIC_results_data['pmag_results'][sample_or_site]["result_description"] = "Paleointensity; V[A]DM"
              else:
                  MagIC_results_data['pmag_results'][sample_or_site]["pmag_result_name"] = "Paleointensity;" + sample_or_site
                  MagIC_results_data['pmag_results'][sample_or_site]["result_description"] = "Paleointensity"
  
              MagIC_results_data['pmag_results'][sample_or_site]["magic_software_packages"] = version
              MagIC_results_data['pmag_results'][sample_or_site]["magic_method_codes"] = magic_codes
              # try to make a more meaningful name
  
              MagIC_results_data['pmag_results'][sample_or_site]["data_type"] = "i"
              MagIC_results_data['pmag_results'][sample_or_site]["er_citation_names"] = "This study"
              if self.data_model != 3:  # look for ages in er_ages - otherwise they are in sites.txt already
                  # add ages
                  found_age = False
                  site = MagIC_results_data['pmag_results'][sample_or_site]["er_site_names"]
                  if sample_or_site in list(self.Data_info["er_ages"].keys()):
                      sample_or_site_with_age = sample_or_site
                      found_age = True
                  elif site in list(self.Data_info["er_ages"].keys()):
                      sample_or_site_with_age = site
                      found_age = True
                  if found_age:
                      for header in ["age", "age_unit", "age_sigma", "age_range_low", "age_range_high"]:
                          if sample_or_site_with_age in list(self.Data_info["er_ages"].keys()) and header in list(self.Data_info["er_ages"][sample_or_site_with_age].keys()):
                              if self.Data_info["er_ages"][sample_or_site_with_age][header] != "":
                                  value = self.Data_info["er_ages"][sample_or_site_with_age][header]
                                  header_result = "average_" + header
                                  if header_result == "average_age_range_high":
                                      header_result = "average_age_high"
                                  if header_result == "average_age_range_low":
                                      header_result = "average_age_low"
                                  MagIC_results_data['pmag_results'][sample_or_site][header_result] = value
  
                                  if header_result not in pmag_results_header_4:
                                      pmag_results_header_4.append(header_result)
  
              else:
  
                  found_age = False
                  if BY_SAMPLES and sample_or_site in list(self.Data_info["er_ages"].keys()):
                      element_with_age = sample_or_site
                      found_age = True
                  elif BY_SAMPLES and sample_or_site not in list(self.Data_info["er_ages"].keys()):
                      site = self.Data_hierarchy['site_of_sample'][sample_or_site]
                      if site in list(self.Data_info["er_ages"].keys()):
                          element_with_age = site
                          found_age = True
                  elif BY_SITES and sample_or_site in list(self.Data_info["er_ages"].keys()):
                      element_with_age = sample_or_site
                      found_age = True
                  else:
                      continue
                  if not found_age:
                      continue
                  foundkeys = False
              # print    "element_with_age",element_with_age
                  for key in ['age', 'age_sigma', 'age_range_low', 'age_range_high', 'age_unit']:
                      # print "Ron debug"
                      # print element_with_age
                      # print sample_or_site
                      if "er_ages" in list(self.Data_info.keys()) and element_with_age in list(self.Data_info["er_ages"].keys()):
                          if key in list(self.Data_info["er_ages"][element_with_age].keys()):
                              if self.Data_info["er_ages"][element_with_age][key] != "":
                                  # print self.Data_info["er_ages"][element_with_age]
                                  # print  self.Data_info["er_ages"][element_with_age][key]
                                  # print
                                  # MagIC_results_data['pmag_results'][sample_or_site]
                                  MagIC_results_data['pmag_results'][sample_or_site][
                                      key] = self.Data_info["er_ages"][element_with_age][key]
                                  foundkeys = True
                  if foundkeys == True:
                      if "er_ages" in list(self.Data_info.keys()) and element_with_age in list(self.Data_info["er_ages"].keys()):
                          if 'magic_method_codes' in list(self.Data_info["er_ages"][element_with_age].keys()):
                              methods = self.Data_info["er_ages"][element_with_age]['magic_method_codes'].replace(
                                  " ", "").strip('\n').split(":")
                              for meth in methods:
                                  MagIC_results_data['pmag_results'][sample_or_site]["magic_method_codes"] = MagIC_results_data[
                                      'pmag_results'][sample_or_site]["magic_method_codes"] + ":" + meth
  
          if self.data_model != 3:
              # write pmag_results.txt
              fout = open(os.path.join(self.WD, "pmag_results.txt"), 'w')
              fout.write("tab\tpmag_results\n")
              headers = pmag_results_header_1 + pmag_results_header_2 + \
                  pmag_results_header_3 + pmag_results_header_4 + pmag_results_header_5
              String = ""
              for key in headers:
                  String = String + key + "\t"
              fout.write(String[:-1] + "\n")
  
              # pmag_samples_list.sort()
              for sample_or_site in pmag_samples_or_sites_list:
                  if sample_or_site is None:
                      continue
                  if isinstance(sample_or_site, type(np.nan)):
                      continue
                  String = ""
                  for key in headers:
                      if key in list(MagIC_results_data['pmag_results'][sample_or_site].keys()):
                          String = String + \
                              MagIC_results_data['pmag_results'][sample_or_site][key] + "\t"
                      else:
                          String = String + "" + "\t"
                  fout.write(String[:-1] + "\n")
              fout.close()
  
              # merge with non-intensity data
              meas_data, file_type = pmag.magic_read(
                  os.path.join(self.WD, "pmag_results.txt"))
              for rec in PmagRecsOld["pmag_results.txt"]:
                  meas_data.append(rec)
              meas_data = self.converge_pmag_rec_headers(meas_data)
              pmag.magic_write(os.path.join(
                  self.WD, "pmag_results.txt"), meas_data, 'pmag_results')
              try:
                  os.remove(os.path.join(self.WD, "pmag_results.txt.backup"))
              except:
                  pass
  
          else:  # write out samples/sites in data model 3.0
              for sample_or_site in pmag_samples_or_sites_list:
                  if sample_or_site is None:
                      continue
                  if isinstance(sample_or_site, type(np.nan)):
                      continue
  
                  # convert, delete, add and save
                  new_sample_or_site_data = MagIC_results_data['pmag_samples_or_sites'][sample_or_site]
  
                  if BY_SAMPLES:
                      new_data = map_magic.convert_samp(
                          'magic3', new_sample_or_site_data)  # convert to 3.0
                      if len(self.test_for_criteria()):
                          new_data['criteria'] = 'IE-SPEC:IE-SAMP'
                      new_data['result_quality'] = 'g'
                      self.samp_data = self.samp_container.df
                      cond1 = self.samp_data['sample'].str.contains(
                          sample_or_site + "$") == True
                      if 'int_abs' not in self.samp_data.columns:
                          self.samp_data['int_abs'] = None
                          print('-W- No intensity data found for samples')
                      cond2 = self.samp_data['int_abs'].notnull() == True
                      condition = (cond1 & cond2)
                      # update record
                      self.samp_data = self.samp_container.update_record(
                          sample_or_site, new_data, condition)
                      self.site_data = self.site_container.df
                      # remove intensity data from site level.
                      if 'int_abs' not in self.site_data.columns:
                          self.site_data['int_abs'] = None
                          print('-W- No intensity data found for sites')
                      site = self.Data_hierarchy['site_of_sample'][sample_or_site]
                      try:  # if site name is blank will skip
                          cond1 = self.site_data['site'].str.contains(
                              site + "$") == True
                          cond2 = self.site_data['int_abs'].notnull() == True
                          condition = (cond1 & cond2)
                          site_keys = ['samples', 'int_abs', 'int_sigma', 'int_n_samples', 'int_sigma_perc', 'specimens',
                                       'int_abs_sigma', 'int_abs_sigma_perc', 'vadm']  # zero these out but keep the rest
                          blank_data = {}
                          for key in site_keys:
                              blank_data[key] = ""
                          self.site_data = self.site_container.update_record(
                              site, blank_data, condition, update_only=True)
                      # add record for sample in the site table
                          cond1 = self.site_data['site'].str.contains(
                              sample_or_site + "$") == True
                          cond2 = self.site_data['int_abs'].notnull() == True
                          condition = (cond1 & cond2)
                      # change 'site' column to reflect sample name,
                      # since we are putting this sample at the site level
                          new_data['site'] = sample_or_site
                          new_data['samples'] = sample_or_site
                          new_data['int_n_samples'] = '1'
                          # get rid of this key for site table
                          del new_data['sample']
                          new_data['vadm'] = MagIC_results_data['pmag_results'][sample_or_site]["vadm"]
                          new_data['vadm_sigma'] = MagIC_results_data['pmag_results'][sample_or_site]["vadm_sigma"]
                          new_data['result_quality'] = 'g'
                          self.site_data = self.site_container.update_record(
                              sample_or_site, new_data, condition, debug=True)
                      except:
                          pass  # no site
                  else:  # do this by site and not by sample START HERE
                      cond1 = self.site_data['site'].str.contains(
                          sample_or_site + "$") == True
                      if 'int_abs' not in self.site_data.columns:
                          self.site_data['int_abs'] = None
                      cond2 = self.site_data['int_abs'].notnull() == True
                      condition = (cond1 & cond2)
                      loc = None
                      locs = self.site_data[cond1]['location']
                      if any(locs):
                          loc = locs.values[0]
                      new_data['site'] = sample_or_site
                      new_data['location'] = loc
                      self.site_data = self.site_container.update_record(
                          sample_or_site, new_data, condition)
                      # remove intensity data from sample level.   # need to look
                      # up samples from this site
                      cond1 = self.samp_data['site'].str.contains(
                          sample_or_site + "$") == True
                      if 'int_abs' not in self.samp_data.columns:
                          self.samp_data['int_abs'] = None
                      cond2 = self.samp_data['int_abs'].notnull() == True
                      condition = (cond1 & cond2)
                      new_data = {}  # zero these out but keep the rest
                      # zero these out but keep the rest
                      samp_keys = ['int_abs', 'int_sigma',
                                   'int_n_specimens', 'int_sigma_perc']
                      for key in samp_keys:
                          new_data[key] = ""
                      samples = self.samp_data[condition].index.unique()
                      for samp_name in samples:
                          self.samp_container.update_record(
                              samp_name, new_data, cond2)
              for col in ['location']:
                  if col in list(self.samp_data.keys()):
                      del self.samp_data[col]
              # if BY_SAMPLES: # replace 'site' with 'sample'
              #    self.samp_data['site']=self.samp_data['sample']
              #    condition= self.samp_container.df['specimens'].notnull()==True  # find all the blank specimens rows
              #    self.samp_container.df = self.samp_container.df.loc[condition]
  
  
  
              # remove sample only columns that have been put into sites
              if BY_SAMPLES:
                  #ignore = ['cooling_rate_corr', 'cooling_rate_mcd']
                  self.site_container.remove_non_magic_cols_from_table(ignore_cols=[]) #ignore)
              #  write out the data
              self.samp_container.write_magic_file(dir_path=self.WD)
              self.site_container.write_magic_file(dir_path=self.WD)
  
          #-------------
          # MagIC_methods.txt
          #-------------
  
          # search for all magic_methods in all files:
          magic_method_codes = []
          for F in ["magic_measurements.txt", "rmag_anisotropy.txt", "rmag_results.txt", "rmag_results.txt", "pmag_samples.txt", "pmag_specimens.txt", "pmag_sites.txt", "er_ages.txt"]:
              try:
                  fin = open(os.path.join(self.WD, F), 'r')
              except:
                  continue
              line = fin.readline()
              line = fin.readline()
              header = line.strip('\n').split('\t')
              if "magic_method_codes" not in header:
                  continue
              else:
                  index = header.index("magic_method_codes")
              for line in fin.readlines():
                  tmp = line.strip('\n').split('\t')
                  if len(tmp) >= index:
                      codes = tmp[index].replace(" ", "").split(":")
                      for code in codes:
                          if code != "" and code not in magic_method_codes:
                              magic_method_codes.append(code)
              fin.close()
  
          if self.data_model == 2:
              magic_method_codes.sort()
              # print magic_method_codes
              magic_methods_header_1 = ["magic_method_code"]
              fout = open(os.path.join(self.WD, "magic_methods.txt"), 'w')
              fout.write("tab\tmagic_methods\n")
              fout.write("magic_method_code\n")
              for code in magic_method_codes:
                  fout.write("%s\n" % code)
              fout.close
  
              # 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")
  
          dlg1 = wx.MessageDialog(
              self, caption="Message:", message="MagIC files are saved in MagIC project folder", style=wx.OK | wx.ICON_INFORMATION)
          self.show_dlg(dlg1)
          dlg1.Destroy()
  
          self.close_warning = False