docs: def dolnp(data, direction_type_key):
      """
      Returns fisher mean, a95 for data  using method of Mcfadden and Mcelhinny '88 for lines and planes
  
      Parameters
      __________
      Data : nested list of dictionaries with keys
          Data model 3.0:
              dir_dec
              dir_inc
              dir_tilt_correction
              method_codes
          Data model 2.5:
              dec
              inc
              tilt_correction
              magic_method_codes
           direction_type_key :  ['specimen_direction_type']
      Returns
      -------
          ReturnData : dictionary with keys
              dec : fisher mean dec of data in Data
              inc : fisher mean inc of data in Data
              n_lines : number of directed lines [method_code = DE-BFL or DE-FM]
              n_planes : number of best fit planes [method_code = DE-BFP]
              alpha95  : fisher confidence circle from Data
              R : fisher R value of Data
              K : fisher k value of Data
      Effects
          prints to screen in case of no data
      """
  
      if 'dir_dec' in data[0].keys():
          tilt_key = 'dir_tilt_correction'  # this is data model 3.0
      else:
          tilt_key = 'tilt_correction'  # this is data model 3.0
      if tilt_key in list(data[0].keys()):
          tc = str(data[0][tilt_key])
      else:
          tc = '-1'
      dirV = [0, 0, 0]
      fpars = {}
  
      # sort data  into lines and planes and collect cartesian coordinates
      fdata, n_lines, L, n_planes, E = process_data_for_mean(
          data, direction_type_key)
  # set up initial points on the great circles
      V, XV = [], []
      if n_planes != 0:
          if n_lines == 0:
              # set the initial direction arbitrarily
              V = dir2cart([180., -45., 1.])
          else:
              R = np.sqrt(E[0]**2 + E[1]**2 + E[2]**2)
              for c in E:
                  # set initial direction as mean of lines
                  V.append(old_div(c, R))
          XV = calculate_best_fit_vectors(L, E, V, n_planes)
  # calculating overall mean direction and R
          U = E[:]
          for dir in XV:
              for c in range(3):
                  U[c] = U[c] + dir[c]
          R = np.sqrt(U[0]**2 + U[1]**2 + U[2]**2)
          for c in range(3):
              U[c] = old_div(U[c], R)
  # get dec and inc of solution points on gt circles
          dirV = cart2dir(U)
  # calculate modified Fisher stats fo fit
          n_total = n_lines + n_planes
          NP = n_lines + 0.5 * n_planes
          if NP < 1.1:
              NP = 1.1
          if n_total - R != 0:
              K = old_div((NP - 1.), (n_total - R))
              fac = (20.**(old_div(1., (NP - 1.))) - 1.)
              fac = fac * (NP - 1.) / K
              a = 1. - old_div(fac, R)
              a95 = a
              if abs(a) > 1.0:
                  a95 = 1.
              if a < 0:
                  a95 = -a95
              a95 = np.arccos(a95) * 180. / np.pi
          else:
              a95 = 0.
              K = 'inf'
      else:
          fdir = fisher_mean(fdata)
          n_total, R, K, a95 = fdir["n"], fdir["r"], fdir["k"], fdir["alpha95"]
          dirV[0], dirV[1] = fdir["dec"], fdir["inc"]
      fpars["tilt_correction"] = tc
      fpars["n_total"] = '%i ' % (n_total)
      fpars["n_lines"] = '%i ' % (n_lines)
      fpars["n_planes"] = '%i ' % (n_planes)
      fpars["R"] = '%5.4f ' % (R)
      if K != 'inf':
          fpars["K"] = '%6.0f ' % (K)
      else:
          fpars["K"] = K
      fpars["alpha95"] = '%7.1f ' % (a95)
      fpars["dec"] = '%7.1f ' % (dirV[0])
      fpars["inc"] = '%7.1f ' % (dirV[1])
      return fpars