code: def _read_evoked_mff(
      fname, condition, channel_naming="E%d", verbose=None
  ):
      """Read evoked data from MFF file."""
      import mffpy
  
      egi_info = _read_header(fname)
      mff = mffpy.Reader(fname)
      categories = mff.categories.categories
  
      if isinstance(condition, str):
          # Condition is interpreted as category name
          category = _check_option(
              "condition",
              condition,
              categories,
              extra="provided as category name",
          )
          epoch = mff.epochs[category]
      elif isinstance(condition, int):
          # Condition is interpreted as epoch index
          try:
              epoch = mff.epochs[condition]
          except IndexError:
              raise ValueError(
                  f'"condition" parameter ({condition}), provided '
                  "as epoch index, is out of range for available "
                  f"epochs ({len(mff.epochs)})."
              )
          category = epoch.name
      else:
          raise TypeError(
              '"condition" parameter must be either int or str.'
          )
  
      # Read in signals from the target epoch
      data = mff.get_physical_samples_from_epoch(epoch)
      eeg_data, t0 = data["EEG"]
      if "PNSData" in data:
          pns_data, t0 = data["PNSData"]
          all_data = np.vstack((eeg_data, pns_data))
          ch_types = egi_info["chan_type"] + egi_info["pns_types"]
      else:
          all_data = eeg_data
          ch_types = egi_info["chan_type"]
      all_data *= 1e-6  # convert to volts
  
      # Load metadata into info object
      # Exclude info['meas_date'] because record time info in
      # averaged MFF is the time of the averaging, not true record time.
      ch_names, mon = _read_locs(fname, egi_info, channel_naming)
      ch_names.extend(egi_info["pns_names"])
      info = create_info(ch_names, mff.sampling_rates["EEG"], ch_types)
      with info._unlock():
          info["device_info"] = dict(type=egi_info["device"])
          info["nchan"] = sum(mff.num_channels.values())
  
      # Add individual channel info
      # Get calibration info for EEG channels
      cals = _get_eeg_calibration_info(fname, egi_info)
      # Initialize calibration for PNS channels, will be updated later
      cals = np.concatenate(
          [cals, np.repeat(1, len(egi_info["pns_names"]))]
      )
      ch_coil = FIFF.FIFFV_COIL_EEG
      ch_kind = FIFF.FIFFV_EEG_CH
      chs = _create_chs(
          ch_names, cals, ch_coil, ch_kind, (), (), (), ()
      )
      # Update PNS channel info
      chs = _add_pns_channel_info(chs, egi_info, ch_names)
      with info._unlock():
          info["chs"] = chs
      if mon is not None:
          info.set_montage(mon, on_missing="ignore")
  
      # Add bad channels to info
      info["description"] = category
      try:
          channel_status = categories[category][0]["channelStatus"]
      except KeyError:
          warn(
              f"Channel status data not found for condition {category}. "
              "No channels will be marked as bad.",
              category=UserWarning,
          )
          channel_status = None
      bads = []
      if channel_status:
          for entry in channel_status:
              if entry["exclusion"] == "badChannels":
                  if entry["signalBin"] == 1:
                      # Add bad EEG channels
                      for ch in entry["channels"]:
                          bads.append(ch_names[ch - 1])
                  elif entry["signalBin"] == 2:
                      # Add bad PNS channels
                      for ch in entry["channels"]:
                          bads.append(egi_info["pns_names"][ch - 1])
      info["bads"] = bads
  
      # Add EEG reference to info
      try:
          fp = mff.directory.filepointer("history")
      except (
          ValueError,
          FileNotFoundError,
      ):  # old (<=0.6.3) vs new mffpy
          pass
      else:
          with fp:
              history = mffpy.XML.from_file(fp)
          for entry in history.entries:
              if entry["method"] == "Montage Operations Tool":
                  if "Average Reference" in entry["settings"]:
                      # Average reference has been applied
                      _, info = setup_proj(info)
  
      # Get nave from categories.xml
      try:
          nave = categories[category][0]["keys"]["#seg"]["data"]
      except KeyError:
          warn(
              f"Number of averaged epochs not found for condition {category}. "
              "nave will default to 1.",
              category=UserWarning,
          )
          nave = 1
  
      # Let tmin default to 0
      return EvokedArray(
          all_data,
          info,
          tmin=0.0,
          comment=category,
          nave=nave,
          verbose=verbose,
      )
  
imports: import datetime
  import math
  import os.path
  import re
  from collections import OrderedDict
  from pathlib import Path
  import numpy
  from ..._fiff.constants import FIFF
  from ..._fiff.meas_info import _empty_info, _ensure_meas_date_none_or_dt, create_info
  from ..._fiff.proj import setup_proj
  from ..._fiff.utils import _create_chs, _mult_cal_one
  from ...annotations import Annotations
  from ...channels.montage import make_dig_montage
  from ...evoked import EvokedArray
  from ...utils import _check_fname, _check_option, _soft_import, logger, verbose, warn
  from ..base import BaseRaw
  from .events import _combine_triggers, _read_events
  from .general import _block_r, _extract, _get_blocks, _get_ep_info, _get_gains, _get_signalfname
label_desc: Use image node_id 8 for calling a global function with example usage: _read_evoked_mff(fname, condition, channel_naming, verbose) and returns: EvokedArray