OSCR

Schumann-anchored golden ratio organization of human neural oscillations.

Code ↔ Paper

15 matches between paragraphs of the paper and lines of its authors' code, computed by the harvester (lexical-v1). Click a colored paragraph or line to see its counterpart.

The 15 matches
  1. [1] § Study 1: discovery and characterization of Schumann ignition events › The emergent pattern: golden ratio frequency ratios › Null control validation ↔ scripts/null_control_7_peak_based.py, lines 412–514 · score 0.79 · random triplets sampled, EEG spectral peaks, better precision, SIE detection, preferentially, SIE events
  2. [2] § Integration: the substrate-ignition model › Convergent evidence from both studies › Methodological triangulation: two complementary approaches ↔ scripts/null_control_7_peak_based.py, lines 412–514 · score 0.78 · EEG spectral structure, high coherence, SIE detection, FOOOF peak, inherent, precision
  3. [3] § Study 1: discovery and characterization of Schumann ignition events › Methods: SIE detection and analysis › Schumann resonance harmonic detection ↔ scripts/analyze_hup_positive_controls.py, lines 1–63 · score 0.75 · 1–50 Hz, peak width limits, periodic peaks, peak height, aperiodic, log
  4. [4] § Study 2: testing the φn hypothesis in continuous EEG › Methods: spectral parameterization and analysis › FOOOF spectral parameterization ↔ scripts/analyze_hup_positive_controls.py, lines 1–63 · score 0.73 · 1–50 Hz, peak width limits, peak height, 1–8 Hz, aperiodic, log
  5. [5] § Study 1: discovery and characterization of Schumann ignition events › The emergent pattern: golden ratio frequency ratios › Null control validation ↔ scripts/null_control_2_constrained.py, lines 674–777 · score 0.61 · cumulative distribution functions, random triplets, error distribution, SIE events, box, histogram
  6. [6] § Study 1: discovery and characterization of Schumann ignition events › The emergent pattern: golden ratio frequency ratios › Null control validation ↔ scripts/null_control_1_unconstrained.py, lines 499–602 · score 0.61 · cumulative distribution functions, random triplets, error distribution, SIE events, box, histogram
  7. [7] § Integration: the substrate-ignition model › SIEs as amplification of continuous φn architecture ↔ scripts/e8_energy_flow.py, lines 516–654 · score 0.58 · enable energy transfer, modulation, model, oscillator, amplitude, coupling
  8. [8] § Study 2: testing the φn hypothesis in continuous EEG › Methods: spectral parameterization and analysis › FOOOF spectral parameterization ↔ lib/irasa_peaks.py, lines 117–251 · score 0.57 · peak height, peak width, bandwidth, aperiodic, fit, FOOOF
  9. [9] § Study 1: discovery and characterization of Schumann ignition events › Methods: SIE detection and analysis › Schumann resonance harmonic detection ↔ lib/irasa_peaks.py, lines 117–251 · score 0.56 · peak height, peak width, Gaussian, log10, aperiodic, FOOOF
  10. [10] § Study 1: discovery and characterization of Schumann ignition events › Methods: SIE detection and analysis › EEG pre-processing ↔ scripts/batch_analyze_sessions.py, lines 190–336 · score 0.55 · Raw EEG signals, Schumann Resonance, filtered, activity, phase
  11. [11] § Theoretical framework: the φn hypothesis › Predictions for continuous spectral organization › Cross-frequency coupling geometry ↔ scripts/e8_energy_flow.py, lines 516–654 · score 0.51 · phase amplitude coupling, frequency bands, PAC, oscillators, gamma, theta
  12. [12] § Study 2: testing the φn hypothesis in continuous EEG › Validation: cross-device and cross-context consistency › Independent replication: EEGEmotions-27 dataset summary ↔ scripts/analyze_emotions_phi_lattice.py, lines 868–992 · score 0.51 · optimal f0, f0 sensitivity, emotion, plateau, alignment, shift
  13. [13] § Study 1: discovery and characterization of Schumann ignition events › Methods: SIE detection and analysis › Overview ↔ lib/comb_quantification.py, lines 1–45 · score 0.51 · Ignition Events, SciPy, MNE, NumPy, meditation, phase
  14. [14] § Study 2: testing the φn hypothesis in continuous EEG › Validation: cross-device and cross-context consistency › f0 sensitivity analysis ↔ scripts/analyze_brain_invaders_phi_lattice.py, lines 820–964 · score 0.50 · f0 sensitivity, boundary depletion, plateau, optimal, alignment, attractor
  15. [15] § Study 1: discovery and characterization of Schumann ignition events › Methods: SIE detection and analysis › Seven-stage detection pipeline ↔ scripts/sie_perionset_multistream.py, lines 1–73 · score 0.50 · Magnitude squared coherence, MSC, PLV, locking, harmonic, phase

Paper

Loaded from Europe PMC by your browser, not stored by OSCR: doi.org · Europe PMC

The paper is loaded when this pane is shown.

The authors' code

