# EEG Analysis Pipeline
A comprehensive Python package for EEG signal processing, trigger detection, and frequency-domain analysis.
## Overview
This package provides a complete pipeline for analyzing EEG data stored in European Data Format (EDF) files. It includes tools for signal loading, trigger detection, inter-trigger window analysis, and multi-band frequency-domain processing.
## Features
- **EDF File Loading**: Load and inspect EEG signals with flexible duration and channel selection
- **Trigger Detection**: Automated detection of trigger events with customizable thresholds
- **Window Analysis**: Generate and analyze inter-trigger intervals with multiple aggregation methods
- **Frequency-Domain Analysis**: Multi-band EEG analysis (Delta, Theta, Alpha, Beta, Gamma)
- **Visualization**: Comprehensive plotting and video generation capabilities
- **ML Integration**: Optional machine learning-based window quality filtering
## Installation
```bash
pip install yousif-raiyan-pip-package
```
## Quick Start
```python
from yousif_raiyan_pip_package import EDFLoader, TriggerDetector, Analyzer, EEGGraphProcessor
# Load EEG data
loader = EDFLoader("data", "subject_name")
loader.load_and_plot_signals(signal_indices=[15, 25], duration=1200.0) # T6, T2
# Option 1: Spectral analysis
detector = TriggerDetector(loader, 'T2')
detector.detect_triggers()
analyzer = Analyzer(loader, detector)
analyzer.extract_signals()
# Option 2: Graph-based connectivity analysis
processor = EEGGraphProcessor(edf_loader=loader)
# Compute time-varying correlation
processor.compute_correlation(start_time=0, stop_time=300, interval_seconds=10)
# Compute coherence across frequency bands
processor.compute_coherence_bands(start_time=0, stop_time=300, interval_seconds=10)
# Generate full graph representations for machine learning
processor.generate_graphs_from_edf()
```
## Data Structure Requirements
### Input Data Format
Your EDF files should be organized as follows:
```
data/
└── subject_name/
└── subject_name.edf
```
**Example:**
```
data/
└── Sebastian/
└── Sebastian.edf
```
### EDF File Requirements
- **Format**: European Data Format (.edf)
- **Channels**: Standard EEG channel names (Fp1, F3, F4, C3, C4, P3, P4, O1, O2, F7, F8, T3, T4, T5, T6, Fz)
- **Sample Rate**: Typically 500 Hz (automatically detected)
- **Duration**: Minimum 10 minutes recommended for trigger detection
## Classes and Methods
### EDFLoader
Handles loading and inspection of EDF files.
#### Initialization
```python
loader = EDFLoader(folder_path, name)
```
**Parameters:**
- `folder_path` (str): Base directory containing subject folders
- `name` (str): Subject name (must match folder and file name)
#### Methods
##### `inspect_data()`
Displays comprehensive file information including:
- File header details
- Number of signals and their properties
- Sample rates and signal ranges
- First 10 samples of each channel
```python
loader.inspect_data()
```
##### `load_and_plot_signals(signal_indices=None, duration=None, save_plots=False, save_path=None)`
Loads and visualizes EEG signals with flexible options.
**Parameters:**
- `signal_indices` (list, optional): Specific channel indices to load (default: all channels)
- `duration` (float, optional): Duration in seconds to load (default: entire file)
- `save_plots` (bool): Save plots instead of displaying (default: False)
- `save_path` (str, optional): Custom save directory (default: `plots/{subject_name}`)
**Examples:**
```python
# Load T6 and T2 channels for 20 minutes
loader.load_and_plot_signals(signal_indices=[15, 25], duration=1200.0)
# Load all channels and save plots
loader.load_and_plot_signals(save_plots=True)
# Load specific duration with custom save path
loader.load_and_plot_signals(duration=1200.0, save_plots=True, save_path="custom_plots")
```
**Output:**
- Time-series plots with time axis in seconds
- Saved to `plots/{subject_name}/signals_plot.png` (if save_plots=True)
### TriggerDetector
Detects triggers and analyzes inter-trigger windows.
#### Initialization
```python
detector = TriggerDetector(edf_loader, signal_choice)
```
**Parameters:**
- `edf_loader` (EDFLoader): Initialized EDFLoader instance
- `signal_choice` (str): Channel name for trigger detection (e.g., 'T2', 'O1')
#### Methods
##### `detect_triggers()`
Detects trigger events using amplitude thresholding.
**Algorithm:**
1. Rectifies and filters the signal (Butterworth low-pass, 30 Hz cutoff)
2. Applies amplitude threshold (60 µV)
3. Filters events by duration (52-65 seconds)
```python
detector.detect_triggers()
print(f"Found {len(detector.df_triggers)} triggers")
```
**Output:**
- `df_triggers` DataFrame with columns:
- `start_index`, `end_index`: Sample indices
- `start_time (s)`, `end_time (s)`: Time in seconds
- `duration_time (s)`: Trigger duration
##### `plot_triggers()`
Visualizes detected triggers overlaid on the filtered signal.
```python
detector.plot_triggers()
```
##### `save_triggers()`
Saves trigger information to CSV file.
```python
detector.save_triggers()
```
**Output:** `{subject_folder}/triggers.csv`
##### `plot_windows()`
Generates individual plots for each inter-trigger window.
```python
detector.plot_windows()
```
**Output:** `{subject_folder}/window plots/plot_{i}.png`
##### `convert_to_video()`
Creates MP4 video from window plots for rapid review.
```python
detector.convert_to_video()
```
**Output:** `{subject_folder}/trigger.mp4`
##### `filter_bad_windows(clf_path=None, classes_path=None)`
ML-based filtering of poor-quality windows using ResNet-50 + logistic regression.
```python
# Use built-in models (recommended)
detector.filter_bad_windows()
# Or use custom models
detector.filter_bad_windows(
clf_path="path/to/custom_classifier.pkl",
classes_path="path/to/custom_classes.npy"
)
```
**Parameters:**
- `clf_path` (str, optional): Path to custom classifier (.pkl file). Uses built-in model if None.
- `classes_path` (str, optional): Path to custom class labels (.npy file). Uses built-in model if None.
### Analyzer
Performs frequency-domain analysis of inter-trigger windows.
#### Initialization
```python
analyzer = Analyzer(loader, trigger_detector, target_length=50)
```
**Parameters:**
- `loader` (EDFLoader): Initialized EDFLoader instance
- `trigger_detector` (TriggerDetector): Initialized TriggerDetector instance
- `target_length` (int): Resampled points per segment for aggregation
#### Methods
##### `plot_signal_window(window_index, lead)`
Plots raw signal for a specific inter-trigger window.
```python
analyzer.plot_signal_window(window_index=0, lead='T2')
```
##### `plot_average_window(channel, start_window=None, end_window=None, target_length=500, aggregation_method='mean', trim_ratio=0.1)`
Aggregates and plots multiple windows using various statistical methods.
**Parameters:**
- `channel` (str): Channel name to analyze
- `start_window`, `end_window` (int, optional): Window range
- `target_length` (int): Resampling length
- `aggregation_method` (str): 'mean', 'median', or 'trimmed'
- `trim_ratio` (float): Trimming ratio for 'trimmed' method
**Examples:**
```python
# Mean aggregation
analyzer.plot_average_window('T6', aggregation_method='mean')
# Robust median aggregation
analyzer.plot_average_window('T6', aggregation_method='median')
# Trimmed mean (removes 10% outliers)
analyzer.plot_average_window('T6', aggregation_method='trimmed', trim_ratio=0.1)
```
##### `extract_signals(channels_to_extract=None)`
Comprehensive frequency-domain analysis across all EEG bands.
**Parameters:**
- `channels_to_extract` (list, optional): Specific channels to process (default: all loaded)
**Processing Pipeline:**
1. **Band-pass filtering** for each EEG band:
- Delta (0.5-4 Hz)
- Theta (4-8 Hz)
- Alpha (8-12 Hz)
- Beta (12-30 Hz)
- Gamma (30-80 Hz)
2. **Signal rectification** (absolute value for power estimation)
3. **Moving-average smoothing** with multiple window sizes:
- 100 ms, 250 ms, 500 ms
4. **Median aggregation** across all windows for robustness
**Examples:**
```python
# Process all loaded channels
analyzer.extract_signals()
# Process specific channels only
analyzer.extract_signals(['T2', 'T6', 'O1'])
```
### EEGGraphProcessor
Converts EEG data to graph representations for network analysis and computes time-varying connectivity measures.
#### Initialization
```python
processor = EEGGraphProcessor(
edf_loader=loader,
output_dir="graph_output", # Optional: custom output directory
window_size=1000, # Optional: analysis window size in samples
adj_window_size=20000, # Optional: adjacency matrix window size
window_step_ratio=0.125 # Optional: window overlap ratio
)
```
#### Methods
##### `generate_graphs_from_edf()`
Creates comprehensive graph representations with adjacency matrices and node/edge features.
**Features Generated:**
- **Adjacency matrices**: Correlation, coherence, phase relationships
- **Node features**: Energy, band-specific energy across frequency bands
- **Edge features**: Connectivity measures across frequency bands
- **Memory efficient**: Streams directly from EDF files
```python
processor.generate_graphs_from_edf()
# Output: {filename}.pickle with graph representations
```
##### `compute_correlation(start_time, stop_time, interval_seconds, overlap_ratio=0.0)`
Computes time-varying correlation matrices over specified time segments.
**Parameters:**
- `start_time` (float): Start time in seconds
- `stop_time` (float): End time in seconds
- `interval_seconds` (float): Window duration for each correlation matrix
- `overlap_ratio` (float): Overlap between windows (0.0 = no overlap, 0.5 = 50% overlap)
```python
# Compute correlation every 5 seconds from 10-60s with 50% overlap
path = processor.compute_correlation(
start_time=10.0,
stop_time=60.0,
interval_seconds=5.0,
overlap_ratio=0.5
)
```
**Output:** `{filename}_{start}s-{stop}s_correlation.pickle` containing:
```python
{
"starts": [10.0, 12.5, 15.0, ...], # Window start times
"corr_matrices": [matrix1, matrix2, ...] # Correlation matrices
}
```
##### `compute_coherence_average(start_time, stop_time, interval_seconds, overlap_ratio=0.0)`
Computes time-varying coherence matrices averaged across all frequency bands.
```python
# Simple averaged coherence analysis
path = processor.compute_coherence_average(
start_time=10.0,
stop_time=60.0,
interval_seconds=5.0
)
```
**Output:** `{filename}_{start}s-{stop}s_coherence_avg.pickle` containing:
```python
{
"starts": [10.0, 15.0, 20.0, ...],
"coherence_matrices": [matrix1, matrix2, ...] # Averaged coherence
}
```
##### `compute_coherence_bands(start_time, stop_time, interval_seconds, overlap_ratio=0.0)`
Computes detailed frequency-specific coherence analysis across EEG bands.
```python
# Detailed frequency-band coherence analysis
path = processor.compute_coherence_bands(
start_time=10.0,
stop_time=60.0,
interval_seconds=5.0,
overlap_ratio=0.25
)
```
**Output:** `{filename}_{start}s-{stop}s_coherence_bands.pickle` containing:
```python
{
"starts": [10.0, 15.0, 20.0, ...],
"coherence_by_band": {
"delta": [matrix1, matrix2, ...], # 1-4 Hz
"theta": [matrix1, matrix2, ...], # 4-8 Hz
"alpha": [matrix1, matrix2, ...], # 8-13 Hz
"beta": [matrix1, matrix2, ...], # 13-30 Hz
"gamma": [matrix1, matrix2, ...], # 30-70 Hz
"gammaHi": [matrix1, matrix2, ...], # 70-100 Hz
# Additional bands based on sampling frequency
},
"frequency_bands": {
"delta": (1, 4), "theta": (4, 8), "alpha": (8, 13), ...
}
}
```
#### Graph Analysis Workflow
```python
from yousif_raiyan_pip_package import EDFLoader, EEGGraphProcessor
# Load EEG data
loader = EDFLoader("data", "subject_name")
loader.load_and_plot_signals(duration=1200.0)
# Initialize graph processor
processor = EEGGraphProcessor(edf_loader=loader)
# Option 1: Full graph representation (for GNN analysis)
processor.generate_graphs_from_edf()
# Option 2: Time-varying connectivity analysis
# Simple correlation over time
corr_path = processor.compute_correlation(
start_time=0, stop_time=300, interval_seconds=10
)
# Average coherence analysis
coh_avg_path = processor.compute_coherence_average(
start_time=0, stop_time=300, interval_seconds=10
)
# Detailed frequency-band coherence
coh_bands_path = processor.compute_coherence_bands(
start_time=0, stop_time=300, interval_seconds=10, overlap_ratio=0.5
)
# Load and analyze results
import pickle
with open(coh_bands_path, 'rb') as f:
coherence_data = pickle.load(f)
# Access specific frequency band
alpha_coherence = coherence_data['coherence_by_band']['alpha']
time_points = coherence_data['starts']
```
## Output Structure
The package creates organized output directories:
```
data/
└── subject_name/
├── subject_name.edf # Input EDF file
├── triggers.csv # Detected triggers
├── window plots/ # Inter-trigger window plots
│ ├── plot_0.png
│ ├── plot_1.png
│ └── ...
├── trigger.mp4 # Video compilation
├── Delta/ # Frequency band results
│ ├── csv/
│ │ ├── T2_Delta_ma100ms_median.csv
│ │ └── ...
│ └── plots/
│ ├── T2_Delta_ma_plot.png
│ └── ...
├── Theta/
├── Alpha/
├── Beta/
└── Gamma/
```
## Complete Workflow Example
```python
from yousif_raiyan_pip_package import EDFLoader, TriggerDetector, Analyzer
# Step 1: Load EEG data
loader = EDFLoader("data", "Sebastian")
loader.inspect_data() # Review file structure
# Load temporal channels for analysis
loader.load_and_plot_signals(
signal_indices=[15, 25], # T6, T2 channels
duration=1200.0, # 20 minutes
save_plots=True
)
# Step 2: Detect triggers
detector = TriggerDetector(loader, 'T2')
detector.detect_triggers()
print(f"Found {len(detector.df_triggers)} triggers")
# Visualize and save results
detector.plot_triggers()
detector.save_triggers()
detector.plot_windows()
detector.convert_to_video()
# Step 3: Frequency-domain analysis
analyzer = Analyzer(loader, detector, target_length=50)
# Test different aggregation methods
analyzer.plot_average_window('T2', aggregation_method='mean')
analyzer.plot_average_window('T2', aggregation_method='median')
analyzer.plot_average_window('T2', aggregation_method='trimmed', trim_ratio=0.1)
# Full multi-band analysis
analyzer.extract_signals(['T6', 'T2']) # Process specific channels
```
## Advanced Usage
### Custom Trigger Detection Parameters
The trigger detection uses hardcoded parameters optimized for trigger detection:
- **Threshold**: 60 µV
- **Duration range**: 52-65 seconds
- **Filter**: 30 Hz low-pass Butterworth
### Memory Management
For large EDF files:
- Use `duration` parameter to limit data loading
- Use `signal_indices` to select specific channels
- Enable `save_plots=True` to avoid memory issues with display
### ML-Based Quality Control
For automated window quality assessment:
1. Train a ResNet-50 + logistic regression model on labeled window images
2. Save the classifier and class labels
3. Use `filter_bad_windows()` to automatically remove poor-quality segments
## Dependencies
- numpy
- scipy
- mne
- pyedflib
- matplotlib
- pandas
- opencv-python
- torch
- torchvision
- joblib
- scikit-learn
- Pillow
## Requirements
- Python ≥ 3.7
- Sufficient RAM for EEG data (recommend 8GB+ for large files)
- GPU optional (for ML-based filtering)
## Citation
If you use this package in your research, please cite:
```
[Your citation information here]
```
## License
MIT License
## Support
For questions or issues, please contact the package maintainer.
Raw data
{
"_id": null,
"home_page": null,
"name": "yousif-raiyan-pip-package",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.7",
"maintainer_email": "Raiyan <raiyan0511@gmail.com>",
"keywords": "eeg, signal-processing, neuroscience, graph-analysis, connectivity, coherence, correlation",
"author": null,
"author_email": "Raiyan <raiyan0511@gmail.com>",
"download_url": "https://files.pythonhosted.org/packages/34/44/17d8155c24e5e52cbebb3d5d50642f1c7b42571f2f410a1ade97d7715b3c/yousif_raiyan_pip_package-1.6.21.tar.gz",
"platform": null,
"description": "# EEG Analysis Pipeline\n\nA comprehensive Python package for EEG signal processing, trigger detection, and frequency-domain analysis.\n\n## Overview\n\nThis package provides a complete pipeline for analyzing EEG data stored in European Data Format (EDF) files. It includes tools for signal loading, trigger detection, inter-trigger window analysis, and multi-band frequency-domain processing.\n\n## Features\n\n- **EDF File Loading**: Load and inspect EEG signals with flexible duration and channel selection\n- **Trigger Detection**: Automated detection of trigger events with customizable thresholds\n- **Window Analysis**: Generate and analyze inter-trigger intervals with multiple aggregation methods\n- **Frequency-Domain Analysis**: Multi-band EEG analysis (Delta, Theta, Alpha, Beta, Gamma)\n- **Visualization**: Comprehensive plotting and video generation capabilities\n- **ML Integration**: Optional machine learning-based window quality filtering\n\n## Installation\n\n```bash\npip install yousif-raiyan-pip-package\n```\n\n## Quick Start\n\n```python\nfrom yousif_raiyan_pip_package import EDFLoader, TriggerDetector, Analyzer, EEGGraphProcessor\n\n# Load EEG data\nloader = EDFLoader(\"data\", \"subject_name\")\nloader.load_and_plot_signals(signal_indices=[15, 25], duration=1200.0) # T6, T2\n\n# Option 1: Spectral analysis\ndetector = TriggerDetector(loader, 'T2')\ndetector.detect_triggers()\n\nanalyzer = Analyzer(loader, detector)\nanalyzer.extract_signals()\n\n# Option 2: Graph-based connectivity analysis\nprocessor = EEGGraphProcessor(edf_loader=loader)\n\n# Compute time-varying correlation\nprocessor.compute_correlation(start_time=0, stop_time=300, interval_seconds=10)\n\n# Compute coherence across frequency bands\nprocessor.compute_coherence_bands(start_time=0, stop_time=300, interval_seconds=10)\n\n# Generate full graph representations for machine learning\nprocessor.generate_graphs_from_edf()\n```\n\n## Data Structure Requirements\n\n### Input Data Format\n\nYour EDF files should be organized as follows:\n\n```\ndata/\n\u2514\u2500\u2500 subject_name/\n \u2514\u2500\u2500 subject_name.edf\n```\n\n**Example:**\n```\ndata/\n\u2514\u2500\u2500 Sebastian/\n \u2514\u2500\u2500 Sebastian.edf\n```\n\n### EDF File Requirements\n\n- **Format**: European Data Format (.edf)\n- **Channels**: Standard EEG channel names (Fp1, F3, F4, C3, C4, P3, P4, O1, O2, F7, F8, T3, T4, T5, T6, Fz)\n- **Sample Rate**: Typically 500 Hz (automatically detected)\n- **Duration**: Minimum 10 minutes recommended for trigger detection\n\n## Classes and Methods\n\n### EDFLoader\n\nHandles loading and inspection of EDF files.\n\n#### Initialization\n```python\nloader = EDFLoader(folder_path, name)\n```\n\n**Parameters:**\n- `folder_path` (str): Base directory containing subject folders\n- `name` (str): Subject name (must match folder and file name)\n\n#### Methods\n\n##### `inspect_data()`\nDisplays comprehensive file information including:\n- File header details\n- Number of signals and their properties\n- Sample rates and signal ranges\n- First 10 samples of each channel\n\n```python\nloader.inspect_data()\n```\n\n##### `load_and_plot_signals(signal_indices=None, duration=None, save_plots=False, save_path=None)`\nLoads and visualizes EEG signals with flexible options.\n\n**Parameters:**\n- `signal_indices` (list, optional): Specific channel indices to load (default: all channels)\n- `duration` (float, optional): Duration in seconds to load (default: entire file)\n- `save_plots` (bool): Save plots instead of displaying (default: False)\n- `save_path` (str, optional): Custom save directory (default: `plots/{subject_name}`)\n\n**Examples:**\n```python\n# Load T6 and T2 channels for 20 minutes\nloader.load_and_plot_signals(signal_indices=[15, 25], duration=1200.0)\n\n# Load all channels and save plots\nloader.load_and_plot_signals(save_plots=True)\n\n# Load specific duration with custom save path\nloader.load_and_plot_signals(duration=1200.0, save_plots=True, save_path=\"custom_plots\")\n```\n\n**Output:**\n- Time-series plots with time axis in seconds\n- Saved to `plots/{subject_name}/signals_plot.png` (if save_plots=True)\n\n### TriggerDetector\n\nDetects triggers and analyzes inter-trigger windows.\n\n#### Initialization\n```python\ndetector = TriggerDetector(edf_loader, signal_choice)\n```\n\n**Parameters:**\n- `edf_loader` (EDFLoader): Initialized EDFLoader instance\n- `signal_choice` (str): Channel name for trigger detection (e.g., 'T2', 'O1')\n\n#### Methods\n\n##### `detect_triggers()`\nDetects trigger events using amplitude thresholding.\n\n**Algorithm:**\n1. Rectifies and filters the signal (Butterworth low-pass, 30 Hz cutoff)\n2. Applies amplitude threshold (60 \u00b5V)\n3. Filters events by duration (52-65 seconds)\n\n```python\ndetector.detect_triggers()\nprint(f\"Found {len(detector.df_triggers)} triggers\")\n```\n\n**Output:**\n- `df_triggers` DataFrame with columns:\n - `start_index`, `end_index`: Sample indices\n - `start_time (s)`, `end_time (s)`: Time in seconds\n - `duration_time (s)`: Trigger duration\n\n##### `plot_triggers()`\nVisualizes detected triggers overlaid on the filtered signal.\n\n```python\ndetector.plot_triggers()\n```\n\n##### `save_triggers()`\nSaves trigger information to CSV file.\n\n```python\ndetector.save_triggers()\n```\n\n**Output:** `{subject_folder}/triggers.csv`\n\n##### `plot_windows()`\nGenerates individual plots for each inter-trigger window.\n\n```python\ndetector.plot_windows()\n```\n\n**Output:** `{subject_folder}/window plots/plot_{i}.png`\n\n##### `convert_to_video()`\nCreates MP4 video from window plots for rapid review.\n\n```python\ndetector.convert_to_video()\n```\n\n**Output:** `{subject_folder}/trigger.mp4`\n\n##### `filter_bad_windows(clf_path=None, classes_path=None)`\nML-based filtering of poor-quality windows using ResNet-50 + logistic regression.\n\n```python\n# Use built-in models (recommended)\ndetector.filter_bad_windows()\n\n# Or use custom models\ndetector.filter_bad_windows(\n clf_path=\"path/to/custom_classifier.pkl\",\n classes_path=\"path/to/custom_classes.npy\"\n)\n```\n\n**Parameters:**\n- `clf_path` (str, optional): Path to custom classifier (.pkl file). Uses built-in model if None.\n- `classes_path` (str, optional): Path to custom class labels (.npy file). Uses built-in model if None.\n\n### Analyzer\n\nPerforms frequency-domain analysis of inter-trigger windows.\n\n#### Initialization\n```python\nanalyzer = Analyzer(loader, trigger_detector, target_length=50)\n```\n\n**Parameters:**\n- `loader` (EDFLoader): Initialized EDFLoader instance\n- `trigger_detector` (TriggerDetector): Initialized TriggerDetector instance\n- `target_length` (int): Resampled points per segment for aggregation\n\n#### Methods\n\n##### `plot_signal_window(window_index, lead)`\nPlots raw signal for a specific inter-trigger window.\n\n```python\nanalyzer.plot_signal_window(window_index=0, lead='T2')\n```\n\n##### `plot_average_window(channel, start_window=None, end_window=None, target_length=500, aggregation_method='mean', trim_ratio=0.1)`\nAggregates and plots multiple windows using various statistical methods.\n\n**Parameters:**\n- `channel` (str): Channel name to analyze\n- `start_window`, `end_window` (int, optional): Window range\n- `target_length` (int): Resampling length\n- `aggregation_method` (str): 'mean', 'median', or 'trimmed'\n- `trim_ratio` (float): Trimming ratio for 'trimmed' method\n\n**Examples:**\n```python\n# Mean aggregation\nanalyzer.plot_average_window('T6', aggregation_method='mean')\n\n# Robust median aggregation\nanalyzer.plot_average_window('T6', aggregation_method='median')\n\n# Trimmed mean (removes 10% outliers)\nanalyzer.plot_average_window('T6', aggregation_method='trimmed', trim_ratio=0.1)\n```\n\n##### `extract_signals(channels_to_extract=None)`\nComprehensive frequency-domain analysis across all EEG bands.\n\n**Parameters:**\n- `channels_to_extract` (list, optional): Specific channels to process (default: all loaded)\n\n**Processing Pipeline:**\n1. **Band-pass filtering** for each EEG band:\n - Delta (0.5-4 Hz)\n - Theta (4-8 Hz) \n - Alpha (8-12 Hz)\n - Beta (12-30 Hz)\n - Gamma (30-80 Hz)\n\n2. **Signal rectification** (absolute value for power estimation)\n\n3. **Moving-average smoothing** with multiple window sizes:\n - 100 ms, 250 ms, 500 ms\n\n4. **Median aggregation** across all windows for robustness\n\n**Examples:**\n```python\n# Process all loaded channels\nanalyzer.extract_signals()\n\n# Process specific channels only\nanalyzer.extract_signals(['T2', 'T6', 'O1'])\n```\n\n### EEGGraphProcessor\n\nConverts EEG data to graph representations for network analysis and computes time-varying connectivity measures.\n\n#### Initialization\n```python\nprocessor = EEGGraphProcessor(\n edf_loader=loader,\n output_dir=\"graph_output\", # Optional: custom output directory\n window_size=1000, # Optional: analysis window size in samples\n adj_window_size=20000, # Optional: adjacency matrix window size\n window_step_ratio=0.125 # Optional: window overlap ratio\n)\n```\n\n#### Methods\n\n##### `generate_graphs_from_edf()`\nCreates comprehensive graph representations with adjacency matrices and node/edge features.\n\n**Features Generated:**\n- **Adjacency matrices**: Correlation, coherence, phase relationships\n- **Node features**: Energy, band-specific energy across frequency bands\n- **Edge features**: Connectivity measures across frequency bands\n- **Memory efficient**: Streams directly from EDF files\n\n```python\nprocessor.generate_graphs_from_edf()\n# Output: {filename}.pickle with graph representations\n```\n\n##### `compute_correlation(start_time, stop_time, interval_seconds, overlap_ratio=0.0)`\nComputes time-varying correlation matrices over specified time segments.\n\n**Parameters:**\n- `start_time` (float): Start time in seconds\n- `stop_time` (float): End time in seconds \n- `interval_seconds` (float): Window duration for each correlation matrix\n- `overlap_ratio` (float): Overlap between windows (0.0 = no overlap, 0.5 = 50% overlap)\n\n```python\n# Compute correlation every 5 seconds from 10-60s with 50% overlap\npath = processor.compute_correlation(\n start_time=10.0,\n stop_time=60.0, \n interval_seconds=5.0,\n overlap_ratio=0.5\n)\n```\n\n**Output:** `{filename}_{start}s-{stop}s_correlation.pickle` containing:\n```python\n{\n \"starts\": [10.0, 12.5, 15.0, ...], # Window start times\n \"corr_matrices\": [matrix1, matrix2, ...] # Correlation matrices\n}\n```\n\n##### `compute_coherence_average(start_time, stop_time, interval_seconds, overlap_ratio=0.0)`\nComputes time-varying coherence matrices averaged across all frequency bands.\n\n```python\n# Simple averaged coherence analysis\npath = processor.compute_coherence_average(\n start_time=10.0,\n stop_time=60.0,\n interval_seconds=5.0\n)\n```\n\n**Output:** `{filename}_{start}s-{stop}s_coherence_avg.pickle` containing:\n```python\n{\n \"starts\": [10.0, 15.0, 20.0, ...],\n \"coherence_matrices\": [matrix1, matrix2, ...] # Averaged coherence\n}\n```\n\n##### `compute_coherence_bands(start_time, stop_time, interval_seconds, overlap_ratio=0.0)`\nComputes detailed frequency-specific coherence analysis across EEG bands.\n\n```python\n# Detailed frequency-band coherence analysis \npath = processor.compute_coherence_bands(\n start_time=10.0,\n stop_time=60.0,\n interval_seconds=5.0,\n overlap_ratio=0.25\n)\n```\n\n**Output:** `{filename}_{start}s-{stop}s_coherence_bands.pickle` containing:\n```python\n{\n \"starts\": [10.0, 15.0, 20.0, ...],\n \"coherence_by_band\": {\n \"delta\": [matrix1, matrix2, ...], # 1-4 Hz\n \"theta\": [matrix1, matrix2, ...], # 4-8 Hz \n \"alpha\": [matrix1, matrix2, ...], # 8-13 Hz\n \"beta\": [matrix1, matrix2, ...], # 13-30 Hz\n \"gamma\": [matrix1, matrix2, ...], # 30-70 Hz\n \"gammaHi\": [matrix1, matrix2, ...], # 70-100 Hz\n # Additional bands based on sampling frequency\n },\n \"frequency_bands\": {\n \"delta\": (1, 4), \"theta\": (4, 8), \"alpha\": (8, 13), ...\n }\n}\n```\n\n#### Graph Analysis Workflow\n\n```python\nfrom yousif_raiyan_pip_package import EDFLoader, EEGGraphProcessor\n\n# Load EEG data\nloader = EDFLoader(\"data\", \"subject_name\")\nloader.load_and_plot_signals(duration=1200.0)\n\n# Initialize graph processor\nprocessor = EEGGraphProcessor(edf_loader=loader)\n\n# Option 1: Full graph representation (for GNN analysis)\nprocessor.generate_graphs_from_edf()\n\n# Option 2: Time-varying connectivity analysis\n# Simple correlation over time\ncorr_path = processor.compute_correlation(\n start_time=0, stop_time=300, interval_seconds=10\n)\n\n# Average coherence analysis\ncoh_avg_path = processor.compute_coherence_average(\n start_time=0, stop_time=300, interval_seconds=10\n)\n\n# Detailed frequency-band coherence\ncoh_bands_path = processor.compute_coherence_bands(\n start_time=0, stop_time=300, interval_seconds=10, overlap_ratio=0.5\n)\n\n# Load and analyze results\nimport pickle\nwith open(coh_bands_path, 'rb') as f:\n coherence_data = pickle.load(f)\n \n# Access specific frequency band\nalpha_coherence = coherence_data['coherence_by_band']['alpha']\ntime_points = coherence_data['starts']\n```\n\n## Output Structure\n\nThe package creates organized output directories:\n\n```\ndata/\n\u2514\u2500\u2500 subject_name/\n \u251c\u2500\u2500 subject_name.edf # Input EDF file\n \u251c\u2500\u2500 triggers.csv # Detected triggers\n \u251c\u2500\u2500 window plots/ # Inter-trigger window plots\n \u2502 \u251c\u2500\u2500 plot_0.png\n \u2502 \u251c\u2500\u2500 plot_1.png\n \u2502 \u2514\u2500\u2500 ...\n \u251c\u2500\u2500 trigger.mp4 # Video compilation\n \u251c\u2500\u2500 Delta/ # Frequency band results\n \u2502 \u251c\u2500\u2500 csv/\n \u2502 \u2502 \u251c\u2500\u2500 T2_Delta_ma100ms_median.csv\n \u2502 \u2502 \u2514\u2500\u2500 ...\n \u2502 \u2514\u2500\u2500 plots/\n \u2502 \u251c\u2500\u2500 T2_Delta_ma_plot.png\n \u2502 \u2514\u2500\u2500 ...\n \u251c\u2500\u2500 Theta/\n \u251c\u2500\u2500 Alpha/\n \u251c\u2500\u2500 Beta/\n \u2514\u2500\u2500 Gamma/\n```\n\n## Complete Workflow Example\n\n```python\nfrom yousif_raiyan_pip_package import EDFLoader, TriggerDetector, Analyzer\n\n# Step 1: Load EEG data\nloader = EDFLoader(\"data\", \"Sebastian\")\nloader.inspect_data() # Review file structure\n\n# Load temporal channels for analysis\nloader.load_and_plot_signals(\n signal_indices=[15, 25], # T6, T2 channels\n duration=1200.0, # 20 minutes\n save_plots=True\n)\n\n# Step 2: Detect triggers\ndetector = TriggerDetector(loader, 'T2')\ndetector.detect_triggers()\nprint(f\"Found {len(detector.df_triggers)} triggers\")\n\n# Visualize and save results\ndetector.plot_triggers()\ndetector.save_triggers()\ndetector.plot_windows()\ndetector.convert_to_video()\n\n# Step 3: Frequency-domain analysis\nanalyzer = Analyzer(loader, detector, target_length=50)\n\n# Test different aggregation methods\nanalyzer.plot_average_window('T2', aggregation_method='mean')\nanalyzer.plot_average_window('T2', aggregation_method='median')\nanalyzer.plot_average_window('T2', aggregation_method='trimmed', trim_ratio=0.1)\n\n# Full multi-band analysis\nanalyzer.extract_signals(['T6', 'T2']) # Process specific channels\n```\n\n## Advanced Usage\n\n### Custom Trigger Detection Parameters\n\nThe trigger detection uses hardcoded parameters optimized for trigger detection:\n- **Threshold**: 60 \u00b5V\n- **Duration range**: 52-65 seconds\n- **Filter**: 30 Hz low-pass Butterworth\n\n### Memory Management\n\nFor large EDF files:\n- Use `duration` parameter to limit data loading\n- Use `signal_indices` to select specific channels\n- Enable `save_plots=True` to avoid memory issues with display\n\n### ML-Based Quality Control\n\nFor automated window quality assessment:\n1. Train a ResNet-50 + logistic regression model on labeled window images\n2. Save the classifier and class labels\n3. Use `filter_bad_windows()` to automatically remove poor-quality segments\n\n## Dependencies\n\n- numpy\n- scipy \n- mne\n- pyedflib\n- matplotlib\n- pandas\n- opencv-python\n- torch\n- torchvision\n- joblib\n- scikit-learn\n- Pillow\n\n## Requirements\n\n- Python \u2265 3.7\n- Sufficient RAM for EEG data (recommend 8GB+ for large files)\n- GPU optional (for ML-based filtering)\n\n## Citation\n\nIf you use this package in your research, please cite:\n\n```\n[Your citation information here]\n```\n\n## License\n\nMIT License\n\n## Support\n\nFor questions or issues, please contact the package maintainer.\n",
"bugtrack_url": null,
"license": null,
"summary": "Comprehensive EEG analysis pipeline with graph-based connectivity analysis, trigger detection, and frequency-domain processing",
"version": "1.6.21",
"project_urls": {
"Documentation": "https://github.com/raiyanUofT/yousif_raiyan_pip_package#readme",
"Homepage": "https://github.com/raiyanUofT/yousif_raiyan_pip_package",
"Issues": "https://github.com/raiyanUofT/yousif_raiyan_pip_package/issues",
"Repository": "https://github.com/raiyanUofT/yousif_raiyan_pip_package"
},
"split_keywords": [
"eeg",
" signal-processing",
" neuroscience",
" graph-analysis",
" connectivity",
" coherence",
" correlation"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "9f7c38ac72fa07f88568f80a20b719625049359d3302576752cea38de63a2a73",
"md5": "4afd61266ec9e6824c115c851240cdf0",
"sha256": "97e7a3656456458d031debe3552ae091fad88eb2db02736dba6bc70255347367"
},
"downloads": -1,
"filename": "yousif_raiyan_pip_package-1.6.21-py3-none-any.whl",
"has_sig": false,
"md5_digest": "4afd61266ec9e6824c115c851240cdf0",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.7",
"size": 41610,
"upload_time": "2025-07-22T22:20:02",
"upload_time_iso_8601": "2025-07-22T22:20:02.681762Z",
"url": "https://files.pythonhosted.org/packages/9f/7c/38ac72fa07f88568f80a20b719625049359d3302576752cea38de63a2a73/yousif_raiyan_pip_package-1.6.21-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "344417d8155c24e5e52cbebb3d5d50642f1c7b42571f2f410a1ade97d7715b3c",
"md5": "654ca1e95bebca9a8d17ec561ed8cc7b",
"sha256": "9df551ee0396e28502434e703fb2ffa6a3dc8ad8d69e1fa5ca9762fc3f7d73be"
},
"downloads": -1,
"filename": "yousif_raiyan_pip_package-1.6.21.tar.gz",
"has_sig": false,
"md5_digest": "654ca1e95bebca9a8d17ec561ed8cc7b",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.7",
"size": 52645,
"upload_time": "2025-07-22T22:20:04",
"upload_time_iso_8601": "2025-07-22T22:20:04.044716Z",
"url": "https://files.pythonhosted.org/packages/34/44/17d8155c24e5e52cbebb3d5d50642f1c7b42571f2f410a1ade97d7715b3c/yousif_raiyan_pip_package-1.6.21.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-07-22 22:20:04",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "raiyanUofT",
"github_project": "yousif_raiyan_pip_package#readme",
"github_not_found": true,
"lcname": "yousif-raiyan-pip-package"
}