docs: def select_ocv_points(cellpydata, cycles=None, selection_method="martin",
                        number_of_points=5,
                        interval=10,
                        relative_voltage=False,
                        report_times=False,
                        direction=None):
  
      """Select points from the ocvrlx steps.
  
          Args:
              cellpydata: CellpyData-object
              cycles: list of cycle numbers to process (optional)
              selection_method: criteria for selecting points
                  martin: select first and last, and then last/2, last/2/2 etc.
                      until you have reached the wanted number of points.
                  fixed_time: select first, and then
              number_of_points: number of points you want.
              interval: interval between each point (in use only for methods
                  where interval makes sense). If it is a list, then
                  number_of_points will be calculated as len(interval) + 1 (and
                  override the set number_of_points).
              relative_voltage: set to True if you would like the voltage to be
                  relative to the voltage before starting the ocv rlx step.
                  Defaults to False. Remark that for the initial rxl step (when
                  you just have put your cell on the tester) does not have any
                  prior voltage. The relative voltage will then be versus the
                  first measurement point.
              report_times: also report the ocv rlx total time if True (defaults
                  to False)
              direction ("up", "down" or "both"): select "up" if you would like
                  to process only the ocv rlx steps where the voltage is relaxing
                  upwards and vize versa. Defaults to "both".
  
          Returns:
              pandas.DataFrame
  
      """
  
      if cycles is None:
          cycles = cellpydata.get_cycle_numbers()
      else:
          if not isinstance(cycles, (list, tuple)):
              cycles = [cycles, ]
  
      if direction is None:
          direction = "both"
  
      if not isinstance(interval, (list, tuple)):
          interval = [float(interval) for _ in range(number_of_points-1)]
  
      ocv_rlx_id = "ocvrlx"
  
      step_table = cellpydata.dataset.step_table
      dfdata = cellpydata.dataset.dfdata
  
      ocv_steps = step_table.loc[
          step_table["cycle"].isin(cycles), :
      ]
  
      ocv_steps = ocv_steps.loc[
          ocv_steps.type.str.startswith(ocv_rlx_id), :
      ]
  
      if selection_method in ["fixed_times", "fixed_points", "selected_times"]:
          number_of_points = len(interval) + 1
  
      headers2 = []
      for j in range(number_of_points):
          n = str(j).zfill(2)
          headers2.append(f"point_{n}")
  
      # doing an iteration (thought I didnt have to, but...) (fix later)
  
      results_list = list()
      iter_range = number_of_points - 1
      if selection_method == "martin":
          iter_range -= 1
  
      for index, row in ocv_steps.iterrows():
  
          # voltage
          first, last, delta = (
              row['voltage_first'],
              row['voltage_last'],
              row['voltage_delta']
          )
  
          voltage_reference = 0.0
  
          if relative_voltage:
              if index > 0:
                  reference_row = step_table.iloc[index-1, :]
                  voltage_reference = reference_row['voltage_last']
  
              else:
                  voltage_reference = first
                  logging.warning("STEP 0: Using first point as ref voltage")
  
          # time
          start, end, duration = (
              row['step_time_first'],
              row['step_time_last'],
              row['step_time_delta']
          )
  
          cycle, step = (row['cycle'], row['step'])
          info = row['type']
  
          v_df = dfdata.loc[
              (dfdata["Cycle_Index"] == cycle) &
              (dfdata["Step_Index"] == step), ["Step_Time", "Voltage"]
          ]
  
          poi = []
  
          _end = end
          _start = start
  
          if report_times:
              t = str(datetime.timedelta(seconds=round(end-start, 0)))
              print(f"Cycle {cycle}:", end=" ")
              print(f"dt = {t}, dv = {first-last:6.3f}")
  
          for i, j in enumerate(range(max(1, iter_range))):
              if selection_method == "martin":
                  logging.debug("using the 'martin'-method")
                  _end = _end / 2.0
                  poi.append(_end)
  
              elif selection_method == "fixed_times":
                  logging.debug(f"using fixed times with interval {interval[i]}")
                  _start = _start + interval[i]
                  logging.debug(f"time: {_start}")
                  poi.append(_start)
              else:
                  # more methods to come?
                  logging.info("this method is not implemented")
                  return None
  
          if selection_method == "martin":
              poi.reverse()
  
          df_poi = pd.DataFrame({"Step_Time": poi})
          df_poi["Voltage"] = np.nan
  
          v_df = v_df.append(df_poi, ignore_index=True)
          v_df = v_df.sort_values("Step_Time").reset_index(drop=True)
          v_df["new"] = v_df["Voltage"].interpolate()
  
          voi = []
          for p in poi:
              _v = v_df.loc[v_df["Step_Time"].isin([p]), "new"].values
              _v = _v - voltage_reference
              voi.append(_v[0])
  
          poi.insert(0, start)
          voi.insert(0, first - voltage_reference)
          if selection_method == "martin":
              poi.append(end)
              voi.append(last - voltage_reference)
  
          d1 = {"cycle": cycle}
          d2 = {h: [v] for h, v in zip(headers2, voi)}
          d = {**d1, **d2}
          result = pd.DataFrame(d)
          result["step"] = step
          result["type"] = info
          results_list.append(result)
  
      final = pd.concat(results_list)
  
      if direction == "down":
          final = final.loc[final["type"] == "ocvrlx_down", :]
      elif direction == "up":
          final = final.loc[final["type"] == "ocvrlx_up", :]
  
      final = final.reset_index(drop=True)
  
      return final