Skip to content

Commit

Permalink
Merge pull request #1 from stadmill/electromagnetic_property
Browse files Browse the repository at this point in the history
Separated R1->C , independent of S->C conversion.
  • Loading branch information
stadmill authored Sep 24, 2024
2 parents e78d9e2 + 58f6dd6 commit 35fcd4c
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 38 deletions.
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

0 comments on commit 35fcd4c

Please sign in to comment.