Python · 643 lines · 23 KB · no license · 2 matches

  1. #!/usr/bin/env python3
  2. """
  3. Null Control 7: Peak-Based Random Triplets from EEG Bands Data
  4. ==============================================================
  5. Tests if SIE events show better φ-convergence than random triplets
  6. sampled from the actual distribution of FOOOF peaks in EEG data.
  7. Uses golden_ratio_peaks_ALL.csv from eeg_bands paper analysis.
  8. Key difference from previous null controls:
  9. - Previous: Uniform sampling from frequency ranges (biased - ranges centered on φⁿ)
  10. - This: Sample from ACTUAL detected FOOOF peaks (controls for EEG spectral structure)
  11. Pass Criteria:
  12. - p < 0.05 (SIE triplets significantly more φ-precise than random peak triplets)
  13. - Cohen's d > 0.5 (substantial effect size)
  14. Note: If p > 0.05, this indicates φⁿ organization is inherent to EEG peaks,
  15. and SIEs represent amplification of existing structure (consistent with
  16. the independence-convergence finding).
  17. """
  18. import os
  19. import numpy as np
  20. import pandas as pd
  21. from scipy import stats
  22. import matplotlib.pyplot as plt
  23. import seaborn as sns
  24. from datetime import datetime
  25. from pathlib import Path
  26. from typing import Dict, List, Tuple, Optional
  27. # ============================================================================
  28. # Constants
  29. # ============================================================================
  30. PHI = (1 + np.sqrt(5)) / 2 # 1.618033988749895
  31. PHI_SQ = PHI ** 2 # 2.618033988749895
  32. PHI_CUBE = PHI ** 3 # 4.236067977499790
  33. # Band definitions for filtering peaks (Hz)
  34. # These should bracket the SR harmonics but not be too tight
  35. SR1_RANGE = (6.5, 9.5) # Fundamental (~7.6 Hz) - avoid alpha contamination
  36. SR3_RANGE = (18.0, 22.0) # ~φ² harmonic (~20 Hz)
  37. SR5_RANGE = (30.0, 36.0) # ~φ³ harmonic (~32 Hz)
  38. # Alternative wider bands for sensitivity analysis
  39. SR1_RANGE_WIDE = (5.0, 11.0)
  40. SR3_RANGE_WIDE = (16.0, 24.0)
  41. SR5_RANGE_WIDE = (28.0, 38.0)
  42. # Number of random triplets
  43. N_RANDOM_TRIPLETS = 10000
  44. # File paths
  45. PEAKS_FILE = 'golden_ratio_peaks_ALL.csv'
  46. SIE_FILE = 'PAPER-3-sie-analysis.csv'
  47. # ============================================================================
  48. # φ-Error Computation
  49. # ============================================================================
  50. def compute_phi_error(f1: float, f2: float, f3: float) -> float:
  51. """
  52. Compute mean φ-error for a frequency triplet.
  53. Expected ratios:
  54. - f2/f1 ≈ φ² (2.618) - SR3/SR1
  55. - f3/f1 ≈ φ³ (4.236) - SR5/SR1
  56. - f3/f2 ≈ φ (1.618) - SR5/SR3
  57. Returns percentage error.
  58. """
  59. r1 = f2 / f1 # Should be ~φ²
  60. r2 = f3 / f1 # Should be ~φ³
  61. r3 = f3 / f2 # Should be ~φ
  62. # Relative errors
  63. e1 = abs(r1 - PHI_SQ) / PHI_SQ
  64. e2 = abs(r2 - PHI_CUBE) / PHI_CUBE
  65. e3 = abs(r3 - PHI) / PHI
  66. return np.mean([e1, e2, e3]) * 100 # Percentage
  67. def compute_phi_error_detailed(f1: float, f2: float, f3: float) -> Dict:
  68. """Compute detailed φ-error breakdown for a triplet."""
  69. r1 = f2 / f1
  70. r2 = f3 / f1
  71. r3 = f3 / f2
  72. e1 = abs(r1 - PHI_SQ) / PHI_SQ * 100
  73. e2 = abs(r2 - PHI_CUBE) / PHI_CUBE * 100
  74. e3 = abs(r3 - PHI) / PHI * 100
  75. return {
  76. 'ratio_sr3_sr1': r1,
  77. 'ratio_sr5_sr1': r2,
  78. 'ratio_sr5_sr3': r3,
  79. 'error_sr3_sr1': e1,
  80. 'error_sr5_sr1': e2,
  81. 'error_sr5_sr3': e3,
  82. 'mean_error': np.mean([e1, e2, e3])
  83. }
  84. # ============================================================================
  85. # Data Loading
  86. # ============================================================================
  87. def load_peaks_data(filepath: str = PEAKS_FILE) -> pd.DataFrame:
  88. """Load FOOOF peaks from eeg_bands analysis."""
  89. print(f"Loading peaks from {filepath}...")
  90. df = pd.read_csv(filepath)
  91. print(f" Loaded {len(df):,} peaks")
  92. return df
  93. def load_sie_events(filepath: str = SIE_FILE) -> pd.DataFrame:
  94. """Load SIE events with harmonic frequencies."""
  95. print(f"Loading SIE events from {filepath}...")
  96. df = pd.read_csv(filepath)
  97. print(f" Loaded {len(df):,} events")
  98. return df
  99. def filter_peaks_by_band(peaks_df: pd.DataFrame,
  100. freq_range: Tuple[float, float]) -> np.ndarray:
  101. """Filter peaks to a frequency band and return frequencies."""
  102. mask = (peaks_df['freq'] >= freq_range[0]) & (peaks_df['freq'] <= freq_range[1])
  103. return peaks_df.loc[mask, 'freq'].values
  104. # ============================================================================
  105. # Triplet Generation
  106. # ============================================================================
  107. def generate_random_triplets(sr1_pool: np.ndarray,
  108. sr3_pool: np.ndarray,
  109. sr5_pool: np.ndarray,
  110. n: int = N_RANDOM_TRIPLETS,
  111. seed: int = None) -> np.ndarray:
  112. """
  113. Generate random triplets by sampling from peak pools.
  114. Returns array of φ-errors for each triplet.
  115. """
  116. if seed is not None:
  117. np.random.seed(seed)
  118. errors = []
  119. for _ in range(n):
  120. f1 = np.random.choice(sr1_pool)
  121. f2 = np.random.choice(sr3_pool)
  122. f3 = np.random.choice(sr5_pool)
  123. errors.append(compute_phi_error(f1, f2, f3))
  124. return np.array(errors)
  125. def extract_sie_errors(sie_df: pd.DataFrame) -> Tuple[np.ndarray, pd.DataFrame]:
  126. """
  127. Extract φ-errors from SIE events.
  128. Returns (errors_array, valid_events_df)
  129. """
  130. # Filter to events with all three harmonics
  131. valid_mask = (
  132. sie_df['sr1'].notna() &
  133. sie_df['sr3'].notna() &
  134. sie_df['sr5'].notna()
  135. )
  136. valid_df = sie_df[valid_mask].copy()
  137. errors = []
  138. for _, row in valid_df.iterrows():
  139. errors.append(compute_phi_error(row['sr1'], row['sr3'], row['sr5']))
  140. return np.array(errors), valid_df
  141. # ============================================================================
  142. # Statistical Analysis
  143. # ============================================================================
  144. def compute_statistics(sie_errors: np.ndarray,
  145. random_errors: np.ndarray) -> Dict:
  146. """Compute comprehensive comparison statistics."""
  147. sie_mean = np.mean(sie_errors)
  148. sie_std = np.std(sie_errors)
  149. sie_median = np.median(sie_errors)
  150. random_mean = np.mean(random_errors)
  151. random_std = np.std(random_errors)
  152. random_median = np.median(random_errors)
  153. # Effect size (Cohen's d) - positive means SIE is better (lower error)
  154. pooled_std = np.sqrt((sie_std**2 + random_std**2) / 2)
  155. cohens_d = (random_mean - sie_mean) / pooled_std
  156. # Percentile rank (what % of random triplets have HIGHER error than SIE mean)
  157. percentile = 100 * np.mean(random_errors > sie_mean)
  158. # P-value (proportion of random triplets with error <= SIE mean)
  159. p_value = np.mean(random_errors <= sie_mean)
  160. # Mann-Whitney U test (non-parametric)
  161. u_stat, p_mw = stats.mannwhitneyu(sie_errors, random_errors, alternative='less')
  162. # Permutation test
  163. observed_diff = sie_mean - random_mean
  164. combined = np.concatenate([sie_errors, random_errors])
  165. n_sie = len(sie_errors)
  166. n_perms = 10000
  167. perm_diffs = []
  168. for _ in range(n_perms):
  169. np.random.shuffle(combined)
  170. perm_sie = combined[:n_sie]
  171. perm_random = combined[n_sie:]
  172. perm_diffs.append(np.mean(perm_sie) - np.mean(perm_random))
  173. p_perm = np.mean(np.array(perm_diffs) <= observed_diff)
  174. # Bootstrap CI for SIE mean
  175. n_boot = 10000
  176. boot_means = []
  177. for _ in range(n_boot):
  178. boot_sample = np.random.choice(sie_errors, len(sie_errors), replace=True)
  179. boot_means.append(np.mean(boot_sample))
  180. ci_low, ci_high = np.percentile(boot_means, [2.5, 97.5])
  181. return {
  182. 'sie_mean': sie_mean,
  183. 'sie_std': sie_std,
  184. 'sie_median': sie_median,
  185. 'sie_ci_low': ci_low,
  186. 'sie_ci_high': ci_high,
  187. 'random_mean': random_mean,
  188. 'random_std': random_std,
  189. 'random_median': random_median,
  190. 'cohens_d': cohens_d,
  191. 'percentile': percentile,
  192. 'p_value_empirical': p_value,
  193. 'p_value_mannwhitney': p_mw,
  194. 'p_value_permutation': p_perm,
  195. 'n_sie': len(sie_errors),
  196. 'n_random': len(random_errors)
  197. }
  198. # ============================================================================
  199. # Visualization
  200. # ============================================================================
  201. def create_visualizations(sie_errors: np.ndarray,
  202. random_errors: np.ndarray,
  203. stats_results: Dict,
  204. output_dir: Path):
  205. """Create comprehensive visualizations."""
  206. sns.set_style("whitegrid")
  207. plt.rcParams['font.size'] = 10
  208. fig = plt.figure(figsize=(14, 10))
  209. gs = fig.add_gridspec(2, 2, hspace=0.3, wspace=0.3)
  210. # 1. Histogram comparison
  211. ax1 = fig.add_subplot(gs[0, 0])
  212. bins = np.linspace(0, max(np.max(sie_errors), np.percentile(random_errors, 99)), 50)
  213. ax1.hist(random_errors, bins=bins, alpha=0.6, label=f'Random Peaks (n={len(random_errors):,})',
  214. color='gray', density=True)
  215. ax1.hist(sie_errors, bins=bins, alpha=0.8, label=f'SIE Events (n={len(sie_errors)})',
  216. color='red', density=True)
  217. ax1.axvline(stats_results['sie_mean'], color='red', linestyle='--', linewidth=2,
  218. label=f"SIE mean: {stats_results['sie_mean']:.2f}%")
  219. ax1.axvline(stats_results['random_mean'], color='gray', linestyle='--', linewidth=2,
  220. label=f"Random mean: {stats_results['random_mean']:.2f}%")
  221. ax1.set_xlabel('Mean φ-Error (%)')
  222. ax1.set_ylabel('Density')
  223. ax1.set_title('φ-Error Distributions: SIE vs Random Peak Triplets')
  224. ax1.legend(fontsize=8)
  225. ax1.grid(True, alpha=0.3)
  226. # 2. Box plot comparison
  227. ax2 = fig.add_subplot(gs[0, 1])
  228. bp = ax2.boxplot([random_errors, sie_errors], labels=['Random\nPeaks', 'SIE\nEvents'],
  229. patch_artist=True, widths=0.6)
  230. bp['boxes'][0].set_facecolor('gray')
  231. bp['boxes'][0].set_alpha(0.6)
  232. bp['boxes'][1].set_facecolor('red')
  233. bp['boxes'][1].set_alpha(0.8)
  234. ax2.set_ylabel('Mean φ-Error (%)')
  235. ax2.set_title('φ-Error Comparison')
  236. ax2.grid(True, alpha=0.3, axis='y')
  237. # Add statistics annotation
  238. textstr = f"Cohen's d = {stats_results['cohens_d']:.3f}\n"
  239. textstr += f"p (perm) = {stats_results['p_value_permutation']:.4f}\n"
  240. textstr += f"p (M-W) = {stats_results['p_value_mannwhitney']:.4f}"
  241. ax2.text(0.95, 0.95, textstr, transform=ax2.transAxes, ha='right', va='top',
  242. bbox=dict(boxstyle='round', facecolor='wheat', alpha=0.5), fontsize=9)
  243. # 3. Cumulative distribution
  244. ax3 = fig.add_subplot(gs[1, 0])
  245. random_sorted = np.sort(random_errors)
  246. sie_sorted = np.sort(sie_errors)
  247. random_cdf = np.arange(1, len(random_sorted) + 1) / len(random_sorted)
  248. sie_cdf = np.arange(1, len(sie_sorted) + 1) / len(sie_sorted)
  249. ax3.plot(random_sorted, random_cdf, label='Random Peaks', color='gray', linewidth=2)
  250. ax3.plot(sie_sorted, sie_cdf, label='SIE Events', color='red', linewidth=2)
  251. ax3.axvline(stats_results['sie_mean'], color='red', linestyle='--', alpha=0.5)
  252. ax3.axhline(stats_results['percentile']/100, color='gray', linestyle=':', alpha=0.5)
  253. ax3.set_xlabel('Mean φ-Error (%)')
  254. ax3.set_ylabel('Cumulative Probability')
  255. ax3.set_title('Cumulative Distribution Functions')
  256. ax3.legend()
  257. ax3.grid(True, alpha=0.3)
  258. # 4. Difference from expected
  259. ax4 = fig.add_subplot(gs[1, 1])
  260. # Show how far each distribution is from perfect φ
  261. percentiles = [5, 10, 25, 50, 75, 90, 95]
  262. random_pcts = np.percentile(random_errors, percentiles)
  263. sie_pcts = np.percentile(sie_errors, percentiles)
  264. x = np.arange(len(percentiles))
  265. width = 0.35
  266. ax4.bar(x - width/2, random_pcts, width, label='Random Peaks', color='gray', alpha=0.6)
  267. ax4.bar(x + width/2, sie_pcts, width, label='SIE Events', color='red', alpha=0.8)
  268. ax4.set_xlabel('Percentile')
  269. ax4.set_ylabel('Mean φ-Error (%)')
  270. ax4.set_title('Percentile Comparison')
  271. ax4.set_xticks(x)
  272. ax4.set_xticklabels([f'{p}th' for p in percentiles])
  273. ax4.legend()
  274. ax4.grid(True, alpha=0.3, axis='y')
  275. # Overall status
  276. is_significant = stats_results['p_value_permutation'] < 0.05
  277. status = "SIGNIFICANT (p < 0.05)" if is_significant else "NOT SIGNIFICANT (p > 0.05)"
  278. color = 'green' if is_significant else 'orange'
  279. fig.suptitle(f'Peak-Based Null Control: {status}', fontsize=14, fontweight='bold', color=color)
  280. plt.tight_layout()
  281. plt.savefig(output_dir / 'nc7_peak_based_results.png', dpi=300, bbox_inches='tight')
  282. plt.savefig(output_dir / 'nc7_peak_based_results.pdf', bbox_inches='tight')
  283. plt.close()
  284. print(f"Visualizations saved to {output_dir}")
  285. def create_supplementary_figure(sie_df: pd.DataFrame,
  286. peaks_df: pd.DataFrame,
  287. sr1_range: Tuple,
  288. sr3_range: Tuple,
  289. sr5_range: Tuple,
  290. output_dir: Path):
  291. """Create supplementary figure showing peak distributions."""
  292. fig, axes = plt.subplots(1, 3, figsize=(14, 4))
  293. bands = [
  294. ('SR1', sr1_range, 'sr1', 'C0'),
  295. ('SR3', sr3_range, 'sr3', 'C1'),
  296. ('SR5', sr5_range, 'sr5', 'C2')
  297. ]
  298. for ax, (name, freq_range, col, color) in zip(axes, bands):
  299. # Peak distribution
  300. pool = filter_peaks_by_band(peaks_df, freq_range)
  301. ax.hist(pool, bins=50, alpha=0.6, color='gray', density=True,
  302. label=f'All peaks (n={len(pool):,})')
  303. # SIE frequencies
  304. sie_freqs = sie_df[col].dropna().values
  305. ax.hist(sie_freqs, bins=30, alpha=0.8, color=color, density=True,
  306. label=f'SIE events (n={len(sie_freqs)})')
  307. ax.axvline(np.mean(pool), color='gray', linestyle='--',
  308. label=f'Peak mean: {np.mean(pool):.2f}')
  309. ax.axvline(np.mean(sie_freqs), color=color, linestyle='--',
  310. label=f'SIE mean: {np.mean(sie_freqs):.2f}')
  311. ax.set_xlabel('Frequency (Hz)')
  312. ax.set_ylabel('Density')
  313. ax.set_title(f'{name} Band ({freq_range[0]}-{freq_range[1]} Hz)')
  314. ax.legend(fontsize=8)
  315. ax.grid(True, alpha=0.3)
  316. plt.tight_layout()
  317. plt.savefig(output_dir / 'nc7_peak_distributions.png', dpi=300, bbox_inches='tight')
  318. plt.close()
  319. # ============================================================================
  320. # Results Report
  321. # ============================================================================
  322. def generate_report(stats_results: Dict,
  323. pool_sizes: Dict,
  324. output_dir: Path) -> str:
  325. """Generate markdown results report."""
  326. is_sig = stats_results['p_value_permutation'] < 0.05
  327. status = "SIGNIFICANT" if is_sig else "NOT SIGNIFICANT"
  328. report = f"""# Null Control 7: Peak-Based Random Triplets - Results
  329. **Status: {status}** (p = {stats_results['p_value_permutation']:.4f})
  330. ## Summary
  331. This test compares SIE frequency triplets against random triplets sampled from
  332. **actual FOOOF peaks** detected in EEG recordings. Unlike the uniform sampling
  333. null (which samples uniformly from frequency ranges), this test controls for
  334. the actual spectral structure of EEG data.
  335. ## Peak Pool Sizes
  336. | Band | Frequency Range | N Peaks |
  337. |------|----------------|---------|
  338. | SR1 | {SR1_RANGE[0]}-{SR1_RANGE[1]} Hz | {pool_sizes['sr1']:,} |
  339. | SR3 | {SR3_RANGE[0]}-{SR3_RANGE[1]} Hz | {pool_sizes['sr3']:,} |
  340. | SR5 | {SR5_RANGE[0]}-{SR5_RANGE[1]} Hz | {pool_sizes['sr5']:,} |
  341. ## Statistical Results
  342. | Metric | SIE Events | Random Peaks |
  343. |--------|-----------|--------------|
  344. | N | {stats_results['n_sie']} | {stats_results['n_random']:,} |
  345. | Mean φ-error | {stats_results['sie_mean']:.2f}% | {stats_results['random_mean']:.2f}% |
  346. | Std | {stats_results['sie_std']:.2f}% | {stats_results['random_std']:.2f}% |
  347. | Median | {stats_results['sie_median']:.2f}% | {stats_results['random_median']:.2f}% |
  348. ### Statistical Tests
  349. | Test | Value | Interpretation |
  350. |------|-------|----------------|
  351. | Cohen's d | {stats_results['cohens_d']:.3f} | {'Large' if abs(stats_results['cohens_d']) > 0.8 else 'Medium' if abs(stats_results['cohens_d']) > 0.5 else 'Small'} effect |
  352. | Percentile | {stats_results['percentile']:.1f}% | {stats_results['percentile']:.1f}% of random triplets worse than SIE mean |
  353. | p (permutation) | {stats_results['p_value_permutation']:.4f} | {'Significant' if stats_results['p_value_permutation'] < 0.05 else 'Not significant'} |
  354. | p (Mann-Whitney) | {stats_results['p_value_mannwhitney']:.4f} | {'Significant' if stats_results['p_value_mannwhitney'] < 0.05 else 'Not significant'} |
  355. ### SIE Mean 95% CI
  356. {stats_results['sie_mean']:.2f}% [{stats_results['sie_ci_low']:.2f}%, {stats_results['sie_ci_high']:.2f}%]
  357. ## Interpretation
  358. """
  359. if is_sig:
  360. report += """SIE events show **significantly better φ-precision** than random triplets
  361. sampled from actual EEG peaks. This indicates that the SIE detection algorithm
  362. preferentially selects frequency combinations that are more φ-aligned than the
  363. typical EEG spectral structure would produce by chance.
  364. **Implication**: The φⁿ organization in SIE events is not simply an artifact of
  365. EEG spectral structure; SIEs represent genuinely exceptional frequency combinations.
  366. """
  367. else:
  368. report += """SIE events do **not** show significantly better φ-precision than random
  369. triplets sampled from actual EEG peaks. This indicates that **φⁿ organization is
  370. inherent to EEG spectral peaks** - when you sample peaks from the actual frequency
  371. distributions in EEG data, they naturally produce good φ-ratios.
  372. **Implication**: SIEs are not "spectrally exceptional" in terms of their frequency
  373. ratios. Instead, they represent **high-power, high-coherence amplification** of a
  374. φⁿ architecture that exists continuously in EEG. This is consistent with the
  375. independence-convergence finding: individual harmonic frequencies vary independently,
  376. yet ratios are preserved because the marginal frequency distributions are already
  377. constrained to φⁿ values.
  378. **This is actually the expected result** given the paper's main finding that φⁿ
  379. relationships are encoded at the population level rather than through event-level
  380. coordination.
  381. """
  382. report += f"""
  383. ## Comparison to Uniform Null
  384. | Null Model | p-value | Cohen's d | Interpretation |
  385. |------------|---------|-----------|----------------|
  386. | Uniform sampling | 0.074 | 1.71 | Marginal (biased null) |
  387. | **Peak-based** | **{stats_results['p_value_permutation']:.3f}** | **{stats_results['cohens_d']:.2f}** | {'Significant' if is_sig else 'Not significant'} (proper null) |
  388. The peak-based null is more appropriate because it controls for the actual
  389. spectral structure of EEG data rather than assuming uniform frequency distributions.
  390. ---
  391. *Generated: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}*
  392. """
  393. report_path = output_dir / 'nc7_results_summary.md'
  394. with open(report_path, 'w') as f:
  395. f.write(report)
  396. print(f"Report saved to {report_path}")
  397. return report
  398. # ============================================================================
  399. # Main Execution
  400. # ============================================================================
  401. def main():
  402. """Main execution function."""
  403. print("=" * 70)
  404. print("NULL CONTROL 7: Peak-Based Random Triplets")
  405. print("=" * 70)
  406. print()
  407. # Create output directory
  408. timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
  409. output_dir = Path(f'results/null_control_7_{timestamp}')
  410. output_dir.mkdir(parents=True, exist_ok=True)
  411. print(f"Output directory: {output_dir}")
  412. print()
  413. # Load data
  414. peaks_df = load_peaks_data()
  415. sie_df = load_sie_events()
  416. print()
  417. # Filter peaks into SR bands
  418. print("Filtering peaks by SR band...")
  419. sr1_pool = filter_peaks_by_band(peaks_df, SR1_RANGE)
  420. sr3_pool = filter_peaks_by_band(peaks_df, SR3_RANGE)
  421. sr5_pool = filter_peaks_by_band(peaks_df, SR5_RANGE)
  422. pool_sizes = {
  423. 'sr1': len(sr1_pool),
  424. 'sr3': len(sr3_pool),
  425. 'sr5': len(sr5_pool)
  426. }
  427. print(f" SR1 ({SR1_RANGE[0]}-{SR1_RANGE[1]} Hz): {len(sr1_pool):,} peaks")
  428. print(f" SR3 ({SR3_RANGE[0]}-{SR3_RANGE[1]} Hz): {len(sr3_pool):,} peaks")
  429. print(f" SR5 ({SR5_RANGE[0]}-{SR5_RANGE[1]} Hz): {len(sr5_pool):,} peaks")
  430. print()
  431. # Check for sufficient peaks
  432. min_peaks = 100
  433. if len(sr1_pool) < min_peaks or len(sr3_pool) < min_peaks or len(sr5_pool) < min_peaks:
  434. print(f"ERROR: Insufficient peaks in one or more bands (minimum {min_peaks} required)")
  435. return
  436. # Extract SIE errors
  437. print("Computing SIE φ-errors...")
  438. sie_errors, valid_sie_df = extract_sie_errors(sie_df)
  439. print(f" Valid SIE events (with all harmonics): {len(sie_errors)}")
  440. print(f" Mean SIE φ-error: {np.mean(sie_errors):.2f}%")
  441. print()
  442. # Generate random triplets
  443. print(f"Generating {N_RANDOM_TRIPLETS:,} random triplets from peak pools...")
  444. random_errors = generate_random_triplets(sr1_pool, sr3_pool, sr5_pool,
  445. n=N_RANDOM_TRIPLETS, seed=42)
  446. print(f" Mean random φ-error: {np.mean(random_errors):.2f}%")
  447. print()
  448. # Compute statistics
  449. print("Computing statistics...")
  450. stats_results = compute_statistics(sie_errors, random_errors)
  451. print()
  452. # Print results
  453. print("=" * 70)
  454. print("RESULTS")
  455. print("=" * 70)
  456. print(f"SIE mean φ-error: {stats_results['sie_mean']:.2f}% ± {stats_results['sie_std']:.2f}%")
  457. print(f"Random mean φ-error: {stats_results['random_mean']:.2f}% ± {stats_results['random_std']:.2f}%")
  458. print()
  459. print(f"Cohen's d: {stats_results['cohens_d']:.3f}")
  460. print(f"Percentile: {stats_results['percentile']:.1f}% of random triplets worse than SIE")
  461. print(f"P-value (perm): {stats_results['p_value_permutation']:.4f}")
  462. print(f"P-value (M-W): {stats_results['p_value_mannwhitney']:.4f}")
  463. print()
  464. is_sig = stats_results['p_value_permutation'] < 0.05
  465. if is_sig:
  466. print("STATUS: SIGNIFICANT - SIE events ARE more φ-precise than typical EEG peaks")
  467. else:
  468. print("STATUS: NOT SIGNIFICANT - φⁿ organization is inherent to EEG spectral peaks")
  469. print(" (consistent with population-level encoding hypothesis)")
  470. print("=" * 70)
  471. print()
  472. # Create visualizations
  473. print("Creating visualizations...")
  474. create_visualizations(sie_errors, random_errors, stats_results, output_dir)
  475. create_supplementary_figure(valid_sie_df, peaks_df, SR1_RANGE, SR3_RANGE, SR5_RANGE, output_dir)
  476. print()
  477. # Generate report
  478. print("Generating report...")
  479. generate_report(stats_results, pool_sizes, output_dir)
  480. print()
  481. # Save raw data
  482. print("Saving raw data...")
  483. # Save statistics
  484. stats_df = pd.DataFrame([stats_results])
  485. stats_df.to_csv(output_dir / 'statistics.csv', index=False)
  486. # Save error distributions (sample for random)
  487. errors_df = pd.DataFrame({
  488. 'sie_errors': np.concatenate([sie_errors, [np.nan] * (N_RANDOM_TRIPLETS - len(sie_errors))]),
  489. 'random_errors': random_errors
  490. })
  491. errors_df.to_csv(output_dir / 'error_distributions.csv', index=False)
  492. print(f"Raw data saved to {output_dir}")
  493. print()
  494. print("=" * 70)
  495. print("ANALYSIS COMPLETE")
  496. print("=" * 70)
  497. print(f"All results saved to: {output_dir}")
  498. print()
  499. return stats_results
  500. if __name__ == "__main__":
  501. results = main()

