code: def _get_info(
      fname,
      stim_channel,
      eog,
      misc,
      exclude,
      infer_types,
      preload,
      include=None,
  ):
      """Extract information from EDF+, BDF or GDF file."""
      eog = eog if eog is not None else []
      misc = misc if misc is not None else []
  
      edf_info, orig_units = _read_header(
          fname, exclude, infer_types, include
      )
  
      # XXX: `tal_ch_names` to pass to `_check_stim_channel` should be computed
      #      from `edf_info['ch_names']` and `edf_info['tal_idx']` but 'tal_idx'
      #      contains stim channels that are not TAL.
      stim_channel_idxs, _ = _check_stim_channel(
          stim_channel, edf_info["ch_names"]
      )
  
      sel = edf_info["sel"]  # selection of channels not excluded
      ch_names = edf_info["ch_names"]  # of length len(sel)
      if "ch_types" in edf_info:
          ch_types = edf_info["ch_types"]  # of length len(sel)
      else:
          ch_types = [None] * len(sel)
      if len(sel) == 0:  # only want stim channels
          n_samps = edf_info["n_samps"][[0]]
      else:
          n_samps = edf_info["n_samps"][sel]
      nchan = edf_info["nchan"]
      physical_ranges = (
          edf_info["physical_max"] - edf_info["physical_min"]
      )
      cals = edf_info["digital_max"] - edf_info["digital_min"]
      bad_idx = np.where((~np.isfinite(cals)) | (cals == 0))[0]
      if len(bad_idx) > 0:
          warn(
              "Scaling factor is not defined in following channels:\n"
              + ", ".join(ch_names[i] for i in bad_idx)
          )
          cals[bad_idx] = 1
      bad_idx = np.where(physical_ranges == 0)[0]
      if len(bad_idx) > 0:
          warn(
              "Physical range is not defined in following channels:\n"
              + ", ".join(ch_names[i] for i in bad_idx)
          )
          physical_ranges[bad_idx] = 1
  
      # Creates a list of dicts of eeg channels for raw.info
      logger.info("Setting channel info structure...")
      chs = list()
      pick_mask = np.ones(len(ch_names))
  
      chs_without_types = list()
  
      for idx, ch_name in enumerate(ch_names):
          chan_info = {}
          chan_info["cal"] = 1.0
          chan_info["logno"] = idx + 1
          chan_info["scanno"] = idx + 1
          chan_info["range"] = 1.0
          chan_info["unit_mul"] = FIFF.FIFF_UNITM_NONE
          chan_info["ch_name"] = ch_name
          chan_info["unit"] = FIFF.FIFF_UNIT_V
          chan_info["coord_frame"] = FIFF.FIFFV_COORD_HEAD
          chan_info["coil_type"] = FIFF.FIFFV_COIL_EEG
          chan_info["kind"] = FIFF.FIFFV_EEG_CH
          # montage can't be stored in EDF so channel locs are unknown:
          chan_info["loc"] = np.full(12, np.nan)
  
          # if the edf info contained channel type information
          # set it now
          ch_type = ch_types[idx]
          if ch_type is not None and ch_type in CH_TYPE_MAPPING:
              chan_info["kind"] = CH_TYPE_MAPPING.get(ch_type)
              if ch_type not in ["EEG", "ECOG", "SEEG", "DBS"]:
                  chan_info["coil_type"] = FIFF.FIFFV_COIL_NONE
              pick_mask[idx] = False
          # if user passes in explicit mapping for eog, misc and stim
          # channels set them here
          if ch_name in eog or idx in eog or idx - nchan in eog:
              chan_info["coil_type"] = FIFF.FIFFV_COIL_NONE
              chan_info["kind"] = FIFF.FIFFV_EOG_CH
              pick_mask[idx] = False
          elif ch_name in misc or idx in misc or idx - nchan in misc:
              chan_info["coil_type"] = FIFF.FIFFV_COIL_NONE
              chan_info["kind"] = FIFF.FIFFV_MISC_CH
              pick_mask[idx] = False
          elif idx in stim_channel_idxs:
              chan_info["coil_type"] = FIFF.FIFFV_COIL_NONE
              chan_info["unit"] = FIFF.FIFF_UNIT_NONE
              chan_info["kind"] = FIFF.FIFFV_STIM_CH
              pick_mask[idx] = False
              chan_info["ch_name"] = ch_name
              ch_names[idx] = chan_info["ch_name"]
              edf_info["units"][idx] = 1
          elif ch_type not in CH_TYPE_MAPPING:
              chs_without_types.append(ch_name)
          chs.append(chan_info)
  
      # warn if channel type was not inferable
      if len(chs_without_types):
          msg = (
              "Could not determine channel type of the following channels, "
              f'they will be set as EEG:\n{", ".join(chs_without_types)}'
          )
          logger.info(msg)
  
      edf_info["stim_channel_idxs"] = stim_channel_idxs
      if any(pick_mask):
          picks = [
              item
              for item, mask in zip(range(nchan), pick_mask)
              if mask
          ]
          edf_info["max_samp"] = max_samp = n_samps[picks].max()
      else:
          edf_info["max_samp"] = max_samp = n_samps.max()
  
      # Info structure
      # -------------------------------------------------------------------------
  
      not_stim_ch = [
          x
          for x in range(n_samps.shape[0])
          if x not in stim_channel_idxs
      ]
      if len(not_stim_ch) == 0:  # only loading stim channels
          not_stim_ch = list(range(len(n_samps)))
      sfreq = (
          np.take(n_samps, not_stim_ch).max()
          * edf_info["record_length"][1]
          / edf_info["record_length"][0]
      )
      del n_samps
      info = _empty_info(sfreq)
      info["meas_date"] = edf_info["meas_date"]
      info["chs"] = chs
      info["ch_names"] = ch_names
  
      # Subject information
      info["subject_info"] = {}
  
      # String subject identifier
      if edf_info["subject_info"].get("id") is not None:
          info["subject_info"]["his_id"] = edf_info["subject_info"][
              "id"
          ]
      # Subject sex (0=unknown, 1=male, 2=female)
      if edf_info["subject_info"].get("sex") is not None:
          if edf_info["subject_info"]["sex"] == "M":
              info["subject_info"]["sex"] = 1
          elif edf_info["subject_info"]["sex"] == "F":
              info["subject_info"]["sex"] = 2
          else:
              info["subject_info"]["sex"] = 0
      # Subject names (first, middle, last).
      if edf_info["subject_info"].get("name") is not None:
          sub_names = edf_info["subject_info"]["name"].split("_")
          if len(sub_names) < 2 or len(sub_names) > 3:
              info["subject_info"]["last_name"] = edf_info[
                  "subject_info"
              ]["name"]
          elif len(sub_names) == 2:
              info["subject_info"]["first_name"] = sub_names[0]
              info["subject_info"]["last_name"] = sub_names[1]
          else:
              info["subject_info"]["first_name"] = sub_names[0]
              info["subject_info"]["middle_name"] = sub_names[1]
              info["subject_info"]["last_name"] = sub_names[2]
      # Birthday in (year, month, day) format.
      if isinstance(edf_info["subject_info"].get("birthday"), datetime):
          info["subject_info"]["birthday"] = (
              edf_info["subject_info"]["birthday"].year,
              edf_info["subject_info"]["birthday"].month,
              edf_info["subject_info"]["birthday"].day,
          )
      # Handedness (1=right, 2=left, 3=ambidextrous).
      if edf_info["subject_info"].get("hand") is not None:
          info["subject_info"]["hand"] = int(
              edf_info["subject_info"]["hand"]
          )
      # Height in meters.
      if edf_info["subject_info"].get("height") is not None:
          info["subject_info"]["height"] = float(
              edf_info["subject_info"]["height"]
          )
      # Weight in kilograms.
      if edf_info["subject_info"].get("weight") is not None:
          info["subject_info"]["weight"] = float(
              edf_info["subject_info"]["weight"]
          )
  
      # Filter settings
      highpass = edf_info["highpass"]
      lowpass = edf_info["lowpass"]
      if highpass.size == 0:
          pass
      elif all(highpass):
          if highpass[0] == "NaN":
              # Placeholder for future use. Highpass set in _empty_info.
              pass
          elif highpass[0] == "DC":
              info["highpass"] = 0.0
          else:
              hp = highpass[0]
              try:
                  hp = float(hp)
              except Exception:
                  hp = 0.0
              info["highpass"] = hp
      else:
          info["highpass"] = float(np.max(highpass))
          warn(
              "Channels contain different highpass filters. Highest filter "
              "setting will be stored."
          )
      if np.isnan(info["highpass"]):
          info["highpass"] = 0.0
      if lowpass.size == 0:
          # Placeholder for future use. Lowpass set in _empty_info.
          pass
      elif all(lowpass):
          if lowpass[0] in ("NaN", "0", "0.0"):
              # Placeholder for future use. Lowpass set in _empty_info.
              pass
          else:
              info["lowpass"] = float(lowpass[0])
      else:
          info["lowpass"] = float(np.min(lowpass))
          warn(
              "Channels contain different lowpass filters. Lowest filter "
              "setting will be stored."
          )
      if np.isnan(info["lowpass"]):
          info["lowpass"] = info["sfreq"] / 2.0
  
      if info["highpass"] > info["lowpass"]:
          warn(
              f'Highpass cutoff frequency {info["highpass"]} is greater '
              f'than lowpass cutoff frequency {info["lowpass"]}, '
              "setting values to 0 and Nyquist."
          )
          info["highpass"] = 0.0
          info["lowpass"] = info["sfreq"] / 2.0
  
      # Some keys to be consistent with FIF measurement info
      info["description"] = None
      edf_info["nsamples"] = int(edf_info["n_records"] * max_samp)
  
      info._unlocked = False
      info._update_redundant()
  
      # Later used for reading
      edf_info["cal"] = physical_ranges / cals
  
      # physical dimension in µV
      edf_info["offsets"] = (
          edf_info["physical_min"]
          - edf_info["digital_min"] * edf_info["cal"]
      )
      del edf_info["physical_min"]
      del edf_info["digital_min"]
  
      if edf_info["subtype"] == "bdf":
          edf_info["cal"][stim_channel_idxs] = 1
          edf_info["offsets"][stim_channel_idxs] = 0
          edf_info["units"][stim_channel_idxs] = 1
  
      return info, edf_info, orig_units
  
imports: import os
  import re
  from datetime import datetime, timedelta, timezone
  import numpy
  from scipy.interpolate import interp1d
  from ..._fiff.constants import FIFF
  from ..._fiff.meas_info import _empty_info, _unique_channel_names
  from ..._fiff.utils import _blk_read_lims, _mult_cal_one
  from ...annotations import Annotations
  from ...filter import resample
  from ...utils import _validate_type, fill_doc, logger, verbose, warn
  from ..base import BaseRaw, _get_scaling
label_desc: Use image node_id 4 for calling a global function with example usage: _get_info(fname, stim_channel, eog, misc, exclude, infer_types, preload, include) and returns: info,  edf_info,  orig_units