TPCCLIB
Loading...
Searching...
No Matches
simoxygen.c File Reference

Simulation of [O-15]O2 tissue kinetics. More...

#include "tpcclibConfig.h"
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include <string.h>
#include "tpccm.h"

Go to the source code of this file.

Functions

int simOxygen (double *t, double *ca1, double *ca2, double *ca1i, double *ca2i, const int n, const double k1a, const double k2a, const double km, const double k1b, const double k2b, const double vb, const double fa, const int vvm, double *scpet, double *sct1, double *sct2, double *sctab, double *sctvb1, double *sctvb2, double *scvb1, double *scvb2, const int verbose)

Detailed Description

Simulation of [O-15]O2 tissue kinetics.

Definition in file simoxygen.c.

Function Documentation

◆ simOxygen()

int simOxygen ( double * t,
double * ca1,
double * ca2,
double * ca1i,
double * ca2i,
const int n,
const double k1a,
const double k2a,
const double km,
const double k1b,
const double k2b,
const double vb,
const double fa,
const int vvm,
double * scpet,
double * sct1,
double * sct2,
double * sctab,
double * sctvb1,
double * sctvb2,
double * scvb1,
double * scvb2,
const int verbose )

Simulate tissue and venous blood TACs using dual-input compartment model for [O-15]O2 (one tissue compartment for [O-15]O2, and another tissue compartment for its metabolite [O-15]H2O). Based on Mintun et al. J Nucl Med. 1984;25(2):177-187.

The units of rate constants must be related to the time unit of the data; 1/min and min, or 1/sec and sec.

Returns
Function returns 0 when successful, else a value >= 1.
Author
Vesa Oikonen
See also
simMBF, simC1, simC2, simC1DI, simDispersion, simDelay, simSamples
Parameters
tArray of sample times.
ca1Array of arterial blood activities of tracer1 ([O-15]O2).
ca2Array of arterial blood activities of tracer2 ([O-15]H2O).
ca1iArray of AUC 0-t of arterial tracer1 activities; NULL if not available.
ca2iArray of AUC 0-t of arterial tracer2 activities; NULL if not available.
nNr of samples (array lengths).
k1aRate constant of the model for tracer1 (from blood to C1).
k2aRate constant of the model for tracer1 (from C1 to blood).
kmRate constant of the model (from tracer1 in C1 to tracer2 in C2).
k1bRate constant of the model for tracer2 (from blood to C2).
k2bRate constant of the model for tracer2 (from C2 to blood).
vbVascular volume fraction [0-1].
faArterial fraction of vascular volume [0-1].
vvmVascular volume modelling: set to 0 to use Cpet = Vb*Cb + (1-Vb)*Ct, or set to 1 to use Cpet = Vb*Cb + Ct.
scpetPointer for TTAC array to be simulated; allocate in the calling program or set to NULL if not needed.
sct1Simulated TAC of tracer1 in tissue; allocate in the calling program or set to NULL if not needed.
sct2Simulated TAC of tracer2 in tissue; allocate in the calling program or set to NULL if not needed.
sctabTotal arterial contribution to PET TTAC; allocate in the calling program or set to NULL if not needed.
sctvb1Venous tracer1 contribution to PET TAC; allocate in the calling program or set to NULL if not needed.
sctvb2Venous tarcer1 contribution to PET TAC; allocate in the calling program or set to NULL if not needed.
scvb1Venous BTAC of tracer1; allocate in the calling program or set to NULL if not needed.
scvb2Venous BTAC of tracer2; allocate in the calling program or set to NULL if not needed.
verboseVerbose level; if zero, then nothing is printed into stdout or stderr.

Definition at line 29 of file simoxygen.c.

