TPCCLIB
Loading...
Searching...
No Matches
extrapol.c
Go to the documentation of this file.
1
7/*****************************************************************************/
8#include "tpcclibConfig.h"
9/*****************************************************************************/
10#include <stdio.h>
11#include <stdlib.h>
12#include <unistd.h>
13#include <string.h>
14#include <math.h>
15/*****************************************************************************/
16#include "libtpcmisc.h"
17#include "libtpcmodel.h"
18#include "libtpccurveio.h"
19#include "libtpcsvg.h"
20#include "libtpcmodext.h"
21/*****************************************************************************/
22
23/*****************************************************************************/
24static char *info[] = {
25 "Extrapolation of the decreasing tail of PET input curve to given time.",
26 "This is accomplished by fitting line to the end-part of the plot of the",
27 "natural logarithm of tracer concentration against time.",
28 "This approach may be applied to TACs which approach zero; thus this",
29 "works best for metabolite-corrected input TACs, and cannot be used with",
30 "tracers with very slow clearance, such as radiowater.",
31 " ",
32 "Usage: @P [Options] inputfile time outputfile",
33 " ",
34 "Options:",
35 " -e[nd]=<Fit end time>",
36 " Start the search to fit end time; by default, the search for the best",
37 " line fit is started from the last sample.",
38 " -minnr=<Minimum nr of samples>",
39 " Set the minimum number of samples used in searching the best fit;",
40 " by default 3.",
41 " -maxnr=<Maximum nr of samples>",
42 " Set the maximum number of samples used in searching the best fit;",
43 " by default all samples.",
44 " -mintime=<Minimum time>",
45 " Set a minimum time range used in searching the best fit.",
46 " -svg=<Filename>",
47 " Measured and extrapolated TACs are plotted in specified SVG file.",
48 " -stdoptions", // List standard options like --help, -v, etc
49 " ",
50 "Input TAC file must contain a time column, and one or more concentration",
51 "columns. The extrapolation time must be given in same units as are the sample",
52 "times in the datafile.",
53 " ",
54 "See also: paucinf, avgbolus, fit_dexp, fit_feng, fit2dat, tacln",
55 " ",
56 "Keywords: input, plasma, TAC, modelling, simulation",
57 0};
58/*****************************************************************************/
59
60/*****************************************************************************/
61/* Turn on the globbing of the command line, since it is disabled by default in
62 mingw-w64 (_dowildcard=0); in MinGW32 define _CRT_glob instead, if necessary;
63 In Unix&Linux wildcard command line processing is enabled by default. */
64/*
65#undef _CRT_glob
66#define _CRT_glob -1
67*/
68int _dowildcard = -1;
69/*****************************************************************************/
70
71/*****************************************************************************/
75int main(int argc, char **argv)
76{
77 int ai, help=0, version=0, verbose=1;
78 char inpfile[FILENAME_MAX], outfile[FILENAME_MAX], svgfile[FILENAME_MAX];
79 char temp[FILENAME_MAX], *cptr;
80 DFT dft, ext;
81 double extr_to=-1.0, fittime=-1.0, mintime=-1.0;
82 int ri, n, ret, min_nr=3, max_nr=-1;
83 FILE *logfp;
84
85
86 /*
87 * Get arguments
88 */
89 if(argc==1) {tpcPrintUsage(argv[0], info, stderr); return(1);}
90 inpfile[0]=outfile[0]=svgfile[0]=(char)0;
91 dftInit(&dft); dftInit(&ext);
92
93 /* Options */
94 for(ai=1; ai<argc; ai++) if(*argv[ai]=='-') {
95 cptr=argv[ai]+1; if(*cptr=='-') cptr++; if(cptr==NULL) continue;
96 if(tpcProcessStdOptions(argv[ai], &help, &version, &verbose)==0) continue;
97 if(strncasecmp(cptr, "E=", 2)==0) {
98 fittime=atof_dpi(cptr+2); if(fittime>0.0) continue;
99 } else if(strncasecmp(cptr, "END=", 4)==0) {
100 fittime=atof_dpi(cptr+4); if(fittime>0.0) continue;
101 } else if(strncasecmp(cptr, "MINNR=", 6)==0) {
102 min_nr=atoi(cptr+6); if(min_nr>1) continue;
103 } else if(strncasecmp(cptr, "MAXNR=", 6)==0) {
104 max_nr=atoi(cptr+6); if(max_nr>1) continue;
105 } else if(strncasecmp(cptr, "MINTIME=", 8)==0) {
106 mintime=atof_dpi(cptr+8); if(mintime>0.0) continue;
107 } else if(strncasecmp(cptr, "SVG=", 4)==0) {
108 strcpy(svgfile, cptr+4); if(strlen(svgfile)>0) continue;
109 }
110 fprintf(stderr, "Error: invalid option '%s'.\n", argv[ai]);
111 return(1);
112 } else break;
113
114 /* Print help or version? */
115 if(help==2) {tpcHtmlUsage(argv[0], info, ""); return(0);}
116 if(help) {tpcPrintUsage(argv[0], info, stdout); return(0);}
117 if(version) {tpcPrintBuild(argv[0], stdout); return(0);}
118
119 /* Process other arguments, starting from the first non-option */
120 for(; ai<argc; ai++) {
121 if(!inpfile[0]) {
122 strcpy(inpfile, argv[ai]); continue;
123 } else if(extr_to<0.0) {
124 extr_to=atof_dpi(argv[ai]); if(extr_to>0.0) continue;
125 fprintf(stderr, "Error: invalid extrapolation time: '%s'.\n", argv[ai]);
126 return(1);
127 } else if(!outfile[0]) {
128 strcpy(outfile, argv[ai]); continue;
129 }
130 /* we should never get this far */
131 fprintf(stderr, "Error: too many arguments: '%s'.\n", argv[ai]);
132 return(1);
133 }
134
135 /* Is something missing? */
136 if(!outfile[0]) {
137 fprintf(stderr, "Error: missing file name for extrapolated data.\n");
138 return(1);
139 }
140
141
142 /* In verbose mode print arguments and options */
143 if(verbose>1) {
144 printf("inpfile := %s\n", inpfile);
145 printf("outfile := %s\n", outfile);
146 printf("extr_to := %g\n", extr_to);
147 printf("svgfile := %s\n", svgfile);
148 printf("fittime := %g\n", fittime);
149 printf("mintime := %g\n", mintime);
150 printf("min_nr := %d\n", min_nr);
151 printf("max_nr := %d\n", max_nr);
152 }
153
154
155 /*
156 * Read data
157 */
158 if(verbose>1) printf("reading %s\n", inpfile);
159 if(dftRead(inpfile, &dft)) {
160 fprintf(stderr, "Error in reading '%s': %s\n", inpfile, dfterrmsg);
161 return(2);
162 }
163
164
165 /*
166 * Delete the ROIs that have name 'SD' (produced at least by avgbolus)
167 */
168 for(ri=0, n=0; ri<dft.voiNr; ri++) {
169 dft.voi[ri].sw=0;
170 if(strcasecmp(dft.voi[ri].voiname, "SD")==0) {
171 dft.voi[ri].sw=1; n++; continue;}
172 if(strcasecmp(dft.voi[ri].hemisphere, "SD")==0) {
173 dft.voi[ri].sw=1; n++; continue;}
174 }
175 if(n>0 && n<dft.voiNr) {
176 ri=dft.voiNr-1;
177 while(ri>=0) {
178 if(dft.voi[ri].sw) {
179 if(verbose>0)
180 printf(" TAC '%s' is not extrapolated\n", dft.voi[ri].name);
181 dftDelete(&dft, ri);
182 }
183 ri--;
184 }
185 }
186 if(dft.voiNr<1) {
187 fprintf(stderr, "Error: file does not contain data for extrapolation.\n");
188 dftEmpty(&dft); return(2);
189 }
190
191
192 /*
193 * Extrapolation
194 */
195 if(verbose>1) printf("extrapolation\n");
196 if(verbose>2) logfp=stdout; else logfp=NULL;
198 &dft, &fittime, &min_nr, max_nr, mintime, extr_to, &ext, logfp, temp
199 );
200 if(ret!=0) {
201 fprintf(stderr, "Error in extrapolation: %s\n", temp);
202 dftEmpty(&dft); dftEmpty(&ext);
203 }
204
205 /*
206 * Writing extrapolated TAC
207 */
208 if(verbose>1) printf("writing %s\n", outfile);
209 /* Set comments */
210 dftSetComments(&ext);
211 snprintf(temp, FILENAME_MAX-1, "# extrapolated: %s %g\n", inpfile, extr_to);
212 strcat(ext.comments, temp);
213 /* Write the file */
214 if(ext._type<1) ext._type=DFT_FORMAT_STANDARD;
215 ret=dftWrite(&ext, outfile);
216 if(ret) {
217 fprintf(stderr, "Error (%d) in writing '%s': %s\n", ret, outfile, dfterrmsg);
218 dftEmpty(&dft); dftEmpty(&ext); return(11);
219 }
220
221 /*
222 * Save SVG plot of original and extrapolated TAC
223 */
224 if(svgfile[0]) {
225 if(verbose>1) printf("saving SVG plot\n");
226 sprintf(temp, "Extrapolation ");
227 if(strlen(dft.studynr)>1) strcat(temp, dft.studynr);
228 ret=plot_fit_svg(&dft, &ext, temp, svgfile, verbose-2);
229 if(ret) {
230 fprintf(stderr, "Error (%d) in writing '%s'.\n", ret, svgfile);
231 dftEmpty(&dft); dftEmpty(&ext);
232 return(30+ret);
233 }
234 if(verbose>=0) printf("Plots written in %s\n", svgfile);
235 }
236
237 /* Free memory */
238 dftEmpty(&dft); dftEmpty(&ext);
239
240 return(0);
241}
242/******************************************************************************/
243
244/******************************************************************************/
double atof_dpi(char *str)
Definition decpoint.c:59
void dftInit(DFT *data)
Definition dft.c:38
char dfterrmsg[64]
Definition dft.c:6
void dftSetComments(DFT *dft)
Definition dft.c:1326
int dftDelete(DFT *dft, int voi)
Definition dft.c:538
void dftEmpty(DFT *data)
Definition dft.c:20
int dftRead(char *filename, DFT *data)
Definition dftio.c:22
int dftWrite(DFT *data, char *filename)
Definition dftio.c:594
int extrapolate_monoexp(DFT *dft, double *fittime, int *min_nr, int max_nr, double mintime, double extr_to, DFT *ext, FILE *loginfo, char *status)
Definition extrapolate.c:22
Header file for libtpccurveio.
#define DFT_FORMAT_STANDARD
Header file for libtpcmisc.
int tpcProcessStdOptions(const char *s, int *print_usage, int *print_version, int *verbose_level)
Definition proginfo.c:40
int tpcHtmlUsage(const char *program, char *text[], const char *path)
Definition proginfo.c:213
void tpcPrintBuild(const char *program, FILE *fp)
Definition proginfo.c:383
void tpcPrintUsage(const char *program, char *text[], FILE *fp)
Definition proginfo.c:158
Header file for libtpcmodel.
Header file for libtpcmodext.
int plot_fit_svg(DFT *dft1, DFT *dft2, char *main_title, char *fname, int verbose)
Definition plotfit.c:216
Header file for libtpcsvg.
int _type
Voi * voi
char studynr[MAX_STUDYNR_LEN+1]
char comments[_DFT_COMMENT_LEN+1]
int voiNr
char voiname[MAX_REGIONSUBNAME_LEN+1]
char sw
char name[MAX_REGIONNAME_LEN+1]
char hemisphere[MAX_REGIONSUBNAME_LEN+1]