code: def _read_evoked_besa_avr(fname, verbose):
      """Create EvokedArray from a BESA .avr file."""
      with open(fname) as f:
          header = f.readline().strip()
  
          # There are two versions of .avr files. The old style, generated by
          # BESA 1, 2 and 3 does not define Nchan and does not have channel names
          # in the file.
          new_style = "Nchan=" in header
          if new_style:
              ch_names = f.readline().strip().split()
          else:
              ch_names = None
  
      fields = _parse_header(header)
      data = np.loadtxt(fname, skiprows=2 if new_style else 1, ndmin=2)
      ch_types = _read_elp_sidecar(fname)
  
      # Consolidate channel names
      if new_style:
          if len(ch_names) != len(data):
              raise RuntimeError(
                  "Mismatch between the number of channel names defined in "
                  f"the .avr file ({len(ch_names)}) and the number of rows "
                  f"in the data matrix ({len(data)})."
              )
      else:
          # Determine channel names from the .elp sidecar file
          if ch_types is not None:
              ch_names = list(ch_types.keys())
              if len(ch_names) != len(data):
                  raise RuntimeError(
                      "Mismatch between the number of channels "
                      f"defined in the .avr file ({len(data)}) "
                      f"and .elp file ({len(ch_names)})."
                  )
          else:
              logger.info(
                  "No .elp file found and no channel names present in "
                  "the .avr file. Falling back to generic names. "
              )
              ch_names = [f"CH{i + 1:02d}" for i in range(len(data))]
  
      # Consolidate channel types
      if ch_types is None:
          logger.info("Marking all channels as EEG.")
          ch_types = ["eeg"] * len(ch_names)
      else:
          ch_types = [ch_types[ch] for ch in ch_names]
  
      # Go over all the header fields and make sure they are all defined to
      # something sensible.
      if "Npts" in fields:
          fields["Npts"] = int(fields["Npts"])
          if fields["Npts"] != data.shape[1]:
              logger.warn(
                  f"The size of the data matrix ({data.shape}) does not "
                  f'match the "Npts" field ({fields["Npts"]}).'
              )
      if "Nchan" in fields:
          fields["Nchan"] = int(fields["Nchan"])
          if fields["Nchan"] != data.shape[0]:
              logger.warn(
                  f"The size of the data matrix ({data.shape}) does not "
                  f'match the "Nchan" field ({fields["Nchan"]}).'
              )
      if "DI" in fields:
          fields["DI"] = float(fields["DI"])
      else:
          raise RuntimeError(
              'No "DI" field present. Could not determine '
              "sampling frequency."
          )
      if "TSB" in fields:
          fields["TSB"] = float(fields["TSB"])
      else:
          fields["TSB"] = 0
      if "SB" in fields:
          fields["SB"] = float(fields["SB"])
      else:
          fields["SB"] = 1.0
      if "SegmentName" not in fields:
          fields["SegmentName"] = ""
  
      # Build the Evoked object based on the header fields.
      info = create_info(
          ch_names, sfreq=1000 / fields["DI"], ch_types="eeg"
      )
      return EvokedArray(
          data / fields["SB"] / 1e6,
          info,
          tmin=fields["TSB"] / 1000,
          comment=fields["SegmentName"],
          verbose=verbose,
      )
  
file_path: mne-python/mne/io/besa/besa.py
imports: from collections import OrderedDict
  from pathlib import Path
  import numpy
  from ..._fiff.meas_info import create_info
  from ...evoked import EvokedArray
  from ...utils import fill_doc, logger, verbose
label_desc: Use image node_id 2 for calling a global function with example usage: _read_evoked_besa_avr(fname, verbose) and returns: EvokedArray