TPCCLIB
Loading...
Searching...
No Matches
tpccm.h File Reference

Header file for libtpccm. More...

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

Go to the source code of this file.

Data Structures

struct  ICMPARC

Functions

int simMBF (double *t, double *ci, const int nr, const double k1, const double k2, const double Vfit, double *ct)
int simC1 (double *t, double *ca, const int nr, const double k1, const double k2, double *ct)
int simC1_i (double *t, double *cai, const int nr, const double k1, const double k2, double *ct)
int simC1_d (double *t, double *ca, const int nr, const double k1, const double k2, double *ct)
int simC2 (double *t, double *ca, const int nr, const double k1, const double k2, const double k3, const double k4, double *ct, double *cta, double *ctb)
int simC2_i (double *t, double *cai, const int nr, const double k1, const double k2, const double k3, const double k4, double *ct, double *cta, double *ctb)
int simC3s (double *t, double *ca, const int nr, double k1, double k2, double k3, double k4, double k5, double k6, double *ct, double *cta, double *ctb, double *ctc)
int simC3vs (double *t, double *ca, double *cb, const int nr, const double k1, const double k2, const double k3, const double k4, const double k5, const double k6, const double f, const double vb, const double fa, const int vvm, double *cpet, double *cta, double *ctb, double *ctc, double *ctab, double *ctvb)
int simC3p (double *t, double *ca, const int nr, const double k1, const double k2, const double k3, const double k4, const double k5, const double k6, double *ct, double *cta, double *ctb, double *ctc)
int simC3vp (double *t, double *ca, double *cb, const int nr, const double k1, const double k2, const double k3, const double k4, const double k5, const double k6, const double f, const double vb, const double fa, const int vvm, double *cpet, double *cta, double *ctb, double *ctc, double *ctab, double *ctvb)
int simC2l (double *t, double *ca, const int nr, const double k1, const double k2, const double k3, const double kLoss, double *ct, double *cta, double *ctb)
int simC2vl (double *t, double *ca, double *cb, const int nr, const double k1, const double k2, const double k3, const double kL, const double f, const double vb, const double fa, const int vvm, double *cpet, double *cta, double *ctb, double *ctab, double *ctvb)
int simC3vpKLoss (double *t, double *ca, double *cb, const int nr, const double k1, const double k2, const double k3, const double k4, const double k5, const double k6, const double kLoss, const double f, const double vb, const double fa, const int vvm, double *cpet, double *cta, double *ctb, double *ctc, double *ctab, double *ctvb)
int simRTCM (double *t, double *cr, const int nr, const double R1, const double k2, const double k3, const double k4, double *ct, double *cta, double *ctb)
int simSRTM (double *t, double *cr, const int nr, const double R1, const double k2, const double BP, double *ct)
int simTRTM (double *t, double *cr, const int nr, const double R1, const double k2, double k3, double *ct)
int simC1DI (double *t, double *cba, double *cbb, const int nr, const double k1a, const double k1b, const double k2, double *ct)
int simC3DIvs (double *t, double *ca1, double *ca2, double *cb, const int nr, const double k1, const double k2, const double k3, const double k4, const double k5, const double k6, const double k1b, const double k2b, const double f, const double vb, const double fa, const int vvm, double *scpet, double *sct1, double *sct2, double *sct3, double *sct1b, double *sctab, double *sctvb)
int simC4DIvp (double *t, double *ca1, double *ca2, double *cb, const int nr, const double k1, const double k2, const double k3, const double k4, const double k5, const double k6, const double k7, const double km, const double k1b, const double k2b, const double f, const double vb, const double fa, const int vvm, double *scpet, double *sct1, double *sct2, double *sct3, double *sct1b, double *sctab, double *sctvb, const int verbose)
int simC4DIvs (double *t, double *ca1, double *ca2, double *cb, const int nr, const double k1, const double k2, const double k3, const double k4, const double k5, const double k6, const double k7, const double km, const double k1b, const double k2b, const double f, const double vb, const double fa, const int vvm, double *scpet, double *sct1, double *sct2, double *sct3, double *sct1b, double *sctab, double *sctvb, const int verbose)
int simDispersion (double *x, double *y, const int n, const double tau1, const double tau2, double *tmp)
int corDispersion (double *x, double *y, const int n, const double tau, double *tmp)
int simTTM (double *t, double *c0, const int n, const double k, const int cn, double *cout)
int simTTM_i (double *t, double *c0i, const int n, const double k, const int cn, double *cout)
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)
int convolve1D (double *data, const int n, double *kernel, const int m, double *out)
 Calculates the convolution sum of a discrete real data set data[0..n-1] and a discretized response function kernel[0..m].
int simIsSteadyInterval (double *x, const int n, double *f)
void icmparcInit (ICMPARC *d)
int icmparcAddMetabolites (ICMPARC *d, unsigned const int mNr)
int icmparcAllocateTACs (ICMPARC *d, unsigned const int sNr, const int sub)
void icmparcFree (ICMPARC *d)
int simBTAC (double *t, const unsigned int nr, ICMPARC *p, double *cb)
int simBM1 (double *t, double *ct, const int nr, const double k, double *cp)

Detailed Description

Header file for libtpccm.

Header file for compartmental model library.

Author
Vesa Oikonen

Definition in file tpccm.h.

Function Documentation

◆ convolve1D()

int convolve1D ( double * data,
const int n,
double * kernel,
const int m,
double * out )

Calculates the convolution sum of a discrete real data set data[0..n-1] and a discretized response function kernel[0..m].

