docs: def aarm_magic(infile, dir_path=".", input_dir_path="",
                 spec_file='specimens.txt', samp_file="samples.txt", data_model_num=3,
                 coord='s'):
      """
      Converts AARM  data to best-fit tensor (6 elements plus sigma)
  
      Parameters
      ----------
      infile : str
          input measurement file
      dir_path : str
          output directory, default "."
      input_dir_path : str
          input file directory IF different from dir_path, default ""
      spec_file : str
          input/output specimen file name, default "specimens.txt"
      samp_file : str
          input sample file name, default "samples.txt"
      data_model_num : number
          MagIC data model [2, 3], default 3
      coord : str
          coordinate system specimen/geographic/tilt-corrected,
          ['s', 'g', 't'], default 's'
  
      Returns
      ---------
      Tuple : (True or False indicating if conversion was sucessful, output file name written)
  
      Info
      ---------
          Input for is a series of baseline, ARM pairs.
        The baseline should be the AF demagnetized state (3 axis demag is
        preferable) for the following ARM acquisition. The order of the
        measurements is:
  
             positions 1,2,3, 6,7,8, 11,12,13 (for 9 positions)
             positions 1,2,3,4, 6,7,8,9, 11,12,13,14 (for 12 positions)
             positions 1-15 (for 15 positions)
  
      """
      data_model_num = int(float(data_model_num))
      input_dir_path, dir_path = pmag.fix_directories(input_dir_path, dir_path)
      # get full file names
      meas_file = pmag.resolve_file_name(infile, input_dir_path)
      spec_file = pmag.resolve_file_name(spec_file, input_dir_path)
      samp_file = pmag.resolve_file_name(samp_file, input_dir_path)
      output_spec_file = os.path.join(dir_path, os.path.split(spec_file)[1])
      # get coordinate system
      coords = {'s': '-1', 'g': '0', 't': '100'}
      if coord not in coords.values():
          coord = coords.get(str(coord), '-1')
  
      if data_model_num == 3:
          meas_data = []
          meas_data3, file_type = pmag.magic_read(meas_file)
          if file_type != 'measurements':
              print(file_type, "This is not a valid MagIC 3.0. measurements file ")
              return False, "{} is not a valid MagIC 3.0. measurements file ".format(meas_file)
          # convert meas_data to 2.5
          for rec in meas_data3:
              meas_map = map_magic.meas_magic3_2_magic2_map
              meas_data.append(map_magic.mapping(rec, meas_map))
          spec_data = []
          spec_data3, file_type = pmag.magic_read(spec_file)
          for rec in spec_data3:
              spec_map = map_magic.spec_magic3_2_magic2_map
              spec_data.append(map_magic.mapping(rec, spec_map))
      else:  # data  model 2
          rmag_anis = "rmag_anisotropy.txt"
          rmag_res = "rmag_results.txt"
          rmag_anis = pmag.resolve_file_name(rmag_anis, input_dir_path)
          rmag_res = pmag.resolve_file_name(rmag_res, input_dir_path)
          meas_data, file_type = pmag.magic_read(meas_file)
          if file_type != 'magic_measurements':
              print(file_type, "This is not a valid MagIC 2.5 magic_measurements file ")
              return False, "{} is not a valid MagIC 2.5. measurements file ".format(meas_file)
      # fish out relevant data
      meas_data = pmag.get_dictitem(
          meas_data, 'magic_method_codes', 'LP-AN-ARM', 'has')
  
      if coord != '-1':  # need to read in sample data
          if data_model_num == 3:
              samp_data3, file_type = pmag.magic_read(samp_file)
              if file_type != 'samples':
                  print(file_type, "This is not a valid samples file ")
                  print("Only specimen coordinates will be calculated")
                  coord = '-1'
              else:
                  # translate to 2
                  samp_data = []
                  samp_map = map_magic.samp_magic3_2_magic2_map
                  for rec in samp_data3:
                      samp_data.append(map_magic.mapping(rec, samp_map))
          else:
              samp_data, file_type = pmag.magic_read(samp_file)
              if file_type != 'er_samples':
                  print(file_type, "This is not a valid er_samples file ")
                  print("Only specimen coordinates will be calculated")
                  coord = '-1'
      #
      # sort the specimen names
      #
      ssort = []
      for rec in meas_data:
          spec = rec["er_specimen_name"]
          if spec not in ssort:
              ssort.append(spec)
      if len(ssort) > 1:
          sids = sorted(ssort)
      else:
          sids = ssort
      #
      # work on each specimen
      #
      specimen = 0
      RmagSpecRecs, RmagResRecs = [], []
      SpecRecs, SpecRecs3 = [], []
      while specimen < len(sids):
          s = sids[specimen]
          RmagSpecRec = {}
          RmagResRec = {}
          # get old specrec here if applicable
          if data_model_num == 3:
              if spec_data:
                  try:
                      RmagResRec = pmag.get_dictitem(
                          spec_data, 'er_specimen_name', s, 'T')[0]
                      RmagSpecRec = pmag.get_dictitem(
                          spec_data, 'er_specimen_name', s, 'T')[0]
                  except IndexError:
                      pass
  
          data = []
          method_codes = []
      #
      # find the data from the meas_data file for this sample
      #
          data = pmag.get_dictitem(meas_data, 'er_specimen_name', s, 'T')
      #
      # find out the number of measurements (9, 12 or 15)
      #
          npos = int(len(data) / 2)
          if npos == 9:
              #
              # get dec, inc, int and convert to x,y,z
              #
              # B matrix made from design matrix for positions
              B, H, tmpH = pmag.designAARM(npos)
              X = []
              for rec in data:
                  Dir = []
                  Dir.append(float(rec["measurement_dec"]))
                  Dir.append(float(rec["measurement_inc"]))
                  Dir.append(float(rec["measurement_magn_moment"]))
                  X.append(pmag.dir2cart(Dir))
          #
          # subtract baseline and put in a work array
          #
              work = np.zeros((npos, 3), 'f')
              for i in range(npos):
                  for j in range(3):
                      work[i][j] = X[2 * i + 1][j] - X[2 * i][j]
          #
          # calculate tensor elements
          # first put ARM components in w vector
          #
              w = np.zeros((npos * 3), 'f')
              index = 0
              for i in range(npos):
                  for j in range(3):
                      w[index] = work[i][j]
                      index += 1
              s = np.zeros((6), 'f')  # initialize the s matrix
              for i in range(6):
                  for j in range(len(w)):
                      s[i] += B[i][j] * w[j]
              trace = s[0] + s[1] + s[2]   # normalize by the trace
              for i in range(6):
                  s[i] = s[i] / trace
              a = pmag.s2a(s)
          # ------------------------------------------------------------
          #  Calculating dels is different than in the Kappabridge
          #  routine. Use trace normalized tensor (a) and the applied
          #  unit field directions (tmpH) to generate model X,Y,Z
          #  components. Then compare these with the measured values.
          # ------------------------------------------------------------
              S = 0.
              comp = np.zeros((npos * 3), 'f')
              for i in range(npos):
                  for j in range(3):
                      index = i * 3 + j
                      compare = a[j][0] * tmpH[i][0] + a[j][1] * \
                          tmpH[i][1] + a[j][2] * tmpH[i][2]
                      comp[index] = compare
              for i in range(npos * 3):
                  d = (w[i] / trace) - comp[i]  # del values
                  S += d * d
              nf = float(npos * 3 - 6)  # number of degrees of freedom
              if S > 0:
                  sigma = np.sqrt(S / nf)
              else:
                  sigma = 0
              RmagSpecRec["rmag_anisotropy_name"] = data[0]["er_specimen_name"]
              RmagSpecRec["er_location_name"] = data[0].get(
                  "er_location_name", "")
              RmagSpecRec["er_specimen_name"] = data[0]["er_specimen_name"]
              if not "er_sample_name" in RmagSpecRec:
                  RmagSpecRec["er_sample_name"] = data[0].get(
                      "er_sample_name", "")
              RmagSpecRec["er_site_name"] = data[0].get("er_site_name", "")
              RmagSpecRec["magic_experiment_names"] = RmagSpecRec["rmag_anisotropy_name"] + ":AARM"
              RmagSpecRec["er_citation_names"] = "This study"
              RmagResRec["rmag_result_name"] = data[0]["er_specimen_name"] + ":AARM"
              RmagResRec["er_location_names"] = data[0].get(
                  "er_location_name", "")
              RmagResRec["er_specimen_names"] = data[0]["er_specimen_name"]
              if not "er_sample_name" not in RmagResRec:
                  RmagResRec["er_sample_names"] = data[0].get(
                      "er_sample_name", "")
              RmagResRec["er_site_names"] = data[0].get("er_site_name", "")
              RmagResRec["magic_experiment_names"] = RmagSpecRec["rmag_anisotropy_name"] + ":AARM"
              RmagResRec["er_citation_names"] = "This study"
              if "magic_instrument_codes" in list(data[0].keys()):
                  RmagSpecRec["magic_instrument_codes"] = data[0]["magic_instrument_codes"]
              else:
                  RmagSpecRec["magic_instrument_codes"] = ""
              RmagSpecRec["anisotropy_type"] = "AARM"
              RmagSpecRec["anisotropy_description"] = "Hext statistics adapted to AARM"
              if coord != '-1':  # need to rotate s
                  # set orientation priorities
                  SO_methods = []
                  for rec in samp_data:
                      if "magic_method_codes" not in rec:
                          rec['magic_method_codes'] = 'SO-NO'
                      if "magic_method_codes" in rec:
                          methlist = rec["magic_method_codes"]
                          for meth in methlist.split(":"):
                              if "SO" in meth and "SO-POM" not in meth.strip():
                                  if meth.strip() not in SO_methods:
                                      SO_methods.append(meth.strip())
                  SO_priorities = pmag.set_priorities(SO_methods, 0)
  # continue here
                  redo, p = 1, 0
                  if len(SO_methods) <= 1:
                      az_type = SO_methods[0]
                      orient = pmag.find_samp_rec(
                          RmagSpecRec["er_sample_name"], samp_data, az_type)
                      if orient["sample_azimuth"] != "":
                          method_codes.append(az_type)
                      redo = 0
                  while redo == 1:
                      if p >= len(SO_priorities):
                          print("no orientation data for ", s)
                          orient["sample_azimuth"] = ""
                          orient["sample_dip"] = ""
                          method_codes.append("SO-NO")
                          redo = 0
                      else:
                          az_type = SO_methods[SO_methods.index(
                              SO_priorities[p])]
                          orient = pmag.find_samp_rec(
                              RmagSpecRec["er_sample_name"], samp_data, az_type)
                          if orient["sample_azimuth"] != "":
                              method_codes.append(az_type)
                              redo = 0
                      p += 1
                  az, pl = orient['sample_azimuth'], orient['sample_dip']
                  s = pmag.dosgeo(s, az, pl)  # rotate to geographic coordinates
                  if coord == '100':
                      sample_bed_dir, sample_bed_dip = orient['sample_bed_dip_direction'], orient['sample_bed_dip']
                      # rotate to geographic coordinates
                      s = pmag.dostilt(s, sample_bed_dir, sample_bed_dip)
              hpars = pmag.dohext(nf, sigma, s)
          #
          # prepare for output
          #
              RmagSpecRec["anisotropy_s1"] = '%8.6f' % (s[0])
              RmagSpecRec["anisotropy_s2"] = '%8.6f' % (s[1])
              RmagSpecRec["anisotropy_s3"] = '%8.6f' % (s[2])
              RmagSpecRec["anisotropy_s4"] = '%8.6f' % (s[3])
              RmagSpecRec["anisotropy_s5"] = '%8.6f' % (s[4])
              RmagSpecRec["anisotropy_s6"] = '%8.6f' % (s[5])
              RmagSpecRec["anisotropy_mean"] = '%8.3e' % (trace / 3)
              RmagSpecRec["anisotropy_sigma"] = '%8.6f' % (sigma)
              RmagSpecRec["anisotropy_unit"] = "Am^2"
              RmagSpecRec["anisotropy_n"] = '%i' % (npos)
              RmagSpecRec["anisotropy_tilt_correction"] = coord
              # used by thellier_gui - must be taken out for uploading
              RmagSpecRec["anisotropy_F"] = '%7.1f ' % (hpars["F"])
              # used by thellier_gui - must be taken out for uploading
              RmagSpecRec["anisotropy_F_crit"] = hpars["F_crit"]
              RmagResRec["anisotropy_t1"] = '%8.6f ' % (hpars["t1"])
              RmagResRec["anisotropy_t2"] = '%8.6f ' % (hpars["t2"])
              RmagResRec["anisotropy_t3"] = '%8.6f ' % (hpars["t3"])
              RmagResRec["anisotropy_v1_dec"] = '%7.1f ' % (hpars["v1_dec"])
              RmagResRec["anisotropy_v2_dec"] = '%7.1f ' % (hpars["v2_dec"])
              RmagResRec["anisotropy_v3_dec"] = '%7.1f ' % (hpars["v3_dec"])
              RmagResRec["anisotropy_v1_inc"] = '%7.1f ' % (hpars["v1_inc"])
              RmagResRec["anisotropy_v2_inc"] = '%7.1f ' % (hpars["v2_inc"])
              RmagResRec["anisotropy_v3_inc"] = '%7.1f ' % (hpars["v3_inc"])
              RmagResRec["anisotropy_ftest"] = '%7.1f ' % (hpars["F"])
              RmagResRec["anisotropy_ftest12"] = '%7.1f ' % (hpars["F12"])
              RmagResRec["anisotropy_ftest23"] = '%7.1f ' % (hpars["F23"])
              RmagResRec["result_description"] = 'Critical F: ' + \
                  hpars["F_crit"] + ';Critical F12/F13: ' + hpars["F12_crit"]
              if hpars["e12"] > hpars["e13"]:
                  RmagResRec["anisotropy_v1_zeta_semi_angle"] = '%7.1f ' % (
                      hpars['e12'])
                  RmagResRec["anisotropy_v1_zeta_dec"] = '%7.1f ' % (
                      hpars['v2_dec'])
                  RmagResRec["anisotropy_v1_zeta_inc"] = '%7.1f ' % (
                      hpars['v2_inc'])
                  RmagResRec["anisotropy_v2_zeta_semi_angle"] = '%7.1f ' % (
                      hpars['e12'])
                  RmagResRec["anisotropy_v2_zeta_dec"] = '%7.1f ' % (
                      hpars['v1_dec'])
                  RmagResRec["anisotropy_v2_zeta_inc"] = '%7.1f ' % (
                      hpars['v1_inc'])
                  RmagResRec["anisotropy_v1_eta_semi_angle"] = '%7.1f ' % (
                      hpars['e13'])
                  RmagResRec["anisotropy_v1_eta_dec"] = '%7.1f ' % (
                      hpars['v3_dec'])
                  RmagResRec["anisotropy_v1_eta_inc"] = '%7.1f ' % (
                      hpars['v3_inc'])
                  RmagResRec["anisotropy_v3_eta_semi_angle"] = '%7.1f ' % (
                      hpars['e13'])
                  RmagResRec["anisotropy_v3_eta_dec"] = '%7.1f ' % (
                      hpars['v1_dec'])
                  RmagResRec["anisotropy_v3_eta_inc"] = '%7.1f ' % (
                      hpars['v1_inc'])
              else:
                  RmagResRec["anisotropy_v1_zeta_semi_angle"] = '%7.1f ' % (
                      hpars['e13'])
                  RmagResRec["anisotropy_v1_zeta_dec"] = '%7.1f ' % (
                      hpars['v3_dec'])
                  RmagResRec["anisotropy_v1_zeta_inc"] = '%7.1f ' % (
                      hpars['v3_inc'])
                  RmagResRec["anisotropy_v3_zeta_semi_angle"] = '%7.1f ' % (
                      hpars['e13'])
                  RmagResRec["anisotropy_v3_zeta_dec"] = '%7.1f ' % (
                      hpars['v1_dec'])
                  RmagResRec["anisotropy_v3_zeta_inc"] = '%7.1f ' % (
                      hpars['v1_inc'])
                  RmagResRec["anisotropy_v1_eta_semi_angle"] = '%7.1f ' % (
                      hpars['e12'])
                  RmagResRec["anisotropy_v1_eta_dec"] = '%7.1f ' % (
                      hpars['v2_dec'])
                  RmagResRec["anisotropy_v1_eta_inc"] = '%7.1f ' % (
                      hpars['v2_inc'])
                  RmagResRec["anisotropy_v2_eta_semi_angle"] = '%7.1f ' % (
                      hpars['e12'])
                  RmagResRec["anisotropy_v2_eta_dec"] = '%7.1f ' % (
                      hpars['v1_dec'])
                  RmagResRec["anisotropy_v2_eta_inc"] = '%7.1f ' % (
                      hpars['v1_inc'])
              if hpars["e23"] > hpars['e12']:
                  RmagResRec["anisotropy_v2_zeta_semi_angle"] = '%7.1f ' % (
                      hpars['e23'])
                  RmagResRec["anisotropy_v2_zeta_dec"] = '%7.1f ' % (
                      hpars['v3_dec'])
                  RmagResRec["anisotropy_v2_zeta_inc"] = '%7.1f ' % (
                      hpars['v3_inc'])
                  RmagResRec["anisotropy_v3_zeta_semi_angle"] = '%7.1f ' % (
                      hpars['e23'])
                  RmagResRec["anisotropy_v3_zeta_dec"] = '%7.1f ' % (
                      hpars['v2_dec'])
                  RmagResRec["anisotropy_v3_zeta_inc"] = '%7.1f ' % (
                      hpars['v2_inc'])
                  RmagResRec["anisotropy_v3_eta_semi_angle"] = '%7.1f ' % (
                      hpars['e13'])
                  RmagResRec["anisotropy_v3_eta_dec"] = '%7.1f ' % (
                      hpars['v1_dec'])
                  RmagResRec["anisotropy_v3_eta_inc"] = '%7.1f ' % (
                      hpars['v1_inc'])
                  RmagResRec["anisotropy_v2_eta_semi_angle"] = '%7.1f ' % (
                      hpars['e12'])
                  RmagResRec["anisotropy_v2_eta_dec"] = '%7.1f ' % (
                      hpars['v1_dec'])
                  RmagResRec["anisotropy_v2_eta_inc"] = '%7.1f ' % (
                      hpars['v1_inc'])
              else:
                  RmagResRec["anisotropy_v2_zeta_semi_angle"] = '%7.1f ' % (
                      hpars['e12'])
                  RmagResRec["anisotropy_v2_zeta_dec"] = '%7.1f ' % (
                      hpars['v1_dec'])
                  RmagResRec["anisotropy_v2_zeta_inc"] = '%7.1f ' % (
                      hpars['v1_inc'])
                  RmagResRec["anisotropy_v3_eta_semi_angle"] = '%7.1f ' % (
                      hpars['e23'])
                  RmagResRec["anisotropy_v3_eta_dec"] = '%7.1f ' % (
                      hpars['v2_dec'])
                  RmagResRec["anisotropy_v3_eta_inc"] = '%7.1f ' % (
                      hpars['v2_inc'])
                  RmagResRec["anisotropy_v3_zeta_semi_angle"] = '%7.1f ' % (
                      hpars['e13'])
                  RmagResRec["anisotropy_v3_zeta_dec"] = '%7.1f ' % (
                      hpars['v1_dec'])
                  RmagResRec["anisotropy_v3_zeta_inc"] = '%7.1f ' % (
                      hpars['v1_inc'])
                  RmagResRec["anisotropy_v2_eta_semi_angle"] = '%7.1f ' % (
                      hpars['e23'])
                  RmagResRec["anisotropy_v2_eta_dec"] = '%7.1f ' % (
                      hpars['v3_dec'])
                  RmagResRec["anisotropy_v2_eta_inc"] = '%7.1f ' % (
                      hpars['v3_inc'])
              RmagResRec["tilt_correction"] = '-1'
              RmagResRec["anisotropy_type"] = 'AARM'
              RmagResRec["magic_method_codes"] = 'LP-AN-ARM:AE-H'
              RmagSpecRec["magic_method_codes"] = 'LP-AN-ARM:AE-H'
              RmagResRec["magic_software_packages"] = pmag.get_version()
              RmagSpecRec["magic_software_packages"] = pmag.get_version()
              specimen += 1
              RmagSpecRecs.append(RmagSpecRec)
              RmagResRecs.append(RmagResRec)
              if data_model_num == 3:
                  SpecRec = RmagResRec.copy()
                  SpecRec.update(RmagSpecRec)
                  SpecRecs.append(SpecRec)
  
          else:
              print('skipping specimen ', s,
                    ' only 9 positions supported', '; this has ', npos)
              specimen += 1
  
      if data_model_num == 3:
          # translate records
          for rec in SpecRecs:
              rec3 = map_magic.convert_aniso('magic3', rec)
              SpecRecs3.append(rec3)
  
          # write output to 3.0 specimens file
          res, ofile = pmag.magic_write(output_spec_file, SpecRecs3, 'specimens')
          print("specimen data stored in {}".format(output_spec_file))
          if not res:
              return False, "Something went wrong and no records were created.  Are you sure your measurement file has the method code 'LP-AN-ARM'?"
          return True, output_spec_file
  
      else:
          if rmag_anis == "":
              rmag_anis = "rmag_anisotropy.txt"
          pmag.magic_write(rmag_anis, RmagSpecRecs, 'rmag_anisotropy')
          print("specimen tensor elements stored in ", rmag_anis)
          if rmag_res == "":
              rmag_res = "rmag_results.txt"
          pmag.magic_write(rmag_res, RmagResRecs, 'rmag_results')
          print("specimen statistics and eigenparameters stored in ", rmag_res)
          return True, rmag_anis