Skip to content

Commit

Permalink
add new section to the docs for dro
Browse files Browse the repository at this point in the history
  • Loading branch information
MohamedNasser8 committed Aug 3, 2024
1 parent 47131c9 commit d03bffc
Show file tree
Hide file tree
Showing 9 changed files with 121 additions and 9 deletions.
3 changes: 3 additions & 0 deletions docs-mk/docs/references/dro/dro_read_mri.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# osipi.dro.read_mri_from_dicom

::: osipi.DRO.read_dicom_slices_as_4d_signal
File renamed without changes.
3 changes: 3 additions & 0 deletions docs-mk/docs/references/dro/signal_enhance.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# osipi.dro.SignalEnhancementExtract

::: osipi.DRO.SignalEnhancementExtract
9 changes: 9 additions & 0 deletions docs-mk/docs/user-guide/dro.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# What is a DRO(digital reference object)?
Digital reference object are synthetic images that have been created
by computer simulations of a target in its environment, you can look here for a more detailed explanation of what a [DRO](https://qibawiki.rsna.org/images/1/14/QIBA_DRO_2015_v1.42.pdf) is.

# How to use DCE DROs in OSIPI
- [Read DRO data](synthetic.md#read-dro-data)
- [Enhance the signal](synthetic.md#enhance-the-signal)
- [Get the AIF](synthetic.md#get-the-aif)
- [Get the perfusion and tissue parameters](synthetic.md#get-the-perfusion-and-tissue-parameters)
2 changes: 2 additions & 0 deletions docs-mk/docs/user-guide/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,5 @@ Welcome to the User Guide section.
- [Relaxation time to concentration](simulate.md)
- [Concentration to tissue parameters](simulate.md)
- [All in one go: signal to tissue parameters](simulate.md)
4. [DRO](dro.md)
- [Read data](simulate.md)
62 changes: 62 additions & 0 deletions docs-mk/docs/user-guide/synthetic.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
## Read MR data from a folder of dicom files
``` python
import osipi


dicom_folder = 'path/to/dicom/folder'

signal, slices, dicom_ref = osipi.read_dicom(dicom_folder)

#Read a DICOM series from a folder path.
#Returns the signal, slices and dicom reference.
# - The signal is a 4D numpy array with dimensions (x, y, z, t)
# - The slices is a list of slices
# - The dicom reference is a sample dicom file from the folder

```

## Enhance the signal
Enhance the signal by removing baseline signal which is the first time point of the signal.
Before the contrast agent is arrived, the signal is assumed to be constant. This constant signal is removed from the signal to enhance the signal.
``` python
import osipi
from osipi import enhance_signal

E, S0, S = enhance_signal(signal, data_shape, 5)

# - E is the enhanced signal after removing the baseline signal
# - S0 is the average baseline signal here in this example of the first 5 time points
# - S is the original raw signal
```

## Get the AIF
Get the Arterial Input Function (AIF) from the signal.
Using a mask, the AIF is extracted from the signal.

``` python
import osipi
from osipi import get_aif_from_ROI
# first you may have to create a mask for the AIF manually or using a saved mask and apply it to the signal
aif_mask, rio_voxels = osipi.rio(signal, slice, saved=True)
# this returns the mask and the number of voxels in the mask
aif = get_aif_from_ROI(signal, aif_mask)
# this returns the AIF from the signal by averaging the signal over the voxels in the mask
```

## Get the perfusion and tissue parameters

Get the perfusion and tissue parameters from the signal and the AIF.
You may here choose different models to fit the signal to get the parameters.

``` python
import osipi
from osipi import extended_tofts_model

# Fit the signal to the extended Tofts model
ktrans, ve, vp = extended_tofts_model(signal, aif, data_shape)

# - ktrans is the volume transfer constant
# - ve is the extravascular extracellular volume fraction
# - vp is the plasma volume fraction
# visit CAPLEX for more information on the model and the parameters
```
14 changes: 11 additions & 3 deletions docs-mk/mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ theme:
language: en
palette:
- scheme: default
primary: teal
primary: deep-purple
accent: purple
toggle:
icon: material/toggle-switch
Expand All @@ -36,7 +36,7 @@ theme:
toggle:
icon: material/toggle-switch
name: Switch to dark mode
primary: teal
primary: purple
accent: lime

plugins:
Expand All @@ -57,12 +57,20 @@ nav:
- Simulating data:
- Overview: user-guide/simulate.md
- Simulate: user-guide/gen_aif.md
- DRO:
- Overview: user-guide/dro.md
- DRO: user-guide/synthetic.md

- About: about/index.md
- Developer Guide: contribution/index.md
- References:
- references/index.md
- Index:
- Dro:
- references/dro/index.md
- DRO functions:
- read_mri_from_dicoms: references/dro/dro_read_mri.md
- signal_enhancement: references/dro/signal_enhance.md
- Models:
- references/models/index.md
- AIF models:
- references/models/aif_models/index.md
Expand Down
35 changes: 29 additions & 6 deletions src/osipi/DRO/DICOM_processing.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,20 @@
from osipi.DRO.filters_and_noise import median_filter


def read_dicom_slices_as_4d_signal(folder_path):
"""
Read a DICOM series from a folder path.
Returns the signal data as a 4D numpy array (x, y, z, t).
def read_dicom_slices_as_4d_signal(folder_path: str) -> (np.ndarray, dict, np.ndarray):
"""Read DICOM files from a folder and return the 4D signal data.
Args:
folder_path (str): Path to the folder containing DICOM files.
Returns:
signal: The 4D signal data (x, y, z, t).
slices: Dictionary containing the slices.
example_data: The first slice.
"""

slices = {}
for root, _, files in os.walk(folder_path):
for file in files:
Expand Down Expand Up @@ -40,8 +49,22 @@ def read_dicom_slices_as_4d_signal(folder_path):
return signal, slices, slices[slice_location][0][1]


def SignalEnhancementExtract(S, datashape, baselinepoints):
# Take baseline average
def SignalEnhancementExtract(
S: np.ndarray, datashape: list, baselinepoints: int = 5
) -> (np.ndarray, np.ndarray, np.ndarray):
"""Signal enhancement extraction from 4D signal data.
Args:
S: is the 4D signal data (x, y, z, t).
datashape: is the shape of the data (x, y, z, t).
baselinepoints: is the number of time points before contrast injection.
Returns:
E: The signal enhancement.
S0: The baseline signal (S0).
S: The 4D signal data (x, y, z, t).
"""
S0 = np.average(S[:, :, :, 0:baselinepoints], axis=3) # Take baseline signal
E = np.zeros_like(S)

Expand Down
2 changes: 2 additions & 0 deletions src/osipi/DRO/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@

from .DICOM_processing import read_dicom_slices_as_4d_signal, SignalEnhancementExtract

0 comments on commit d03bffc

Please sign in to comment.