OSCR

Neuromagnetism "On the Cheap": Evaluating a Combined Cylindrical Shield and Partial-Coverage OPM-MEG System for Detecting Sensorimotor Responses in Humans.

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] § 2. Materials and Methods ↔ work/10_SEF_stats.r, lines 1–41 · score 0.89 · superior precentral sulcus, superior parietal lobule, postcentral sulcus, precentral gyrus, postcentral gyrus, ROIs
  2. [2] § 2. Materials and Methods ↔ work/11_mubeta_stats.r, lines 1–43 · score 0.88 · superior precentral sulcus, superior parietal lobule, postcentral sulcus, precentral gyrus, postcentral gyrus, ROIs
  3. [3] § 2. Materials and Methods ↔ work/04_find_bad_channels.ipynb, lines 45–125 · score 0.85 · linear regression, notch filtered, bad channels, 145 Hz, scored, spectral
  4. [4] § 2. Materials and Methods ↔ work/07_compute_sensor_evoked_and_tfrs.py, lines 262–318 · score 0.78 · edge artifacts, baseline corrected TFRs, epoch TFRs, Morlet, cycles, power
  5. [5] § 3. Results › 3.3. Source-Level Results › 3.3.2. Source-Level Mu and Beta Modulation ↔ work/11_mubeta_stats.r, lines 1–43 · score 0.78 · superior precentral sulcus, precentral gyrus, postcentral gyrus, beta ERS, ERD, ROIs
  6. [6] § 3. Results › 3.3. Source-Level Results › 3.3.2. Source-Level Mu and Beta Modulation ↔ work/10_SEF_stats.r, lines 1–41 · score 0.78 · superior precentral sulcus, precentral gyrus, postcentral gyrus, beta ERS, ERD, ROIs
  7. [7] § 2. Materials and Methods ↔ work/05_sensor_preprocessing.py, lines 392–435 · score 0.74 · notch filtered, bad channels, 145 Hz, scored, regression, 120
  8. [8] § 2. Materials and Methods ↔ work/09_extract_label_tfrs.py, lines 242–313 · score 0.68 · edge artifacts, baseline corrected, Morlet, cycles, TFRs, power
  9. [9] § 2. Materials and Methods ↔ work/11_mubeta_stats.r, lines 45–85 · score 0.66 · 0.2–0.4 s, 0.5–1 s, artifact, ERD, 0.5 s, ERS
  10. [10] § 2. Materials and Methods ↔ work/07_compute_sensor_evoked_and_tfrs.py, lines 222–260 · score 0.63 · short ISI, evoked response, baseline corrected, subtracting, rejected, epochs
  11. [11] § 3. Results › 3.3. Source-Level Results › 3.3.2. Source-Level Mu and Beta Modulation ↔ work/14_plot_label_tfrs.ipynb, lines 178–213 · score 0.63 · mu ERD, beta ERD, Bayes factors, beta ERS, power change, Boxplots
  12. [12] § 2. Materials and Methods ↔ work/10_SEF_stats.r, lines 94–158 · score 0.58 · baseline window, narrow, opposite, tailed, BF10, Bayes
  13. [13] § 2. Materials and Methods ↔ work/01_registrationPrep.py, lines 123–196 · score 0.58 · head coordinate frame, matrices, nasion, translated, fiducial, transformation
  14. [14] § 2. Materials and Methods ↔ work/02_register.py, lines 265–293 · score 0.54 · ICP, iterative, nasion, BEM, translated, fiducial
  15. [15] § 2. Materials and Methods ↔ work/05_sensor_preprocessing.py, lines 437–497 · score 0.50 · evoked response, rejected, event, artifacts, filtered, HFC

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