null_control_7_peak_based.py at commit a032dc0, no license · at the source

Overview

Authors: Michael Lacy1
  1. Independent Researcher, Austin, TX, United States
Journal: Frontiers in computational neuroscience, volume 20, article 1786996
Dates: received 13 January 2026; accepted 10 April 2026; published online 2 June 2026
Type: Research article · Language: English
License: CC BY
Identifiers: DOI 10.3389/fncom.2026.1786996 · PMID 42312247 · PMCID PMC13269411 · OpenAlex W7163174329
Open access: gold, a free copy (OpenAlex)
Status: code verified
Categories: EEG (modality), human (organism), systems (subfield)
Methods: Spectral & time-frequency, Statistics, Connectivity, Preprocessing, Physiology & signal measures
Keywords: EEG, FOOOF, golden ratio, neural oscillations, Schumann resonance, spectral parameterization, EEG band definitions, cross-frequency coupling
Topic: Neural dynamics and brain function (Cognitive Neuroscience, Neuroscience), according to OpenAlex
Citations: not cited yet (Europe PMC); 47 references in the paper

Abstract

Introduction: Human neural oscillations are organized according to golden ratio (φ = 1.618) mathematics: frequencies follow f(n)=f0×φn where f0≈7.6 Hz. This architecture manifests as spectral peak depletion at integer n positions (band boundaries) and enrichment at half-integer positions (band centers), providing empirical validation of a previously theorized φn architecture and identifying the absolute fundamental frequency f0 = 7.6 Hz. This organization was discovered and validated through two complementary studies.

