TPCCLIB
Loading...
Searching...
No Matches
simblood.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/*****************************************************************************/
22 ICMPARC *d
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}
36/*****************************************************************************/
37
38/*****************************************************************************/
45 ICMPARC *d,
47 unsigned const int mNr
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}
65/*****************************************************************************/
66
67/*****************************************************************************/
74 ICMPARC *d,
76 unsigned const int sNr,
78 const int sub
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}
118/*****************************************************************************/
119
120/*****************************************************************************/
127 ICMPARC *d
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}
146/*****************************************************************************/
147
148/*****************************************************************************/
156 double *t,
158 const unsigned int nr,
161 ICMPARC *p,
164 double *c_BA
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}
258/*****************************************************************************/
259
260/*****************************************************************************/
277 double *t,
279 double *ct,
281 const int nr,
283 const double k,
285 double *cp
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}
319/*****************************************************************************/
320
321/*****************************************************************************/
void icmparcFree(ICMPARC *d)
Definition simblood.c:125
int icmparcAllocateTACs(ICMPARC *d, unsigned const int sNr, const int sub)
Definition simblood.c:72
int simBM1(double *t, double *ct, const int nr, const double k, double *cp)
Definition simblood.c:275
int icmparcAddMetabolites(ICMPARC *d, unsigned const int mNr)
Definition simblood.c:43
int simBTAC(double *t, const unsigned int nr, ICMPARC *p, double *c_BA)
Definition simblood.c:154
void icmparcInit(ICMPARC *d)
Definition simblood.c:20
double k_TF_BV
Definition tpccm.h:207
double * c_BA
Definition tpccm.h:229
struct ICMPARC * parent
Definition tpccm.h:215
double k_BA_TS
Definition tpccm.h:205
double Tdur
Definition tpccm.h:195
double Ti
Definition tpccm.h:193
unsigned int mNr
Definition tpccm.h:211
double * c_TF
Definition tpccm.h:235
double k_BV_BA
Definition tpccm.h:199
double * ic_BV
Definition tpccm.h:223
double * ic_TF
Definition tpccm.h:227
double k_TS_BV
Definition tpccm.h:209
struct ICMPARC * metabolite
Definition tpccm.h:213
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 * c_BV
Definition tpccm.h:231
double * c_TS
Definition tpccm.h:233
double kp_TS
Definition tpccm.h:221
double Irate
Definition tpccm.h:197
double * ic_TS
Definition tpccm.h:225
Header file for libtpccm.