R · 158 lines · 5.7 KB · BSD-3-Clause · 3 matches

  1. # Outline: The purpose of this script is to compute Bayes factors for mu and beta ERS and ERD, in a selected sensor (ususally C3) and in a set of labels (i.e., ROIs)
  2. # Import packages
  3. library(BayesFactor)
  4. library(reticulate)
  5. library(ggplot2)
  6. library(scales)
  7. library(effsize)
  8. library(abind)
  9. np <- import('numpy') # This will trigger a prompt to set up a new environment. Enter "no"
  10. dataPre = 'MNS_shortISI'
  11. method_sufx = 'MNE-constrained'
  12. pick='C3'
  13. # Main directories
  14. data_path = '/media/NAS/lbailey/OPM_mnsbp/Data/results/'
  15. support_path = '/media/NAS/lbailey/OPM_mnsbp/Data/support_files/'
  16. # Input files
  17. times_fname = paste(data_path, dataPre, '-sens-evoked-times.npy', sep='')
  18. data_sens_evoked_fname = paste(data_path, dataPre,
  19. '-trans-cleaned-manRej-baseCorrected-evoked-', pick, '_N=11.npy', sep='')
  20. data_labels_evoked_fname = paste(data_path, dataPre,
  21. '-trans-cleaned-manRej-baseCorrected-', method_sufx, '-labelEvoked_N=12.npy', sep='')
  22. # Output files
  23. bfs_fname = paste(data_path, dataPre, '_', pick, '_and_label_evoked_stats.csv', sep='')
  24. magns_fname = paste(data_path, dataPre, '_', pick, '_and_label_evoked_magnitudes.csv', sep='')
  25. # Define labels
  26. labels = c('C3', 'Superior Precentral Sulcus', 'Precentral Gyrus',
  27. 'Central Sulcus','Postcentral Gyrus',
  28. 'Postcentral Sulcus', 'Superior Parietal Lobule'
  29. )
  30. # Define periods for baseline and peaks: 20 ms, 25 ms, 60 ms
  31. times_baseline = c(-0.2, -0.1)
  32. times_win20 = c(0.015, 0.025) # 10 ms window around 20 ms peak
  33. times_win35 = c(0.030, 0.040) # 10 ms window around 35 ms peak
  34. times_win60 = c(0.055, 0.065) # 10 ms window around 60 ms peak
  35. ###################
  36. # Load data
  37. # Load the times array and convert to r array
  38. times = np$load(times_fname)
  39. times = py_to_r(times)
  40. # Define indices for the baseline window and our 3 peaks
  41. idxs_baseline = which(times >= times_baseline[1] & times <= times_baseline[2])
  42. idxs_win20 = which(times >= times_win20[1] & times <= times_win20[2])
  43. idxs_win35 = which(times >= times_win35[1] & times <= times_win35[2])
  44. idxs_win60 = which(times >= times_win60[1] & times <= times_win60[2])
  45. # Load the sens and labels data and convert to r array
  46. data_sens = np$load(data_sens_evoked_fname)
  47. data_sens = py_to_r(data_sens)
  48. data_labels = np$load(data_labels_evoked_fname)
  49. data_labels = py_to_r(data_labels)
  50. # Create empty dataframes to store BFs and effect magnitudes for all labels
  51. all_bfs = data.frame()
  52. all_magns = data.frame()
  53. # Loop through labels. This is inefficient because we're loading the data on each loop, but it gets the job done...
  54. for (i in seq_along(labels)) {
  55. label = labels[i]
  56. # Select the data for this label (or if i==1, use the sensor data)
  57. if (i == 1) {
  58. data = data_sens[, i, ]
  59. } else {
  60. data = data_labels[, i-1, ]
  61. }
  62. # Define a dataframe to store bfs for this label
  63. bfs = data.frame(label = label,
  64. SEF20 = NA,
  65. SEF35 = NA,
  66. SEF60 = NA
  67. )
  68. magns = data.frame(label = label,
  69. SEF20 = NA,
  70. SEF35 = NA,
  71. SEF60 = NA
  72. )
  73. # Find the index for the max value in each time window, averaged across subjects.
  74. idx_peak20 = which.max(abs(apply(data[, idxs_win20], 2, mean))) + min(idxs_win20)
  75. idx_peak35 = which.max(apply(data[, idxs_win35], 2, mean)) + min(idxs_win35)
  76. idx_peak60 = which.max(apply(data[, idxs_win60], 2, mean)) + min(idxs_win60)
  77. # Create a very narrow time window (peak +/- 1 ms) around the peak
  78. idxs_peak20_3ms = c(idx_peak20 - 1, idx_peak20, idx_peak20 + 1)
  79. idxs_peak35_3ms = c(idx_peak35 - 1, idx_peak35, idx_peak35 + 1)
  80. idxs_peak60_3ms = c(idx_peak60 - 1, idx_peak60, idx_peak60 + 1)
  81. # Average over each 3ms time window, preserving subjects. Also average over the baseline window
  82. data_baseline = apply(data[, idxs_baseline], 1, mean)
  83. data_peak20 = apply(data[, idxs_peak20_3ms], 1, mean)
  84. data_peak35 = apply(data[, idxs_peak35_3ms], 1, mean)
  85. data_peak60 = apply(data[, idxs_peak60_3ms], 1, mean)
  86. # Compute magntiude of each response: abs(peak - baseline)
  87. magn_peak20 = abs(data_peak20 - data_baseline)
  88. magn_peak35 = abs(data_peak35 - data_baseline)
  89. magn_peak60 = abs(data_peak60 - data_baseline)
  90. # Determine the sign of the first peak, and select left/right tailed test.
  91. # The tail for the other two peaks will be the opposite of the first peak
  92. if (sign(mean(data_peak20))==1) {
  93. peak20_nullInterval = c(0, Inf)
  94. peak35_nullInterval = c(-Inf, 0)
  95. peak60_nullInterval = c(-Inf, 0)
  96. } else {
  97. peak20_nullInterval = c(-Inf, 0)
  98. peak35_nullInterval = c(0, Inf)
  99. peak60_nullInterval = c(0, Inf)
  100. }
  101. # Perform Bayes paired t-tests
  102. BF10_peak20 = ttestBF(data_peak20, data_baseline, paired=TRUE,
  103. nullInterval = peak20_nullInterval)
  104. BF10_peak35 = ttestBF(data_peak35, data_baseline, paired=TRUE,
  105. nullInterval = peak35_nullInterval)
  106. BF10_peak60 = ttestBF(data_peak60, data_baseline, paired=TRUE,
  107. nullInterval = peak60_nullInterval)
  108. # Assign BF10 to bfs dataframe
  109. bfs$SEF20 = as.vector(BF10_peak20)[[1]]
  110. bfs$SEF35 = as.vector(BF10_peak35)[[1]]
  111. bfs$SEF60 = as.vector(BF10_peak60)[[1]]
  112. # Store magnitudes in each cell (label / effect) as a list
  113. magns$SEF20 = paste(magn_peak20, collapse=',')
  114. magns$SEF35 = paste(magn_peak35, collapse=',')
  115. magns$SEF60 = paste(magn_peak60, collapse=',')
  116. # Append bfs to the all labels dataframe
  117. all_bfs = rbind(all_bfs, bfs)
  118. all_magns = rbind(all_magns, magns)
  119. } # labels loop
  120. all_bfs
  121. # Write bfs to disk
  122. write.csv(all_bfs, file=bfs_fname, row.names=FALSE)
  123. # Write magnitudes to disk. Each cell will be enclosed in quotes, to preserve the lists without disrupting csv formatting
  124. write.csv(all_magns, file=magns_fname, row.names=FALSE, quote=TRUE)

