Advertisement
El_Chaderino

Neuroguide .ng to .EDF example script

May 20th, 2025
132
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.62 KB | None | 0 0
  1. def robust_convert_ng_to_edf(ng_file_path, edf_output_path, ch_names=None, sfreq=None, ch_types='eeg', header_size=2048):
  2.     """
  3.    Robustly convert a NeuroGuide .ng EEG file to EDF format.
  4.  
  5.    Args:
  6.        ng_file_path (str or Path): Path to .ng binary file.
  7.        edf_output_path (str or Path): Desired output path for the .edf file.
  8.        ch_names (list[str], optional): EEG channel labels. Defaults to generic if None.
  9.        sfreq (float, optional): Sampling rate. If None, attempts heuristic fallback.
  10.        ch_types (str or list, optional): EEG channel types. Default is 'eeg'.
  11.        header_size (int): Bytes to skip for header.
  12.  
  13.    Returns:
  14.        Path: Path to the written EDF file.
  15.  
  16.    Raises:
  17.        ValueError: If conversion fails due to data integrity or format issues.
  18.    """
  19.     try:
  20.         parsed = parse_neuroguide_ng(ng_file_path, header_size=header_size)
  21.     except Exception as e:
  22.         raise ValueError(f"Failed to parse .ng file: {e}")
  23.  
  24.     signals = parsed.get("signals")
  25.     metadata = parsed.get("metadata", {})
  26.  
  27.     if not signals or not isinstance(signals, list) or len(signals) == 0:
  28.         raise ValueError("No signal data extracted from .ng file.")
  29.  
  30.     n_channels = len(signals)
  31.     n_samples = len(signals[0])
  32.     if any(len(ch) != n_samples for ch in signals):
  33.         raise ValueError("Inconsistent sample lengths across channels.")
  34.  
  35.     data = np.array(signals, dtype=np.float64)
  36.  
  37.     # Channel labels
  38.     if ch_names is None:
  39.         known_19 = ["Fp1", "Fp2", "F7", "F3", "Fz", "F4", "F8",
  40.                     "T3", "C3", "Cz", "C4", "T4",
  41.                     "T5", "P3", "Pz", "P4", "T6", "O1", "O2"]
  42.         ch_names = known_19[:n_channels] if n_channels == 19 else [f"EEG {i+1}" for i in range(n_channels)]
  43.  
  44.     # Fallback sfreq guess
  45.     if sfreq is None:
  46.         # Naively assume 256Hz as typical default
  47.         sfreq = 256.0
  48.         print("⚠️ Sampling rate not specified. Defaulting to 256 Hz.")
  49.  
  50.     try:
  51.         info = mne.create_info(ch_names=ch_names, sfreq=sfreq, ch_types=ch_types)
  52.         raw = RawArray(data, info)
  53.     except Exception as e:
  54.         raise ValueError(f"Failed to create MNE Raw object: {e}")
  55.  
  56.     # EDF export fallback
  57.     try:
  58.         from mne.export import export_raw
  59.         edf_output_path = Path(edf_output_path)
  60.         export_raw(edf_output_path, raw, fmt='edf', overwrite=True)
  61.         return edf_output_path
  62.     except ImportError:
  63.         raise ImportError("MNE export_raw not available. Please update MNE to use EDF export.")
  64.     except Exception as e:
  65.         raise RuntimeError(f"Failed to export EDF: {e}")
  66.  
  67.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement