cedalion.imagereco.forward_model

Forward model for simulating light transport in the head. NOTE: Cedalion currently supports two ways to compute fluence: 1) via monte-carlo simulation using the MonteCarloXtreme (MCX) package, and 2) via the finite element method (FEM) using the NIRFASTer package. While MCX is automatically installed using pip, NIRFASTER has to be manually installed runnning <$ bash install_nirfaster.sh CPU # or GPU> from a within your cedalion root directory.

Functions

apply_inv_sensitivity(od, inv_sens)

Apply the inverted sensitivity matrix to optical density data.

Classes

ForwardModel(head_model, geo3d, measurement_list)

Forward model for simulating light transport in the head.

TwoSurfaceHeadModel(segmentation_masks, ...)

Head Model class to represent a segmented head.

class cedalion.imagereco.forward_model.TwoSurfaceHeadModel(
segmentation_masks: xr.DataArray,
brain: cdc.Surface,
scalp: cdc.Surface,
landmarks: cdt.LabeledPointCloud,
t_ijk2ras: cdt.AffineTransform,
t_ras2ijk: cdt.AffineTransform,
voxel_to_vertex_brain: scipy.sparse.spmatrix,
voxel_to_vertex_scalp: scipy.sparse.spmatrix,
)[source]

Bases: object

Head Model class to represent a segmented head.

Its main functions are reduced to work on voxel projections to scalp and cortex surfaces.

segmentation_masks[source]

xr.DataArray Segmentation masks of the head for each tissue type.

Type:

xarray.core.dataarray.DataArray

brain[source]

cdc.Surface Surface of the brain.

Type:

cedalion.dataclasses.geometry.Surface

scalp[source]

cdc.Surface Surface of the scalp.

Type:

cedalion.dataclasses.geometry.Surface

landmarks[source]

cdt.LabeledPointCloud Anatomical landmarks in RAS space.

Type:

xarray.core.dataarray.DataArray

t_ijk2ras[source]

cdt.AffineTransform Affine transformation from ijk to RAS space.

Type:

xarray.core.dataarray.DataArray

t_ras2ijk[source]

cdt.AffineTransform Affine transformation from RAS to ijk space.

Type:

xarray.core.dataarray.DataArray

voxel_to_vertex_brain[source]

scipy.sparse.spmatrix Mapping from voxel to brain vertices.

Type:

scipy.sparse._matrix.spmatrix

voxel_to_vertex_scalp[source]

scipy.sparse.spmatrix Mapping from voxel to scalp vertices.

Type:

scipy.sparse._matrix.spmatrix

crs[source]

str Coordinate reference system of the head model.

from_segmentation(cls, segmentation_dir, mask_files, landmarks_ras_file,

brain_seg_types, scalp_seg_types, smoothing, brain_face_count, scalp_face_count): Construct instance from segmentation masks in NIfTI format.

apply_transform(transform)[source]

Apply a coordinate transformation to the head model.

save(foldername)[source]

Save the head model to a folder.

load(foldername)[source]

Load the head model from a folder.

align_and_snap_to_scalp(points)[source]

Align and snap optodes or points to the scalp surface.

segmentation_masks: DataArray[source]
brain: Surface[source]
scalp: Surface[source]
landmarks: Annotated[DataArray, DataArraySchema(dims='label', coords='label', 'label', 'type')][source]
t_ijk2ras: DataArray[source]
t_ras2ijk: DataArray[source]
voxel_to_vertex_brain: spmatrix[source]
voxel_to_vertex_scalp: spmatrix[source]
classmethod from_segmentation(
segmentation_dir: str,
mask_files: dict[str, str] = {'csf': 'csf.nii', 'gm': 'gm.nii', 'scalp': 'scalp.nii', 'skull': 'skull.nii', 'wm': 'wm.nii'},
landmarks_ras_file: str | None = None,
brain_seg_types: list[str] = ['gm', 'wm'],
scalp_seg_types: list[str] = ['scalp'],
smoothing: float = 0.5,
brain_face_count: int | None = 180000,
scalp_face_count: int | None = 60000,
fill_holes: bool = True,
) TwoSurfaceHeadModel[source]