10_SEF_stats.r at commit b703004, under BSD-3-Clause · at the source

Overview

Authors: Lyam M. Bailey1, Clara Knox2, Timothy Bardouille2
  1. Diagnostic & Interventional Radiology, Hospital for Sick Children, Toronto, ON M5G 0A4, Canada
  2. Department of Physics & Atmospheric Science, Dalhousie University, Halifax, NS B3H 4R2, Canada
Institutions: Hospital for Sick Children (Canada); Dalhousie University (Canada)
Journal: Sensors (Basel, Switzerland), volume 26, issue 10, article 3131
Dates: received 13 February 2026; accepted 29 April 2026; published online 15 May 2026
Type: Research article · Language: English
License: CC BY
Identifiers: DOI 10.3390/s26103131 · PMID 42197937 · PMCID PMC13210914 · OpenAlex W7161272517
Open access: gold, a free copy (OpenAlex)
Status: code verified
Categories: MEG (modality), human (organism), systems (subfield)
Methods: Spectral & time-frequency, Preprocessing, Statistics, Smoothing, state filtering, decompositions, Evoked potentials, fMRI & imaging, Single-unit activity, calcium imaging
Keywords: OPM, MEG, MNS
MeSH: Magnetoencephalography*, Adult, Evoked Potentials, Somatosensory, Female, Humans, Male, Median Nerve, Young Adult (* major topic)
Topic: Atomic and Subatomic Physics Research (Atomic and Molecular Physics, and Optics, Physics and Astronomy), according to OpenAlex
Funding: an NSERC Discovery grant (RGPIN-2018-05470); a CFI John R Evans Leaders Fund (38127); an NSERC Alliance International Catalyst Fund (ALLRP 587261-23)
Citations: not cited yet (Europe PMC); 48 references in the paper

