class_docstr: RawNeuralynx class.
code: def __init__(
      self,
      fname,
      *,
      preload=False,
      exclude_fname_patterns=None,
      verbose=None,
  ):
      fname = _check_fname(fname, "read", True, "fname", need_dir=True)
  
      _soft_import("neo", "Reading NeuralynxIO files", strict=True)
      from neo.io import NeuralynxIO
  
      logger.info(f"Checking files in {fname}")
  
      # construct a list of filenames to ignore
      exclude_fnames = None
      if exclude_fname_patterns:
          exclude_fnames = []
          for pattern in exclude_fname_patterns:
              fnames = glob.glob(os.path.join(fname, pattern))
              fnames = [os.path.basename(fname) for fname in fnames]
              exclude_fnames.extend(fnames)
  
          logger.info(
              "Ignoring .ncs files:\n" + "\n".join(exclude_fnames)
          )
  
      # get basic file info from header, throw Error if NeuralynxIO can't parse
      try:
          nlx_reader = NeuralynxIO(
              dirname=fname, exclude_filename=exclude_fnames
          )
      except ValueError as e:
          # give a more informative error message and what the user can do about it
          if "Incompatible section structures across streams" in str(e):
              raise ValueError(
                  "It seems .ncs channels have different numbers of samples. "
                  + "This is likely due to different sampling rates. "
                  + "Try reading in only channels with uniform sampling rate "
                  + "by excluding other channels with `exclude_fname_patterns` "
                  + "input argument."
                  + f"\nOriginal neo.NeuralynxRawIO ValueError:\n{e}"
              ) from None
          else:
              raise
  
      info = create_info(
          ch_types="seeg",
          ch_names=nlx_reader.header["signal_channels"][
              "name"
          ].tolist(),
          sfreq=nlx_reader.get_signal_sampling_rate(),
      )
  
      # Neo reads only valid contiguous .ncs samples grouped as segments
      n_segments = nlx_reader.header["nb_segment"][0]
      block_id = 0  # assumes there's only one block of recording
  
      # get segment start/stop times
      start_times = np.array(
          [
              nlx_reader.segment_t_start(block_id, i)
              for i in range(n_segments)
          ]
      )
      stop_times = np.array(
          [
              nlx_reader.segment_t_stop(block_id, i)
              for i in range(n_segments)
          ]
      )
  
      # find discontinuous boundaries (of length n-1)
      next_start_times = start_times[1::]
      previous_stop_times = stop_times[:-1]
      seg_diffs = next_start_times - previous_stop_times
  
      # mark as discontinuous any two segments that have
      # start/stop delta larger than sampling period (1.5/sampling_rate)
      logger.info(
          "Checking for temporal discontinuities in Neo data segments."
      )
      delta = 1.5 / info["sfreq"]
      gaps = seg_diffs > delta
  
      seg_gap_dict = {}
  
      logger.info(
          f"N = {gaps.sum()} discontinuous Neo segments detected "
          + f"with delta > {delta} sec. "
          + "Annotating gaps as BAD_ACQ_SKIP."
          if gaps.any()
          else "No discontinuities detected."
      )
  
      gap_starts = stop_times[:-1][gaps]  # gap starts at segment offset
      gap_stops = start_times[1::][gaps]  # gap stops at segment onset
  
      # (n_gaps,) array of ints giving number of samples per inferred gap
      gap_n_samps = np.array(
          [
              int(round(stop * info["sfreq"]))
              - int(round(start * info["sfreq"]))
              for start, stop in zip(gap_starts, gap_stops)
          ]
      ).astype(
          int
      )  # force an int array (if no gaps, empty array is a float)
  
      # get sort indices for all segments (valid and gap) in ascending order
      all_starts_ids = np.argsort(
          np.concatenate([start_times, gap_starts])
      )
  
      # variable indicating whether each segment is a gap or not
      gap_indicator = np.concatenate(
          [
              np.full(len(start_times), fill_value=0),
              np.full(len(gap_starts), fill_value=1),
          ]
      )
      gap_indicator = gap_indicator[all_starts_ids].astype(bool)
  
      # store this in a dict to be passed to _raw_extras
      seg_gap_dict = {
          "gap_n_samps": gap_n_samps,
          "isgap": gap_indicator,  # False (data segment) or True (gap segment)
      }
  
      valid_segment_sizes = [
          nlx_reader.get_signal_size(block_id, i)
          for i in range(n_segments)
      ]
  
      sizes_sorted = np.concatenate([valid_segment_sizes, gap_n_samps])[
          all_starts_ids
      ]
  
      # now construct an (n_samples,) indicator variable
      sample2segment = np.concatenate(
          [
              np.full(shape=(n,), fill_value=i)
              for i, n in enumerate(sizes_sorted)
          ]
      )
  
      # construct Annotations()
      gap_seg_ids = np.unique(sample2segment)[gap_indicator]
      gap_start_ids = np.array(
          [
              np.where(sample2segment == seg_id)[0][0]
              for seg_id in gap_seg_ids
          ]
      )
  
      # recreate time axis for gap annotations
      mne_times = np.arange(0, len(sample2segment)) / info["sfreq"]
  
      assert len(gap_start_ids) == len(gap_n_samps)
      annotations = Annotations(
          onset=[mne_times[onset_id] for onset_id in gap_start_ids],
          duration=[
              mne_times[onset_id + (n - 1)] - mne_times[onset_id]
              for onset_id, n in zip(gap_start_ids, gap_n_samps)
          ],
          description=["BAD_ACQ_SKIP"] * len(gap_start_ids),
      )
  
      super().__init__(
          info=info,
          last_samps=[sizes_sorted.sum() - 1],
          filenames=[fname],
          preload=preload,
          raw_extras=[
              dict(
                  smp2seg=sample2segment,
                  exclude_fnames=exclude_fnames,
                  segment_sizes=sizes_sorted,
                  seg_gap_dict=seg_gap_dict,
              )
          ],
      )
  
      self.set_annotations(annotations)
  
file_path: mne-python/mne/io/neuralynx/neuralynx.py
imports: import glob
  import os
  import numpy
  from ..._fiff.meas_info import create_info
  from ..._fiff.utils import _mult_cal_one
  from ...annotations import Annotations
  from ...utils import _check_fname, _soft_import, fill_doc, logger, verbose
  from ..base import BaseRaw
label_desc: Use image node_id 1 to create a new RawNeuralynx object from inherited base classes: BaseRaw with example: obj = RawNeuralynx(fname)