TPCCLIB
Loading...
Searching...
No Matches
liverinp.c
Go to the documentation of this file.
1
8/*****************************************************************************/
9#include "tpcclibConfig.h"
10/*****************************************************************************/
11#include <stdio.h>
12#include <stdlib.h>
13#include <string.h>
14#include <math.h>
15/*****************************************************************************/
16#include "tpcextensions.h"
17#include "tpcift.h"
18#include "tpctac.h"
19#include "tpcli.h"
20/*****************************************************************************/
21
22/*****************************************************************************/
23static char *info[] = {
24 "Input for liver models consists of two parts: portal vein and hepatic artery.",
25 "This program calculates a weighted average of TACs of portal vein and",
26 "hepatic artery.",
27 " ",
28 "Usage: @P [Options] portalfile arteryfile portal_fraction outputfile",
29 " ",
30 "Options:",
31 " -stdoptions", // List standard options like --help, -v, etc
32 " ",
33 "Example:",
34 " @P ue65pv.blo ue65ha.blo 0.90 ue65hi.blo",
35 " ",
36 "See also: liverpv, taccalc, interpol, taccat, tacformat, b2plasma",
37 " ",
38 "Keywords: input, blood, TAC, modelling, simulation, liver",
39 0};
40/*****************************************************************************/
41
42/*****************************************************************************/
43/* Turn on the globbing of the command line, since it is disabled by default in
44 mingw-w64 (_dowildcard=0); in MinGW32 define _CRT_glob instead, if necessary;
45 In Unix&Linux wildcard command line processing is enabled by default. */
46/*
47#undef _CRT_glob
48#define _CRT_glob -1
49*/
50int _dowildcard = -1;
51/*****************************************************************************/
52
53/*****************************************************************************/
57int main(int argc, char **argv)
58{
59 int ai, help=0, version=0, verbose=1;
60 int fi, ret, dataNr=0;
61 char pfile[FILENAME_MAX], afile[FILENAME_MAX], wfile[FILENAME_MAX];
62 double portalf=-1.0;
63 TAC pdata, adata;
64
65
66 /*
67 * Get arguments
68 */
69 if(argc==1) {tpcPrintUsage(argv[0], info, stderr); return(1);}
70 pfile[0]=afile[0]=wfile[0]=(char)0;
71 tacInit(&pdata); tacInit(&adata);
72 /* Options */
73 for(ai=1; ai<argc; ai++) if(*argv[ai]=='-') {
74 if(tpcProcessStdOptions(argv[ai], &help, &version, &verbose)==0) continue;
75 fprintf(stderr, "Error: invalid option '%s'.\n", argv[ai]);
76 return(1);
77 } else break; // tac name argument may start with '-'
78
79 TPCSTATUS status; statusInit(&status);
80 statusSet(&status, __func__, __FILE__, __LINE__, TPCERROR_OK);
81 status.verbose=verbose-1;
82
83 /* Print help or version? */
84 if(help==2) {tpcHtmlUsage(argv[0], info, ""); return(0);}
85 if(help) {tpcPrintUsage(argv[0], info, stdout); return(0);}
86 if(version) {tpcPrintBuild(argv[0], stdout); return(0);}
87
88 /* Arguments */
89 for(; ai<argc; ai++) {
90 if(!pfile[0]) {
91 strlcpy(pfile, argv[ai], FILENAME_MAX); continue;
92 } else if(!afile[0]) {
93 strlcpy(afile, argv[ai], FILENAME_MAX); continue;
94 } else if(portalf<0.0) {
95 if(atofCheck(argv[ai], &portalf)==0) {
96 if(portalf>1.0) portalf/=100.0;
97 if(portalf>=0.0 && portalf<=1.0) continue;
98 }
99 fprintf(stderr, "Error: invalid proportion of portal vein input.\n");
100 return(1);
101 } else if(!wfile[0]) {
102 strlcpy(wfile, argv[ai], FILENAME_MAX); continue;
103 }
104 fprintf(stderr, "Error: invalid argument '%s'.\n", argv[ai]);
105 return(1);
106 }
107
108 /* Is something missing? */
109 if(!wfile[0]) {
110 fprintf(stderr, "Error: missing command-line argument; use option --help\n");
111 return(1);
112 }
113
114
115 /* In verbose mode print arguments and options */
116 if(verbose>1) {
117 for(ai=0; ai<argc; ai++) printf("%s ", argv[ai]);
118 printf("\n");
119 printf("pfile := %s\n", pfile);
120 printf("afile := %s\n", afile);
121 printf("wfile := %s\n", wfile);
122 printf("portalf := %g\n", portalf);
123 }
124
125
126 /*
127 * Read TAC files
128 */
129
130 /* Read portal vein data */
131 if(verbose>0) printf("reading %s\n", pfile);
132 ret=tacRead(&pdata, pfile, &status);
133 if(ret!=TPCERROR_OK) {
134 fprintf(stderr, "Error (%d): %s\n", ret, errorMsg(status.error));
135 tacFree(&pdata); return(2);
136 }
137 if(verbose>2) {
138 printf("fileformat := %s\n", tacFormattxt(pdata.format));
139 printf("tacNr := %d\n", pdata.tacNr);
140 printf("sampleNr := %d\n", pdata.sampleNr);
141 printf("xunit := %s\n", unitName(pdata.tunit));
142 printf("yunit := %s\n", unitName(pdata.cunit));
143 }
144 if(pdata.tacNr>1) {
145 fprintf(stderr, "Warning: only first TAC in portal data is used.\n");
146 pdata.tacNr=1;
147 }
148
149 /* Read hepatic artery data */
150 if(verbose>0) printf("reading %s\n", afile);
151 ret=tacRead(&adata, afile, &status);
152 if(ret!=TPCERROR_OK) {
153 fprintf(stderr, "Error (%d): %s\n", ret, errorMsg(status.error));
154 tacFree(&pdata); tacFree(&adata); return(2);
155 }
156 if(verbose>2) {
157 printf("fileformat := %s\n", tacFormattxt(adata.format));
158 printf("tacNr := %d\n", adata.tacNr);
159 printf("sampleNr := %d\n", adata.sampleNr);
160 printf("xunit := %s\n", unitName(adata.tunit));
161 printf("yunit := %s\n", unitName(adata.cunit));
162 }
163 if(adata.tacNr>1) {
164 fprintf(stderr, "Warning: only first TAC in hepatic arterial data is used.\n");
165 adata.tacNr=1;
166 }
167
168 /* Sort by sample times */
169 tacSortByTime(&pdata, NULL);
170 tacSortByTime(&adata, NULL);
171
172 /* Convert units */
173 ret=tacXUnitConvert(&adata, pdata.tunit, &status);
174 if(ret!=TPCERROR_OK && verbose>0) {
175 fprintf(stderr, "Warning: different or unknown time units.\n");
176 }
177 ret=tacYUnitConvert(&adata, pdata.cunit, &status);
178 if(ret!=TPCERROR_OK && verbose>0) {
179 fprintf(stderr, "Warning: different or unknown concentration units.\n");
180 }
181
182 /* Check that hepatic artery TAC has higher peak */
183 {
184 double pmax, amax;
185 ret=tacYRange(&pdata, 0, NULL, &pmax, NULL, NULL, NULL, NULL);
186 if(ret==0) ret=tacYRange(&adata, 0, NULL, &amax, NULL, NULL, NULL, NULL);
187 if(ret) {
188 fprintf(stderr, "Error: invalid data.\n");
189 tacFree(&pdata); tacFree(&adata); return(2);
190 }
191 if(amax<pmax) {
192 fprintf(stderr, "Warning: unexpectedly portal vein has higher peak than hepatic artery.\n");
193 }
194 }
195
196 /* Interpolate hepatic artery data to same sample times as portal vein data */
197 ret=tacAllocateMore(&pdata, 1);
198 if(!ret)
199 ret=liInterpolate(adata.x, adata.c[0].y, adata.sampleNr,
200 pdata.x, pdata.c[1].y, NULL, NULL, pdata.sampleNr, 4, 1, verbose-2);
201 if(ret) {
202 fprintf(stderr, "Error: cannot interpolate plasma TAC.\n");
203 tacFree(&pdata); tacFree(&adata); return(4);
204 }
205
206
207 /*
208 * Calculate weighted average TAC
209 */
210 if(verbose>1) printf("calculating weighted average TAC\n");
211 for(fi=0, dataNr=0; fi<pdata.sampleNr; fi++) {
212 if(isnan(pdata.c[0].y[fi]) || isnan(pdata.c[1].y[fi])) {
213 pdata.c[0].y[fi]=nan(""); continue;
214 }
215 if(pdata.x[fi]<=(1.1*adata.x[adata.sampleNr-1])) {
216 pdata.c[0].y[fi]= portalf*pdata.c[0].y[fi] + (1.0-portalf)*pdata.c[1].y[fi];
217 dataNr++;
218 } // else keep all data as portal TAC
219 }
220 if(dataNr<2) {
221 fprintf(stderr, "Error: check the TAC sample times.\n");
222 tacFree(&pdata); tacFree(&adata);
223 return(6);
224 }
225 if(dataNr+1<pdata.sampleNr) {
226 fprintf(stderr,
227 "Warning: last %d samples are taken from hepatic vein alone.\n",
228 pdata.sampleNr-dataNr
229 );
230 }
231
232
233 /*
234 * Save average TAC
235 */
236 if(verbose>1) printf("writing %s\n", wfile);
237 {
238 char tmp[256];
239 tpcProgramName(argv[0], 1, 0, tmp, 128);
240 iftPut(&pdata.h, "program", tmp, 1, NULL);
241 filenameRmPath(pfile);
242 iftPut(&pdata.h, "portal_vein_file", pfile, 1, NULL);
243 filenameRmPath(afile);
244 iftPut(&pdata.h, "hepatic_artery_file", afile, 1, NULL);
245 sprintf(tmp, "%g", portalf);
246 iftPut(&pdata.h, "portal_vein_fraction", tmp, 1, NULL);
247 }
248 pdata.tacNr=1; // just to be sure
249 FILE *fp; fp=fopen(wfile, "w");
250 if(fp==NULL) {
251 fprintf(stderr, "Error: cannot open file for writing (%s)\n", wfile);
252 tacFree(&pdata); tacFree(&adata); return(11);
253 }
254 ret=tacWrite(&pdata, fp, TAC_FORMAT_UNKNOWN, 1, &status);
255 fclose(fp); tacFree(&pdata); tacFree(&adata);
256 if(ret!=TPCERROR_OK) {
257 fprintf(stderr, "Error (%d): %s\n", ret, errorMsg(status.error));
258 return(12);
259 }
260 if(verbose>0) printf("Liver input TAC written in %s\n", wfile);
261
262 return(0);
263}
264/*****************************************************************************/
265
266/*****************************************************************************/
int atofCheck(const char *s, double *v)
Definition decpoint.c:94
void filenameRmPath(char *s)
Definition filename.c:20
int iftPut(IFT *ift, const char *key, const char *value, char comment, TPCSTATUS *status)
Definition ift.c:63
int liInterpolate(double *x, double *y, const int nr, double *newx, double *newy, double *newyi, double *newyii, const int newnr, const int se, const int ee, const int verbose)
Linear interpolation and/or integration with trapezoidal method.
int tpcProcessStdOptions(const char *s, int *print_usage, int *print_version, int *verbose_level)
Definition proginfo.c:47
void tpcProgramName(const char *program, int version, int copyright, char *prname, int n)
Definition proginfo.c:406
int tpcHtmlUsage(const char *program, char *text[], const char *path)
Definition proginfo.c:169
void tpcPrintBuild(const char *program, FILE *fp)
Definition proginfo.c:339
void tpcPrintUsage(const char *program, char *text[], FILE *fp)
Definition proginfo.c:114
void statusInit(TPCSTATUS *s)
Definition statusmsg.c:104
char * errorMsg(tpcerror e)
Definition statusmsg.c:68
void statusSet(TPCSTATUS *s, const char *func, const char *srcfile, int srcline, tpcerror error)
Definition statusmsg.c:142
size_t strlcpy(char *dst, const char *src, size_t dstsize)
Definition stringext.c:632
double * y
Definition tpctac.h:75
Definition tpctac.h:87
double * x
Definition tpctac.h:97
unit cunit
Definition tpctac.h:105
tacformat format
Definition tpctac.h:93
int sampleNr
Definition tpctac.h:89
IFT h
Optional (but often useful) header information.
Definition tpctac.h:141
TACC * c
Definition tpctac.h:117
unit tunit
Definition tpctac.h:109
int tacNr
Definition tpctac.h:91
int verbose
Verbose level, used by statusPrint() etc.
tpcerror error
Error code.
void tacFree(TAC *tac)
Definition tac.c:106
void tacInit(TAC *tac)
Definition tac.c:24
int tacAllocateMore(TAC *tac, int tacNr)
Definition tac.c:178
int tacRead(TAC *d, const char *fname, TPCSTATUS *status)
Definition tacio.c:413
char * tacFormattxt(tacformat c)
Definition tacio.c:98
int tacWrite(TAC *tac, FILE *fp, tacformat format, int extra, TPCSTATUS *status)
Definition tacio.c:332
int tacSortByTime(TAC *d, TPCSTATUS *status)
Definition tacorder.c:74
int tacYUnitConvert(TAC *tac, const int u, TPCSTATUS *status)
Definition tacunits.c:72
int tacXUnitConvert(TAC *tac, const int u, TPCSTATUS *status)
Definition tacunits.c:23
int tacYRange(TAC *d, int i, double *ymin, double *ymax, int *smin, int *smax, int *imin, int *imax)
Get the range of y values (concentrations) in TAC struct.
Definition tacy.c:26
Header file for library libtpcextensions.
@ TPCERROR_OK
No error.
char * unitName(int unit_code)
Definition units.c:143
Header file for library libtpcift.
Header file for libtpcli.
Header file for library libtpctac.
@ TAC_FORMAT_UNKNOWN
Unknown format.
Definition tpctac.h:28