Abstract

Background: Optically pumped magnetometers (OPMs) have emerged as a promising technology for neuromagnetic recording in humans. Current state-of-the-art OPM systems are housed in large magnetically shielded rooms to reduce external electromagnetic noise and typically comprise sensor arrays covering the entire head. Such systems are extremely costly to purchase and install, and take up large amounts of physical space, which limits the accessibility of this technology to research groups with limited funding. Here we sought to evaluate the utility of a more accessible “starter” OPM system comprising a small cylindrical mu-metal shield and partial sensor coverage. Methods: Twelve participants underwent right-sided median nerve stimulation (MNS) intended to elicit ubiquitous sensorimotor responses: somatosensory-evoked fields (SEFs, comprising N20m, P35m and P60m components) and event-related (de)synchronization (ERD/ERS) of oscillatory neuronal rhythms in the mu and beta frequency ranges. Results: Following MNS, we observed robust N20m and P60m peaks, as well as the expected mu ERD and beta ERS effects. Moreover, these responses could be localized to expected cortical generators. However, we observed markedly lower SNR than that seen in state-of-the-art systems. We make recommendations for further improvements to this system and others like it.

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

Repository

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

lyambailey/OPM_MNSBP

License: BSD-3-Clause
State: the link answers, verified on 28 September 2026
Evidence: files inventoried
Commit: b703004e1c69958174ff57de80fb59343d868240, 11 June 2025
Languages: Python (9), Jupyter (6), R (2)
Size: 18 files, 17 scripts
Software Heritage: not archived
Found in: “Data Availability Statement”
Holds: license file, 6 notebooks
Not found: README, CITATION.cff, environment file, tests, continuous integration, documentation
Tools: MNE-Python (15 files), NumPy (12 files), Matplotlib (8 files), pandas (8 files), SciPy (4 files), seaborn (3 files), BayesFactor (2 files), ggplot2 (2 files), reticulate (2 files), scikit-learn (2 files)
Availability: 1 check, the latest on 28 September 2026: the link answers
  • 28 September 2026: the link answers
18 files

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:

  • 1 repository of the authors' code, each at its verified commit, with its license and how the link was found in the paper;
  • 17 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

No dataset and no data link were found in the paper.

Data Availability Statement

Data for this study is not publicly available, as participants did not consent to their data being made publicly available. Code for all analyses presented in this manuscript is publicly available on GitHub: https://github.com/lyambailey/OPM_MNSBP (accessed on 28 April 2026).

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, 28 September 2026: the first record

Recorded: type, language, journal, volume, issue, pages, dates, 3 authors, 3 keywords, 8 MeSH terms, 3 funders, 45 references.

Cite

This paper

Bailey, L. M., Knox, C., & Bardouille, T. (2026). Neuromagnetism "On the Cheap": Evaluating a Combined Cylindrical Shield and Partial-Coverage OPM-MEG System for Detecting Sensorimotor Responses in Humans. Sensors (Basel, Switzerland), 26(10), 3131. https://doi.org/10.3390/s26103131

BibTeX

