{ "cells": [ { "cell_type": "markdown", "id": "0", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# Data Structures and I/O" ] }, { "cell_type": "code", "execution_count": 1, "id": "1", "metadata": { "execution": { "iopub.execute_input": "2025-04-14T12:54:25.448774Z", "iopub.status.busy": "2025-04-14T12:54:25.448342Z", "iopub.status.idle": "2025-04-14T12:54:27.038700Z", "shell.execute_reply": "2025-04-14T12:54:27.038198Z" }, "slideshow": { "slide_type": "skip" } }, "outputs": [], "source": [ "import numpy as np\n", "import pandas as pd\n", "import xarray as xr\n", "import tempfile\n", "from pathlib import Path\n", "\n", "import cedalion\n", "import cedalion.io\n", "import cedalion.datasets\n", "import cedalion.nirs\n", "import cedalion.xrutils as xrutils\n", "\n", "pd.set_option('display.max_rows', 10)\n", "xr.set_options(display_expand_data=False);" ] }, { "cell_type": "code", "execution_count": 2, "id": "2", "metadata": { "execution": { "iopub.execute_input": "2025-04-14T12:54:27.041156Z", "iopub.status.busy": "2025-04-14T12:54:27.040790Z", "iopub.status.idle": "2025-04-14T12:54:27.044106Z", "shell.execute_reply": "2025-04-14T12:54:27.043623Z" } }, "outputs": [], "source": [ "# helper function\n", "def calc_concentratoin(rec):\n", " od = cedalion.nirs.int2od(rec[\"amp\"])\n", " dpf = xr.DataArray([6, 6], dims=\"wavelength\", coords={\"wavelength\" : od.wavelength})\n", " return cedalion.nirs.od2conc(od, rec.geo3d, dpf)" ] }, { "cell_type": "markdown", "id": "3", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "## Reading Snirf Files\n", "\n", "Snirf files can be loaded with the `cedalion.io.read_snirf` method. This returns a list of `cedalion.dataclasses.Recording` objects. The " ] }, { "cell_type": "code", "execution_count": 3, "id": "4", "metadata": { "execution": { "iopub.execute_input": "2025-04-14T12:54:27.046143Z", "iopub.status.busy": "2025-04-14T12:54:27.045825Z", "iopub.status.idle": "2025-04-14T12:54:27.155977Z", "shell.execute_reply": "2025-04-14T12:54:27.155494Z" } }, "outputs": [ { "data": { "text/plain": [ "PosixPath('/home/runner/.cache/cedalion/fingertapping.zip.unzip/fingertapping/sub-01_task-tapping_nirs.snirf')" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "[]" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "1" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "path_to_snirf_file = cedalion.datasets.get_fingertapping_snirf_path()\n", "\n", "recordings = cedalion.io.read_snirf(path_to_snirf_file)\n", "\n", "display(path_to_snirf_file)\n", "display(recordings)\n", "display(len(recordings))" ] }, { "cell_type": "markdown", "id": "5", "metadata": {}, "source": [ "## Accessing example datasets\n", "\n", "Example datasets are accessible through functions in `cedalion.datasets`. These take care of downloading, caching and updating the data files. Often they also already load the data." ] }, { "cell_type": "markdown", "id": "6", "metadata": {}, "source": [] }, { "cell_type": "code", "execution_count": 4, "id": "7", "metadata": { "execution": { "iopub.execute_input": "2025-04-14T12:54:27.157965Z", "iopub.status.busy": "2025-04-14T12:54:27.157808Z", "iopub.status.idle": "2025-04-14T12:54:27.261037Z", "shell.execute_reply": "2025-04-14T12:54:27.260530Z" } }, "outputs": [ { "data": { "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "rec = cedalion.datasets.get_fingertapping()\n", "display(rec)" ] }, { "cell_type": "markdown", "id": "8", "metadata": {}, "source": [ "## Recording containers\n", "\n", "The class `cedalion.dataclasses.Recording` is Cedalion's **main data container** to carry related data objects through the program. \n", "It can store time series, masks, auxiliary timeseries, probe, headmodel and stimulus information as well as meta data about the recording.\n", "It has the following properties:\n", "\n", "\n", "\n", "| field | description | \n", "|------------|------------------------------------------------------------|\n", "| timeseries | a dictionary of timeseries objects | \n", "| masks | a dictionary of masks that flag time points as good or bad | \n", "| geo3d | 3D probe geometry | \n", "| geo2d | 2D probe geometry | \n", "| stim | dataframe with stimulus information |\n", "| aux_tx | dictionary of auxiliary time series objects |\n", "| aux_tx | dictionary for any other auxiliary objects |\n", "| head_model | voxel image, cortex and scalp surfaces |\n", "| meta_data | dictionary for meta data |\n", "\n", "* container is very similar to the layout of a snirf file\n", "* `Recording` maps mainly to nirs groups\n", "* timeseries objects map to data elements\n", "\n", "\n", "### Dictionaries in `Recording`\n", "\n", "- dictionaries are key value stores\n", "- maintain order in which values are added -> facilitate workflows\n", "- the user differentiates time series by name. \n", "- names are free to choose but there are a few **canonical names** used by `read_snirf` and expected by `write_snirf`:\n", "\n", "| data type | canonical name| \n", "|-----------------------------------|---------------|\n", "| unprocessed raw | \"amp\" |\n", "| processed raw | \"amp\" |\n", "| processed dOD | \"od\" |\n", "| processed concentrations | \"conc\" |\n", "| processed central moments\" | \"moments\" |\n", "| processed blood flow inddata_structures_oldex | \"bfi\" |\n", "| processed HRF dOD | \"hrf_od\" |\n", "| processed HRF central moments | \"hrf_moments\" |\n", "| processed HRF concentrations\" | \"hrf_conc\" |\n", "| processed HRF blood flow index | \"hrf_bfi\" |\n", "| processed absorption coefficient | \"mua\" |\n", "| processed scattering coefficient | \"musp\" |\n", " \n", " \n", "\n" ] }, { "cell_type": "markdown", "id": "9", "metadata": {}, "source": [ "### Inspecting a Recording container" ] }, { "cell_type": "code", "execution_count": 5, "id": "10", "metadata": { "execution": { "iopub.execute_input": "2025-04-14T12:54:27.262979Z", "iopub.status.busy": "2025-04-14T12:54:27.262825Z", "iopub.status.idle": "2025-04-14T12:54:27.266944Z", "shell.execute_reply": "2025-04-14T12:54:27.266569Z" } }, "outputs": [ { "data": { "text/plain": [ "odict_keys(['amp'])" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "xarray.core.dataarray.DataArray" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "display(rec.timeseries.keys())\n", "display(type(rec.timeseries[\"amp\"]))" ] }, { "cell_type": "code", "execution_count": 6, "id": "11", "metadata": { "execution": { "iopub.execute_input": "2025-04-14T12:54:27.268689Z", "iopub.status.busy": "2025-04-14T12:54:27.268539Z", "iopub.status.idle": "2025-04-14T12:54:27.271934Z", "shell.execute_reply": "2025-04-14T12:54:27.271500Z" } }, "outputs": [ { "data": { "text/plain": [ "OrderedDict([('SubjectID', 'P1'),\n", " ('MeasurementDate', '2020-01-01'),\n", " ('MeasurementTime', '13:16:16Z'),\n", " ('LengthUnit', 'm'),\n", " ('TimeUnit', 's'),\n", " ('FrequencyUnit', 'Hz'),\n", " ('DateOfBirth', '1986-01-01'),\n", " ('MNE_coordFrame', 4),\n", " ('sex', '1')])" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "rec.meta_data" ] }, { "cell_type": "markdown", "id": "12", "metadata": {}, "source": [ "Shortcut for accessing time series:" ] }, { "cell_type": "code", "execution_count": 7, "id": "13", "metadata": { "execution": { "iopub.execute_input": "2025-04-14T12:54:27.273646Z", "iopub.status.busy": "2025-04-14T12:54:27.273500Z", "iopub.status.idle": "2025-04-14T12:54:27.276615Z", "shell.execute_reply": "2025-04-14T12:54:27.276194Z" } }, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "rec[\"amp\"] is rec.timeseries[\"amp\"]" ] }, { "cell_type": "markdown", "id": "14", "metadata": {}, "source": [ "## Time Series\n", "\n", "
\n", "\n", "
\n", "\n", "- mulitvariate time series are stored in `xarray.DataArrays`\n", "- if it has dimensions 'channel' and 'time' we call it a `NDTimeSeries`\n", "- named dimensions\n", "- coordinates\n", "- physical units\n", "\n" ] }, { "cell_type": "code", "execution_count": 8, "id": "15", "metadata": { "execution": { "iopub.execute_input": "2025-04-14T12:54:27.278539Z", "iopub.status.busy": "2025-04-14T12:54:27.278118Z", "iopub.status.idle": "2025-04-14T12:54:27.290547Z", "shell.execute_reply": "2025-04-14T12:54:27.290056Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
<xarray.DataArray (channel: 28, wavelength: 2, time: 23239)> Size: 10MB\n",
       "[V] 0.09137 0.09099 0.09102 0.09044 0.09094 ... 1.277 1.273 1.273 1.273 1.276\n",
       "Coordinates:\n",
       "  * time        (time) float64 186kB 0.0 0.128 0.256 ... 2.974e+03 2.974e+03\n",
       "    samples     (time) int64 186kB 0 1 2 3 4 5 ... 23234 23235 23236 23237 23238\n",
       "  * channel     (channel) object 224B 'S1D1' 'S1D2' 'S1D3' ... 'S8D8' 'S8D16'\n",
       "    source      (channel) object 224B 'S1' 'S1' 'S1' 'S1' ... 'S8' 'S8' 'S8'\n",
       "    detector    (channel) object 224B 'D1' 'D2' 'D3' 'D9' ... 'D7' 'D8' 'D16'\n",
       "  * wavelength  (wavelength) float64 16B 760.0 850.0\n",
       "Attributes:\n",
       "    data_type_group:  unprocessed raw
" ], "text/plain": [ " Size: 10MB\n", "[V] 0.09137 0.09099 0.09102 0.09044 0.09094 ... 1.277 1.273 1.273 1.273 1.276\n", "Coordinates:\n", " * time (time) float64 186kB 0.0 0.128 0.256 ... 2.974e+03 2.974e+03\n", " samples (time) int64 186kB 0 1 2 3 4 5 ... 23234 23235 23236 23237 23238\n", " * channel (channel) object 224B 'S1D1' 'S1D2' 'S1D3' ... 'S8D8' 'S8D16'\n", " source (channel) object 224B 'S1' 'S1' 'S1' 'S1' ... 'S8' 'S8' 'S8'\n", " detector (channel) object 224B 'D1' 'D2' 'D3' 'D9' ... 'D7' 'D8' 'D16'\n", " * wavelength (wavelength) float64 16B 760.0 850.0\n", "Attributes:\n", " data_type_group: unprocessed raw" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "rec[\"amp\"]" ] }, { "cell_type": "code", "execution_count": 9, "id": "16", "metadata": { "execution": { "iopub.execute_input": "2025-04-14T12:54:27.292567Z", "iopub.status.busy": "2025-04-14T12:54:27.292137Z", "iopub.status.idle": "2025-04-14T12:54:27.346012Z", "shell.execute_reply": "2025-04-14T12:54:27.345497Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
<xarray.DataArray 'concentration' (chromo: 2, channel: 28, time: 23239)> Size: 10MB\n",
       "[µM] 0.1336 0.00383 0.3486 0.1915 0.4156 ... -1.037 -1.004 -1.073 -1.067 -1.076\n",
       "Coordinates:\n",
       "  * chromo    (chromo) <U3 24B 'HbO' 'HbR'\n",
       "  * time      (time) float64 186kB 0.0 0.128 0.256 ... 2.974e+03 2.974e+03\n",
       "    samples   (time) int64 186kB 0 1 2 3 4 5 ... 23234 23235 23236 23237 23238\n",
       "  * channel   (channel) object 224B 'S1D1' 'S1D2' 'S1D3' ... 'S8D8' 'S8D16'\n",
       "    source    (channel) object 224B 'S1' 'S1' 'S1' 'S1' ... 'S7' 'S8' 'S8' 'S8'\n",
       "    detector  (channel) object 224B 'D1' 'D2' 'D3' 'D9' ... 'D7' 'D8' 'D16'
" ], "text/plain": [ " Size: 10MB\n", "[µM] 0.1336 0.00383 0.3486 0.1915 0.4156 ... -1.037 -1.004 -1.073 -1.067 -1.076\n", "Coordinates:\n", " * chromo (chromo) \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
<xarray.DataArray (label: 55, digitized: 3)> Size: 1kB\n",
       "[m] -0.04161 0.0268 0.1299 -0.06477 0.05814 ... 0.06258 0.08226 0.01751 0.06619\n",
       "Coordinates:\n",
       "    type     (label) object 440B PointType.SOURCE ... PointType.LANDMARK\n",
       "  * label    (label) <U3 660B 'S1' 'S2' 'S3' 'S4' 'S5' ... '25' '26' '27' '28'\n",
       "Dimensions without coordinates: digitized
" ], "text/plain": [ " Size: 1kB\n", "[m] -0.04161 0.0268 0.1299 -0.06477 0.05814 ... 0.06258 0.08226 0.01751 0.06619\n", "Coordinates:\n", " type (label) object 440B PointType.SOURCE ... PointType.LANDMARK\n", " * label (label) \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
<xarray.DataArray (channel: 28, wavelength: 2)> Size: 448B\n",
       "[V] 0.09514 0.1902 0.2256 0.6123 0.1177 ... 0.485 0.5704 0.9371 0.6681 1.259\n",
       "Coordinates:\n",
       "  * channel     (channel) object 224B 'S1D1' 'S1D2' 'S1D3' ... 'S8D8' 'S8D16'\n",
       "    source      (channel) object 224B 'S1' 'S1' 'S1' 'S1' ... 'S8' 'S8' 'S8'\n",
       "    detector    (channel) object 224B 'D1' 'D2' 'D3' 'D9' ... 'D7' 'D8' 'D16'\n",
       "  * wavelength  (wavelength) float64 16B 760.0 850.0
" ], "text/plain": [ " Size: 448B\n", "[V] 0.09514 0.1902 0.2256 0.6123 0.1177 ... 0.485 0.5704 0.9371 0.6681 1.259\n", "Coordinates:\n", " * channel (channel) object 224B 'S1D1' 'S1D2' 'S1D3' ... 'S8D8' 'S8D16'\n", " source (channel) object 224B 'S1' 'S1' 'S1' 'S1' ... 'S8' 'S8' 'S8'\n", " detector (channel) object 224B 'D1' 'D2' 'D3' 'D9' ... 'D7' 'D8' 'D16'\n", " * wavelength (wavelength) float64 16B 760.0 850.0" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "amp = rec[\"amp\"]\n", "\n", "amp.mean(\"time\") " ] }, { "cell_type": "markdown", "id": "21", "metadata": {}, "source": [ "get the second channel formed by S1 and D2:" ] }, { "cell_type": "code", "execution_count": 12, "id": "22", "metadata": { "execution": { "iopub.execute_input": "2025-04-14T12:54:27.371448Z", "iopub.status.busy": "2025-04-14T12:54:27.371110Z", "iopub.status.idle": "2025-04-14T12:54:27.381796Z", "shell.execute_reply": "2025-04-14T12:54:27.381424Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
<xarray.DataArray (wavelength: 2, time: 23239)> Size: 372kB\n",
       "[V] 0.2275 0.2297 0.2261 0.2259 0.2267 ... 0.6126 0.6136 0.6072 0.6087 0.6091\n",
       "Coordinates:\n",
       "  * time        (time) float64 186kB 0.0 0.128 0.256 ... 2.974e+03 2.974e+03\n",
       "    samples     (time) int64 186kB 0 1 2 3 4 5 ... 23234 23235 23236 23237 23238\n",
       "    channel     <U4 16B 'S1D2'\n",
       "    source      object 8B 'S1'\n",
       "    detector    object 8B 'D2'\n",
       "  * wavelength  (wavelength) float64 16B 760.0 850.0\n",
       "Attributes:\n",
       "    data_type_group:  unprocessed raw
" ], "text/plain": [ " Size: 372kB\n", "[V] 0.2275 0.2297 0.2261 0.2259 0.2267 ... 0.6126 0.6136 0.6072 0.6087 0.6091\n", "Coordinates:\n", " * time (time) float64 186kB 0.0 0.128 0.256 ... 2.974e+03 2.974e+03\n", " samples (time) int64 186kB 0 1 2 3 4 5 ... 23234 23235 23236 23237 23238\n", " channel \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
<xarray.DataArray (channel: 28, digitized: 3)> Size: 672B\n",
       "[m] -0.04161 0.0268 0.1299 -0.04161 0.0268 ... 0.06571 0.08189 0.02043 0.06571\n",
       "Coordinates:\n",
       "    type      (channel) object 224B PointType.SOURCE ... PointType.SOURCE\n",
       "    label     (channel) <U3 336B 'S1' 'S1' 'S1' 'S1' ... 'S7' 'S8' 'S8' 'S8'\n",
       "  * channel   (channel) object 224B 'S1D1' 'S1D2' 'S1D3' ... 'S8D8' 'S8D16'\n",
       "    source    (channel) object 224B 'S1' 'S1' 'S1' 'S1' ... 'S7' 'S8' 'S8' 'S8'\n",
       "    detector  (channel) object 224B 'D1' 'D2' 'D3' 'D9' ... 'D7' 'D8' 'D16'\n",
       "Dimensions without coordinates: digitized
" ], "text/plain": [ " Size: 672B\n", "[m] -0.04161 0.0268 0.1299 -0.04161 0.0268 ... 0.06571 0.08189 0.02043 0.06571\n", "Coordinates:\n", " type (channel) object 224B PointType.SOURCE ... PointType.SOURCE\n", " label (channel) \n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
<xarray.DataArray (channel: 28)> Size: 224B\n",
       "[m] 0.03929 0.03891 0.04089 0.00826 0.03718 ... 0.00732 0.04067 0.03344 0.007534\n",
       "Coordinates:\n",
       "  * channel   (channel) object 224B 'S1D1' 'S1D2' 'S1D3' ... 'S8D8' 'S8D16'\n",
       "    source    (channel) object 224B 'S1' 'S1' 'S1' 'S1' ... 'S7' 'S8' 'S8' 'S8'\n",
       "    detector  (channel) object 224B 'D1' 'D2' 'D3' 'D9' ... 'D7' 'D8' 'D16'
" ], "text/plain": [ " Size: 224B\n", "[m] 0.03929 0.03891 0.04089 0.00826 0.03718 ... 0.00732 0.04067 0.03344 0.007534\n", "Coordinates:\n", " * channel (channel) object 224B 'S1D1' 'S1D2' 'S1D3' ... 'S8D8' 'S8D16'\n", " source (channel) object 224B 'S1' 'S1' 'S1' 'S1' ... 'S7' 'S8' 'S8' 'S8'\n", " detector (channel) object 224B 'D1' 'D2' 'D3' 'D9' ... 'D7' 'D8' 'D16'" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "distances = xrutils.norm(rec.geo3d.loc[amp.source] - rec.geo3d.loc[amp.detector], \"digitized\")\n", "display(distances)" ] }, { "cell_type": "markdown", "id": "26", "metadata": {}, "source": [ "Physical units:" ] }, { "cell_type": "code", "execution_count": 15, "id": "27", "metadata": { "execution": { "iopub.execute_input": "2025-04-14T12:54:27.412270Z", "iopub.status.busy": "2025-04-14T12:54:27.412121Z", "iopub.status.idle": "2025-04-14T12:54:27.421028Z", "shell.execute_reply": "2025-04-14T12:54:27.420645Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
<xarray.DataArray (channel: 28)> Size: 28B\n",
       "True True True False True True True ... False True True False True True False\n",
       "Coordinates:\n",
       "  * channel   (channel) object 224B 'S1D1' 'S1D2' 'S1D3' ... 'S8D8' 'S8D16'\n",
       "    source    (channel) object 224B 'S1' 'S1' 'S1' 'S1' ... 'S7' 'S8' 'S8' 'S8'\n",
       "    detector  (channel) object 224B 'D1' 'D2' 'D3' 'D9' ... 'D7' 'D8' 'D16'
" ], "text/plain": [ " Size: 28B\n", "True True True False True True True ... False True True False True True False\n", "Coordinates:\n", " * channel (channel) object 224B 'S1D1' 'S1D2' 'S1D3' ... 'S8D8' 'S8D16'\n", " source (channel) object 224B 'S1' 'S1' 'S1' 'S1' ... 'S7' 'S8' 'S8' 'S8'\n", " detector (channel) object 224B 'D1' 'D2' 'D3' 'D9' ... 'D7' 'D8' 'D16'" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "rec.masks[\"distance_mask\"] = distances > 1.5 * cedalion.units.cm\n", "display(rec.masks[\"distance_mask\"])" ] }, { "cell_type": "markdown", "id": "28", "metadata": {}, "source": [ "Additional functionality through accessors:" ] }, { "cell_type": "code", "execution_count": 16, "id": "29", "metadata": { "execution": { "iopub.execute_input": "2025-04-14T12:54:27.422781Z", "iopub.status.busy": "2025-04-14T12:54:27.422637Z", "iopub.status.idle": "2025-04-14T12:54:27.431680Z", "shell.execute_reply": "2025-04-14T12:54:27.431247Z" } }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
<xarray.DataArray (channel: 28)> Size: 224B\n",
       "[mm] 39.29 38.91 40.89 8.26 37.18 37.6 ... 40.43 37.22 7.32 40.67 33.44 7.534\n",
       "Coordinates:\n",
       "  * channel   (channel) object 224B 'S1D1' 'S1D2' 'S1D3' ... 'S8D8' 'S8D16'\n",
       "    source    (channel) object 224B 'S1' 'S1' 'S1' 'S1' ... 'S7' 'S8' 'S8' 'S8'\n",
       "    detector  (channel) object 224B 'D1' 'D2' 'D3' 'D9' ... 'D7' 'D8' 'D16'
" ], "text/plain": [ " Size: 224B\n", "[mm] 39.29 38.91 40.89 8.26 37.18 37.6 ... 40.43 37.22 7.32 40.67 33.44 7.534\n", "Coordinates:\n", " * channel (channel) object 224B 'S1D1' 'S1D2' 'S1D3' ... 'S8D8' 'S8D16'\n", " source (channel) object 224B 'S1' 'S1' 'S1' 'S1' ... 'S7' 'S8' 'S8' 'S8'\n", " detector (channel) object 224B 'D1' 'D2' 'D3' 'D9' ... 'D7' 'D8' 'D16'" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "distances.pint.to(\"mm\")" ] }, { "cell_type": "markdown", "id": "30", "metadata": {}, "source": [ "## Writing snirf files\n", "\n", "- pass `Recording` object to `cedalion.io.write_snirf`\n", "- caveat: many `Recording`fields have correspondants in snirf files, but not all." ] }, { "cell_type": "code", "execution_count": 17, "id": "31", "metadata": { "execution": { "iopub.execute_input": "2025-04-14T12:54:27.433456Z", "iopub.status.busy": "2025-04-14T12:54:27.433261Z", "iopub.status.idle": "2025-04-14T12:54:27.716452Z", "shell.execute_reply": "2025-04-14T12:54:27.716004Z" } }, "outputs": [], "source": [ "with tempfile.TemporaryDirectory() as tmpdir:\n", " output_path = Path(tmpdir).joinpath(\"test.snirf\")\n", "\n", " cedalion.io.write_snirf(output_path, rec)" ] } ], "metadata": { "celltoolbar": "Slideshow", "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.11.8" } }, "nbformat": 4, "nbformat_minor": 5 }