{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Advanced single-trial fNIRS finger tapping classification\n", "\n", "This notebook analyzes a multi-subject finger-tapping dataset and trains a\n", "Linear Discriminant Analysis (LDA) classifier to distinguish single trials of\n", "left-hand tapping from a resting/control condition.\n", "\n", "Compared to the introductory\n", "[50_finger_tapping_lda_classification.ipynb](./50_finger_tapping_lda_classification.ipynb)\n", "notebook, this one goes into more depth:\n", "\n", "- Channels are pruned per subject using the Scalp Coupling Index (SCI) and\n", " Peak Spectral Power (PSP) quality metrics.\n", "- A GLM-based short-separation channel (SSC) regression is used to remove the\n", " systemic/superficial component from the long-channel concentration signal,\n", " and classification accuracy with and without this regression is compared\n", " via cross-validation.\n", "- At the end of the notebook, the same trials are additionally analyzed in\n", " **image (parcel) space**: channel-space optical density is projected onto\n", " the cortical surface via diffuse optical tomography (DOT) image\n", " reconstruction, aggregated into brain parcels, and classified with the same\n", " features and classifier used for channel space — allowing a direct\n", " comparison of classification performance between channel-space and\n", " parcel-space representations.\n", "\n", "On a basic level, this notebook illustrates some of the elements investigated\n", "more rigorously in (Fischer et al., 2026),\n", "who show that single-trial fNIRS decoding accuracy improves systematically\n", "with higher optode density, model-based (GLM) noise regression, and image\n", "reconstruction. This notebook uses a single, comparatively sparse probe and a\n", "simple LDA classifier, so it should be read as a minimal illustration of the\n", "*type* of comparison made in that paper (channel space vs. image/parcel\n", "space, with/without regression), not as a reproduction of its results.\n", "\n", "**PLEASE NOTE:** For simplicity's sake we still skip several preprocessing\n", "steps that a rigorous analysis would include (e.g. motion artifact rejection\n", "beyond TDDR/wavelet correction, physiological noise regression beyond\n", "short-separation channels). These are the subject of other example notebooks.\n", "The purpose of this notebook is to demonstrate how cedalion interfaces with\n", "scikit-learn for both channel-space and image-space classification." ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "execution": { "iopub.execute_input": "2026-07-13T22:15:41.436155Z", "iopub.status.busy": "2026-07-13T22:15:41.435980Z", "iopub.status.idle": "2026-07-13T22:15:41.441539Z", "shell.execute_reply": "2026-07-13T22:15:41.440904Z" } }, "outputs": [], "source": [ "# This cells setups the environment when executed in Google Colab.\n", "try:\n", " import google.colab\n", " !curl -s https://raw.githubusercontent.com/ibs-lab/cedalion/dev/scripts/colab_setup.py -o colab_setup.py\n", " # Select branch with --branch \"branch name\" (default is \"dev\")\n", " %run colab_setup.py\n", "except ImportError:\n", " pass" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "execution": { "iopub.execute_input": "2026-07-13T22:15:41.443490Z", "iopub.status.busy": "2026-07-13T22:15:41.443319Z", "iopub.status.idle": "2026-07-13T22:15:45.505952Z", "shell.execute_reply": "2026-07-13T22:15:45.504943Z" } }, "outputs": [], "source": [ "from collections import defaultdict\n", "import gc\n", "\n", "import matplotlib.pyplot as p\n", "import numpy as np\n", "import pyvista as pv\n", "import xarray as xr\n", "from sklearn.discriminant_analysis import LinearDiscriminantAnalysis\n", "from sklearn.pipeline import make_pipeline\n", "from sklearn.preprocessing import LabelEncoder, StandardScaler\n", "\n", "import cedalion\n", "import cedalion.data\n", "import cedalion.dot\n", "import cedalion.geometry.landmarks\n", "import cedalion.io\n", "import cedalion.mlutils as mlutils\n", "import cedalion.models.glm as glm\n", "import cedalion.nirs\n", "import cedalion.sigproc.motion as motion\n", "import cedalion.sigproc.quality as quality\n", "import cedalion.vis.anatomy\n", "import cedalion.vis.anatomy.sensitivity_matrix\n", "import cedalion.vis.blocks as vbx\n", "from cedalion import units\n", "from cedalion.data import get_multisubject_fingertapping_snirf_paths\n", "from cedalion.sigproc.frequency import freq_filter\n", "\n", "# set to True for interactive (rotatable) 3D plots, False for static images\n", "INTERACTIVE_PLOTS = False\n", "pv.set_jupyter_backend(\"server\" if INTERACTIVE_PLOTS else \"static\")\n", "\n", "xr.set_options(display_max_rows=3, display_values_threshold=50)\n", "np.set_printoptions(precision=4)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Loading raw CW-NIRS data from SNIRF files\n", "\n", "This notebook uses a finger-tapping dataset in BIDS layout provided by [Rob Luke](https://github.com/rob-luke/BIDS-NIRS-Tapping). It can can be downloaded via `cedalion.data`." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Cedalion's `read_snirf` method returns a list of `Recording` objects. These are containers for timeseries and adjunct data objects." ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "execution": { "iopub.execute_input": "2026-07-13T22:15:45.508386Z", "iopub.status.busy": "2026-07-13T22:15:45.507828Z", "iopub.status.idle": "2026-07-13T22:16:02.505727Z", "shell.execute_reply": "2026-07-13T22:16:02.505219Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "sub-01: number of clean channels: 23/28\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "sub-02: number of clean channels: 19/28\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "sub-03: number of clean channels: 18/28\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "sub-04: number of clean channels: 27/28\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "sub-05: number of clean channels: 13/28\n" ] } ], "source": [ "fnames = get_multisubject_fingertapping_snirf_paths()\n", "subjects = [f\"sub-{i:02d}\" for i in [1, 2, 3, 4, 5]]\n", "\n", "sci_threshold = 0.6\n", "psp_threshold = 0.05\n", "window_length = 5 * units.s\n", "pc_clean_threshold = 0.5\n", "\n", "# store data of different subjects in a dictionary\n", "data = {}\n", "for subject, fname in zip(subjects, fnames):\n", " records = cedalion.io.read_snirf(fname)\n", " rec = records[0]\n", "\n", " # Cedalion registers an accessor (attribute .cd ) on pandas DataFrames.\n", " # Use this to rename trial_types inplace.\n", " rec.stim.cd.rename_events(\n", " {\n", " \"1.0\": \"control\",\n", " \"2.0\": \"Tapping/Left\",\n", " \"3.0\": \"Tapping/Right\",\n", " \"15.0\": \"sentinel\",\n", " }\n", " )\n", "\n", " # remove unused events, sort by onset\n", " rec.stim = (\n", " rec.stim[rec.stim.trial_type.isin([\"control\", \"Tapping/Left\"])]\n", " .sort_values(\"onset\")\n", " .reset_index(drop=True)\n", " )\n", "\n", " rec.geo3d = cedalion.geometry.landmarks.normalize_landmarks_labels(rec.geo3d)\n", "\n", " rec[\"od\"] = cedalion.nirs.cw.int2od(rec[\"amp\"])\n", " rec[\"od_tddr\"] = motion.tddr(rec[\"od\"])\n", " rec[\"od_wavelet\"] = motion.wavelet(rec[\"od_tddr\"])\n", "\n", " # SCI & PSP\n", " sci, sci_mask = quality.sci(rec[\"od_wavelet\"], window_length, sci_threshold)\n", " psp, psp_mask = quality.psp(rec[\"od_wavelet\"], window_length, psp_threshold)\n", " sci_psp_mask = sci_mask & psp_mask\n", "\n", " rec.aux_obj[\"perc_time_clean\"] = sci_psp_mask.sum(dim=\"time\") / len(\n", " sci_psp_mask.time\n", " )\n", "\n", " rec.masks[\"clean_mask\"] = rec.aux_obj[\"perc_time_clean\"] > pc_clean_threshold\n", " ncleanchannels = rec.masks[\"clean_mask\"].sum().values\n", "\n", " print(\n", " f\"{subject}: number of clean channels: \"\n", " f\"{ncleanchannels}/{rec['amp'].sizes['channel']}\"\n", " )\n", "\n", " rec[\"od_pruned\"] = rec[\"od_wavelet\"].sel(channel=rec.masks[\"clean_mask\"])\n", "\n", " dpf = xr.DataArray(\n", " [6, 6],\n", " dims=\"wavelength\",\n", " coords={\"wavelength\": rec[\"amp\"].wavelength},\n", " )\n", "\n", " rec[\"conc\"] = cedalion.nirs.cw.od2conc(rec[\"od_pruned\"], rec.geo3d, dpf)\n", "\n", " rec[\"conc_freqfilt\"] = freq_filter(\n", " rec[\"conc\"], fmin=0.01 * units.Hz, fmax=0.5 * units.Hz\n", " )\n", "\n", " data[subject] = rec" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Inspect Trials" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "execution": { "iopub.execute_input": "2026-07-13T22:16:02.509002Z", "iopub.status.busy": "2026-07-13T22:16:02.508793Z", "iopub.status.idle": "2026-07-13T22:16:02.521528Z", "shell.execute_reply": "2026-07-13T22:16:02.519172Z" } }, "outputs": [ { "data": { "text/html": [ "
| \n", " | # trials | \n", "
|---|---|
| trial_type | \n", "\n", " |
| Tapping/Left | \n", "30 | \n", "
| control | \n", "30 | \n", "
<xarray.DataArray (epoch: 60, chromo: 2, channel: 16, reltime: 135)> Size: 2MB\n",
"<Quantity([[[[-9.3714e-02 -7.8124e-02 -6.2774e-02 ... -8.6741e-02 -9.7942e-02\n",
" -1.0924e-01]\n",
" [-9.5185e-02 -8.5083e-02 -7.4190e-02 ... -1.6120e-01 -1.5882e-01\n",
" -1.5665e-01]\n",
" [-7.1943e-02 -5.9558e-02 -4.7282e-02 ... -1.8900e-01 -1.9434e-01\n",
" -2.0007e-01]\n",
" ...\n",
" [-1.2025e-01 -1.0697e-01 -9.2745e-02 ... -4.4288e-01 -4.5381e-01\n",
" -4.6637e-01]\n",
" [-8.7524e-02 -7.4605e-02 -6.1478e-02 ... -3.9973e-01 -4.0392e-01\n",
" -4.0840e-01]\n",
" [-5.8143e-02 -4.9710e-02 -4.0982e-02 ... -3.9304e-01 -3.9282e-01\n",
" -3.9267e-01]]\n",
"\n",
" [[ 2.4046e-03 1.2129e-03 3.2792e-04 ... -6.0494e-02 -4.9949e-02\n",
" -4.0034e-02]\n",
" [ 8.1752e-03 1.0916e-02 1.2657e-02 ... -2.3302e-02 -2.7449e-02\n",
" -3.2918e-02]\n",
" [ 5.3153e-03 1.9881e-03 -9.6345e-04 ... -5.5447e-02 -5.1820e-02\n",
" -4.8051e-02]\n",
"...\n",
" [ 8.6953e-02 7.6663e-02 6.5407e-02 ... 2.3010e-02 3.8361e-02\n",
" 5.3422e-02]\n",
" [ 7.3274e-02 6.5880e-02 5.7208e-02 ... 1.0535e-01 1.1702e-01\n",
" 1.2830e-01]\n",
" [ 3.2520e-02 2.6869e-02 2.0952e-02 ... 3.5230e-01 3.6504e-01\n",
" 3.7687e-01]]\n",
"\n",
" [[-1.9129e-02 -1.5943e-02 -1.2350e-02 ... 5.0320e-02 5.0038e-02\n",
" 4.8112e-02]\n",
" [-2.4353e-02 -2.3238e-02 -1.9715e-02 ... 2.3422e-02 2.2695e-02\n",
" 2.0638e-02]\n",
" [-1.2239e-02 -1.3154e-02 -1.3375e-02 ... 6.7565e-02 6.8972e-02\n",
" 7.0489e-02]\n",
" ...\n",
" [ 9.5585e-04 -2.4874e-03 -6.2408e-03 ... 9.1244e-02 9.4591e-02\n",
" 9.8010e-02]\n",
" [-1.0578e-02 -1.1294e-02 -1.1444e-02 ... 4.6553e-03 5.6745e-03\n",
" 6.5657e-03]\n",
" [ 5.7040e-03 4.0702e-03 1.8860e-03 ... -2.2583e-02 -2.1053e-02\n",
" -1.9265e-02]]]], 'micromolar')>\n",
"Coordinates: (3/9)\n",
" * reltime (reltime) float64 1kB -2.048 -1.92 -1.792 ... 14.85 14.98 15.1\n",
" trial_type (epoch) <U12 3kB 'control' 'control' ... 'Tapping/Left'\n",
" ... ...\n",
" y (epoch) int64 480B 1 1 1 0 0 1 0 0 0 0 1 ... 1 0 0 1 1 0 1 0 1 0\n",
"Dimensions without coordinates: epoch<xarray.DataArray (epoch: 60, chromo: 2, channel: 16, reltime: 135)> Size: 2MB\n",
"<Quantity([[[[-9.3714e-02 -7.8124e-02 -6.2774e-02 ... -8.6741e-02 -9.7942e-02\n",
" -1.0924e-01]\n",
" [-9.5185e-02 -8.5083e-02 -7.4190e-02 ... -1.6120e-01 -1.5882e-01\n",
" -1.5665e-01]\n",
" [-7.1943e-02 -5.9558e-02 -4.7282e-02 ... -1.8900e-01 -1.9434e-01\n",
" -2.0007e-01]\n",
" ...\n",
" [-1.2025e-01 -1.0697e-01 -9.2745e-02 ... -4.4288e-01 -4.5381e-01\n",
" -4.6637e-01]\n",
" [-8.7524e-02 -7.4605e-02 -6.1478e-02 ... -3.9973e-01 -4.0392e-01\n",
" -4.0840e-01]\n",
" [-5.8143e-02 -4.9710e-02 -4.0982e-02 ... -3.9304e-01 -3.9282e-01\n",
" -3.9267e-01]]\n",
"\n",
" [[ 2.4046e-03 1.2129e-03 3.2792e-04 ... -6.0494e-02 -4.9949e-02\n",
" -4.0034e-02]\n",
" [ 8.1752e-03 1.0916e-02 1.2657e-02 ... -2.3302e-02 -2.7449e-02\n",
" -3.2918e-02]\n",
" [ 5.3153e-03 1.9881e-03 -9.6345e-04 ... -5.5447e-02 -5.1820e-02\n",
" -4.8051e-02]\n",
"...\n",
" [ 8.6953e-02 7.6663e-02 6.5407e-02 ... 2.3010e-02 3.8361e-02\n",
" 5.3422e-02]\n",
" [ 7.3274e-02 6.5880e-02 5.7208e-02 ... 1.0535e-01 1.1702e-01\n",
" 1.2830e-01]\n",
" [ 3.2520e-02 2.6869e-02 2.0952e-02 ... 3.5230e-01 3.6504e-01\n",
" 3.7687e-01]]\n",
"\n",
" [[-1.9129e-02 -1.5943e-02 -1.2350e-02 ... 5.0320e-02 5.0038e-02\n",
" 4.8112e-02]\n",
" [-2.4353e-02 -2.3238e-02 -1.9715e-02 ... 2.3422e-02 2.2695e-02\n",
" 2.0638e-02]\n",
" [-1.2239e-02 -1.3154e-02 -1.3375e-02 ... 6.7565e-02 6.8972e-02\n",
" 7.0489e-02]\n",
" ...\n",
" [ 9.5585e-04 -2.4874e-03 -6.2408e-03 ... 9.1244e-02 9.4591e-02\n",
" 9.8010e-02]\n",
" [-1.0578e-02 -1.1294e-02 -1.1444e-02 ... 4.6553e-03 5.6745e-03\n",
" 6.5657e-03]\n",
" [ 5.7040e-03 4.0702e-03 1.8860e-03 ... -2.2583e-02 -2.1053e-02\n",
" -1.9265e-02]]]], 'micromolar')>\n",
"Coordinates: (3/9)\n",
" * reltime (reltime) float64 1kB -2.048 -1.92 -1.792 ... 14.85 14.98 15.1\n",
" trial_type (epoch) <U12 3kB 'control' 'control' ... 'Tapping/Left'\n",
" ... ...\n",
" y (epoch) int64 480B 1 1 1 0 0 1 0 0 0 0 1 ... 1 0 0 1 1 0 1 0 1 0\n",
"Dimensions without coordinates: epoch"
],
"text/plain": [
"<xarray.DataArray (epoch: 60, feature: 80)> Size: 38kB\n",
"array([[ 0.0075, 0.0044, 0.0057, ..., 0.2717, 0.2893, 0.3286],\n",
" [ 0.0393, 0.0229, 0.0067, ..., -0.2663, -1.2641, -0.6725],\n",
" [-0.0049, 0.0025, -0.0078, ..., -0.6788, 1.1415, -0.188 ],\n",
" ...,\n",
" [ 0.0473, 0.0486, 0.0491, ..., 1.2899, 0.0246, -0.2599],\n",
" [ 0.0082, -0.0168, -0.0023, ..., 0.1861, -0.8478, -0.8331],\n",
" [-0.0158, 0.025 , 0.0033, ..., -2.2424, -1.7198, -2.0566]],\n",
" shape=(60, 80))\n",
"Coordinates: (3/10)\n",
" trial_type (epoch) <U12 3kB 'control' 'control' ... 'Tapping/Left'\n",
" source (feature) object 640B 'S2' 'S3' 'S4' 'S4' ... 'S7' 'S8' 'S8'\n",
" ... ...\n",
" * channel (feature) object 640B 'S2D4' 'S3D3' 'S4D3' ... 'S8D7' 'S8D8'\n",
"Dimensions without coordinates: epoch| [1] | Luke2021 | cedalion.data.get_multisubject_fingertapping_snirf_paths | Robert Luke and David McAlpine.\n", "fNIRS Finger Tapping Data in BIDS Format.\n", "September 2021.\n", "doi:10.5281/zenodo.5529797. |
| [2] | Tucker2022 | cedalion.io.snirf.read_snirf | Stephen Tucker, Jay Dubb, Sreekanth Kura, Alexander von Lühmann, Robert Franke, Jörn M. Horschig, Samuel Powell, Robert Oostenveld, Michael Lührs, Édouard Delaire, Zahra M. Aghajan, Hanseok Yun, Meryem A. Yücel, Qianqian Fang, Theodore J. Huppert, Blaise deB. Frederick, Luca Pollonini, David A. Boas, and Robert Luke.\n", "Introduction to the shared near infrared spectroscopy format.\n", "Neurophotonics, 10(1):013507, 2022.\n", "doi:10.1117/1.NPh.10.1.013507. |
| [3] | Delpy1988 | cedalion.nirs.cw.int2od, cedalion.nirs.cw.od2conc | D. T. Delpy, M. Cope, P. van der Zee, S. Arridge, S. Wray, and J. Wyatt.\n", "Estimation of optical pathlength through tissue from direct time of flight measurement.\n", "Physics in Medicine and Biology, 33(12):1433–1442, 1988.\n", "doi:10.1088/0031-9155/33/12/008. |
| [4] | Villringer1997 | cedalion.nirs.cw.int2od, cedalion.nirs.cw.od2conc | Arno Villringer and Britton Chance.\n", "Non-invasive optical spectroscopy and imaging of human brain function.\n", "Trends in Neurosciences, 20(10):435–442, 1997.\n", "doi:10.1016/S0166-2236(97)01132-6. |
| [5] | Fishburn2019 | cedalion.sigproc.motion.tddr | Frank A. Fishburn, Ruth S. Ludlum, Chandan J. Vaidya, and Andrei V. Medvedev.\n", "Temporal derivative distribution repair (tddr): a motion correction method for fnirs.\n", "NeuroImage, 184:171–179, 2019.\n", "doi:https://doi.org/10.1016/j.neuroimage.2018.09.025. |
| [6] | Fishburn2018 | cedalion.sigproc.motion.tddr | Frank Fishburn.\n", "Tddr.\n", "2018.\n", "URL: https://github.com/frankfishburn/TDDR/. |
| [7] | Molavi2012 | cedalion.sigproc.motion.wavelet | Behnam Molavi and Guy A Dumont.\n", "Wavelet-based motion artifact removal for functional near-infrared spectroscopy.\n", "Physiological Measurement, 33(2):259, 2012.\n", "doi:10.1088/0967-3334/33/2/259. |
| [8] | Huppert2009 | cedalion.models.glm.design_matrix.average_short_channel_regressor, cedalion.sigproc.motion.wavelet | Theodore J. Huppert, Solomon G. Diamond, Maria A. Franceschini, and David A. Boas.\n", "Homer: a review of time-series analysis methods for near-infrared spectroscopy of the brain.\n", "Appl. Opt., 48(10):D280–D298, Apr 2009.\n", "doi:https://doi.org/10.1364/AO.48.00D280. |
| [9] | Pollonini2014 | cedalion.sigproc.quality.psp, cedalion.sigproc.quality.sci | Luca Pollonini, Cristen Olds, Homer Abaya, Heather Bortfeld, Michael S. Beauchamp, and John S. Oghalai.\n", "Auditory cortex activation to natural speech and simulated cochlear implant speech measured with functional near-infrared spectroscopy.\n", "Hearing Research, 309:84–93, 2014.\n", "doi:https://doi.org/10.1016/j.heares.2013.11.007. |
| [10] | Pollonini2016 | cedalion.sigproc.quality.psp, cedalion.sigproc.quality.sci | Luca Pollonini, Heather Bortfeld, and John S. Oghalai.\n", "PHOEBE: a method for real time mapping of optodes-scalp coupling in functional near-infrared spectroscopy.\n", "Biomedical Optics Express, 7(12):5104, Dec 2016.\n", "doi:10.1364/BOE.7.005104. |
| [11] | Prahl1998 | cedalion.nirs.common.get_extinction_coefficients | Scott A. Prahl.\n", "Optical absorption of hemoglobin.\n", "Oregon Medical Laser Center, online resource, 1998.\n", "URL: https://omlc.org/spectra/hemoglobin/. |
| [12] | Strangman2002 | cedalion.models.glm.basis_functions.Gamma.__call__ | Gary Strangman, Joseph P. Culver, John H. Thompson, and David A. Boas.\n", "A quantitative comparison of simultaneous BOLD fMRI and NIRS recordings during functional brain activation.\n", "NeuroImage, 17(2):719–731, 2002.\n", "doi:10.1006/nimg.2002.1227. |
| [13] | vonLuhmann2020 | cedalion.mlutils.cv.mask_design_matrix | Alexander von Lühmann, Antonio Ortega-Martinez, David A. Boas, and Meryem Ayşe Yücel.\n", "Using the General Linear Model to Improve Performance in fNIRS Single Trial Analysis and Classification: A Perspective.\n", "Frontiers in Human Neuroscience, 14:30, February 2020.\n", "URL: https://www.frontiersin.org/article/10.3389/fnhum.2020.00030/full, doi:10.3389/fnhum.2020.00030. |
| [14] | Barker2013 | cedalion.models.glm.solve.fit | Jeffrey W. Barker, Ardalan Aarabi, and Theodore J. Huppert.\n", "Autoregressive model based algorithm for correcting motion and serially correlated errors in fnirs.\n", "Biomed. Opt. Express, 4(8):1366–1379, Aug 2013.\n", "doi:10.1364/BOE.4.001366. |
| [15] | Fang2009 | cedalion.data.get_precomputed_sensitivity | Qianqian Fang and David A Boas.\n", "Monte carlo simulation of photon migration in 3d turbid media accelerated by graphics processing units.\n", "Optics express, 17(22):20178–20190, 2009.\n", "doi:10.1364/OE.17.020178. |
| [16] | Yu2018 | cedalion.data.get_precomputed_sensitivity | Leiming Yu, Fanny Nina-Paravecino, David Kaeli, and Qianqian Fang.\n", "Scalable and massively parallel monte carlo photon transport simulations for heterogeneous computing platforms.\n", "Journal of biomedical optics, 23(1):010504–010504, 2018.\n", "doi:10.1117/1.JBO.23.1.010504. |
| [17] | Yan2020 | cedalion.data.get_precomputed_sensitivity | Shijie Yan and Qianqian Fang.\n", "Hybrid mesh and voxel based monte carlo algorithm for accurate and efficient photon transport modeling in complex bio-tissues.\n", "Biomedical Optics Express, 11(11):6262–6270, 2020.\n", "doi:10.1364/BOE.409468. |
| [18] | Fonov2011 | cedalion.data.get_icbm152_headmodel_files | Vladimir Fonov, Alan C. Evans, Kelly Botteron, C. Robert Almli, Robert C. McKinstry, and D. Louis Collins.\n", "Unbiased average age-appropriate atlases for pediatric studies.\n", "NeuroImage, 54(1):313–327, January 2011.\n", "doi:10.1016/j.neuroimage.2010.07.033. |
| [19] | Fischl2012 | cedalion.data.get_icbm152_headmodel_files | Bruce Fischl.\n", "FreeSurfer.\n", "NeuroImage, 62(2):774–781, 2012.\n", "doi:10.1016/j.neuroimage.2012.01.021. |
| [20] | Schaefer2018 | cedalion.data.get_icbm152_headmodel_files | Alexander Schaefer, Ru Kong, Evan M Gordon, Timothy O Laumann, Xi-Nian Zuo, Avram J Holmes, Simon B Eickhoff, and BT Thomas Yeo.\n", "Local-global parcellation of the human cerebral cortex from intrinsic functional connectivity mri.\n", "Cerebral cortex, 28(9):3095–3114, 2018.\n", "doi:10.1093/cercor/bhx179. |
| [21] | Carlton2026 | cedalion.dot.image_recon.ImageRecon.__init__ | Laura B. Carlton, Miray Altınkaynak, Shannon Kelley, Bernhard B. Zimmermann, Sreekanth Kura, Eike Middell, Alexander von Lühmann, Emily P. Stephen, Meryem A. Yücel, and David A. Boas.\n", "Surface-based image reconstruction optimization for high-density functional near-infrared spectroscopy.\n", "Neurophotonics, 13(2):025001, 2026.\n", "doi:10.1117/1.NPh.13.2.025001. |
| [22] | Markow2025 | cedalion.dot.image_recon.ImageRecon.__init__ | Zachary E. Markow, Jason W. Trobaugh, Edward J. Richter, Kalyan Tripathy, Sean M. Rafferty, Alexandra M. Svoboda, Mariel L. Schroeder, Tracy M. Burns-Yocum, Karla M. Bergonzi, Mark A. Chevillet, Emily M. Mugler, Adam T. Eggebrecht, and Joseph P. Culver.\n", "Ultra high density imaging arrays in diffuse optical tomography for human brain mapping improve image quality and decoding performance.\n", "Scientific Reports, 15(1):3175, January 2025.\n", "doi:10.1038/s41598-025-85858-7. |