TPCCLIB
Loading...
Searching...
No Matches
simoxygen.c
Go to the documentation of this file.
1
4/*****************************************************************************/
5#include "tpcclibConfig.h"
6/*****************************************************************************/
7#include <stdio.h>
8#include <stdlib.h>
9#include <math.h>
10#include <time.h>
11#include <string.h>
12/*****************************************************************************/
13#include "tpccm.h"
14/*****************************************************************************/
15
16/*****************************************************************************/
31 double *t,
33 double *ca1,
35 double *ca2,
37 double *ca1i,
39 double *ca2i,
41 const int n,
43 const double k1a,
45 const double k2a,
47 const double km,
49 const double k1b,
51 const double k2b,
53 const double vb,
55 const double fa,
59 const int vvm,
62 double *scpet,
65 double *sct1,
68 double *sct2,
71 double *sctab,
74 double *sctvb1,
77 double *sctvb2,
79 double *scvb1,
81 double *scvb2,
83 const int verbose
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}
184/*****************************************************************************/
185
186/*****************************************************************************/
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)
Definition simoxygen.c:29
Header file for libtpccm.