@article{bailey2026neuromagnetism,
author = {Bailey, Lyam M. and Knox, Clara and Bardouille, Timothy},
title = {{Neuromagnetism "On the Cheap": Evaluating a Combined Cylindrical Shield and Partial-Coverage OPM-MEG System for Detecting Sensorimotor Responses in Humans}},
journal = {Sensors (Basel, Switzerland)},
year = {2026},
month = may,
volume = {26},
number = {10},
pages = {3131},
publisher = {Multidisciplinary Digital Publishing Institute (MDPI)},
issn = {1424-8220},
doi = {10.3390/s26103131},
url = {https://doi.org/10.3390/s26103131},
pmid = {42197937},
pmcid = {PMC13210914}
}

RIS

TY - JOUR
AU - Bailey, Lyam M.
AU - Knox, Clara
AU - Bardouille, Timothy
TI - Neuromagnetism "On the Cheap": Evaluating a Combined Cylindrical Shield and Partial-Coverage OPM-MEG System for Detecting Sensorimotor Responses in Humans
T2 - Sensors (Basel, Switzerland)
J2 - Sensors (Basel)
PY - 2026
DA - 2026/05/15
VL - 26
IS - 10
SP - 3131
SN - 1424-8220
PB - Multidisciplinary Digital Publishing Institute (MDPI)
DO - 10.3390/s26103131
UR - https://doi.org/10.3390/s26103131
LA - en
ER -

CSL-JSON

{
"id": "10.3390/s26103131",
"type": "article-journal",
"title": "Neuromagnetism \"On the Cheap\": Evaluating a Combined Cylindrical Shield and Partial-Coverage OPM-MEG System for Detecting Sensorimotor Responses in Humans",
"container-title": "Sensors (Basel, Switzerland)",
"author": [
{
"family": "Bailey",
"given": "Lyam M."
},
{
"family": "Knox",
"given": "Clara"
},
{
"family": "Bardouille",
"given": "Timothy"
}
],
"container-title-short": "Sensors (Basel)",
"volume": "26",
"issue": "10",
"page": "3131",
"DOI": "10.3390/s26103131",
"PMID": "42197937",
"PMCID": "PMC13210914",
"ISSN": "1424-8220",
"publisher": "Multidisciplinary Digital Publishing Institute (MDPI)",
"URL": "https://doi.org/10.3390/s26103131",
"language": "en",
"issued": {
"date-parts": [
[
2026,
5,
15
]
]
}
}

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.1162/imag.a.1040 [code]
Novel 4 He-OPMs support waveform-specific beta burst analysis comparable to SQUID-MEG
Journal: n/a
In common: MNE-Python, scikit-learn, pandas, 3 other tools, MEG, 6 references
[2] doi:10.1038/s41598-025-08037-8 [code]
OPM-MEG reveals dynamics of beta bursts underlying attentional processes in sensory cortex
Journal: n/a
In common: NumPy, MEG, 8 references
[3] doi:10.1167/jov.26.8.4 [code]
The neural processes of illusory occlusion in object recognition.
Journal: Journal of vision
In common: BayesFactor, MNE-Python, ggplot2, 6 other tools, 2 references
[4] doi:10.1038/s41597-026-07350-9 [code]
An open multi-center MEG-EEG dataset for studying conscious visual perception.
Journal: Scientific data
In common: BayesFactor, MNE-Python, ggplot2, 6 other tools, MEG, 1 reference
[5] doi:10.1038/s41467-026-74824-0 [code]
Learning regularities in noise engages both neural predictive activity and representational changes.
Journal: Nature communications
In common: reticulate, MNE-Python, scikit-learn, 4 other tools, MEG, 3 references
[6] 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: BayesFactor, MNE-Python, ggplot2, 6 other tools, MEG, 1 reference
[7] doi:10.1002/hbm.70368 [code]
The Mismatch Negativity Compared: EEG, SQUID‐MEG, and Novel 4 Helium‐OPMs
Journal: n/a
In common: MNE-Python, seaborn, scikit-learn, 3 other tools, MEG, 3 references
[8] doi:10.1038/s41597-026-07377-y [code]
An open-access multi-site fMRI dataset for investigating conscious visual perception.
Journal: Scientific data
In common: BayesFactor, MNE-Python, ggplot2, 6 other tools
[9] doi:10.1162/imag.a.1269 [code]
From early to contemporary normative modeling: Mapping individual differences in neurophysiological signals.
Journal: Imaging neuroscience (Cambridge, Mass.)
In common: MNE-Python, seaborn, scikit-learn, 4 other tools, MEG, 2 references
[10] doi:10.1038/s41598-026-41532-0 [code]
Prediction, syntax and semantic grounding in the brain and large language models.
Journal: Scientific reports
In common: MNE-Python, seaborn, scikit-learn, 4 other tools, MEG, 2 references

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.