Constructor from binary masks as gained from segmented MRI scans.

Parameters:
  • segmentation_dir (str) – Folder containing the segmentation masks in NIFTI format.

  • mask_files (Dict[str, str]) – Dictionary mapping segmentation types to NIFTI filenames.

  • landmarks_ras_file (Optional[str]) – Filename of the landmarks in RAS space.

  • brain_seg_types (list[str]) – List of segmentation types to be included in the brain surface.

  • scalp_seg_types (list[str]) – List of segmentation types to be included in the scalp surface.

  • smoothing (float) – Smoothing factor for the brain and scalp surfaces.

  • brain_face_count (Optional[int]) – Number of faces for the brain surface.

  • scalp_face_count (Optional[int]) – Number of faces for the scalp surface.

  • fill_holes (bool) – Whether to fill holes in the segmentation masks.

classmethod from_surfaces(
segmentation_dir: str,
mask_files: dict[str, str] = {'csf': 'csf.nii', 'gm': 'gm.nii', 'scalp': 'scalp.nii', 'skull': 'skull.nii', 'wm': 'wm.nii'},
brain_surface_file: str = None,
scalp_surface_file: str = None,
landmarks_ras_file: str | None = None,
brain_seg_types: list[str] = ['gm', 'wm'],
scalp_seg_types: list[str] = ['scalp'],
smoothing: float = 0.5,
brain_face_count: int | None = 180000,
scalp_face_count: int | None = 60000,
fill_holes: bool = False,
) TwoSurfaceHeadModel[source]

Constructor from seg.masks, brain and head surfaces as gained from MRI scans.

Parameters:
  • segmentation_dir (str) – Folder containing the segmentation masks in NIFTI format.

  • mask_files (dict[str, str]) – Dictionary mapping segmentation types to NIFTI filenames.

  • brain_surface_file (str) – Path to the brain surface.

  • scalp_surface_file (str) – Path to the scalp surface.

  • landmarks_ras_file (Optional[str]) – Filename of the landmarks in RAS space.

  • brain_seg_types (list[str]) – List of segmentation types to be included in the brain surface.

  • scalp_seg_types (list[str]) – List of segmentation types to be included in the scalp surface.

  • smoothing (float) – Smoothing factor for the brain and scalp surfaces.

  • brain_face_count (Optional[int]) – Number of faces for the brain surface.

  • scalp_face_count (Optional[int]) – Number of faces for the scalp surface.

  • fill_holes (bool) – Whether to fill holes in the segmentation masks.

Returns:

An instance of the TwoSurfaceHeadModel class.

Return type:

TwoSurfaceHeadModel

property crs[source]

Coordinate reference system of the head model.

apply_transform(
transform: cdt.AffineTransform,
) TwoSurfaceHeadModel[source]

Apply a coordinate transformation to the head model.

Parameters:

transform – Affine transformation matrix (4x4) to be applied.

Returns:

Transformed head model.

save(foldername: str)[source]

Save the head model to a folder.

Parameters:

foldername (str) – Folder to save the head model into.

Returns:

None

classmethod load(foldername: str)[source]

Load the head model from a folder.

Parameters:

foldername (str) – Folder to load the head model from.

Returns:

Loaded head model.

Return type:

TwoSurfaceHeadModel

align_and_snap_to_scalp(
points: cdt.LabeledPointCloud,
) cdt.LabeledPointCloud[source]

Align and snap optodes or points to the scalp surface.

Parameters:

points (cdt.LabeledPointCloud) – Points to be aligned and snapped to the scalp surface.

Returns:

Points aligned and snapped to the scalp surface.

Return type:

cdt.LabeledPointCloud

snap_to_scalp_voxels(
points: cdt.LabeledPointCloud,
) cdt.LabeledPointCloud[source]

Snap optodes or points to the closest scalp voxel.

Parameters:

points (cdt.LabeledPointCloud) – Points to be snapped to the closest scalp voxel.

Returns:

Points aligned and snapped to the closest scalp

voxel.

Return type:

cdt.LabeledPointCloud

