Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Separated code for R1 to C #50

Merged
merged 2 commits into from
Sep 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions src/osipi/_electromagnetic_property.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import numpy as np
from numpy.typing import NDArray


def R1_to_C_linear_relaxivity(
R1: NDArray[np.float64], R10: np.float64, r1: np.float64
) -> NDArray[np.float64]:
"""
Electromagnetic property inverse model:
- longitudinal relaxation rate, linear with relaxivity

Converts R1 to tissue concentration

Args:
R1 (1D array of np.float64):
Vector of longitudinal relaxation rate in units of /s. [OSIPI code Q.EL1.001]
R10 (np.float64):
Native longitudinal relaxation rate in units of /s. [OSIPI code Q.EL1.002]
r1 (np.float64):
Longitudinal relaxivity in units of /s/mM. [OSIPI code Q.EL1.015]

Returns:
NDArray[np.float64]:
Vector of indicator concentration in units of mM. [OSIPI code Q.IC1.001]

References:
- Lexicon URL: https://osipi.github.io/OSIPI_CAPLEX/perfusionProcesses/#
- Lexicon code: P.EC1.001
- OSIPI name: model-based
- Inversion method: analytical inversion [OSIPI code G.MI1.001]
- Forward model:
longitudinal relaxation rate, linear with relaxivity model [OSIPI code M.EL1.003]
- Adapted from equation given in lexicon
"""
# Check R1 is a 1D array of floats
if not (isinstance(R1, np.ndarray) and R1.ndim == 1 and R1.dtype == np.float64):
raise TypeError("R1 must be a 1D NumPy array of np.float64")
elif not (r1 >= 0):
raise ValueError("r1 must be positive")
return (R1 - R10) / r1 # C
40 changes: 2 additions & 38 deletions src/osipi/_signal_to_concentration.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import numpy as np
from numpy.typing import NDArray

from ._electromagnetic_property import R1_to_C_linear_relaxivity


def S_to_C_via_R1_SPGR(
S: NDArray[np.float64],
Expand Down Expand Up @@ -88,41 +90,3 @@ def S_to_R1_SPGR(
cos_a = np.cos(a_rad)
S0 = S_baseline * (1 - cos_a * exp_TR_R10) / (sin_a * (1 - exp_TR_R10))
return np.log(((S0 * sin_a) - S) / (S0 * sin_a - (S * cos_a))) * (-1 / TR) # R1


def R1_to_C_linear_relaxivity(
R1: NDArray[np.float64], R10: np.float64, r1: np.float64
) -> NDArray[np.float64]:
"""
Electromagnetic property inverse model:
- longitudinal relaxation rate, linear with relaxivity

Converts R1 to tissue concentration

Args:
R1 (1D array of np.float64):
Vector of longitudinal relaxation rate in units of /s. [OSIPI code Q.EL1.001]
R10 (np.float64):
Native longitudinal relaxation rate in units of /s. [OSIPI code Q.EL1.002]
r1 (np.float64):
Longitudinal relaxivity in units of /s/mM. [OSIPI code Q.EL1.015]

Returns:
NDArray[np.float64]:
Vector of indicator concentration in units of mM. [OSIPI code Q.IC1.001]

References:
- Lexicon URL: https://osipi.github.io/OSIPI_CAPLEX/perfusionProcesses/#
- Lexicon code: P.EC1.001
- OSIPI name: model-based
- Inversion method: analytical inversion [OSIPI code G.MI1.001]
- Forward model:
longitudinal relaxation rate, linear with relaxivity model [OSIPI code M.EL1.003]
- Adapted from equation given in lexicon
"""
# Check R1 is a 1D array of floats
if not (isinstance(R1, np.ndarray) and R1.ndim == 1 and R1.dtype == np.float64):
raise TypeError("R1 must be a 1D NumPy array of np.float64")
elif not (r1 >= 0):
raise ValueError("r1 must be positive")
return (R1 - R10) / r1 # C
Loading