docs: def get_cap(self, cycle=None, dataset_number=None,
                  method="back-and-forth",
                  shift=0.0,
                  categorical_column=False,
                  label_cycle_number=False,
                  split=False,
                  interpolated=False,
                  dx=0.1,
                  number_of_points=None,
                  dynamic=False,
                  ):
          """Gets the capacity for the run.
          For cycle=None: not implemented yet, cycle set to 1.
  
          Args:
              cycle (int): cycle number.
              method (string): how the curves are given
                  "back-and-forth" - standard back and forth; discharge
                      (or charge) reversed from where charge (or discharge) ends.
                  "forth" - discharge (or charge) continues along x-axis.
                  "forth-and-forth" - discharge (or charge) also starts at 0
                      (or shift if not shift=0.0)
              shift: start-value for charge (or discharge) (typically used when
                  plotting shifted-capacity).
              categorical_column: add a categorical column showing if it is
                  charge or discharge.
              dataset_number (int): test number (default first)
                  (usually not used).
              label_cycle_number (bool): add column for cycle number
                  (tidy format).
              split (bool): return a list of c and v instead of the defualt
                  that is to return them combined in a DataFrame. This is only
                  possible for some specific combinations of options (neither
                  categorical_colum=True or label_cycle_number=True are
                  allowed).
              interpolated (bool): set to True if you would like to get
                  interpolated data (typically if you want to save disk space
                  or memory). Defaults to False.
              dx (float): the step used when interpolating.
              number_of_points (int): number of points to use (over-rides dx)
                  for interpolation (i.e. the length of the interpolated data).
              dynamic: for dynamic retrieving data from cellpy-file.
                  [NOT IMPLEMNETED YET]
  
          Returns:
              pandas.DataFrame ((cycle) voltage, capacity, (direction (-1, 1)))
                  unless split is explicitly set to True. Then it returns a tuple
                  with capacity (mAh/g) and voltage.
          """
  
          dataset_number = self._validate_dataset_number(dataset_number)
          if dataset_number is None:
              self._report_empty_dataset()
              return
  
          # if cycle is not given, then this function should
          # iterate through cycles
          if cycle is None:
              cycle = self.get_cycle_numbers()
  
          if not isinstance(cycle, (collections.Iterable,)):
              cycle = [cycle]
  
          if split and not (categorical_column or label_cycle_number):
              return_dataframe = False
          else:
              return_dataframe = True
  
          method = method.lower()
          if method not in ["back-and-forth", "forth", "forth-and-forth"]:
              warnings.warn(f"method '{method}' is not a valid option "
                            f"- setting to 'back-and-forth'")
              method = "back-and-forth"
  
          capacity = None
          voltage = None
          cycle_df = pd.DataFrame()
  
          initial = True
          for current_cycle in cycle:
              # self.logger.debug(f"processing cycle {current_cycle}")
              try:
                  cc, cv = self.get_ccap(current_cycle, dataset_number)
                  dc, dv = self.get_dcap(current_cycle, dataset_number)
              except NullData as e:
                  self.logger.debug(e)
                  self.logger.debug("breaking out of loop")
                  break
  
              if cc.empty:
                  self.logger.debug("get_ccap returns empty cc Series")
  
              if dc.empty:
                  self.logger.debug("get_ccap returns empty dc Series")
  
              if initial:
                  # self.logger.debug("(initial cycle)")
                  prev_end = shift
                  initial = False
  
              if self._cycle_mode == "anode":
                  _first_step_c = dc
                  _first_step_v = dv
                  _last_step_c = cc
                  _last_step_v = cv
              else:
                  _first_step_c = cc
                  _first_step_v = cv
                  _last_step_c = dc
                  _last_step_v = dv
  
              if method == "back-and-forth":
                  _last = np.amax(_first_step_c)
                  # should change amax to last point
                  _first = None
                  _new_first = None
                  if _last_step_c is not None:
                      _last_step_c = _last - _last_step_c + prev_end
                  else:
                      self.logger.debug("no last charge step found")
                  if _first_step_c is not None:
                      _first = _first_step_c.iat[0]
                      _first_step_c += prev_end
                      _new_first = _first_step_c.iat[0]
                  else:
                      self.logger.debug("probably empty (_first_step_c is None)")
                  # self.logger.debug(f"current shifts used: prev_end = {prev_end}")
                  # self.logger.debug(f"shifting start from {_first} to "
                  #                   f"{_new_first}")
  
                  prev_end = np.amin(_last_step_c)
                  # should change amin to last point
  
              elif method == "forth":
                  _last = np.amax(_first_step_c)
                  # should change amax to last point
                  if _last_step_c is not None:
                      _last_step_c += _last + prev_end
                  else:
                      self.logger.debug("no last charge step found")
                  if _first_step_c is not None:
                      _first_step_c += prev_end
                  else:
                      self.logger.debug("no first charge step found")
  
                  prev_end = np.amax(_last_step_c)
                  # should change amin to last point
  
              elif method == "forth-and-forth":
                  if _last_step_c is not None:
                      _last_step_c += shift
                  else:
                      self.logger.debug("no last charge step found")
                  if _first_step_c is not None:
                      _first_step_c += shift
                  else:
                      self.logger.debug("no first charge step found")
  
              if return_dataframe:
  
                  try:
                      _first_df = pd.DataFrame(
                              {
                                  "voltage": _first_step_v.values,
                                  "capacity": _first_step_c.values
                               }
                      )
                      if interpolated:
                          _first_df = _interpolate_df_col(
                              _first_df, y="capacity", x="voltage",
                              dx=dx, number_of_points=number_of_points,
                              direction=-1
                          )
                      if categorical_column:
                          _first_df["direction"] = -1
  
                      _last_df = pd.DataFrame(
                          {
                              "voltage": _last_step_v.values,
                              "capacity": _last_step_c.values
                          }
                      )
                      if interpolated:
                          _last_df = _interpolate_df_col(
                              _last_df, y="capacity", x="voltage",
                              dx=dx, number_of_points=number_of_points,
                              direction=1
                          )
                      if categorical_column:
                          _last_df["direction"] = 1
  
                  except AttributeError:
                      self.logger.info(f"could not extract cycle {current_cycle}")
                  else:
                      c = pd.concat([_first_df, _last_df], axis=0)
                      if label_cycle_number:
                          c.insert(0, "cycle", current_cycle)
                          # c["cycle"] = current_cycle
                          # c = c[["cycle", "voltage", "capacity", "direction"]]
                      if cycle_df.empty:
                          cycle_df = c
                      else:
                          cycle_df = pd.concat([cycle_df, c], axis=0)
  
              else:
                  logging.warning("returning non-dataframe")
                  c = pd.concat([_first_step_c, _last_step_c], axis=0)
                  v = pd.concat([_first_step_v, _last_step_v], axis=0)
  
                  capacity = pd.concat([capacity, c], axis=0)
                  voltage = pd.concat([voltage, v], axis=0)
  
          if return_dataframe:
              return cycle_df
          else:
              return capacity, voltage