class cedalion.imagereco.forward_model.ForwardModel(
head_model: TwoSurfaceHeadModel,
geo3d: cdt.LabeledPointCloud,
measurement_list: DataFrame,
)[source]

Bases: object

Forward model for simulating light transport in the head.

Args: head_model (TwoSurfaceHeadModel): Head model containing voxel projections to brain

and scalp surfaces.

optode_pos (cdt.LabeledPointCloud): Optode positions. optode_dir (xr.DataArray): Optode orientations (directions of light beams). tissue_properties (xr.DataArray): Tissue properties for each tissue type. volume (xr.DataArray): Voxelated head volume from segmentation masks. unitinmm (float): Unit of head model, optodes expressed in mm. measurement_list (pd.DataFrame): List of measurements of experiment with source,

detector, channel, and wavelength.

compute_fluence(nphoton)[source]

Compute fluence for each channel and wavelength from photon simulation.

compute_sensitivity(fluence_all, fluence_at_optodes)[source]

Compute sensitivity matrix from fluence.

compute_fluence_mcx(**kwargs)[source]

Compute fluence for each channel and wavelength using MCX package.

Parameters:

kwargs – key-value pairs are passed to MCX’s configuration dict. For example nphoton (int) to control the number of photons to simulate. See https://pypi.org/project/pmcx for further options.

Returns:

Fluence in each voxel for each channel and wavelength.

Return type:

xr.DataArray

References

(Fang and Boas [FB09]) Qianqian Fang and David A. Boas, “Monte Carlo Simulation of Photon Migration in 3D Turbid Media Accelerated by Graphics Processing Units,” Optics Express, vol.17, issue 22, pp. 20178-20190 (2009).

(Yu et al. [YNPKF18]) Leiming Yu, Fanny Nina-Paravecino, David Kaeli, Qianqian Fang, “Scalable and massively parallel Monte Carlo photon transport simulations for heterogeneous computing platforms,” J. Biomed. Opt. 23(1), 010504 (2018).

(Yan and Fang [YF20]) Shijie Yan and Qianqian Fang* (2020), “Hybrid mesh and voxel based Monte Carlo algorithm for accurate and efficient photon transport modeling in complex bio-tissues,” Biomed. Opt. Express, 11(11) pp. 6262-6270. https://www.osapublishing.org/boe/abstract.cfm?uri=boe-11-11-6262

compute_fluence_nirfaster(meshingparam=None)[source]

Compute fluence for each channel and wavelength using NIRFASTer package.

Parameters:

meshingparam (ff.utils.MeshingParam) – Parameters to be used by the CGAL mesher. Note: they should all be double

Returns: xr.DataArray: Fluence in each voxel for each channel and wavelength.

References

(Dehghani et al. [DEY+09]) Dehghani, Hamid, et al. “Near infrared optical tomography using NIRFAST: Algorithm for numerical model and image reconstruction.” Communications in numerical methods in engineering 25.6 (2009): 711-732.

compute_sensitivity(fluence_all, fluence_at_optodes)[source]

Compute sensitivity matrix from fluence.

Parameters:
  • fluence_all (xr.DataArray) – Fluence in each voxel for each wavelength.

  • fluence_at_optodes (xr.DataArray) – Fluence at all optode positions for each wavelength.

Returns:

Sensitivity matrix for each channel, vertex and wavelength.

Return type:

xr.DataArray

static compute_stacked_sensitivity(sensitivity: DataArray)[source]

Compute stacked HbO and HbR sensitivity matrices from fluence.

Parameters:

sensitivity (xr.DataArray) – Sensitivity matrix for each vertex and wavelength.

Returns:

Stacked sensitivity matrix for each channel and vertex.

Return type:

xr.DataArray

cedalion.imagereco.forward_model.apply_inv_sensitivity(
od: cdt.NDTimeSeries,
inv_sens: DataArray,
) tuple[DataArray, DataArray][source]

Apply the inverted sensitivity matrix to optical density data.

Parameters:
  • od – time series of optical density data

  • inv_sens – the inverted sensitivity matrix

Returns:

Two DataArrays for the brain and scalp with the reconcstructed time series per vertex and chromophore.