code: def _read_ctf_comp(fid, node, chs, ch_names_mapping):
      """Read the CTF software compensation data from the given node.
  
      Parameters
      ----------
      fid : file
          The file descriptor.
      node : dict
          The node in the FIF tree.
      chs : list
          The list of channels from info['chs'] to match with
          compensators that are read.
      ch_names_mapping : dict | None
          The channel renaming to use.
      %(verbose)s
  
      Returns
      -------
      compdata : list
          The compensation data
      """
      from .meas_info import _rename_comps
  
      ch_names_mapping = (
          dict() if ch_names_mapping is None else ch_names_mapping
      )
      compdata = []
      comps = dir_tree_find(node, FIFF.FIFFB_MNE_CTF_COMP_DATA)
  
      for node in comps:
          #   Read the data we need
          mat = _read_named_matrix(
              fid, node, FIFF.FIFF_MNE_CTF_COMP_DATA
          )
          for p in range(node["nent"]):
              kind = node["directory"][p].kind
              pos = node["directory"][p].pos
              if kind == FIFF.FIFF_MNE_CTF_COMP_KIND:
                  tag = read_tag(fid, pos)
                  break
          else:
              raise Exception("Compensation type not found")
  
          #   Get the compensation kind and map it to a simple number
          one = dict(ctfkind=tag.data.item())
          del tag
          _add_kind(one)
          for p in range(node["nent"]):
              kind = node["directory"][p].kind
              pos = node["directory"][p].pos
              if kind == FIFF.FIFF_MNE_CTF_COMP_CALIBRATED:
                  tag = read_tag(fid, pos)
                  calibrated = tag.data
                  break
          else:
              calibrated = False
  
          one["save_calibrated"] = bool(calibrated)
          one["data"] = mat
          _rename_comps([one], ch_names_mapping)
          if not calibrated:
              #   Calibrate...
              _calibrate_comp(
                  one, chs, mat["row_names"], mat["col_names"]
              )
          else:
              one["rowcals"] = np.ones(
                  mat["data"].shape[0], dtype=np.float64
              )
              one["colcals"] = np.ones(
                  mat["data"].shape[1], dtype=np.float64
              )
  
          compdata.append(one)
  
      if len(compdata) > 0:
          logger.info(
              "    Read %d compensation matrices" % len(compdata)
          )
  
      return compdata
  
file_path: mne-python/mne/_fiff/ctf_comp.py
imports: from copy import deepcopy
  import numpy
  from ..utils import _pl, logger, verbose
  from .constants import FIFF
  from .matrix import _read_named_matrix, write_named_matrix
  from .tag import read_tag
  from .tree import dir_tree_find
  from .write import end_block, start_block, write_int
label_desc: Use image node_id 4 for calling a global function with example usage: _read_ctf_comp(fid, node, chs, ch_names_mapping) and returns: compdata