Convolution is not aware of the step size (default is 1); if step size is not 1 (it usually isn't), the step size must be taken into account either when computing the kernel or by scaling the convolution sum.

Remarks
This function does not use FFT, which would be faster with very large dataset, but slightly less precise.
See also
tacInterpolateToEqualLengthFrames, simDispersion, simC1
Returns
Function returns 0 when successful, or 1 if input data is not valid.
Parameters
dataData array of length n-1 to be convolved, including any user-defined zero-padding.
nNr of data values.
kernelResponse function values in an array of length m.
mLength of kernel array.
outThe convolved sum data is returned in out[0..n-1]; this must not overlap the input data.

Definition at line 27 of file convolut.c.

38 {
39 if(n<1 || m<1 || data==NULL || kernel==NULL || out==NULL || out==data) return(1);
40
41 for(int di=0; di<n; di++) out[di]=0.0;
42
43 for(int di=m-1; di<n; di++) {
44 int dj=di;
45 for(int k=0; k<m; k++)
46 out[di] += data[dj--] * kernel[k];
47 }
48
49 for(int di=0; di<n && di<m-1; di++) {
50 int k=0;
51 for(int dj=di; dj>=0; dj--)
52 out[di] += data[dj] * kernel[k++];
53 }
54
55 return(0);
56}

◆ corDispersion()

int corDispersion ( double * x,
double * y,
const int n,
const double tau,
double * tmp )

Correct time-activity curve for the effect of dispersion.

Data must be noise-free and have very short sampling intervals. The units of rate constants must be related to the TAC time units; 1/min and min, or 1/sec and sec.

Returns
Function returns 0 when successful, else a value >= 1.
Author
Vesa Oikonen
See also
simDispersion, simDelay
Parameters
xArray of sample times; must be in increasing order and >=0.
yArray of sample values, which will be replaced here by dispersion corrected values.
nNr of samples.
tauDispersion time constant (zero if no dispersion); in same time unit as sample times.
tmpArray for temporary data, for at least n samples; enter NULL to let function to allocate and free the temporary space.

Definition at line 88 of file simdispersion.c.

100 {
101 /* Check input */
102 if(x==NULL || y==NULL || n<2) return 1;
103 if(tau<0.0) return 2;
104 if(x[0]<0.0) return 3;
105
106 /* Allocate memory if not allocated by user */
107 double *buf;
108 if(tmp!=NULL) buf=tmp; else buf=(double*)malloc(n*sizeof(double));
109 if(buf==NULL) return 3;
110
111 /* Integrate measured data */
112 buf[0]=0.5*y[0]*x[0];
113 for(int i=1; i<n; i++) buf[i]=buf[i-1]+0.5*(y[i]+y[i-1])*(x[i]-x[i-1]);
114
115 /* Calculate the integral of dispersion corrected data */
116 for(int i=0; i<n; i++) buf[i]+=tau*y[i];
117
118 /* Calculate dispersion corrected curve from its integral */
119 {
120 int i=0;
121 double dt=x[i];
122 if(dt>0.0) y[i]=2.0*buf[i]/dt; else y[i]=0.0;
123 for(i=1; i<n-1; i++) {
124 dt=x[i+1]-x[i-1]; if(dt>0.0) y[i]=(buf[i+1]-buf[i-1])/dt; else y[i]=y[i-1];
125 }
126 dt=x[i]-x[i-1]; if(dt>0.0) y[i]=(buf[i]-buf[i-1])/dt; else y[i]=y[i-1];
127 }
128
129 if(tmp==NULL) free(buf);
130 return 0;
131}

◆ icmparcAddMetabolites()

int icmparcAddMetabolites ( ICMPARC * d,
unsigned const int mNr )

Add sub-structures for metabolite(s) in parent ICMPARC structure.

See also
ICMPARC, icmparcInit, icmparcFree, icmparcAllocateTACs
Returns
Function returns 0 when successful, else a value >= 1.
Parameters
dPointer to parent ICMPARC; can itself be a sub-structure.
mNrNumber of metabolites to add.

Definition at line 43 of file simblood.c.

48 {
49 if(d==NULL) return(1);
50 if(d->mNr>0 && d->metabolite!=NULL) { // delete any previous metabolite(s)
51 for(unsigned int i=0; i<d->mNr; i++) icmparcFree(&d->metabolite[i]);
52 free(d->metabolite); d->mNr=0; d->metabolite=(ICMPARC*)NULL;
53 }
54 if(mNr==0) return(0);
55
56 d->metabolite=(ICMPARC*)malloc(sizeof(ICMPARC)*mNr);
57 if(d->metabolite==NULL) return(3);
58 d->mNr=mNr;
59 for(unsigned int i=0; i<mNr; i++) {
60 icmparcInit(&d->metabolite[i]);
61 d->metabolite[i].parent=d;
62 }
63 return(0);
64}
void icmparcFree(ICMPARC *d)
Definition simblood.c:125
void icmparcInit(ICMPARC *d)
Definition simblood.c:20
struct ICMPARC * parent
Definition tpccm.h:215
unsigned int mNr
Definition tpccm.h:211
struct ICMPARC * metabolite
Definition tpccm.h:213

◆ icmparcAllocateTACs()

int icmparcAllocateTACs ( ICMPARC * d,
unsigned const int sNr,
const int sub )

Allocate space for optional TACs inside ICMPARC structure.

See also
ICMPARC, icmparcInit, icmparcAddMetabolites, icmparcFree
Returns
Function returns 0 when successful, else a value >= 1.
Parameters
dPointer to ICMPARC.
sNrNumber of TAC samples (array lengths); set to zero to just free previous data.
subAllocate (1) or do not allocate (0) space for TACs inside sub-structures.

Definition at line 72 of file simblood.c.

79 {
80 if(d==NULL) return(1);
81
82 /* Delete any existing TAC data */
83 if(d->ic_BV!=NULL) free(d->ic_BV);
84 if(d->ic_TS!=NULL) free(d->ic_TS);
85 if(d->ic_TF!=NULL) free(d->ic_TF);
86 d->ic_BV=d->ic_TS=d->ic_TF=(double*)NULL;
87 if(d->c_BA!=NULL) free(d->c_BA);
88 if(d->c_BV!=NULL) free(d->c_BV);
89 if(d->c_TS!=NULL) free(d->c_TS);
90 if(d->c_TF!=NULL) free(d->c_TF);
91 d->c_BA=d->c_BV=d->c_TS=d->c_TF=(double*)NULL;
92 if(sub!=0 && d->mNr>0 && d->metabolite!=NULL) {
93 for(unsigned int i=0; i<d->mNr; i++) icmparcAllocateTACs(&d->metabolite[i], 0, sub);
94 }
95 if(sNr==0) return(0);
96
97 /* Allocate space */
98 d->c_BA=(double*)malloc(sNr*sizeof(double));
99 d->c_BV=(double*)malloc(sNr*sizeof(double));
100 d->c_TS=(double*)malloc(sNr*sizeof(double));
101 d->c_TF=(double*)malloc(sNr*sizeof(double));
102 d->ic_BV=(double*)malloc(sNr*sizeof(double));
103 d->ic_TS=(double*)malloc(sNr*sizeof(double));
104 d->ic_TF=(double*)malloc(sNr*sizeof(double));
105 if(d->c_BA==NULL || d->c_BV==NULL || d->c_TS==NULL || d->c_TF==NULL ||
106 d->ic_BV==NULL || d->ic_TS==NULL || d->ic_TF==NULL) {
107 icmparcAllocateTACs(d, 0, sub); return(3);
108 }
109 if(sub!=0 && d->mNr>0 && d->metabolite!=NULL) {
110 int ret=0;
111 for(unsigned int i=0; i<d->mNr && !ret; i++)
112 ret=icmparcAllocateTACs(&d->metabolite[i], sNr, sub);
113 if(ret) return(ret);
114 }
115
116 return(0);
117}
int icmparcAllocateTACs(ICMPARC *d, unsigned const int sNr, const int sub)
Definition simblood.c:72
double * c_BA
Definition tpccm.h:229
double * c_TF
Definition tpccm.h:235
double * ic_BV
Definition tpccm.h:223
double * ic_TF
Definition tpccm.h:227
double * c_BV
Definition tpccm.h:231
double * c_TS
Definition tpccm.h:233
double * ic_TS
Definition tpccm.h:225

Referenced by icmparcAllocateTACs().

◆ icmparcFree()

void icmparcFree ( ICMPARC * d)

Free memory that is (optionally) allocated inside the ICMPARC structure or in its sub-structures. Field values are not changed, except for pointers to allocated memory that are set to NULL.

See also
ICMPARC, icmparcInit, icmparcAddMetabolites, icmparcAllocateTACs
Parameters
dPointer to ICMPARC.

Definition at line 125 of file simblood.c.

128 {
129 if(d==NULL) return;
130 /* Free sub-structures recursively */
131 if(d->mNr>0 && d->metabolite!=NULL) {
132 for(unsigned int i=0; i<d->mNr; i++) icmparcFree(&d->metabolite[i]);
133 free(d->metabolite); d->mNr=0; d->metabolite=(ICMPARC*)NULL;
134 }
135 /* Free optional TACs */
136 if(d->ic_BV!=NULL) free(d->ic_BV);
137 if(d->ic_TS!=NULL) free(d->ic_TS);
138 if(d->ic_TF!=NULL) free(d->ic_TF);
139 d->ic_BV=d->ic_TS=d->ic_TF=(double*)NULL;
140 if(d->c_BA!=NULL) free(d->c_BA);
141 if(d->c_BV!=NULL) free(d->c_BV);
142 if(d->c_TS!=NULL) free(d->c_TS);
143 if(d->c_TF!=NULL) free(d->c_TF);
144 d->c_BA=d->c_BV=d->c_TS=d->c_TF=(double*)NULL;
145}

Referenced by icmparcAddMetabolites(), and icmparcFree().

◆ icmparcInit()

void icmparcInit ( ICMPARC * d)

Initiate the ICMPARC structure before any use.

See also
ICMPARC, icmparcAddMetabolites, icmparcFree, icmparcAllocateTACs
Parameters
dPointer to ICMPARC.

Definition at line 20 of file simblood.c.

23 {
24 if(d==NULL) return;
25 d->name[0]=(char)0;
26 d->Ti=d->Tdur=d->Irate=0.0;
27 d->k_BV_BA=0.0;
28 d->k_BA_U=d->k_BA_TF=d->k_BA_TS=0.0;
29 d->k_TF_BV=d->k_TS_BV=0.0;
30 d->mNr=0; d->metabolite=(ICMPARC*)NULL;
31 d->parent=(ICMPARC*)NULL;
32 d->kp_BV=d->kp_TF=d->kp_TS=0.0;
33 d->ic_BV=d->ic_TS=d->ic_TF=(double*)NULL;
34 d->c_BA=d->c_BV=d->c_TS=d->c_TF=(double*)NULL;
35}
double k_TF_BV
Definition tpccm.h:207
double k_BA_TS
Definition tpccm.h:205
double Tdur
Definition tpccm.h:195
double Ti
Definition tpccm.h:193
double k_BV_BA
Definition tpccm.h:199
double k_TS_BV
Definition tpccm.h:209
double kp_TF
Definition tpccm.h:219
double k_BA_U
Definition tpccm.h:201
double kp_BV
Definition tpccm.h:217
double k_BA_TF
Definition tpccm.h:203
char name[256]
Definition tpccm.h:191
double kp_TS
Definition tpccm.h:221
double Irate
Definition tpccm.h:197

Referenced by icmparcAddMetabolites().

◆ simBM1()

int simBM1 ( double * t,
double * ct,
const int nr,
const double k,
double * cp )

Calculate metabolite correct input curve from total input curve using simplistic 1K model dCmetabolite(t)/dt = k*Cparent(t) and since Ctotal(t) = Cparent(t) + Cmetabolite(t), we calculate metabolite corrected curve as dCparent(t)/dt = dCtotal(t)/dt - k*Cparent(t). Note that this model may result in negative parent values.

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

See also
simC1, simDispersion
Returns
Function returns 0 when successful, else a value >= 1.
Author
Vesa Oikonen
Parameters
tArray of time values.
ctArray of total activities.
nrNumber of values in TACs.
kRate constant of the model.
cpPointer for metabolite corrected data array to be simulated; must be allocated.

Definition at line 275 of file simblood.c.

286 {
287 int i;
288 double dt2;
289 double cp_last, t_last;
290 double cpi, cpi_last;
291
292
293 /* Check for data */
294 if(nr<2) return 1;
295 if(t==NULL || ct==NULL || cp==NULL) return 2;
296
297 /* Check actual parameter number */
298 if(!(k>=0.0)) return 3;
299
300 /* Calculate curves */
301 t_last=0.0; if(t[0]<t_last) t_last=t[0];
302 cp_last=0.0; cpi=0.0; cpi_last=0.0; cpi_last=0.0;
303 for(i=0; i<nr; i++) {
304 /* delta time / 2 */
305 dt2=0.5*(t[i]-t_last);
306 /* calculate values */
307 if(dt2<0.0) {
308 return 5;
309 } else if(dt2>0.0) {
310 cp[i] = (ct[i] - k*(cpi_last + dt2*cp_last)) / (1.0 + dt2*k);
311 cpi = cpi_last + dt2*(cp_last+cp[i]);
312 }
313 /* prepare to the next loop */
314 t_last=t[i]; cp_last=cp[i]; cpi_last=cpi;
315 }
316
317 return 0;
318}

◆ simBTAC()

int simBTAC ( double * t,
const unsigned int nr,
ICMPARC * p,
double * c_BA )

Simulate BTAC using compartmental model. NOT FUNCTIONAL!

See also
ICMPARC, icmparcInit, icmparcAddMetabolites, icmparcAllocateTACs, simDispersion, simSamples, parExampleTTACs, parExamplePerfectBolus, simDelay
Returns
Function returns 0 when successful, else a value >= 1.
Parameters
tArray of sample time values; must be non-negative and in increasing order.
nrNumber of values (samples) in TACs.
pPointer to data structure containing simulation parameters.
See also
icmparcInit, icmparcAddMetabolites, icmparcAllocateTACs
Parameters
c_BAPointer for arterial BTAC array to be simulated; must be allocated. NULL can be given, if TAC space is allocated inside p structure.

Definition at line 154 of file simblood.c.

165 {
166 /* Check for data */
167 if(nr<2 || t==NULL) return(1);
168 if(p==NULL || (c_BA==NULL && p->c_BA==NULL)) return(2);
169 if(!(t[0]>=0.0)) return(3);
170 if(p->mNr>0 && p->metabolite==NULL) return(4);
171
172 /* Calculate sum rates of metabolism */
173 double km_BV=0.0, km_TS=0.0, km_TF=0.0;
174 for(unsigned int i=0; i<p->mNr; i++) {
175 if(p->metabolite[i].kp_BV>0.0) km_BV+=p->metabolite[i].kp_BV;
176 if(p->metabolite[i].kp_TS>0.0) km_TS+=p->metabolite[i].kp_TS;
177 if(p->metabolite[i].kp_TF>0.0) km_TF+=p->metabolite[i].kp_TF;
178 }
179
180 /* Calculate compartmental TACs */
181 double t_last=0.0;
182 double ic_BA_last=0.0, c_BA_last=0.0;
183 double ic_BV_last=0.0, c_BV_last=0.0;
184 double ic_TS_last=0.0, c_TS_last=0.0;
185 double ic_TF_last=0.0, c_TF_last=0.0;
186 for(unsigned int i=0; i<nr; i++) {
187 double dt2=0.5*(t[i]-t_last); // delta time / 2
188 if(!(dt2>=0.0)) return(3);
189 else if(dt2==0.0) {
190 if(c_BA!=NULL) c_BA[i]=c_BA_last;
191 if(p->ic_BV!=NULL) p->ic_BV[i]=ic_BV_last;
192 if(p->ic_TS!=NULL) p->ic_TS[i]=ic_TS_last;
193 if(p->ic_TF!=NULL) p->ic_TF[i]=ic_TF_last;
194 if(p->c_BA!=NULL) p->c_BA[i]=c_BA_last;
195 if(p->c_BV!=NULL) p->c_BV[i]=c_BV_last;
196 if(p->c_TS!=NULL) p->c_TS[i]=c_TS_last;
197 if(p->c_TF!=NULL) p->c_TF[i]=c_TF_last;
198 continue;
199 }
200 /* Infusion integral; before infusion start 0; during infusion: time*level;
201 thereafter (infusion time)*level and level is set to 1. */
202 double ii=0.0;
203 if(p->Ti>=0.0 && p->Tdur>0.0 && t[i]>p->Ti) {
204 if(t[i] <= p->Ti + p->Tdur) ii=p->Irate*(t[i]-p->Ti); else ii=p->Irate*p->Tdur;
205 }
206 /* Helpers */
207 double rBA=1.0/(1.0+dt2*(p->k_BA_TS+p->k_BA_TF+p->k_BA_U));
208 double rTS=1.0/(1.0+dt2*(p->k_TS_BV+km_TS));
209 double rTF=1.0/(1.0+dt2*(p->k_TF_BV+km_TF));
210 double eBA=ic_BA_last+dt2*c_BA_last;
211 double eBV=ic_BV_last+dt2*c_BV_last;
212 double eTS=ic_TS_last+dt2*c_TS_last;
213 double eTF=ic_TF_last+dt2*c_TF_last;
214if(0) {
215 printf("dt2=%g\n", dt2);
216 printf("%g %g %g %g %g %g %g\n", rBA, rTS, rTF, eBA, eBV, eTS, eTF);
217}
218 /* Get integral of parent compound (if available) in compartments where it could be transformed
219 into current compound */
220 double icp_BV=0.0, icp_TS=0.0, icp_TF=0.0;
221 if(p->parent!=NULL) {
222 // copy pre-calculated values
223 if(p->parent->ic_BV!=NULL) icp_BV=p->parent->ic_BV[i];
224 if(p->parent->ic_TS!=NULL) icp_TS=p->parent->ic_TS[i];
225 if(p->parent->ic_TF!=NULL) icp_TF=p->parent->ic_TF[i];
226 }
227 /* Calculate integral of BV TAC */
228 double ic_BV;
229 ic_BV = eBV + dt2*ii - p->kp_BV*dt2*icp_BV
230 + dt2*dt2*rBA*eBA*(p->k_TS_BV*p->k_BA_TS*rTS + p->k_TF_BV*p->k_BA_TF*rTF)
231 + p->k_TS_BV*dt2*rTS*(dt2*icp_TS + eTS) + p->k_TF_BV*dt2*rTF*(dt2*icp_TF + eTF);
232 ic_BV /= 1.0 + dt2*(p->k_BV_BA + km_BV - dt2*dt2*rBA*p->k_BV_BA*(p->k_TS_BV*p->k_BA_TS*rTS + p->k_TF_BV*p->k_BA_TF*rTF));
233 /* Calculate integral of BA TAC */
234 double ic_BA = rBA * (dt2*p->k_BV_BA*ic_BV + eBA);
235 /* Calculate integrals of TTACs */
236 double ic_TS = rTS * (dt2*p->k_BA_TS*ic_BA + dt2*p->kp_TS*icp_TS + eTS);
237 double ic_TF = rTF * (dt2*p->k_BA_TF*ic_BA + dt2*p->kp_TF*icp_TF + eTF);
238 /* Prepare for the next sample */
239 t_last=t[i];
240 ic_BV_last=ic_BV; c_BV_last=(ic_BV-eBV)/dt2;
241 ic_BA_last=ic_BA; c_BA_last=(ic_BA-eBA)/dt2;
242 ic_TS_last=ic_TS; c_TS_last=(ic_TS-eTS)/dt2;
243 ic_TF_last=ic_TF; c_TF_last=(ic_TF-eTF)/dt2;
244 /* Copy sample concentration to output TAC */
245 if(c_BA!=NULL) c_BA[i]=c_BA_last;
246 /* If requested for metabolite calculations, copy also the compartmental TAC integrals */
247 if(p->ic_BV!=NULL) p->ic_BV[i]=ic_BV;
248 if(p->ic_TS!=NULL) p->ic_TS[i]=ic_TS;
249 if(p->ic_TF!=NULL) p->ic_TF[i]=ic_TF;
250 /* If requested, copy also the compartmental TACs */
251 if(p->c_BA!=NULL) p->c_BA[i]=c_BA_last;
252 if(p->c_BV!=NULL) p->c_BV[i]=c_BV_last;
253 if(p->c_TS!=NULL) p->c_TS[i]=c_TS_last;
254 if(p->c_TF!=NULL) p->c_TF[i]=c_TF_last;
255 }
256 return(0);
257}

◆ simC1()

int simC1 ( double * t,
double * ca,
const int nr,
const double k1,
const double k2,
double * ct )

Simulate tissue TAC using 1 tissue compartmental model and plasma TAC, at plasma TAC times.

Memory for ct must be allocated in the calling program.

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

See also
simC1_d, simC1_i, simDispersion, simMBF, simC2, simOxygen, simC3vs, convolve1D, simC1DI, simSamples, parExampleTTACs, parExamplePerfectBolus
Returns
Function returns 0 when successful, else a value >= 1.
Author
Vesa Oikonen
Parameters
tArray of time values.
caArray of arterial activities.
nrNumber of values in TACs.
k1Rate constant of the model.
k2Rate constant of the model.
ctPointer for TAC array to be simulated; must be allocated.

Definition at line 93 of file sim1cm.c.

106 {
107 int i;
108 double dt2;
109 double cai, ca_last, t_last;
110 double ct1, ct1_last;
111 double ct1i, ct1i_last;
112
113
114 /* Check for data */
115 if(nr<2) return 1;
116 if(t==NULL || ca==NULL || ct==NULL) return 2;
117
118 /* Check actual parameter number */
119 if(!(k1>=0.0)) return 3;
120
121 /* Calculate curves */
122 t_last=0.0; if(t[0]<t_last) t_last=t[0];
123 cai=ca_last=0.0;
124 ct1_last=ct1i_last=0.0;
125 ct1=ct1i=0.0;
126 for(i=0; i<nr; i++) {
127 /* delta time / 2 */
128 dt2=0.5*(t[i]-t_last);
129 /* calculate values */
130 if(dt2<0.0) {
131 return 5;
132 } else if(dt2>0.0) {
133 /* arterial integral */
134 cai+=(ca[i]+ca_last)*dt2;
135 /* tissue compartment and its integral */
136 ct1 = (k1*cai - k2*(ct1i_last+dt2*ct1_last)) / (1.0 + dt2*k2);
137 ct1i = ct1i_last + dt2*(ct1_last+ct1);
138 }
139 /* copy values to argument arrays */
140 ct[i]=ct1;
141 /* prepare to the next loop */
142 t_last=t[i]; ca_last=ca[i];
143 ct1_last=ct1; ct1i_last=ct1i;
144 }
145
146 return 0;
147}

Referenced by bfm1TCM(), and simDispersion().

◆ simC1_d()

int simC1_d ( double * t,
double * ca,
const int nr,
const double k1,
const double k2,
double * ct )

Simulate tissue TAC using 1 tissue compartmental model and input TAC, at input TAC times.

This version is directly based on ODE, and does not use integral of input TAC.

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

See also
simC1, simDelay, simDispersion
Returns
Function returns 0 when successful, else a value >= 1.
Author
Vesa Oikonen
Parameters
tArray of time values.
caArray of arterial activities.
nrNumber of values in TACs.
k1Rate constant of the model.
k2Rate constant of the model.
ctPointer for TAC array to be simulated; must be allocated.

Definition at line 229 of file sim1cm.c.

242 {
243 int i;
244 double dt2;
245 double cap, ctp, tp; // 'p' marks previous
246
247
248 /* Check for data */
249 if(nr<2) return 1;
250 if(t==NULL || ca==NULL || ct==NULL) return 2;
251
252 /* Check actual parameter number */
253 if(!(k1>=0.0)) return 3;
254
255 /* Set 'previous' sample */
256 tp=0.0; if(t[0]<tp) tp=t[0];
257 cap=ctp=0.0;
258 /* Calculate curves */
259 for(i=0; i<nr; i++) {
260 /* delta time / 2 */
261 dt2=0.5*(t[i]-tp);
262 /* calculate values */
263 if(dt2<0.0) {
264 return 5;
265 } else if(dt2>=0.0) { // must be >= because ct[0] is not set elsewhere
266 ct[i]=(k1*dt2*(cap+ca[i]) + (1.0 - k2*dt2)*ctp) / (1.0 + k2*dt2);
267 }
268 /* prepare to the next sample */
269 tp=t[i]; cap=ca[i];
270 ctp=ct[i];
271 }
272
273 return 0;
274}

◆ simC1_i()

int simC1_i ( double * t,
double * cai,
const int nr,
const double k1,
const double k2,
double * ct )

Simulate tissue TAC using 1 tissue compartmental model and plasma TAC, at plasma TAC times.

This version uses integral of arterial TAC as input function. Only advantage over simC1() is that the calculation of integral can be fully controlled and possibly more precise in some situations.

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

See also
simC1, simC2_i, simDelay, simDispersion
Returns
Function returns 0 when successful, else a value >= 1.
Author
Vesa Oikonen
Parameters
tArray of time values.
caiArray of AUC 0-t of arterial activities.
nrNumber of values in TACs.
k1Rate constant of the model.
k2Rate constant of the model.
ctPointer for TAC array to be simulated; must be allocated.

Definition at line 164 of file sim1cm.c.

177 {
178 int i;
179 double dt2;
180 double t_last;
181 double ct1, ct1_last;
182 double ct1i, ct1i_last;
183
184
185 /* Check for data */
186 if(nr<2) return 1;
187 if(t==NULL || cai==NULL || ct==NULL) return 2;
188
189 /* Check actual parameter number */
190 if(!(k1>=0.0)) return 3;
191
192 /* Calculate curves */
193 t_last=0.0; if(t[0]<t_last) t_last=t[0];
194 ct1_last=ct1i_last=0.0;
195 ct1=ct1i=0.0;
196 for(i=0; i<nr; i++) {
197 /* delta time / 2 */
198 dt2=0.5*(t[i]-t_last);
199 /* calculate values */
200 if(dt2<0.0) {
201 return 5;
202 } else if(dt2>0.0) {
203 /* tissue compartment and its integral */
204 ct1 = (k1*cai[i] - k2*(ct1i_last+dt2*ct1_last)) / (1.0 + dt2*k2);
205 ct1i = ct1i_last + dt2*(ct1_last+ct1);
206 }
207 /* copy values to argument arrays */
208 ct[i]=ct1;
209 /* prepare to the next loop */
210 t_last=t[i]; ct1_last=ct1; ct1i_last=ct1i;
211 }
212
213 return 0;
214}

Referenced by bfm1TCM(), and bfmSRTM().

◆ simC1DI()

int simC1DI ( double * t,
double * cba,
double * cbb,
const int nr,
const double k1a,
const double k1b,
const double k2,
double * ct )

Simulate tissue TAC using dual-input tissue compartment model with a single tissue compartment.

Simulates tissue TAC using dual-input tissue compartment model (1 compartment, common for both inputs) at input TAC times. Vascular volume is not accounted for. The units of rate constants must be related to the time unit; 1/min and min, or 1/sec and sec.

Returns
Function returns 0 when successful, else a value >= 1.
Author
Vesa Oikonen
See also
simC1, simDispersion, simOxygen, simC3vp, simC3vs, parExamplePerfectBolus
Todo
Finish coding and test.
Parameters
tArray of time values.
cbaArray of concentrations of input A.
cbbArray of concentrations of input B.
nrNumber of values in TACs.
k1aRate constant of the model for input A (from blood to C1).
k1bRate constant of the model for input B (from blood to C1).
k2Rate constant of the model (from C1 to blood).
ctPointer for TAC array to be simulated; must be allocated.

Definition at line 30 of file simdicm.c.

47 {
48 /* Check for data */
49 if(nr<2 || t==NULL || cba==NULL || cbb==NULL) return(1);
50 if(ct==NULL) return(2);
51
52 /* Check parameters */
53 if(!(k1a>=0.0)) return(3);
54 if(!(k1b>=0.0)) return(4);
55 if(!(k2>=0.0)) return(5);
56
57 /* Calculate curves */
58 double t_last=0.0; if(t[0]<t_last) t_last=t[0];
59 double cbai=0.0, cba_last=0.0, cbbi=0.0, cbb_last=0.0;
60 double ct1=0.0, ct1i=0.0, ct1_last=0.0, ct1i_last=0.0;
61 for(int i=0; i<nr; i++) {
62 /* delta time / 2 */
63 double dt2=0.5*(t[i]-t_last);
64 /* calculate values */
65 if(dt2<0.0) {
66 return(6);
67 } else if(dt2>0.0) {
68 /* input integrals */
69 cbai+=(cba[i]+cba_last)*dt2;
70 cbbi+=(cbb[i]+cbb_last)*dt2;
71 /* tissue compartment and its integral */
72 ct1 = (k1a*cbai + k1b*cbbi - k2*(ct1i_last+dt2*ct1_last)) / (1.0 + dt2*k2);
73 ct1i = ct1i_last + dt2*(ct1_last+ct1);
74 }
75 /* copy values to argument array */
76 ct[i]=ct1;
77 /* prepare to the next loop */
78 t_last=t[i]; cba_last=cba[i]; cbb_last=cbb[i];
79 ct1_last=ct1; ct1i_last=ct1i;
80 }
81
82 return(0);
83}

◆ simC2()

int simC2 ( double * t,
double * ca,
const int nr,
const double k1,
const double k2,
const double k3,
const double k4,
double * ct,
double * cta,
double * ctb )

Simulate tissue TAC using two-tissue compartment model and plasma TAC, at plasma TAC times.

Memory for ct must be allocated in the calling program. To retrieve the separate tissue compartment TACs, pointer to allocated memory for cta and/or ctb can be given; if compartmental TACs are not required, NULL pointer can be given instead.

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

Returns
Function returns 0 when successful, else a value >= 1.
Author
Vesa Oikonen
See also
simC2_i, simC1, simC1DI, simC2l, simC3s, simC3p, simSRTM, simSamples, simDispersion, parExampleTTACs, parExamplePerfectBolus
Parameters
tArray of time values.
caArray of arterial activities.
nrNumber of values in TACs.
k1Rate constant of the model.
k2Rate constant of the model.
k3Rate constant of the model.
k4Rate constant of the model.
ctPointer for TAC array to be simulated; must be allocated.
ctaPointer for 1st compartment TAC to be simulated, or NULL.
ctbPointer for 2nd compartment TAC to be simulated, or NULL.

Definition at line 31 of file sim2cm.c.

52 {
53 int i;
54 double dt2, r, u, v;
55 double cai, ca_last, t_last;
56 double ct1, ct1_last, ct2, ct2_last;
57 double ct1i, ct1i_last, ct2i, ct2i_last;
58
59
60 /* Check for data */
61 if(nr<2) return 1;
62 if(t==NULL || ca==NULL || ct==NULL) return 2;
63
64 /* Check parameters */
65 if(k1<0.0) return 3;
66
67 /* Calculate curves */
68 t_last=0.0; if(t[0]<t_last) t_last=t[0];
69 cai=ca_last=0.0;
70 ct1_last=ct2_last=ct1i_last=ct2i_last=0.0;
71 ct1=ct2=ct1i=ct2i=0.0;
72 for(i=0; i<nr; i++) {
73 /* delta time / 2 */
74 dt2=0.5*(t[i]-t_last);
75 /* calculate values */
76 if(dt2<0.0) {
77 return 5;
78 } else if(dt2>0.0) {
79 /* arterial integral */
80 cai+=(ca[i]+ca_last)*dt2;
81 /* Calculate partial results */
82 r=1.0+k4*dt2;
83 u=ct1i_last+dt2*ct1_last;
84 v=ct2i_last+dt2*ct2_last;
85 /* 1st tissue compartment and its integral */
86 ct1 = ( k1*cai - (k2 + (k3/r))*u + (k4/r)*v ) / ( 1.0 + dt2*(k2 + (k3/r)) );
87 ct1i = ct1i_last + dt2*(ct1_last+ct1);
88 /* 2nd tissue compartment and its integral */
89 ct2 = (k3*ct1i - k4*v) / r;
90 ct2i = ct2i_last + dt2*(ct2_last+ct2);
91 }
92 /* copy values to argument arrays */
93 ct[i]=ct1+ct2;
94 if(cta!=NULL) cta[i]=ct1;
95 if(ctb!=NULL) ctb[i]=ct2;
96 /* prepare to the next loop */
97 t_last=t[i]; ca_last=ca[i];
98 ct1_last=ct1; ct1i_last=ct1i;
99 ct2_last=ct2; ct2i_last=ct2i;
100 }
101
102 return 0;
103}

◆ simC2_i()

int simC2_i ( double * t,
double * cai,
const int nr,
const double k1,
const double k2,
const double k3,
const double k4,
double * ct,
double * cta,
double * ctb )

Simulate tissue TAC using two-tissue compartment model and plasma TAC, at plasma TAC times.

Memory for ct must be allocated in the calling program. To retrieve the separate tissue compartment TACs, pointer to allocated memory for cta and/or ctb can be given; if compartmental TACs are not required, NULL pointer can be given instead.

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

This version uses integral of arterial TAC as input function. Only advantage over simC2() is that the calculation of integral can be fully controlled and possibly more precise in some situations.

Returns
Function returns 0 when successful, else a value >= 1.
Author
Vesa Oikonen
See also
simC2, simC1, simC1_i, simC3s, simC3p, simSamples, simDelay
Parameters
tArray of time values.
caiArray of AUC 0-t of arterial activities.
nrNumber of values in TACs.
k1Rate constant of the model.
k2Rate constant of the model.
k3Rate constant of the model.
k4Rate constant of the model.
ctPointer for TAC array to be simulated; must be allocated.
ctaPointer for 1st compartment TAC to be simulated, or NULL.
ctbPointer for 2nd compartment TAC to be simulated, or NULL.

Definition at line 124 of file sim2cm.c.

145 {
146 int i;
147 double dt2, r, u, v;
148 double t_last;
149 double ct1, ct1_last, ct2, ct2_last;
150 double ct1i, ct1i_last, ct2i, ct2i_last;
151
152
153 /* Check for data */
154 if(nr<2) return 1;
155 if(t==NULL || cai==NULL || ct==NULL) return 2;
156
157 /* Check parameters */
158 if(k1<0.0) return 3;
159
160 /* Calculate curves */
161 t_last=0.0; if(t[0]<t_last) t_last=t[0];
162 ct1_last=ct2_last=ct1i_last=ct2i_last=0.0;
163 ct1=ct2=ct1i=ct2i=0.0;
164 for(i=0; i<nr; i++) {
165 /* delta time / 2 */
166 dt2=0.5*(t[i]-t_last);
167 /* calculate values */
168 if(dt2<0.0) {
169 return 5;
170 } else if(dt2>0.0) {
171 /* Calculate partial results */
172 r=1.0+k4*dt2;
173 u=ct1i_last+dt2*ct1_last;
174 v=ct2i_last+dt2*ct2_last;
175 /* 1st tissue compartment and its integral */
176 ct1 = ( k1*cai[i] - (k2 + (k3/r))*u + (k4/r)*v ) / ( 1.0 + dt2*(k2 + (k3/r)) );
177 ct1i = ct1i_last + dt2*(ct1_last+ct1);
178 /* 2nd tissue compartment and its integral */
179 ct2 = (k3*ct1i - k4*v) / r;
180 ct2i = ct2i_last + dt2*(ct2_last+ct2);
181 }
182 /* copy values to argument arrays */
183 ct[i]=ct1+ct2;
184 if(cta!=NULL) cta[i]=ct1;
185 if(ctb!=NULL) ctb[i]=ct2;
186 /* prepare to the next loop */
187 t_last=t[i];
188 ct1_last=ct1; ct1i_last=ct1i;
189 ct2_last=ct2; ct2i_last=ct2i;
190 }
191
192 return 0;
193}

◆ simC2l()

int simC2l ( double * t,
double * ca,
const int nr,
const double k1,
const double k2,
const double k3,
const double kLoss,
double * ct,
double * cta,
double * ctb )

Simulate tissue TAC using 2 tissue compartment model (in series) and plasma TAC, at plasma TAC times. In contrary to the common model, kLoss represents a direct loss rate from the 2nd tissue compartment to venous plasma.

Memory for ct must be allocated in the calling program. To retrieve the separate tissue compartment TACs, pointer to allocated memory for cta and ctb can be given; if compartmental TACs are not required, NULL pointer can be given instead.

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

See also
simC2, simC2vl, simC3vs, simC3vpKLoss
Returns
Function returns 0 when successful, else a value >= 1.
Author
Vesa Oikonen
Parameters
tArray of time values.
caArray of arterial activities.
nrNumber of values in TACs.
k1Rate constant of the model.
k2Rate constant of the model.
k3Rate constant of the model.
kLossRate constant of the model.
ctPointer for TAC array to be simulated; must be allocated.
ctaPointer for 1st compartment TAC to be simulated, or NULL.
ctbPointer for 2nd compartment TAC to be simulated, or NULL.

Definition at line 169 of file simkloss.c.

190 {
191 int i;
192 double b, c, dt2;
193 double cai, ca_last, t_last;
194 double ct1, ct1_last, ct2, ct2_last;
195 double ct1i, ct1i_last, ct2i, ct2i_last;
196
197
198 /* Check for data */
199 if(nr<2) return 1;
200 if(ct==NULL) return 2;
201
202 /* Check actual parameter number */
203 if(k1<0.0) return 3;
204
205 /* Calculate curves */
206 t_last=0.0; if(t[0]<t_last) t_last=t[0];
207 cai=ca_last=0.0;
208 ct1_last=ct2_last=ct1i_last=ct2i_last=ct1=ct2=ct1i=ct2i=0.0;
209 for(i=0; i<nr; i++) {
210 /* delta time / 2 */
211 dt2=0.5*(t[i]-t_last);
212 /* calculate values */
213 if(dt2<0.0) {
214 return 5;
215 } else if(dt2>0.0) {
216 /* arterial integral */
217 cai+=(ca[i]+ca_last)*dt2;
218 /* partial results */
219 b=ct1i_last+dt2*ct1_last;
220 c=ct2i_last+dt2*ct2_last;
221 /* 1st tissue compartment and its integral */
222 ct1 = (k1*cai - (k2+k3)*b) / (1.0 + (k2+k3)*dt2 );
223 ct1i = ct1i_last + dt2*(ct1_last+ct1);
224 /* 2nd tissue compartment and its integral */
225 ct2 = (k3*ct1i - kLoss*c) / (1.0 + kLoss*dt2);
226 ct2i = ct2i_last + dt2*(ct2_last+ct2);
227 }
228 /* copy values to argument arrays */
229 ct[i]=ct1+ct2;
230 if(cta!=NULL) cta[i]=ct1;
231 if(ctb!=NULL) ctb[i]=ct2;
232 /* prepare to the next loop */
233 t_last=t[i]; ca_last=ca[i];
234 ct1_last=ct1; ct1i_last=ct1i;
235 ct2_last=ct2; ct2i_last=ct2i;
236 }
237
238 return 0;
239}

◆ simC2vl()

int simC2vl ( double * t,
double * ca,
double * cb,
const int nr,
const double k1,
const double k2,
const double k3,
const double kL,
const double f,
const double vb,
const double fa,
const int vvm,
double * cpet,
double * cta,
double * ctb,
double * ctab,
double * ctvb )

Simulate tissue TAC using 2 tissue compartment model and plasma TAC, at plasma TAC times, considering also arterial and venous vasculature. The efflux from 2nd tissue compartment (at rate kL) goes directly to blood.

Memory for cpet must be allocated in the calling program. To retrieve the separate tissue compartment TACs, pointer to allocated memory for cta, ctb, ctab, and/or ctvb can be given; if compartmental TACs are not required, NULL pointer can be given instead.

The units of rate constants must be related to the time unit; 1/min and min, or 1/sec and sec. If blood flow is set to 0, function assumes that f>>k1, and Cvb=Cab.

See also
simC2, simC2l, simC3vs, simC3vpKLoss, simC3DIvs
Returns
Function returns 0 when successful, else a value >= 1.
Author
Vesa Oikonen
Parameters
tArray of time values.
caArray of arterial plasma activities.
cbArray of arterial blood activities.
nrNumber of values in TACs.
k1Rate constant of the model.
k2Rate constant of the model.
k3Rate constant of the model.
kLRate constant of the model.
fBlood flow; if 0, function assumes that f>>k1, and Cvb=Cab.
vbVascular volume fraction.
faArterial fraction of vascular volume.
vvmVascular volume modelling: set to 0 to use Cpet = Vb*Cb + (1-Vb)*Ct, or set to 1 to use Cpet = Vb*Cb + Ct.
cpetPointer for TAC array to be simulated; must be allocated.
ctaPointer for 1st compartment TAC to be simulated, or NULL.
ctbPointer for 2nd compartment TAC to be simulated, or NULL.
ctabPointer for arterial TAC in tissue, or NULL.
ctvbPointer for venous TAC in tissue, or NULL.

Definition at line 261 of file simkloss.c.

298 {
299 int i;
300 double dt2, b, c, va, vv;
301 double cai, ca_last, t_last, dct, cvb;
302 double ct1, ct1_last, ct2, ct2_last;
303 double ct1i, ct1i_last, ct2i, ct2i_last;
304
305
306 /* Check for data */
307 if(nr<2) return 1;
308 if(cpet==NULL) return 2;
309
310 /* Check parameters */
311 if(k1<0.0) return 3;
312 if(vb<0.0 || vb>=1.0) return 4;
313 if(fa<=0.0 || fa>1.0) return 5;
314 va=fa*vb; vv=(1.0-fa)*vb;
315
316 /* Calculate curves */
317 t_last=0.0; if(t[0]<t_last) t_last=t[0];
318 cai=ca_last=0.0;
319 ct1_last=ct2_last=ct1i_last=ct2i_last=ct1=ct2=ct1i=ct2i=0.0;
320 for(i=0; i<nr; i++) {
321 /* delta time / 2 */
322 dt2=0.5*(t[i]-t_last);
323 /* calculate values */
324 if(dt2<0.0) {
325 return 5;
326 } else if(dt2>0.0) {
327 /* arterial integral */
328 cai+=(ca[i]+ca_last)*dt2;
329 /* Calculate partial results */
330 b=ct1i_last+dt2*ct1_last;
331 c=ct2i_last+dt2*ct2_last;
332 /* 1st tissue compartment and its integral */
333 ct1 = (k1*cai - (k2+k3)*b) / (1.0 + (k2+k3)*dt2 );
334 ct1i = ct1i_last + dt2*(ct1_last+ct1);
335 /* 2nd tissue compartment and its integral */
336 ct2 = (k3*ct1i - kL*c) / (1.0 + kL*dt2);
337 ct2i = ct2i_last + dt2*(ct2_last+ct2);
338 }
339 /* Venous curve */
340 if(f>0.) {dct = k1*ca[i] - k2*ct1 - kL*ct2; cvb = cb[i] - dct/f;}
341 else cvb=cb[i];
342
343 /* copy values to argument arrays */
344 if(vvm==0) cpet[i]= va*cb[i] + vv*cvb + (1.0-vb)*(ct1+ct2);
345 else cpet[i]= va*cb[i] + vv*cvb + (ct1+ct2);
346 if(cta!=NULL) {cta[i]=ct1; if(vvm==0) cta[i]*=(1.0-vb);}
347 if(ctb!=NULL) {ctb[i]=ct2; if(vvm==0) ctb[i]*=(1.0-vb);}
348 if(ctab!=NULL) {ctab[i]=va*cb[i];}
349 if(ctvb!=NULL) {ctvb[i]=vv*cvb;}
350 /* prepare to the next loop */
351 t_last=t[i]; ca_last=ca[i];
352 ct1_last=ct1; ct1i_last=ct1i;
353 ct2_last=ct2; ct2i_last=ct2i;
354 }
355
356 return 0;
357}

◆ simC3DIvs()

int simC3DIvs ( double * t,
double * ca1,
double * ca2,
double * cb,
const int nr,
const double k1,
const double k2,
const double k3,
const double k4,
const double k5,
const double k6,
const double k1b,
const double k2b,
const double f,
const double vb,
const double fa,
const int vvm,
double * scpet,
double * sct1,
double * sct2,
double * sct3,
double * sct1b,
double * sctab,
double * sctvb )

Simulate tissue TAC using dual-input tissue compartment model with compartments in series.

Simulates tissue TAC using dual-input tissue compartment model (1-3 compartments in series for tracer1, and 1 compartment for tracer2) at plasma TAC times, considering also contribution of arterial and venous vasculature, but no exchange between compartments for tracer1 and tracer2. The units of rate constants must be related to the time unit; 1/min and min, or 1/sec and sec. If blood flow is set to 0, function assumes that f>>k1, and Cvb=Cab.

Returns
Function returns 0 when successful, else a value >= 1.
Author
Vesa Oikonen
See also
simC4DIvp, simC4DIvs, simC1DI, simC3vp, simC3vs, simDelay, parExamplePerfectBolus
Parameters
tArray of time values.
ca1Array of arterial plasma activities of tracer1.
ca2Array of arterial plasma activities of tracer2.
cbArray of arterial blood activities.
nrNumber of values in TACs.
k1Rate constant of the model for tracer1 (from plasma to C1).
k2Rate constant of the model for tracer1 (from C1 to plasma).
k3Rate constant of the model for tracer1 (from C1 to C2).
k4Rate constant of the model for tracer1 (from C2 to C1).
k5Rate constant of the model for tracer1 (from C2 to C3).
k6Rate constant of the model for tracer1 (from C3 to C2).
k1bRate constant of the model for tracer2 (from plasma to C4).
k2bRate constant of the model for tracer2 (from C4 to plasma).
fBlood flow; if 0, function assumes that f>>k1, and Cvb=Cab.
vbVascular volume fraction.
faArterial fraction of vascular volume.
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 TAC array to be simulated; must be allocated.
sct1Pointer for 1st tracer1 compartment TAC, or NULL if not needed.
sct2Pointer for 2nd tracer1 compartment TAC, or NULL if not needed.
sct3Pointer for 3rd tracer1 compartment TAC, or NULL if not needed.
sct1bPointer for 1st tracer2 compartment TAC, or NULL if not needed.
sctabPointer for arterial TAC in tissue, or NULL if not needed.
sctvbPointer for venous TAC in tissue, or NULL if not needed.

Definition at line 101 of file simdicm.c.

152 {
153 int i;
154 double b, c, d, e, w, z, dt2, va, vv;
155 double ca1i, ca1_last, ca2i, ca2_last, t_last, dct, cvb;
156 double ct1, ct1_last, ct2, ct2_last, ct3, ct3_last;
157 double ct1i, ct1i_last, ct2i, ct2i_last, ct3i, ct3i_last;
158 double ct1b, ct1b_last, ct1bi, ct1bi_last;
159
160
161 /* Check for data */
162 if(nr<2) return 1;
163 if(scpet==NULL) return 2;
164
165 /* Check parameters */
166 if(k1<0.0) return 3;
167 if(vb<0.0 || vb>=1.0) return 4;
168 if(fa<=0.0 || fa>1.0) return 5;
169 va=fa*vb; vv=(1.0-fa)*vb;
170
171 /* Calculate curves */
172 t_last=0.0; if(t[0]<t_last) t_last=t[0];
173 ca1i=ca1_last=ca2i=ca2_last=0.0;
174 ct1_last=ct2_last=ct3_last=ct1i_last=ct2i_last=ct3i_last=0.0;
175 ct1b_last=ct1bi_last=0.0;
176 ct1=ct2=ct3=ct1b=ct1i=ct2i=ct3i=ct1bi=0.0;
177 for(i=0; i<nr; i++) {
178 /* delta time / 2 */
179 dt2=0.5*(t[i]-t_last);
180 /* calculate values */
181 if(dt2<0.0) {
182 return 5;
183 } else if(dt2>0.0) {
184 /* arterial integrals */
185 ca1i+=(ca1[i]+ca1_last)*dt2;
186 ca2i+=(ca2[i]+ca2_last)*dt2;
187 /* partial results */
188 b=ct1i_last+dt2*ct1_last;
189 c=ct2i_last+dt2*ct2_last;
190 d=ct3i_last+dt2*ct3_last;
191 e=ct1bi_last+dt2*ct1b_last;
192 w=k4 + k5 - (k5*k6*dt2)/(1.0+k6*dt2);
193 z=1.0+w*dt2;
194 /* 1st tissue compartment and its integral */
195 ct1 = (
196 + k1*z*ca1i + (k3*k4*dt2 - (k2+k3)*z)*b
197 + k4*c + k4*k6*dt2*d/(1.0+k6*dt2)
198 ) / ( z*(1.0 + dt2*(k2+k3)) - k3*k4*dt2*dt2 );
199 ct1i = ct1i_last + dt2*(ct1_last+ct1);
200 ct1b = (k1b*ca2i - k2b*e) / (1.0 + dt2*k2b);
201 ct1bi = ct1bi_last + dt2*(ct1b_last+ct1b);
202 /* 2nd tissue compartment and its integral */
203 ct2 = (k3*ct1i - w*c + k6*d/(1.0+k6*dt2)) / z;
204 ct2i = ct2i_last + dt2*(ct2_last+ct2);
205 /* 3rd tissue compartment and its integral */
206 ct3 = (k5*ct2i - k6*d) / (1.0 + k6*dt2);
207 ct3i = ct3i_last + dt2*(ct3_last+ct3);
208 }
209 /* Venous curve */
210 if(f>0.) {
211 dct = k1*ca1[i] - k2*ct1 + k1b*ca2[i] - k2b*ct1b;
212 cvb = cb[i] - dct/f;
213 } else cvb=cb[i];
214 /* copy values to argument arrays */
215 if(vvm==0) scpet[i]= va*cb[i] + vv*cvb + (1.0-vb)*(ct1+ct2+ct3+ct1b);
216 else scpet[i]= va*cb[i] + vv*cvb + (ct1+ct2+ct3+ct1b);
217 if(sct1!=NULL) {sct1[i]=(1.0-vb)*ct1; if(vvm==0) sct1[i]*=(1.0-vb);}
218 if(sct2!=NULL) {sct2[i]=(1.0-vb)*ct2; if(vvm==0) sct2[i]*=(1.0-vb);}
219 if(sct3!=NULL) {sct3[i]=(1.0-vb)*ct3; if(vvm==0) sct3[i]*=(1.0-vb);}
220 if(sct1b!=NULL) {sct1b[i]=(1.0-vb)*ct1b; if(vvm==0) sct1b[i]*=(1.0-vb);}
221 if(sctab!=NULL) sctab[i]=va*cb[i];
222 if(sctvb!=NULL) sctvb[i]=vv*cvb;
223 /* prepare to the next loop */
224 t_last=t[i]; ca1_last=ca1[i]; ca2_last=ca2[i];
225 ct1_last=ct1; ct1i_last=ct1i;
226 ct2_last=ct2; ct2i_last=ct2i;
227 ct3_last=ct3; ct3i_last=ct3i;
228 ct1b_last=ct1b; ct1bi_last=ct1bi;
229 }
230
231 return 0;
232}

◆ simC3p()

int simC3p ( double * t,
double * ca,
const int nr,
const double k1,
const double k2,
const double k3,
const double k4,
const double k5,
const double k6,
double * ct,
double * cta,
double * ctb,
double * ctc )

Simulate tissue TAC using 1-3 tissue compartment model (2nd and 3rd compartments in parallel) and plasma TAC, at plasma TAC times.

Memory for ct must be allocated in the calling program. To retrieve the separate tissue compartment TACs, pointer to allocated memory for cta, ctb and/or ctc can be given; if compartmental TACs are not required, NULL pointer can be given instead.

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

Returns
Function returns 0 when successful, else a value >= 1.
Author
Vesa Oikonen
See also
simC3s, simC1, simC1DI, simC2, simC2l, simC3vp, simC3vs, simSamples, parExampleTTACs, parExamplePerfectBolus
Parameters
tArray of time values.
caArray of arterial activities.
nrNumber of values in TACs.
k1Rate constant of the model.
k2Rate constant of the model.
k3Rate constant of the model.
k4Rate constant of the model.
k5Rate constant of the model.
k6Rate constant of the model.
ctPointer for TAC array to be simulated; must be allocated.
ctaPointer for 1st compartment TAC to be simulated, or NULL.
ctbPointer for 2nd compartment TAC to be simulated, or NULL.
ctcPointer for 3rd compartment TAC to be simulated, or NULL.

Definition at line 33 of file sim3cmp.c.

60 {
61 int i;
62 double dt2, r, s, u, v, w;
63 double cai, ca_last, t_last;
64 double ct1, ct1_last, ct2, ct2_last, ct3, ct3_last;
65 double ct1i, ct1i_last, ct2i, ct2i_last, ct3i, ct3i_last;
66
67
68 /* Check for data */
69 if(nr<2) return 1;
70 if(ct==NULL) return 2;
71
72 /* Check parameters */
73 if(k1<0.0) return 3;
74
75 /* Calculate curves */
76 t_last=0.0; if(t[0]<t_last) t_last=t[0];
77 cai=ca_last=0.0;
78 ct1_last=ct2_last=ct3_last=ct1i_last=ct2i_last=ct3i_last=0.0;
79 ct1=ct2=ct3=ct1i=ct2i=ct3i=0.0;
80 for(i=0; i<nr; i++) {
81 /* delta time / 2 */
82 dt2=0.5*(t[i]-t_last);
83 /* calculate values */
84 if(dt2<0.0) {
85 return 5;
86 } else if(dt2>0.0) {
87 /* arterial integral */
88 cai+=(ca[i]+ca_last)*dt2;
89 /* Calculate partial results */
90 r=1.0+k4*dt2;
91 s=1.0+k6*dt2;
92 u=ct1i_last+dt2*ct1_last;
93 v=ct2i_last+dt2*ct2_last;
94 w=ct3i_last+dt2*ct3_last;
95 /* 1st tissue compartment and its integral */
96 ct1 = ( k1*cai - (k2 + (k3/r) + (k5/s))*u + (k4/r)*v + (k6/s)*w )
97 / ( 1.0 + dt2*(k2 + (k3/r) + (k5/s)) );
98 ct1i = ct1i_last + dt2*(ct1_last+ct1);
99 /* 2nd tissue compartment and its integral */
100 ct2 = (k3*ct1i - k4*v) / r;
101 ct2i = ct2i_last + dt2*(ct2_last+ct2);
102 /* 3rd tissue compartment and its integral */
103 ct3 = (k5*ct1i - k6*w) / s;
104 ct3i = ct3i_last + dt2*(ct3_last+ct3);
105 }
106 /* copy values to argument arrays; set very small values to zero */
107 ct[i]=ct1+ct2+ct3;
108 if(cta!=NULL) cta[i]=ct1;
109 if(ctb!=NULL) ctb[i]=ct2;
110 if(ctc!=NULL) ctc[i]=ct3;
111 /* prepare to the next loop */
112 t_last=t[i]; ca_last=ca[i];
113 ct1_last=ct1; ct1i_last=ct1i;
114 ct2_last=ct2; ct2i_last=ct2i;
115 ct3_last=ct3; ct3i_last=ct3i;
116 }
117
118 return 0;
119}

◆ simC3s()

int simC3s ( double * t,
double * ca,
const int nr,
double k1,
double k2,
double k3,
double k4,
double k5,
double k6,
double * ct,
double * cta,
double * ctb,
double * ctc )

Simulate tissue TAC using 1-3 tissue compartment model (compartments in series) and plasma TAC, at plasma TAC times.

Memory for ct must be allocated in the calling program. To retrieve the separate tissue compartment TACs, pointer to allocated memory for cta, ctb and/or ctc can be given; if compartmental TACs are not required, NULL pointer can be given instead.

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

Returns
Function returns 0 when successful, else a value >= 1.
Author
Vesa Oikonen
See also
simC3vs, simC1, simC3p, simC3vp, simC2l, simDispersion, simDelay
Parameters
tArray of time values.
caArray of arterial activities.
nrNumber of values in TACs.
k1Rate constant of the model.
k2Rate constant of the model.
k3Rate constant of the model.
k4Rate constant of the model.
k5Rate constant of the model.
k6Rate constant of the model.
ctPointer for TAC array to be simulated; must be allocated.
ctaPointer for 1st compartment TAC to be simulated, or NULL.
ctbPointer for 2nd compartment TAC to be simulated, or NULL.
ctcPointer for 3rd compartment TAC to be simulated, or NULL.

Definition at line 32 of file sim3cms.c.

59 {
60 int i;
61 double b, c, d, w, z, dt2;
62 double cai, ca_last, t_last;
63 double ct1, ct1_last, ct2, ct2_last, ct3, ct3_last;
64 double ct1i, ct1i_last, ct2i, ct2i_last, ct3i, ct3i_last;
65
66
67 /* Check for data */
68 if(nr<2) return 1;
69 if(ct==NULL) return 2;
70
71 /* Check actual parameter number */
72 if(k1<0.0) return 3;
73 if(k3<=0.0) {k3=0.0; if(k2<=0.0) k2=0.0;}
74 else if(k5<=0.0) {k5=0.0; if(k4<=0.0) k4=0.0;}
75 else {if(k6<=0.0) k6=0.0;}
76
77 /* Calculate curves */
78 t_last=0.0; if(t[0]<t_last) t_last=t[0];
79 cai=ca_last=0.0;
80 ct1_last=ct2_last=ct3_last=ct1i_last=ct2i_last=ct3i_last=0.0;
81 ct1=ct2=ct3=ct1i=ct2i=ct3i=0.0;
82 for(i=0; i<nr; i++) {
83 /* delta time / 2 */
84 dt2=0.5*(t[i]-t_last);
85 /* calculate values */
86 if(dt2<0.0) {
87 return 5;
88 } else if(dt2>0.0) {
89 /* arterial integral */
90 cai+=(ca[i]+ca_last)*dt2;
91 /* partial results */
92 b=ct1i_last+dt2*ct1_last;
93 c=ct2i_last+dt2*ct2_last;
94 d=ct3i_last+dt2*ct3_last;
95 w=k4 + k5 - (k5*k6*dt2)/(1.0+k6*dt2);
96 z=1.0+w*dt2;
97 /* 1st tissue compartment and its integral */
98 ct1 = (
99 + k1*z*cai + (k3*k4*dt2 - (k2+k3)*z)*b
100 + k4*c + k4*k6*dt2*d/(1.0+k6*dt2)
101 ) / ( z*(1.0 + dt2*(k2+k3)) - k3*k4*dt2*dt2 );
102 ct1i = ct1i_last + dt2*(ct1_last+ct1);
103 /* 2nd tissue compartment and its integral */
104 ct2 = (k3*ct1i - w*c + k6*d/(1.0+k6*dt2)) / z;
105 ct2i = ct2i_last + dt2*(ct2_last+ct2);
106 /* 3rd tissue compartment and its integral */
107 ct3 = (k5*ct2i - k6*d) / (1.0 + k6*dt2);
108 ct3i = ct3i_last + dt2*(ct3_last+ct3);
109 }
110 /* copy values to argument arrays */
111 ct[i]=ct1+ct2+ct3;
112 if(cta!=NULL) cta[i]=ct1;
113 if(ctb!=NULL) ctb[i]=ct2;
114 if(ctc!=NULL) ctc[i]=ct3;
115 /* prepare to the next loop */
116 t_last=t[i]; ca_last=ca[i];
117 ct1_last=ct1; ct1i_last=ct1i;
118 ct2_last=ct2; ct2i_last=ct2i;
119 ct3_last=ct3; ct3i_last=ct3i;
120 }
121
122 return 0;
123}

◆ simC3vp()

int simC3vp ( double * t,
double * ca,
double * cb,
const int nr,
const double k1,
const double k2,
const double k3,
const double k4,
const double k5,
const double k6,
const double f,
const double vb,
const double fa,
const int vvm,
double * cpet,
double * cta,
double * ctb,
double * ctc,
double * ctab,
double * ctvb )

Simulate tissue TAC using 1-3 tissue compartment model (2nd and 3rd compartments in parallel) and plasma TAC, at plasma TAC times, considering also arterial and venous vasculature.

Memory for ct must be allocated in the calling program. To retrieve the separate tissue compartment TACs, pointer to allocated memory for cta, ctb, ctc, ctab, and/or ctvb can be given; if compartmental TACs are not required, NULL pointer can be given instead.

The units of rate constants must be related to the time unit; 1/min and min, or 1/sec and sec. If blood flow is set to 0, function assumes that f>>k1, and Cvb=Cab.,

Returns
Function returns 0 when successful, else a value >= 1.
Author
Vesa Oikonen
See also
simC3vs, simC3p, simC3s, simC3vpKLoss, simC4DIvp, simSamples, simDispersion, simDelay, parExampleTTACs, parExamplePerfectBolus
Parameters
tArray of time values.
caArray of arterial plasma activities.
cbArray of arterial blood activities.
nrNumber of values in TACs.
k1Rate constant of the model.
k2Rate constant of the model.
k3Rate constant of the model.
k4Rate constant of the model.
k5Rate constant of the model.
k6Rate constant of the model.
fBlood flow; if 0, function assumes that f>>k1, and Cvb=Cab.
vbVascular volume fraction.
faArterial fraction of vascular volume.
vvmVascular volume modelling: set to 0 to use Cpet = Vb*Cb + (1-Vb)*Ct, or set to 1 to use Cpet = Vb*Cb + Ct.
cpetPointer for TAC array to be simulated; must be allocated.
ctaPointer for 1st compartment TAC to be simulated, or NULL.
ctbPointer for 2nd compartment TAC to be simulated, or NULL.
ctcPointer for 3rd compartment TAC to be simulated, or NULL.
ctabPointer for arterial TAC in tissue, or NULL.
ctvbPointer for venous TAC in tissue, or NULL.

Definition at line 140 of file sim3cmp.c.

183 {
184 int i;
185 double dt2, r, s, u, v, w, va, vv;
186 double cai, ca_last, t_last, dct, cvb;
187 double ct1, ct1_last, ct2, ct2_last, ct3, ct3_last;
188 double ct1i, ct1i_last, ct2i, ct2i_last, ct3i, ct3i_last;
189
190
191 /* Check for data */
192 if(nr<2) return 1;
193 if(cpet==NULL) return 2;
194
195 /* Check parameters */
196 if(k1<0.0) return 3;
197 if(vb<0.0 || vb>=1.0) return 4;
198 if(fa<=0.0 || fa>1.0) return 5;
199 va=fa*vb; vv=(1.0-fa)*vb;
200
201 /* Calculate curves */
202 t_last=0.0; if(t[0]<t_last) t_last=t[0];
203 cai=ca_last=0.0;
204 ct1_last=ct2_last=ct3_last=ct1i_last=ct2i_last=ct3i_last=0.0;
205 ct1=ct2=ct3=ct1i=ct2i=ct3i=0.0;
206 for(i=0; i<nr; i++) {
207 /* delta time / 2 */
208 dt2=0.5*(t[i]-t_last);
209 /* calculate values */
210 if(dt2<0.0) {
211 return 5;
212 } else if(dt2>0.0) {
213 /* arterial integral */
214 cai+=(ca[i]+ca_last)*dt2;
215 /* Calculate partial results */
216 r=1.0+k4*dt2;
217 s=1.0+k6*dt2;
218 u=ct1i_last+dt2*ct1_last;
219 v=ct2i_last+dt2*ct2_last;
220 w=ct3i_last+dt2*ct3_last;
221 /* 1st tissue compartment and its integral */
222 ct1 = ( k1*cai - (k2 + (k3/r) + (k5/s))*u + (k4/r)*v + (k6/s)*w )
223 / ( 1.0 + dt2*(k2 + (k3/r) + (k5/s)) );
224 ct1i = ct1i_last + dt2*(ct1_last+ct1);
225 /* 2nd tissue compartment and its integral */
226 ct2 = (k3*ct1i - k4*v) / r;
227 ct2i = ct2i_last + dt2*(ct2_last+ct2);
228 /* 3rd tissue compartment and its integral */
229 ct3 = (k5*ct1i - k6*w) / s;
230 ct3i = ct3i_last + dt2*(ct3_last+ct3);
231 }
232 /* Venous curve */
233 if(f>0.) {dct = k1*ca[i] - k2*ct1; cvb = cb[i] - dct/f;} else cvb=cb[i];
234 /* copy values to argument arrays */
235 if(vvm==0) cpet[i]= va*cb[i] + vv*cvb + (1.0-vb)*(ct1+ct2+ct3);
236 else cpet[i]= va*cb[i] + vv*cvb + (ct1+ct2+ct3);
237 if(cta!=NULL) {cta[i]=ct1; if(vvm==0) cta[i]*=(1.0-vb);}
238 if(ctb!=NULL) {ctb[i]=ct2; if(vvm==0) ctb[i]*=(1.0-vb);}
239 if(ctc!=NULL) {ctc[i]=ct3; if(vvm==0) ctc[i]*=(1.0-vb);}
240 if(ctab!=NULL) {ctab[i]=va*cb[i];}
241 if(ctvb!=NULL) {ctvb[i]=vv*cvb;}
242 /* prepare to the next loop */
243 t_last=t[i]; ca_last=ca[i];
244 ct1_last=ct1; ct1i_last=ct1i;
245 ct2_last=ct2; ct2i_last=ct2i;
246 ct3_last=ct3; ct3i_last=ct3i;
247 }
248
249 return 0;
250}

◆ simC3vpKLoss()

int simC3vpKLoss ( double * t,
double * ca,
double * cb,
const int nr,
const double k1,
const double k2,
const double k3,
const double k4,
const double k5,
const double k6,
const double kLoss,
const double f,
const double vb,
const double fa,
const int vvm,
double * cpet,
double * cta,
double * ctb,
double * ctc,
double * ctab,
double * ctvb )

Simulate tissue TAC using 3 tissue compartmental model with two parallel compartments, and plasma TAC, at plasma TAC sample times, considering also arterial and venous vasculature. The efflux from 3rd tissue compartment (C) goes directly to blood at rate kLoss.

Memory for cpet must be allocated in the calling program. To retrieve the separate tissue compartment TACs, pointer to allocated memory for cta, ctb, ctab, and/or ctvb can be given; if compartmental TACs are not required, NULL pointer can be given instead.

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

If blood flow is set to 0, function assumes that f>>k1, and Cvb=Cab.,

See also
simC2vl, simC2l, simC3vs, simC4DIvp, parExamplePerfectBolus
Returns
Function returns 0 when successful, else a value >= 1.
Author
Vesa Oikonen
Parameters
tArray of sample times.
caArray of arterial plasma activities.
cbArray of arterial blood activities.
nrNumber of sample values in TACs.
k1Rate constant of the model.
k2Rate constant of the model.
k3Rate constant of the model.
k4Rate constant of the model.
k5Rate constant of the model.
k6Rate constant of the model.
kLossRate constant of the model.
fBlood flow; if 0, function assumes that f>>k1, and Cvb=Cab.
vbVascular volume fraction.
faArterial fraction of vascular volume.
vvmVascular volume modelling: set to 0 to use Cpet = Vb*Cb + (1-Vb)*Ct, or set to 1 to use Cpet = Vb*Cb + Ct.
cpetPointer for TAC array to be simulated; must be allocated.
ctaPointer for 1st tissue compartment TAC to be simulated, or NULL.
ctbPointer for 2nd compartment TAC to be simulated, or NULL.
ctcPointer for 3rd compartment TAC to be simulated, or NULL.
ctabPointer for arterial TAC in tissue, or NULL.
ctvbPointer for venous TAC in tissue, or NULL.

Definition at line 36 of file simkloss.c.

81 {
82 int i;
83 double dt2, b, c, d, w, z, u, va, vv;
84 double cai, ca_last, t_last, dct, cvb;
85 double ct1, ct1_last, ct2, ct2_last, ct3, ct3_last;
86 double ct1i, ct1i_last, ct2i, ct2i_last, ct3i, ct3i_last;
87
88
89 /* Check for data */
90 if(nr<2) return 1;
91 if(cpet==NULL) return 2;
92
93 /* Check parameters */
94 if(k1<0.0) return 3;
95 if(vb<0.0 || vb>=1.0) return 4;
96 if(fa<=0.0 || fa>1.0) return 5;
97 va=fa*vb; vv=(1.0-fa)*vb;
98
99 /* Calculate curves */
100 t_last=0.0; if(t[0]<t_last) t_last=t[0];
101 cai=ca_last=0.0;
102 ct1_last=ct2_last=ct3_last=ct1i_last=ct2i_last=ct3i_last=0.0;
103 ct1=ct2=ct3=ct1i=ct2i=ct3i=0.0;
104 for(i=0; i<nr; i++) {
105 /* delta time / 2 */
106 dt2=0.5*(t[i]-t_last);
107 /* calculate values */
108 if(dt2<0.0) {
109 return 5;
110 } else if(dt2>0.0) {
111 /* arterial integral */
112 cai+=(ca[i]+ca_last)*dt2;
113 /* Calculate partial results */
114 w = 1.0 + k4*dt2;
115 z = 1.0 + dt2*(k6 + kLoss);
116 u = k2 + k3 + k5 - k3*k4*dt2/w - k5*k6*dt2/z;
117 b = ct1i_last+dt2*ct1_last;
118 c = ct2i_last+dt2*ct2_last;
119 d = ct3i_last+dt2*ct3_last;
120 /* 1st tissue compartment and its integral */
121 ct1 = ( k1*cai - u*b + k4*c/w + k6*d/z ) / ( 1.0 + dt2*u);
122 ct1i = ct1i_last + dt2*(ct1_last+ct1);
123 /* 2nd tissue compartment and its integral */
124 ct2 = (k3*ct1i - k4*c) / w;
125 ct2i = ct2i_last + dt2*(ct2_last+ct2);
126 /* 3rd tissue compartment and its integral */
127 ct3 = (k5*ct1i - (k6 + kLoss)*d) / z;
128 ct3i = ct3i_last + dt2*(ct3_last+ct3);
129 }
130 /* Venous curve */
131 if(f>0.) {dct = k1*ca[i] - k2*ct1 - kLoss*ct3; cvb = cb[i] - dct/f;}
132 else cvb=cb[i];
133 /* copy values to argument arrays */
134 if(vvm==0) cpet[i]= va*cb[i] + vv*cvb + (1.0-vb)*(ct1+ct2+ct3);
135 else cpet[i]= va*cb[i] + vv*cvb + (ct1+ct2+ct3);
136 if(cta!=NULL) {cta[i]=ct1; if(vvm==0) cta[i]*=(1.0-vb);}
137 if(ctb!=NULL) {ctb[i]=ct2; if(vvm==0) ctb[i]*=(1.0-vb);}
138 if(ctc!=NULL) {ctc[i]=ct3; if(vvm==0) ctc[i]*=(1.0-vb);}
139 if(ctab!=NULL) {ctab[i]=va*cb[i];}
140 if(ctvb!=NULL) {ctvb[i]=vv*cvb;}
141 /* prepare to the next loop */
142 t_last=t[i]; ca_last=ca[i];
143 ct1_last=ct1; ct1i_last=ct1i;
144 ct2_last=ct2; ct2i_last=ct2i;
145 ct3_last=ct3; ct3i_last=ct3i;
146 }
147
148 return 0;
149}

◆ simC3vs()

int simC3vs ( double * t,
double * ca,
double * cb,
const int nr,
const double k1,
const double k2,
const double k3,
const double k4,
const double k5,
const double k6,
const double f,
const double vb,
const double fa,
const int vvm,
double * cpet,
double * cta,
double * ctb,
double * ctc,
double * ctab,
double * ctvb )

Simulate tissue TAC using 1-3 tissue compartment model (compartments in series) and plasma TAC, at plasma TAC times, considering also arterial and venous vasculature.

Memory for ct must be allocated in the calling program. To retrieve the separate tissue compartment TACs, pointer to allocated memory for cta, ctb, ctc, ctab, and/or ctvb can be given; if compartmental TACs are not required, NULL pointer can be given instead.

The units of rate constants must be related to the time unit; 1/min and min, or 1/sec and sec. If blood flow is set to 0, function assumes that f>>k1, and Cvb=Cab.,

Returns
Function returns 0 when successful, else a value >= 1.
Author
Vesa Oikonen
See also
simC3vp, simC3s, simC3p, simC2l, simC3vpKLoss, simC3DIvs, simC4DIvs, parExamplePerfectBolus
Parameters
tArray of time values.
caArray of arterial plasma activities.
cbArray of arterial blood activities.
nrNumber of values in TACs.
k1Rate constant of the model.
k2Rate constant of the model.
k3Rate constant of the model.
k4Rate constant of the model.
k5Rate constant of the model.
k6Rate constant of the model.
fBlood flow; if 0, function assumes that f>>k1, and Cvb=Cab.
vbVascular volume fraction.
faArterial fraction of vascular volume.
vvmVascular volume modelling: set to 0 to use Cpet = Vb*Cb + (1-Vb)*Ct, or set to 1 to use Cpet = Vb*Cb + Ct.
cpetPointer for TAC array to be simulated; must be allocated.
ctaPointer for 1st compartment TAC to be simulated, or NULL.
ctbPointer for 2nd compartment TAC to be simulated, or NULL.
ctcPointer for 3rd compartment TAC to be simulated, or NULL.
ctabPointer for arterial TAC in tissue, or NULL.
ctvbPointer for venous TAC in tissue, or NULL.

Definition at line 143 of file sim3cms.c.

186 {
187 int i;
188 double b, c, d, w, z, dt2, va, vv;
189 double cai, ca_last, t_last, dct, cvb;
190 double ct1, ct1_last, ct2, ct2_last, ct3, ct3_last;
191 double ct1i, ct1i_last, ct2i, ct2i_last, ct3i, ct3i_last;
192
193
194 /* Check for data */
195 if(nr<2) return 1;
196 if(cpet==NULL) return 2;
197
198 /* Check parameters */
199 if(k1<0.0) return 3;
200 if(vb<0.0 || vb>=1.0) return 4;
201 if(fa<=0.0 || fa>1.0) return 5;
202 va=fa*vb; vv=(1.0-fa)*vb;
203
204 /* Calculate curves */
205 t_last=0.0; if(t[0]<t_last) t_last=t[0];
206 cai=ca_last=0.0;
207 ct1_last=ct2_last=ct3_last=ct1i_last=ct2i_last=ct3i_last=0.0;
208 ct1=ct2=ct3=ct1i=ct2i=ct3i=0.0;
209 for(i=0; i<nr; i++) {
210 /* delta time / 2 */
211 dt2=0.5*(t[i]-t_last);
212 /* calculate values */
213 if(dt2<0.0) {
214 return 5;
215 } else if(dt2>0.0) {
216 /* arterial integral */
217 cai+=(ca[i]+ca_last)*dt2;
218 /* partial results */
219 b=ct1i_last+dt2*ct1_last;
220 c=ct2i_last+dt2*ct2_last;
221 d=ct3i_last+dt2*ct3_last;
222 w=k4 + k5 - (k5*k6*dt2)/(1.0+k6*dt2);
223 z=1.0+w*dt2;
224 /* 1st tissue compartment and its integral */
225 ct1 = (
226 + k1*z*cai + (k3*k4*dt2 - (k2+k3)*z)*b
227 + k4*c + k4*k6*dt2*d/(1.0+k6*dt2)
228 ) / ( z*(1.0 + dt2*(k2+k3)) - k3*k4*dt2*dt2 );
229 ct1i = ct1i_last + dt2*(ct1_last+ct1);
230 /* 2nd tissue compartment and its integral */
231 ct2 = (k3*ct1i - w*c + k6*d/(1.0+k6*dt2)) / z;
232 ct2i = ct2i_last + dt2*(ct2_last+ct2);
233 /* 3rd tissue compartment and its integral */
234 ct3 = (k5*ct2i - k6*d) / (1.0 + k6*dt2);
235 ct3i = ct3i_last + dt2*(ct3_last+ct3);
236 }
237 /* Venous curve */
238 if(f>0.) {dct = k1*ca[i] - k2*ct1; cvb = cb[i] - dct/f;} else cvb=cb[i];
239 /* copy values to argument arrays */
240 if(vvm==0) cpet[i]= va*cb[i] + vv*cvb + (1.0-vb)*(ct1+ct2+ct3);
241 else cpet[i]= va*cb[i] + vv*cvb + (ct1+ct2+ct3);
242 if(cta!=NULL) {cta[i]=ct1; if(vvm==0) cta[i]*=(1.0-vb);}
243 if(ctb!=NULL) {ctb[i]=ct2; if(vvm==0) ctb[i]*=(1.0-vb);}
244 if(ctc!=NULL) {ctc[i]=ct3; if(vvm==0) ctc[i]*=(1.0-vb);}
245 if(ctab!=NULL) {ctab[i]=va*cb[i];}
246 if(ctvb!=NULL) {ctvb[i]=vv*cvb;}
247 /* prepare to the next loop */
248 t_last=t[i]; ca_last=ca[i];
249 ct1_last=ct1; ct1i_last=ct1i;
250 ct2_last=ct2; ct2i_last=ct2i;
251 ct3_last=ct3; ct3i_last=ct3i;
252 }
253
254 return 0;
255}

◆ simC4DIvp()

int simC4DIvp ( double * t,
double * ca1,
double * ca2,
double * cb,
const int nr,
const double k1,
const double k2,
const double k3,
const double k4,
const double k5,
const double k6,
const double k7,
const double km,
double k1b,
const double k2b,
const double f,
const double vb,
double fa,
const int vvm,
double * scpet,
double * sct1,
double * sct2,
double * sct3,
double * sct1b,
double * sctab,
double * sctvb,
const int verbose )

Simulate tissue TAC using dual-input tissue compartment model (compartments 2 and 3 in parallel for tracer1, and 1 compartment for tracer2) at plasma TAC sample times, considering also contribution of arterial and venous vasculature, and transfer of tracer1 to tracer2.

The units of rate constants must be related to the time unit; 1/min and min, or 1/sec and sec. If blood flow is set to 0, function assumes that f>>k1, and Cvb=Cab. Reference: TPCMOD0001 Appendix C. Tested with program p2t_di -parallel.

Returns
Function returns 0 when successful, else a value >= 1.
Author
Vesa Oikonen
See also
simC3DIvs, simC4DIvs, simC1DI, simC3vp, simC3vs, parExamplePerfectBolus
Parameters
tArray of time values.
ca1Array of arterial plasma activities of tracer1 (parent tracer).
ca2Array of arterial plasma activities of tracer2 (metabolite).
cbArray of (total) arterial blood activities.
nrNumber of values in TACs.
k1Rate constant of the model for tracer1 (from plasma to C1).
k2Rate constant of the model for tracer1 (from C1 to plasma).
k3Rate constant of the model for tracer1 (from C1 to C2).
k4Rate constant of the model for tracer1 (from C2 to C1).
k5Rate constant of the model for tracer1 (from C1 to C3).
k6Rate constant of the model for tracer1 (from C3 to C1).
k7Rate constant of the model for tracer1 (from C3 to plasma).
kmRate constant of the model (from tracer1 in C1 to tracer2 in C4).
k1bRate constant of the model for tracer2 (from plasma to C4).
k2bRate constant of the model for tracer2 (from C4 to plasma).
fBlood flow; if 0, function assumes that f>>k1, and Cvb=Cab.
vbVascular volume fraction (0<=Vb<1).
faArterial fraction of vascular volume (0<=fa<=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 TAC array to be simulated; must be allocated.
sct1Pointer for 1st tracer1 compartment TAC, or NULL if not needed.
sct2Pointer for 2nd tracer1 compartment TAC, or NULL if not needed.
sct3Pointer for 3rd tracer1 compartment TAC, or NULL if not needed.
sct1bPointer for 1st tracer2 compartment TAC, or NULL if not needed.
sctabPointer for arterial TAC in tissue, or NULL if not needed.
sctvbPointer for venous TAC in tissue, or NULL if not needed.
verboseVerbose level; if zero, then nothing is printed into stdout or stderr.

Definition at line 251 of file simdicm.c.

308 {
309 int i;
310 double b, c, d, e, pt, qt, dt2, va, vv;
311 double ca1i, ca1_last, ca2i, ca2_last, t_last, dct, cvb;
312 double ct1, ct1_last, ct2, ct2_last, ct3, ct3_last;
313 double ct1i, ct1i_last, ct2i, ct2i_last, ct3i, ct3i_last;
314 double ct1b, ct1b_last, ct1bi, ct1bi_last;
315
316
317 if(verbose>0) {
318 printf("%s()\n", __func__);
319 if(verbose>1) {
320 printf(" k1 := %g\n", k1);
321 printf(" k2 := %g\n", k2);
322 printf(" k3 := %g\n", k3);
323 printf(" k4 := %g\n", k4);
324 printf(" k5 := %g\n", k5);
325 printf(" k6 := %g\n", k6);
326 printf(" k7 := %g\n", k7);
327 printf(" km := %g\n", km);
328 printf(" k1b := %g\n", k1b);
329 printf(" k2b := %g\n", k2b);
330 printf(" vb := %g\n", vb);
331 printf(" fa := %g\n", fa);
332 printf(" f := %g\n", f);
333 }
334 }
335
336 /* Check for data */
337 if(nr<2) return 1;
338 if(scpet==NULL) return 2;
339
340 /* Check parameters */
341 if(k1<0.0 || k1b<0.0) return 3;
342 if(vb<0.0 || vb>=1.0) return 4;
343 if(fa<0.0 || fa>1.0) return 5;
344 va=fa*vb; vv=(1.0-fa)*vb;
345
346 /* Calculate curves */
347 t_last=0.0; if(t[0]<t_last) t_last=t[0];
348 ca1i=ca1_last=ca2i=ca2_last=0.0;
349 ct1_last=ct2_last=ct3_last=ct1i_last=ct2i_last=ct3i_last=ct1b_last=
350 ct1bi_last=0.0;
351 ct1=ct2=ct3=ct1b=ct1i=ct2i=ct3i=ct1bi=0.0;
352 for(i=0; i<nr; i++) {
353 /* delta time / 2 */
354 dt2=0.5*(t[i]-t_last);
355 /* calculate values */
356 if(dt2<0.0) {
357 return 5;
358 } else if(dt2>0.0) {
359 /* arterial integrals */
360 ca1i+=(ca1[i]+ca1_last)*dt2;
361 ca2i+=(ca2[i]+ca2_last)*dt2;
362 /* partial results */
363 b=ct1i_last+dt2*ct1_last;
364 c=ct2i_last+dt2*ct2_last;
365 d=ct3i_last+dt2*ct3_last;
366 e=ct1bi_last+dt2*ct1b_last;
367 pt=k6+k7;
368 qt=k2+k3+k5+km-(k3*k4*dt2)/(1.0+k4*dt2)-(k5*k6*dt2)/(1.0+pt*dt2);
369 /* 1st tissue compartment and its integral */
370 ct1 = (k1/(1.0+qt*dt2))*ca1i
371 - (qt/(1.0+qt*dt2))*b
372 + (k4/((1.0+qt*dt2)*(1.0+k4*dt2)))*c
373 + (k6/((1.0+qt*dt2)*(1.0+pt*dt2)))*d;
374 ct1i = ct1i_last + dt2*(ct1_last+ct1);
375 /* 2nd tissue compartment and its integral */
376 ct2 = (k3/(1.0+k4*dt2))*ct1i
377 - (k4/(1.0+k4*dt2))*c;
378 ct2i = ct2i_last + dt2*(ct2_last+ct2);
379 /* 3rd tissue compartment and its integral */
380 ct3 = (k5/(1.0+pt*dt2))*ct1i
381 - (pt/(1.0+pt*dt2))*d;
382 ct3i = ct3i_last + dt2*(ct3_last+ct3);
383 /* 4th tissue compartment (the 1st for tracer 2) and its integral */
384 ct1b = (k1b/(1.0+k2b*dt2))*ca2i
385 - (k2b/(1.0+k2b*dt2))*e
386 + (km/(1.0+k2b*dt2))*ct1i;
387 ct1bi = ct1bi_last + dt2*(ct1b_last+ct1b);
388 }
389 /* Venous curve */
390 if(f>0.) {
391 dct = k1*ca1[i] - k2*ct1 - k7*ct3 + k1b*ca2[i] - k2b*ct1b;
392 cvb = cb[i] - dct/f;
393 } else cvb=cb[i];
394 /* copy values to argument arrays */
395 if(vvm==0) scpet[i]= va*cb[i] + vv*cvb + (1.0-vb)*(ct1+ct2+ct3+ct1b);
396 else scpet[i]= va*cb[i] + vv*cvb + (ct1+ct2+ct3+ct1b);
397 if(sct1!=NULL) {sct1[i]=(1.0-vb)*ct1; if(vvm==0) sct1[i]*=(1.0-vb);}
398 if(sct2!=NULL) {sct2[i]=(1.0-vb)*ct2; if(vvm==0) sct2[i]*=(1.0-vb);}
399 if(sct3!=NULL) {sct3[i]=(1.0-vb)*ct3; if(vvm==0) sct3[i]*=(1.0-vb);}
400 if(sct1b!=NULL) {sct1b[i]=(1.0-vb)*ct1b; if(vvm==0) sct1b[i]*=(1.0-vb);}
401 if(sctab!=NULL) sctab[i]=va*cb[i];
402 if(sctvb!=NULL) sctvb[i]=vv*cvb;
403 /* prepare to the next loop */
404 t_last=t[i]; ca1_last=ca1[i]; ca2_last=ca2[i];
405 ct1_last=ct1; ct1i_last=ct1i;
406 ct2_last=ct2; ct2i_last=ct2i;
407 ct3_last=ct3; ct3i_last=ct3i;
408 ct1b_last=ct1b; ct1bi_last=ct1bi;
409 }
410
411 if(verbose>2) {
412 printf("AUC 0-%g:\n", t_last);
413 printf(" ca1i := %g\n", ca1i);
414 printf(" ca2i := %g\n", ca2i);
415 printf(" ct1i := %g\n", ct1i_last);
416 printf(" ct2i := %g\n", ct2i_last);
417 printf(" ct3i := %g\n", ct3i_last);
418 printf(" ct1bi := %g\n", ct1bi_last);
419 }
420
421 return 0;
422}

◆ simC4DIvs()

int simC4DIvs ( double * t,
double * ca1,
double * ca2,
double * cb,
const int nr,
const double k1,
const double k2,
const double k3,
const double k4,
const double k5,
const double k6,
const double k7,
const double km,
double k1b,
double k2b,
double f,
double vb,
double fa,
const int vvm,
double * scpet,
double * sct1,
double * sct2,
double * sct3,
double * sct1b,
double * sctab,
double * sctvb,
const int verbose )

Simulate tissue TAC using dual-input tissue compartment model (1-3 compartments in series for tracer1, and 1 compartment for tracer2) at plasma TAC times, considering also contribution of arterial and venous vasculature, and transfer of tracer1 to tracer2.


The units of rate constants must be related to the time unit; 1/min and min, or 1/sec and sec. If blood flow is set to 0, function assumes that f>>k1, and Cvb=Cab. Reference: TPCMOD0001 Appendix B. Tested with program p2t_di -series.

Returns
Function returns 0 when successful, else a value >= 1.
Author
Vesa Oikonen
See also
simC3DIvs, simC4DIvp, simC1DI, simC3vp, simC3vs, parExamplePerfectBolus
Parameters
tArray of time values.
ca1Array of arterial plasma activities of tracer1 (parent tracer).
ca2Array of arterial plasma activities of tracer2 (metabolite).
cbArray of (total) arterial blood activities.
nrNumber of values in TACs.
k1Rate constant of the model for tracer1 (from plasma to C1).
k2Rate constant of the model for tracer1 (from C1 to plasma).
k3Rate constant of the model for tracer1 (from C1 to C2).
k4Rate constant of the model for tracer1 (from C2 to C1).
k5Rate constant of the model for tracer1 (from C2 to C3).
k6Rate constant of the model for tracer1 (from C3 to C2).
k7Rate constant of the model for tracer1 (from C3 to plasma).
kmRate constant of the model (from tracer1 in C1 to tracer2 in C4).
k1bRate constant of the model for tracer2 (from plasma to C4).
k2bRate constant of the model for tracer2 (from C4 to plasma).
fBlood flow; if 0, function assumes that f>>k1, and Cvb=Cab.
vbVascular volume fraction.
faArterial fraction of vascular volume.
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 TAC array to be simulated; must be allocated.
sct1Pointer for 1st tracer1 compartment TAC, or NULL if not needed.
sct2Pointer for 2nd tracer1 compartment TAC, or NULL if not needed.
sct3Pointer for 3rd tracer1 compartment TAC, or NULL if not needed.
sct1bPointer for 1st tracer2 compartment TAC, or NULL if not needed.
sctabPointer for arterial TAC in tissue, or NULL if not needed.
sctvbPointer for venous TAC in tissue, or NULL if not needed.
verboseVerbose level; if zero, then nothing is printed into stdout or stderr.

Definition at line 441 of file simdicm.c.

498 {
499 int i;
500 double b, c, d, e, pt, qt, rt, dt2, va, vv;
501 double ca1i, ca1_last, ca2i, ca2_last, t_last, dct, cvb;
502 double ct1, ct1_last, ct2, ct2_last, ct3, ct3_last;
503 double ct1i, ct1i_last, ct2i, ct2i_last, ct3i, ct3i_last;
504 double ct1b, ct1b_last, ct1bi, ct1bi_last;
505
506
507 if(verbose>0) {
508 printf("%s()\n", __func__);
509 if(verbose>1) {
510 printf(" k1 := %g\n", k1);
511 printf(" k2 := %g\n", k2);
512 printf(" k3 := %g\n", k3);
513 printf(" k4 := %g\n", k4);
514 printf(" k5 := %g\n", k5);
515 printf(" k6 := %g\n", k6);
516 printf(" k7 := %g\n", k7);
517 printf(" km := %g\n", km);
518 printf(" k1b := %g\n", k1b);
519 printf(" k2b := %g\n", k2b);
520 printf(" vb := %g\n", vb);
521 printf(" fa := %g\n", fa);
522 printf(" f := %g\n", f);
523 }
524 }
525
526 /* Check for data */
527 if(nr<2) return 1;
528 if(scpet==NULL) return 2;
529
530 /* Check parameters */
531 if(k1<0.0 || k1b<0.0) return 3;
532 if(vb<0.0 || vb>=1.0) return 4;
533 if(fa<0.0 || fa>1.0) return 5;
534 va=fa*vb; vv=(1.0-fa)*vb;
535
536 /* Calculate curves */
537 t_last=0.0; if(t[0]<t_last) t_last=t[0];
538 ca1i=ca1_last=ca2i=ca2_last=0.0;
539 ct1_last=ct2_last=ct3_last=ct1i_last=ct2i_last=ct3i_last=ct1b_last=
540 ct1bi_last=0.0;
541 ct1=ct2=ct3=ct1b=ct1i=ct2i=ct3i=ct1bi=0.0;
542 for(i=0; i<nr; i++) {
543 /* delta time / 2 */
544 dt2=0.5*(t[i]-t_last);
545 /* calculate values */
546 if(dt2<0.0) {
547 return 5;
548 } else if(dt2>0.0) {
549 /* arterial integrals */
550 ca1i+=(ca1[i]+ca1_last)*dt2;
551 ca2i+=(ca2[i]+ca2_last)*dt2;
552 //printf("ca1[%d]=%g int=%g\n", i, ca1[i], ca1i);
553 //printf("ca2[%d]=%g int=%g\n", i, ca2[i], ca2i);
554 /* partial results */
555 b=ct1i_last+dt2*ct1_last;
556 c=ct2i_last+dt2*ct2_last;
557 d=ct3i_last+dt2*ct3_last;
558 e=ct1bi_last+dt2*ct1b_last;
559 pt=k6+k7;
560 qt=k4+k5-(k5*k6*dt2)/(1.0+pt*dt2);
561 rt=k2+k3+km-(k3*k4*dt2)/(1.0+qt*dt2);
562 /* 1st tissue compartment and its integral */
563 ct1 = (k1/(1.0+rt*dt2))*ca1i
564 - (rt/(1.0+rt*dt2))*b
565 + (k4/((1.0+qt*dt2)*(1.0+rt*dt2)))*c
566 + ((k4*k6*dt2)/((1.0+pt*dt2)*(1.0+qt*dt2)*(1.0+rt*dt2)))*d;
567 ct1i = ct1i_last + dt2*(ct1_last+ct1);
568 /* 2nd tissue compartment and its integral */
569 ct2 = (k3/(1.0+qt*dt2))*ct1i
570 - (qt/(1.0+qt*dt2))*c
571 + (k6/((1.0+pt*dt2)*(1.0+qt*dt2)))*d;
572 ct2i = ct2i_last + dt2*(ct2_last+ct2);
573 /* 3rd tissue compartment and its integral */
574 ct3 = (k5/(1.0+pt*dt2))*ct2i
575 - (pt/(1.0+pt*dt2))*d;
576 ct3i = ct3i_last + dt2*(ct3_last+ct3);
577 /* 4th tissue compartment (the 1st for tracer 2) and its integral */
578 ct1b = (k1b/(1.0+k2b*dt2))*ca2i
579 - (k2b/(1.0+k2b*dt2))*e
580 + (km/(1.0+k2b*dt2))*ct1i;
581 ct1bi = ct1bi_last + dt2*(ct1b_last+ct1b);
582 }
583 /* Venous curve */
584 if(f>0.) {
585 dct = k1*ca1[i] - k2*ct1 - k7*ct3 + k1b*ca2[i] - k2b*ct1b;
586 cvb = cb[i] - dct/f;
587 } else cvb=cb[i];
588 /* copy values to argument arrays; set very small values to zero */
589 if(vvm==0) scpet[i]= va*cb[i] + vv*cvb + (1.0-vb)*(ct1+ct2+ct3+ct1b);
590 else scpet[i]= va*cb[i] + vv*cvb + (ct1+ct2+ct3+ct1b);
591 if(sct1!=NULL) {sct1[i]=(1.0-vb)*ct1; if(vvm==0) sct1[i]*=(1.0-vb);}
592 if(sct2!=NULL) {sct2[i]=(1.0-vb)*ct2; if(vvm==0) sct2[i]*=(1.0-vb);}
593 if(sct3!=NULL) {sct3[i]=(1.0-vb)*ct3; if(vvm==0) sct3[i]*=(1.0-vb);}
594 if(sct1b!=NULL) {sct1b[i]=(1.0-vb)*ct1b; if(vvm==0) sct1b[i]*=(1.0-vb);}
595 if(sctab!=NULL) sctab[i]=va*cb[i];
596 if(sctvb!=NULL) sctvb[i]=vv*cvb;
597 /* prepare to the next loop */
598 t_last=t[i]; ca1_last=ca1[i]; ca2_last=ca2[i];
599 ct1_last=ct1; ct1i_last=ct1i;
600 ct2_last=ct2; ct2i_last=ct2i;
601 ct3_last=ct3; ct3i_last=ct3i;
602 ct1b_last=ct1b; ct1bi_last=ct1bi;
603 }
604
605 if(verbose>2) {
606 printf("AUC 0-%g:\n", t_last);
607 printf(" ca1i := %g\n", ca1i);
608 printf(" ca2i := %g\n", ca2i);
609 printf(" ct1i := %g\n", ct1i_last);
610 printf(" ct2i := %g\n", ct2i_last);
611 printf(" ct3i := %g\n", ct3i_last);
612 printf(" ct1bi := %g\n", ct1bi_last);
613 }
614
615 return 0;
616}

◆ simDispersion()

int simDispersion ( double * x,
double * y,
const int n,
const double tau1,
const double tau2,
double * tmp )

Simulate the effect of dispersion on a time-activity curve.

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

Returns
Function returns 0 when successful, else a value >= 1.
Author
Vesa Oikonen
See also
simC1, simC1_i, corDispersion, simDelay, simTTM, simBTAC
Parameters
xArray of sample times; must be in increasing order.
yArray of sample values, which will be replaced here by dispersion added values.
nNr of samples.
tau1First dispersion time constant (zero if no dispersion); in same time unit as sample times.
tau22nd dispersion time constant (zero if no dispersion); in same time unit as sample times.
tmpArray for temporary data, for at least n samples; enter NULL to let function to allocate and free the temporary space.

Definition at line 26 of file simdispersion.c.

40 {
41 /* Check input */
42 if(x==NULL || y==NULL || n<2) return 1;
43 if(tau1<0.0 || tau2<0.0) return 2;
44
45 /* Allocate memory if not allocated by user */
46 double *buf;
47 if(tmp!=NULL) buf=tmp; else buf=(double*)malloc(n*sizeof(double));
48 if(buf==NULL) return 3;
49
50 /* First dispersion */
51 if(tau1>0.0) {
52 double k=1.0/tau1;
53 int ret=simC1(x, y, n, k, k, buf);
54 if(ret!=0) {
55 if(tmp==NULL) free(buf);
56 return 100+ret;
57 }
58 for(int i=0; i<n; i++) y[i]=buf[i];
59 }
60
61 /* Second dispersion */
62 if(tau2>0.0) {
63 double k=1.0/tau2;
64 int ret=simC1(x, y, n, k, k, buf);
65 if(ret!=0) {
66 if(tmp==NULL) free(buf);
67 return 200+ret;
68 }
69 for(int i=0; i<n; i++) y[i]=buf[i];
70 }
71
72 if(tmp==NULL) free(buf);
73 return 0;
74}
int simC1(double *t, double *ca, const int nr, const double k1, const double k2, double *ct)
Definition sim1cm.c:93

◆ simIsSteadyInterval()

int simIsSteadyInterval ( double * x,
const int n,
double * f )

Check whether given values have steady intervals, with the first interval starting at zero. Optionally return the interval, or in case of uneven intervals, the shortest interval.

Returns
Returns 1 if values are equidistant, and 0 if intervals are uneven, or cannot be determined.
See also
convolve1D, tacInterpolateToEqualLengthFrames
Parameters
xArray of values to check; must be sorted in ascending order.
nSize of the data array; at least two.
fPointer for the interval, either the common or the shortest interval; enter NULL, if not needed.

Definition at line 66 of file convolut.c.

74 {
75 if(f!=NULL) *f=nan("");
76 if(x==NULL || n<2) return(0);
77 //if(!(fabs(x[0])>1.0E-12)) return(0); // on purpose, to catch NaN
78
79 double d, freq=nan("");
80 int isdif=0;
81 for(int i=1; i<n; i++) {
82 d=x[i]-x[i-1];
83 if(!(d>1.0E-12)) return(0); // interval must be > 0
84 if(isnan(freq)) {freq=d; continue;} // first interval
85 if(fabs(freq-d)<1.0E-12) continue; // same interval as before
86 isdif++; // different
87 if(d<freq) freq=d; // save smaller interval
88 }
89 if(f!=NULL) *f=freq;
90 if(isdif>0) return(0); // variable intervals
91 /* Check that first sample time is at the midpoint of interval starting from 0 */
92 d=0.5*freq; //printf("d=%g x[0]=%g\n", d, x[0]);
93 if(fabs(x[0]-d)>1.0E-06) return(0);
94 return(1);
95}

◆ simMBF()

int simMBF ( double * t,
double * ci,
const int nr,
const double k1,
const double k2,
const double Vfit,
double * ct )

Simulate myocardial tissue TAC using Iida's compartment model.

Memory for ct must be allocated in the calling program. The units of rate constants must be related to the time unit; 1/min and min, or 1/sec and sec.

Returns
Function returns 0 when successful, else a value >= 1.
Author
Vesa Oikonen
See also
simC1, simOxygen, simSamples, simDelay
Parameters
tArray of time values.
ciInput activities.
nrNumber of values in TACs.
k1Apparent k1.
k2Apparent k2.
VfitVfit
ctPointer for TAC array to be simulated; must be allocated.

Definition at line 28 of file sim1cm.c.

43 {
44 int i;
45 double dt2;
46 double cii, ci_last, t_last;
47 double ct_last, cti, cti_last;
48
49
50 /* Check for data */
51 if(nr<2) return(1);
52 if(t==NULL || ci==NULL || ct==NULL) return(2);
53
54 /* Calculate curves */
55 t_last=0.0; cii=ci_last=0.0;
56 cti=ct_last=cti_last=0.0;
57 for(i=0; i<nr; i++) {
58 /* delta time / 2 */
59 dt2=0.5*(t[i]-t_last);
60 /* calculate values */
61 if(dt2<0.0) {
62 return(5);
63 } else if(dt2>0.0) {
64 /* input integral */
65 cii+=(ci[i]+ci_last)*dt2;
66 /* Tissue compartment and its integral */
67 ct[i] = (Vfit*ci[i] + k1*cii - k2*(cti_last+dt2*ct_last)) / (1.0 + dt2*k2);
68 cti = cti_last + dt2*(ct_last+ct[i]);
69 }
70 /* set very small values to zero
71 if(fabs(ct[i])<1.0e-12) ct[i]=0.0; */
72 /* prepare to the next loop */
73 t_last=t[i]; ci_last=ci[i];
74 ct_last=ct[i]; cti_last=cti;
75 }
76 return(0);
77}

◆ 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}

◆ simRTCM()

int simRTCM ( double * t,
double * cr,
const int nr,
const double R1,
const double k2,
const double k3,
const double k4,
double * ct,
double * cta,
double * ctb )

Simulate tissue TAC using full reference tissue compartment model (original) and reference region TAC, at reference region TAC times.

Memory for ct must be allocated in the calling program. To retrieve the separate tissue compartment TACs, pointer to allocated memory for cf and/or cb can be given; if compartmental TACs are not required, NULL pointer can be given instead.

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

See also
simSRTM, simTRTM, simC2, parExampleTTACs, parExamplePerfectBolus
Returns
Function returns 0 when successful, else a value >= 1.
Author
Vesa Oikonen
Parameters
tArray of time values.
crReference region activities.
nrNumber of values in TACs.
R1Ratio K1/K1'.
k2Rate constant of the model.
k3Rate constant of the model.
k4Rate constant of the model.
ctPointer for TAC array to be simulated; must be allocated.
ctaPointer for 1st compartment TAC to be simulated, or NULL.
ctbPointer for 2nd compartment TAC to be simulated, or NULL.

Definition at line 32 of file simrtcm.c.

53 {
54 int i;
55 double f, b, w, dt2;
56 double cri, cr_last, t_last;
57 double cf, cf_last, cb, cb_last;
58 double cfi, cfi_last, cbi, cbi_last;
59
60
61 /* Check for data */
62 if(nr<2) return 1;
63 if(ct==NULL) return 2;
64
65 /* Calculate curves */
66 t_last=0.0; if(t[0]<t_last) t_last=t[0];
67 cri=cr_last=0.0; cf_last=cb_last=cfi_last=cbi_last=cf=cb=cfi=cbi=0.0;
68 for(i=0; i<nr; i++) {
69 /* delta time / 2 */
70 dt2=0.5*(t[i]-t_last);
71 /* calculate values */
72 if(dt2<0.0) {
73 return 5;
74 } else if(dt2>0.0) {
75 /* reference integral */
76 cri+=(cr[i]+cr_last)*dt2;
77 /* partial results */
78 f=cfi_last+dt2*cf_last;
79 b=cbi_last+dt2*cb_last;
80 w=k2 + k3 + k2*k4*dt2;
81 /* 1st tissue compartment and its integral */
82 cf = ( (1.0 + k4*dt2)*(R1*cr[i] + k2*cri) + k4*b - w*f ) / ( 1.0 + dt2*(w+k4) );
83 cfi = cfi_last + dt2*(cf_last+cf);
84 /* 2nd tissue compartment and its integral */
85 cb = (k3*cfi - k4*b) / (1.0 + k4*dt2);
86 cbi = cbi_last + dt2*(cb_last+cb);
87 }
88 /* copy values to argument arrays */
89 ct[i]=cf+cb;
90 if(cta!=NULL) cta[i]=cf;
91 if(ctb!=NULL) ctb[i]=cb;
92 /* prepare to the next loop */
93 t_last=t[i]; cr_last=cr[i];
94 cf_last=cf; cfi_last=cfi;
95 cb_last=cb; cbi_last=cbi;
96 }
97
98 return 0;
99}

◆ simSRTM()

int simSRTM ( double * t,
double * cr,
const int nr,
const double R1,
const double k2,
const double BP,
double * ct )

Simulate tissue TAC using simplified reference tissue input compartment model.

Memory for ct must be allocated in the calling program. The units of rate constants must be related to the time unit; 1/min and min, or 1/sec and sec.

See also
simRTCM, simTRTM, simC2, simC1_i
Returns
Function returns 0 when successful, else a value >= 1.
Author
Vesa Oikonen
Parameters
tArray of time values.
crReference region activities.
nrNumber of values in TACs.
R1Ratio K1/K1'.
k2Rate constant of the model.
BPBinding potential.
ctPointer for TAC array to be simulated; must be allocated.

Definition at line 114 of file simrtcm.c.

129 {
130 int i;
131 double dt2;
132 double cri, cr_last, t_last;
133 double ct_last, cti, cti_last;
134
135
136 /* Check for data */
137 if(nr<2) return 1;
138 if(ct==NULL) return 2;
139
140 /* Calculate curves */
141 t_last=0.0; if(t[0]<t_last) t_last=t[0];
142 cri=cr_last=0.0; cti=ct_last=cti_last=0.0;
143 for(i=0; i<nr; i++) {
144 /* delta time / 2 */
145 dt2=0.5*(t[i]-t_last);
146 /* calculate values */
147 if(dt2<0.0) {
148 return 5;
149 } else if(dt2>0.0) {
150 /* reference integral */
151 cri+=(cr[i]+cr_last)*dt2;
152 /* Tissue compartment and its integral */
153 ct[i] = ( R1*cr[i] + k2*cri - (k2/(1.0+BP))*(cti_last+dt2*ct_last) ) /
154 ( 1.0 + dt2*(k2/(1.0+BP)) );
155 cti = cti_last + dt2*(ct_last+ct[i]);
156 } else { // dt==0
157 ct[i]=ct_last;
158 }
159 /* prepare to the next loop */
160 t_last=t[i]; cr_last=cr[i];
161 ct_last=ct[i]; cti_last=cti;
162 }
163
164 return 0;
165}

◆ simTRTM()

int simTRTM ( double * t,
double * cr,
const int nr,
const double R1,
const double k2,
const double k3,
double * ct )

Simulate tissue TAC using reference tissue compartment model (transport limited in ref region) and reference region TAC, at reference region TAC times.

Memory for ct must be allocated in the calling program.

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

See also
simSRTM, simSRTM, simC2
Returns
Function returns 0 when successful, else a value >= 1.
Author
Vesa Oikonen
Parameters
tArray of time values.
crReference region activities.
nrNumber of values in TACs.
R1Ratio K1/K1'.
k2Rate constant of the model.
k3Rate constant of the model.
ctPointer for TAC array to be simulated; must be allocated.

Definition at line 182 of file simrtcm.c.

197 {
198 int i;
199 double dt2;
200 double cri, cr_last, t_last;
201 double ct_last, cti, cti_last;
202
203
204 /* Check for data */
205 if(nr<2) return 1;
206 if(ct==NULL) return 2;
207
208 /* Calculate curves */
209 t_last=0.0; if(t[0]<t_last) t_last=t[0];
210 cri=cr_last=0.0; cti=ct_last=cti_last=0.0;
211 for(i=0; i<nr; i++) {
212 /* delta time / 2 */
213 dt2=0.5*(t[i]-t_last);
214 /* calculate values */
215 if(dt2<0.0) {
216 return 5;
217 } else if(dt2>0.0) {
218 /* reference integral */
219 cri+=(cr[i]+cr_last)*dt2;
220 /* Tissue compartment and its integral */
221 ct[i] = ( R1*cr[i] + R1*k3*cri - (k2+k3)*(cti_last+dt2*ct_last) ) / ( 1.0 + dt2*(k2+k3) );
222 cti = cti_last + dt2*(ct_last+ct[i]);
223 } else { // dt==0
224 ct[i]=ct_last;
225 }
226 /* prepare to the next loop */
227 t_last=t[i]; cr_last=cr[i];
228 ct_last=ct[i]; cti_last=cti;
229 }
230
231 return 0;
232}

◆ simTTM()

int simTTM ( double * t,
double * c0,
const int n,
const double k,
const int cn,
double * cout )

Simulate output of n-compartmental transit-time model, at input TAC sample times.

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

See also
simTTM_i, simDispersion, simC1, simSamples, simDelay
Returns
Function returns 0 when successful, else a value >= 1.
Author
Vesa Oikonen
Parameters
tArray of time values.
c0Array of input values.
nNumber of values in TACs.
kRate constant of the model.
cnNumber of compartments (cn>0).
coutPointer for TAC array to be simulated; must be allocated.

Definition at line 144 of file simdispersion.c.

157 {
158 /* Check for data */
159 if(n<2 || cn<1) return(1);
160 if(t==NULL || c0==NULL || cout==NULL) return(2);
161 /* Check the rate constant */
162 if(!(k>=0.0)) return(3);
163
164 double c[cn+1], ci[cn+1]; // Compartmental concentrations for current sample
165 double c_last[cn+1], ci_last[cn+1]; // Compartmental concentrations for previous sample
166 for(int j=0; j<=cn; j++) c[j]=c_last[j]=ci[j]=ci_last[j]=0.0;
167
168 /* Calculate curves */
169#if(0)
170 printf("\nTime\tC0\tiC0");
171 for(int j=1; j<=cn; j++) printf("\tC%d", j);
172 printf("\n");
173#endif
174 double t_last=0.0; if(t[0]<t_last) t_last=t[0];
175 double c0_last=0.0, c0i=0.0;
176 for(int i=0; i<n; i++) { // loop through sample times
177 /* delta time / 2 */
178 double dt2=0.5*(t[i]-t_last); if(!(dt2>=0.0)) return(5);
179 /* input integral */
180 c0i+=(c0[i]+c0_last)*dt2;
181 /* k/(1+k*(dt/2)) */
182 double kdt=k/(1.0+dt2*k);
183 /* calculate compartmental concentrations */
184 ci[0]=c0i;
185 if(dt2>0.0) {
186 for(int j=1; j<=cn; j++) {
187 c[j] = kdt * (ci[j-1] - ci_last[j] - dt2*c_last[j]);
188 ci[j] = ci_last[j] + dt2*(c_last[j]+c[j]);
189 }
190 } else { // sample time same as previously, thus concentration do not change either
191 for(int j=0; j<=cn; j++) {
192 c[j]=c_last[j];
193 ci[j]=ci_last[j];
194 }
195 }
196#if(0)
197 printf("%g\t%g\t%g", t[i], c0[i], ci[0]);
198 for(int j=1; j<=cn; j++) printf("\t%g", c[j]);
199 printf("\n");
200#endif
201 cout[i]=c[cn];
202 /* prepare to the next loop */
203 t_last=t[i]; c0_last=c0[i];
204 for(int j=0; j<=cn; j++) {
205 c_last[j]=c[j];
206 ci_last[j]=ci[j];
207 }
208 }
209
210 return(0);
211}

◆ simTTM_i()

int simTTM_i ( double * t,
double * c0i,
const int n,
const double k,
const int cn,
double * cout )

Simulate output of n-compartmental transit-time model, at input TAC sample times.

This version uses integral of input function, enabling user to fully control the calculation of integral, which is more precise when input is based on an integrable mathematical function.

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

See also
simTTM, simDispersion, simC1_i, simSamples
Returns
Function returns 0 when successful, else a value >= 1.
Author
Vesa Oikonen
Parameters
tArray of time values.
c0iArray of AUC 0-t of input function.
nNumber of values in TACs.
kRate constant of the model.
cnNumber of compartments (cn>0).
coutPointer for TAC array to be simulated; must be allocated.

Definition at line 227 of file simdispersion.c.

240 {
241 /* Check for data */
242 if(n<2 || cn<1) return(1);
243 if(t==NULL || c0i==NULL || cout==NULL) return(2);
244 /* Check the rate constant */
245 if(!(k>=0.0)) return(3);
246
247 double c[cn+1], ci[cn+1]; // Compartmental concentrations for current sample
248 double c_last[cn+1], ci_last[cn+1]; // Compartmental concentrations for previous sample
249 for(int j=0; j<=cn; j++) c[j]=c_last[j]=ci[j]=ci_last[j]=0.0;
250
251 /* Calculate curves */
252#if(0)
253 printf("\nTime\tiC0");
254 for(int j=1; j<=cn; j++) printf("\tC%d", j);
255 printf("\n");
256#endif
257 double t_last=0.0; if(t[0]<t_last) t_last=t[0];
258 for(int i=0; i<n; i++) { // loop through sample times
259 /* delta time / 2 */
260 double dt2=0.5*(t[i]-t_last); if(!(dt2>=0.0)) return(5);
261 /* k/(1+k*(dt/2)) */
262 double kdt=k/(1.0+dt2*k);
263 /* calculate compartmental concentrations */
264 ci[0]=c0i[i];
265 if(dt2>0.0) {
266 for(int j=1; j<=cn; j++) {
267 c[j] = kdt * (ci[j-1] - ci_last[j] - dt2*c_last[j]);
268 ci[j] = ci_last[j] + dt2*(c_last[j]+c[j]);
269 }
270 } else { // sample time same as previously, thus concentration do not change either
271 for(int j=0; j<=cn; j++) {
272 c[j]=c_last[j];
273 ci[j]=ci_last[j];
274 }
275 }
276#if(0)
277 printf("%g\t%g", t[i], ci[0]);
278 for(int j=1; j<=cn; j++) printf("\t%g", c[j]);
279 printf("\n");
280#endif
281 cout[i]=c[cn];
282 /* prepare to the next loop */
283 t_last=t[i];
284 for(int j=0; j<=cn; j++) {
285 c_last[j]=c[j];
286 ci_last[j]=ci[j];
287 }
288 }
289
290 return(0);
291}