84 {
85 if(verbose>0) {
86 printf("%s()\n", __func__);
87 if(verbose>1) {
88 printf(" k1a := %g\n", k1a);
89 printf(" k2a := %g\n", k2a);
90 printf(" km := %g\n", km);
91 printf(" k1b := %g\n", k1b);
92 printf(" k2b := %g\n", k2b);
93 printf(" vb := %g\n", vb);
94 printf(" fa := %g\n", fa);
95 printf(" n := %d\n", n);
96 }
97 }
98
99 /* Check for data */
100 if(n<2) return 1;
101 if(t==NULL) return 2;
102 if(ca1==NULL || ca2==NULL) return 3;
103
104 /* Check parameters */
105 if(k1a<0.0 || k1b<0.0 || k2a<0.0 || k2b<0.0) return(4);
106 if(vb<0.0 || vb>=1.0) return(5);
107 if(fa<0.0 || fa>1.0) return(6);
108 double va=fa*vb; // arterial volume fraction in tissue
109 double vv=(1.0-fa)*vb; // venous volume fraction in tissue
110
111 /* Set initial condition */
112 double t_last=0.0; // previous sample time
113 if(t[0]<t_last) t_last=t[0];
114 /* Concentrations, integrals, and previous values are zero */
115 double cba1i=0.0, cba1_last=0.0;
116 double cba2i=0.0, cba2_last=0.0;
117 double ct1=0.0, ct1_last=0.0, ct1i=0.0, ct1i_last=0.0;
118 double ct2=0.0, ct2_last=0.0, ct2i=0.0, ct2i_last=0.0;
119 double cvb1=0.0, cvb2=0.0;
120
121 /* Calculate curves */
122 double p, q;
123 double dt2; // delta t / 2
124 for(int i=0; i<n; i++) {
125 dt2=0.5*(t[i]-t_last);
126 if(dt2>0.0) {
127 /* arterial integrals */
128 if(ca1i!=NULL) cba1i=ca1i[i]; else cba1i+=(ca1[i]+cba1_last)*dt2;
129 if(ca2i!=NULL) cba2i=ca2i[i]; else cba2i+=(ca2[i]+cba2_last)*dt2;
130 /* partial results */
131 p=ct1i_last+dt2*ct1_last;
132 q=ct2i_last+dt2*ct2_last;
133 /* 1st tissue compartment and its integral */
134 ct1 = (k1a*cba1i - (k2a+km)*p) / (1.0 + dt2*(k2a+km));
135 ct1i = ct1i_last + dt2*(ct1_last+ct1);
136 /* 2nd tissue compartment and its integral */
137 ct2 = (km*ct1i + k1b*cba2i - k2b*q) / (1.0 + dt2*k2b);
138 ct2i = ct2i_last + dt2*(ct2_last+ct2);
139 }
140 /* Venous BTACs */
141 if(k1a>0.0 && k2a>0.0) cvb1=ct1/(k1a/k2a);
142 else if(k2a>0.0) cvb1=0.0; else cvb1=ca1[i];
143 if(k1b>0.0 && k2b>0.0) cvb2=ct2/(k1b/k2b);
144 else if(k2b>0.0) cvb2=0.0; else cvb2=ca2[i];
145 /* copy values to argument arrays */
146 if(scpet!=NULL) {
147 if(vvm==0) scpet[i]= va*(ca1[i]+ca2[i]) + vv*(cvb1+cvb2) + (1.0-vb)*(ct1+ct2);
148 else scpet[i]= va*(ca1[i]+ca2[i]) + vv*(cvb1+cvb2) + (ct1+ct2);
149 }
150 if(sct1!=NULL) {
151 sct1[i]=ct1; if(vvm==0) sct1[i]*=(1.0-vb);
152 }
153 if(sct2!=NULL) {
154 sct2[i]=ct2; if(vvm==0) sct2[i]*=(1.0-vb);
155 }
156 if(sctab!=NULL) {
157 sctab[i]=va*(ca1[i]+ca2[i]);
158 }
159 if(sctvb1!=NULL) {
160 sctvb1[i]=vv*cvb1;
161 }
162 if(sctvb2!=NULL) {
163 sctvb2[i]=vv*cvb2;
164 }
165 if(scvb1!=NULL) scvb1[i]=cvb1;
166 if(scvb2!=NULL) scvb2[i]=cvb2;
167 /* prepare for the next loop */
168 t_last=t[i];
169 cba1_last=ca1[i]; cba2_last=ca2[i];
170 ct1_last=ct1; ct1i_last=ct1i;
171 ct2_last=ct2; ct2i_last=ct2i;
172 } // next sample
173
174 if(verbose>2) {
175 printf("AUC 0-%g:\n", t_last);
176 printf(" cba1i := %g\n", cba1i);
177 printf(" cba2i := %g\n", cba2i);
178 printf(" ct1i := %g\n", ct1i_last);
179 printf(" ct2i := %g\n", ct2i_last);
180 }
181
182 return 0;
183}