code: def read_custom_montage(
      fname, head_size=HEAD_SIZE_DEFAULT, coord_frame=None
  ):
      """Read a montage from a file.
  
      Parameters
      ----------
      fname : path-like
          File extension is expected to be:
          ``'.loc'`` or ``'.locs'`` or ``'.eloc'`` (for EEGLAB files),
          ``'.sfp'`` (BESA/EGI files), ``'.csd'``,
          ``'.elc'``, ``'.txt'``, ``'.csd'``, ``'.elp'`` (BESA spherical),
          ``'.bvef'`` (BrainVision files),
          ``'.csv'``, ``'.tsv'``, ``'.xyz'`` (XYZ coordinates).
      head_size : float | None
          The size of the head (radius, in [m]). If ``None``, returns the values
          read from the montage file with no modification. Defaults to 0.095m.
      coord_frame : str | None
          The coordinate frame of the points. Usually this is ``"unknown"``
          for native digitizer space. Defaults to None, which is ``"unknown"``
          for most readers but ``"head"`` for EEGLAB.
  
          .. versionadded:: 0.20
  
      Returns
      -------
      montage : instance of DigMontage
          The montage.
  
      See Also
      --------
      make_dig_montage
      make_standard_montage
  
      Notes
      -----
      The function is a helper to read electrode positions you may have
      in various formats. Most of these format are weakly specified
      in terms of units, coordinate systems. It implies that setting
      a montage using a DigMontage produced by this function may
      be problematic. If you use a standard/template (eg. 10/20,
      10/10 or 10/05) we recommend you use :func:`make_standard_montage`.
      If you can have positions in memory you can also use
      :func:`make_dig_montage` that takes arrays as input.
      """
      from ._standard_montage_utils import (
          _read_brainvision,
          _read_csd,
          _read_elc,
          _read_elp_besa,
          _read_sfp,
          _read_theta_phi_in_degrees,
          _read_xyz,
      )
  
      SUPPORTED_FILE_EXT = {
          "eeglab": (
              ".loc",
              ".locs",
              ".eloc",
          ),
          "hydrocel": (".sfp",),
          "matlab": (".csd",),
          "asa electrode": (".elc",),
          "generic (Theta-phi in degrees)": (".txt",),
          "standard BESA spherical": (
              ".elp",
          ),  # NB: not same as polhemus elp
          "brainvision": (".bvef",),
          "xyz": (".csv", ".tsv", ".xyz"),
      }
  
      fname = str(
          _check_fname(fname, overwrite="read", must_exist=True)
      )
      _, ext = op.splitext(fname)
      _check_option(
          "fname", ext, list(sum(SUPPORTED_FILE_EXT.values(), ()))
      )
  
      if ext in SUPPORTED_FILE_EXT["eeglab"]:
          if head_size is None:
              raise ValueError(
                  f"``head_size`` cannot be None for '{ext}'"
              )
          ch_names, pos = _read_eeglab_locations(fname)
          scale = head_size / np.median(np.linalg.norm(pos, axis=-1))
          pos *= scale
  
          montage = make_dig_montage(
              ch_pos=OrderedDict(zip(ch_names, pos)),
              coord_frame="head",
          )
  
      elif ext in SUPPORTED_FILE_EXT["hydrocel"]:
          montage = _read_sfp(fname, head_size=head_size)
  
      elif ext in SUPPORTED_FILE_EXT["matlab"]:
          montage = _read_csd(fname, head_size=head_size)
  
      elif ext in SUPPORTED_FILE_EXT["asa electrode"]:
          montage = _read_elc(fname, head_size=head_size)
  
      elif ext in SUPPORTED_FILE_EXT["generic (Theta-phi in degrees)"]:
          if head_size is None:
              raise ValueError(
                  f"``head_size`` cannot be None for '{ext}'"
              )
          montage = _read_theta_phi_in_degrees(
              fname, head_size=head_size, fid_names=("Nz", "LPA", "RPA")
          )
  
      elif ext in SUPPORTED_FILE_EXT["standard BESA spherical"]:
          montage = _read_elp_besa(fname, head_size)
  
      elif ext in SUPPORTED_FILE_EXT["brainvision"]:
          montage = _read_brainvision(fname, head_size)
  
      elif ext in SUPPORTED_FILE_EXT["xyz"]:
          montage = _read_xyz(fname)
  
      if coord_frame is not None:
          coord_frame = _coord_frame_const(coord_frame)
          for d in montage.dig:
              d["coord_frame"] = coord_frame
  
      return montage
  
imports: import os.path
  import re
  from collections import OrderedDict
  from copy import deepcopy
  from dataclasses import dataclass
  import numpy
  from .._fiff._digitization import _coord_frame_const, _count_points_by_type, _ensure_fiducials_head, _format_dig_points, _get_data_as_dict_from_dig, _get_dig_eeg, _get_fid_coords, _make_dig_points, _read_dig_fif, write_dig
  from .._fiff.constants import CHANNEL_LOC_ALIASES, FIFF
  from .._fiff.meas_info import create_info
  from .._fiff.open import fiff_open
  from .._fiff.pick import _picks_to_idx, channel_type, pick_types
  from .._freesurfer import get_mni_fiducials
  from ..defaults import HEAD_SIZE_DEFAULT
  from ..transforms import Transform, _ensure_trans, _fit_matched_points, _frame_to_str, _quat_to_affine, _sph_to_cart, _topo_to_sph, _verbose_frames, apply_trans, get_ras_to_neuromag_trans
  from ..utils import _check_fname, _check_option, _on_missing, _pl, _validate_type, copy_function_doc_to_method_doc, fill_doc, verbose, warn
  from ..utils.docs import docdict
  from ..viz import plot_montage
  from ._dig_montage_utils import _parse_brainvision_dig_montage, _read_dig_montage_egi
label_desc: Use image node_id 21 for calling a global function with example usage: read_custom_montage(fname, head_size, coord_frame) and returns: montage