Study 1—transient events: Analysis of 1,366 Schumann Ignition Events (SIEs)—transient episodes of multi-band network synchronization at Earth-resonant frequencies—across 91 participants, 661 sessions, and three EEG devices characterized harmonic frequencies that suggested φn relationships (< 1% mean ratio error). Individual frequencies varied independently across events (all |r| < 0.03), yet ratio precision was preserved—an “independence-convergence paradox” indicating population-level rather than event-level constraints. Null controls confirmed genuine organization (Cohen's d = 1.44, p < 0.0001).

Study 2—single-channel spectral architecture: Spectral parameterization of 244,955 oscillatory peaks across 968 sessions confirmed predictions derived from the φn framework: boundaries showed −18% depletion, attractors +21% enrichment, and noble positions (n+0.618) +39% enrichment in aggregate cross-band analysis. The framework extends to an eight-position hierarchy including “inverse nobles” (n+0.764, n+0.854)—symmetric to regular nobles about the attractor—which inherit stability through multi-scale Fibonacci pathways. Gamma exhibited strongest aggregate adherence (+144.8% at Noble1 in cross-band analysis), consistent with functional requirements for precise phase relationships, though this aggregate figure may partially reflect cross-band density effects (see Section 6.8, Limitation 5). Independent replication in the EEGEmotions-27 dataset (612,990 peaks, 2,342 sessions) confirmed the same qualitative pattern with Kendall's τ = 1.0.

Synthesis: Two independent methodological approaches—transient event detection and single-channel spectral parameterization—converge on identical conclusions: neural oscillations follow φn organization with perfect position ordering (Kendall's τ = 1.0) across all analyses. The fundamental frequency f0 = 7.6 Hz emerges independently from geophysical monitoring of Earth's Schumann Resonance and from neural spectral optimization, agreeing within 0.4%. These findings support a “substrate-ignition” model: the φn lattice exists continuously as an architectural scaffold organizing neural oscillations, while transient high-coherence events (SIEs) represent moments when this substrate is amplified and frequencies “snap” into tighter compliance. The golden ratio's unique mathematical properties—maximal resistance to mode-locking between frequency bands combined with precise Fibonacci-mediated cross-frequency coupling pathways—may represent evolution's solution to a fundamental computational challenge: maintaining independent parallel processing streams (segregation) while enabling flexible, controlled communication between them (integration).

Reproduced under the paper's license (CC BY), from the paper cited above.

Repositories

Its files are read in the Code ↔ Paper reader above, with 15 matches between paragraphs and lines of code.

neurokinetikz/research

License: none: the authors keep all their rights
State: the link answers, verified on 27 September 2026
Evidence: files inventoried
Commit: a032dc0edaa5d3820a49cfad3a20f8fc51d731b6, 29 June 2026
Languages: Python (857), Shell (27)
Size: 1,003 files, 884 scripts
Software Heritage: not archived
Found in: “Data availability statement”
Holds: README, tests
Not found: license file, CITATION.cff, environment file, continuous integration, documentation
Tools: NumPy (798 files), pandas (698 files), SciPy (605 files), Matplotlib (529 files), MNE-Python (267 files), scikit-learn (35 files), specparam (formerly FOOOF) (34 files), statsmodels (32 files), NetworkX (15 files), seaborn (13 files), MNE-Connectivity (3 files), NiBabel (3 files), Pillow (3 files), UMAP (3 files), h5py (1 file), imageio (1 file)
Availability: 1 check, the latest on 27 September 2026: the link answers
  • 27 September 2026: the link answers
885 files

neurokinetikz/schumann

License: CC-BY-4.0
State: the link answers, verified on 27 September 2026
Evidence: files inventoried
Commit: f31b9f1f6bafd9ae9aff746366137417d94ce631, 6 March 2026
Languages: Python (236), Jupyter (6)
Size: 303 files, 242 scripts
Software Heritage: not checked
Found in: “Generative AI statement”
Holds: README, tests, documentation, 6 notebooks
Not found: license file, CITATION.cff, environment file, continuous integration
Tools: NumPy (222 files), pandas (203 files), Matplotlib (148 files), SciPy (143 files), MNE-Python (23 files), scikit-learn (20 files), specparam (formerly FOOOF) (19 files), NetworkX (16 files), seaborn (14 files), statsmodels (10 files), UMAP (3 files), MNE-Connectivity (2 files), imageio (1 file), Pillow (1 file)
Availability: 1 check, the latest on 27 September 2026: the link answers
  • 27 September 2026: the link answers
243 files

Zenodo 18828203

License: CC-BY-4.0
State: the link answers, verified on 27 September 2026
Evidence: files inventoried
Size: 1 file, 0 scripts
Software Heritage: not checked
Found in: the references
Not found: README, license file, CITATION.cff, environment file, tests, continuous integration, documentation
Availability: 1 check, the latest on 27 September 2026: the link answers (HTTP 200)
  • 27 September 2026: the link answers (HTTP 200)
At the source:

Zenodo 18728199

License: CC-BY-4.0
State: the link answers, verified on 27 September 2026
Evidence: files inventoried
Size: 1 file, 0 scripts
Software Heritage: not checked
Found in: the references
Not found: README, license file, CITATION.cff, environment file, tests, continuous integration, documentation
Availability: 1 check, the latest on 27 September 2026: the link answers (HTTP 200)
  • 27 September 2026: the link answers (HTTP 200)
At the source:

The paper's code and data availability statement is in the Data section.

Tracing map

Proposed by the machine: these links were found in the paper and verified at the source, without human review. The map will receive a Zenodo DOI once one of the paper's authors has validated it with their ORCID.

What the map holds:

  • 4 repositories of the authors' code, each at its verified commit, with its license and how the link was found in the paper;
  • 1,126 scripts, each with its path and the digest of its content;
  • 15 matches between paragraphs of the paper and lines of the code (method lexical-v1);
  • neither the text of the paper nor the code itself.

Its JSON (tracing-map.json) is deposited on Zenodo with its DOI once the map is validated.

Data

Datasets cited

Data availability statement

The analysis code (FOOOF spectral parameterization pipeline, SIE detection, statistical analyses, figure generation) is publicly available at https://github.com/neurokinetikz/research. Validation datasets analyzed in this study were obtained from the following public sources: PhySF (Irshad et al., 2023), MultiPENG (Rashed et al., 2025), VEP (Tiwari et al., 2025), and EEGEmotions-27 (Phuong et al., 2025); access procedures are described in the original publications. The longitudinal meditation EEG recordings used as the discovery dataset are available from the corresponding author upon reasonable request, subject to privacy considerations of single-subject longitudinal data. FOOOF peak detection outputs and derived analysis files are available as supplementary data.

Reproduced under the paper's license (CC BY), from the paper cited above.

Versions

The history of this record: each version stored by the harvester or made by a correction of its authors or of the maintainers of its code, and what changed in its facts. The texts of the paper (its abstract, its availability statements) are not part of it; versions that changed only those are not listed.

Version 1, 27 September 2026: the first record

Recorded: type, language, journal, volume, pages, dates, 1 author, 8 keywords, 42 references.

Cite

This paper

Lacy, M. (2026). Schumann-anchored golden ratio organization of human neural oscillations. Frontiers in computational neuroscience, 20, 1786996. https://doi.org/10.3389/fncom.2026.1786996

BibTeX

@article{lacy2026schumann,
author = {Lacy, Michael},
title = {{Schumann-anchored golden ratio organization of human neural oscillations}},
journal = {Frontiers in computational neuroscience},
year = {2026},
month = jun,
volume = {20},
pages = {1786996},
publisher = {Frontiers Media SA},
issn = {1662-5188},
doi = {10.3389/fncom.2026.1786996},
url = {https://doi.org/10.3389/fncom.2026.1786996},
pmid = {42312247},
pmcid = {PMC13269411}
}

RIS

TY - JOUR
AU - Lacy, Michael
TI - Schumann-anchored golden ratio organization of human neural oscillations
T2 - Frontiers in computational neuroscience
J2 - Front Comput Neurosci
PY - 2026
DA - 2026/06/02
VL - 20
SP - 1786996
SN - 1662-5188
PB - Frontiers Media SA
DO - 10.3389/fncom.2026.1786996
UR - https://doi.org/10.3389/fncom.2026.1786996
LA - en
ER -

CSL-JSON

{
"id": "10.3389/fncom.2026.1786996",
"type": "article-journal",
"title": "Schumann-anchored golden ratio organization of human neural oscillations",
"container-title": "Frontiers in computational neuroscience",
"author": [
{
"family": "Lacy",
"given": "Michael"
}
],
"container-title-short": "Front Comput Neurosci",
"volume": "20",
"page": "1786996",
"DOI": "10.3389/fncom.2026.1786996",
"PMID": "42312247",
"PMCID": "PMC13269411",
"ISSN": "1662-5188",
"publisher": "Frontiers Media SA",
"URL": "https://doi.org/10.3389/fncom.2026.1786996",
"language": "en",
"issued": {
"date-parts": [
[
2026,
6,
2
]
]
}
}

The tracing map gets a citation of its own once an author has validated it and it has a DOI.

Similar papers

The papers with a page that share the most with this one: the tools found in their code, their categories, datasets, cited references and authors, the rarest counting most.

[1] doi:10.3389/fnhum.2026.1781338 [code]
Golden ratio organization in human EEG is associated with theta-alpha frequency convergence: a multi-dataset validation study.
Journal: Frontiers in human neuroscience
In common: specparam (formerly FOOOF), MNE-Python, seaborn, 4 other tools, EEG, 8 references
[2] doi:10.7554/elife.100605 [code]
Age-related changes in ‘cortical’ 1/f dynamics are linked to cardiac activity
Journal: n/a
In common: specparam (formerly FOOOF), MNE-Python, NetworkX, 8 other tools, 2 references
[3] doi:10.1093/nc/niag029 [code]
A data-driven approach to identifying and evaluating connectivity-based neural correlates of conscious visual perception.
Journal: Neuroscience of consciousness
In common: MNE-Connectivity, MNE-Python, NetworkX, 8 other tools, 2 references
[4] doi:10.1038/s41467-026-70287-5 [code]
Cortical-limbic circuit dynamics of approach-avoidance conflict in humans.
Journal: Nature communications
In common: specparam (formerly FOOOF), MNE-Python, NiBabel, 6 other tools, EEG, 3 references
[5] doi:10.1038/s41593-026-02285-1 [code]
Fixation duration on natural scenes is explained by memory encoding not processing demand.
Journal: Nature neuroscience
In common: MNE-Python, h5py, Pillow, 7 other tools, 3 references
[6] doi:10.1523/eneuro.0041-26.2026 [code]
Ocular Speech Tracking Persists in Blindness, but Its Dynamics and Oculo-Cerebral Connectivity Depend on Visual Status.
Journal: eNeuro
In common: MNE-Connectivity, MNE-Python, Pillow, 8 other tools, 1 reference
[7] doi:10.1371/journal.pone.0353371 [code]
Inter-brain functional connectivity: Are we measuring the right thing?
Journal: PloS one
In common: MNE-Connectivity, specparam (formerly FOOOF), MNE-Python, 4 other tools, EEG, 3 references
[8] doi:10.1002/mds.70348 [code]
Electroencephalography-Based Clustering Reveals Robust Neurophysiological Subtypes in Parkinson's Disease.
Journal: Movement disorders : official journal of the Movement Disorder Society
In common: specparam (formerly FOOOF), UMAP, MNE-Python, 7 other tools, EEG, 1 reference
[9] doi:10.1097/j.pain.0000000000004044 [code]
No effect of rhythmic visual stimulation on experimental pain perception.
Journal: Pain
In common: MNE-Connectivity, specparam (formerly FOOOF), MNE-Python, 6 other tools, EEG, 1 reference
[10] doi:10.1117/1.nph.13.2.025001 [code]
Surface-based image reconstruction optimization for high-density functional near-infrared spectroscopy.
Journal: Neurophotonics
In common: MNE-Python, NetworkX, h5py, 9 other tools

Contribute

The authors of this paper can claim it, correct its record and validate its tracing map, and the maintainers of its code (its owner, or a public member of its organization) correct what it says of their repository; anyone signed in can ask for its removal. Every request goes to OSCR's own machine, which answers it; your account page follows them.

Sign in with ORCID to claim this paper as one of its authors, correct its record or validate its tracing map: when the paper's metadata lists your ORCID iD, you are recognized at once. Maintainers of its code: sign in with GitHub, then claim the repository on your account page.

Request its removal

To ask OSCR to remove this record, the copies of its authors' scripts or its tracing map, use the removal request page: signed in, you say who you are, what to remove and why, then review and confirm the request. Published rules decide every request (how).

Discussion, reproductions, activity

Discussion: questions and error reports about this paper and its code, from signed-in readers and its authors. It opens with sign-in.

Reproductions: reports from readers who ran the authors' code: what they reproduced, with which environment, commit and data. It opens with sign-in.

Activity: what happens around this paper: new versions of its record, its map's validation, discussions and reproductions. It opens with sign-in.