TPCCLIB
Loading...
Searching...
No Matches
lhtest.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 <string.h>
13#include <math.h>
14/*****************************************************************************/
15#include "tpcextensions.h"
16#include "tpcift.h"
17#include "tpctac.h"
18#include "tpcpar.h"
19#include "tpcli.h"
20#include "tpctacmod.h"
21#include "tpclinopt.h"
22/*****************************************************************************/
23
24/*****************************************************************************/
25static char *info[] = {
26 "Method testing.",
27 " ",
28 "Usage: @P [options] PTAC TTAC results",
29 " ",
30 "Options:",
31 " -svg=<Filename>",
32 " Fitted and measured TACs are plotted in specified SVG file.",
33 " -fit=<Filename>",
34 " Fitted regional TTACs are written in specified file.",
35 " -lp=<Filename>",
36 " Parameters of linear model are saved in specified file.",
37 " -stdoptions", // List standard options like --help, -v, etc
38 " ",
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/*****************************************************************************/
54/*****************************************************************************/
55
56/*****************************************************************************/
60int main(int argc, char **argv)
61{
62 int ai, help=0, version=0, verbose=1;
63 char ptacfile[FILENAME_MAX], ttacfile[FILENAME_MAX], resfile[FILENAME_MAX],
64 fitfile[FILENAME_MAX], svgfile[FILENAME_MAX], lpfile[FILENAME_MAX];
65
66 /*
67 * Get arguments
68 */
69 if(argc==1) {tpcPrintUsage(argv[0], info, stderr); return(1);}
70 ptacfile[0]=ttacfile[0]=resfile[0]=fitfile[0]=svgfile[0]=lpfile[0]=(char)0;
71 /* Options */
72 for(ai=1; ai<argc; ai++) if(*argv[ai]=='-') {
73 if(tpcProcessStdOptions(argv[ai], &help, &version, &verbose)==0) continue;
74 char *cptr=argv[ai]+1; if(*cptr=='-') cptr++; if(!*cptr) continue;
75 if(strncasecmp(cptr, "SVG=", 4)==0) {
76 strlcpy(svgfile, cptr+4, FILENAME_MAX); if(strlen(svgfile)>0) continue;
77 } else if(strncasecmp(cptr, "FIT=", 4)==0) {
78 strlcpy(fitfile, cptr+4, FILENAME_MAX); if(strlen(fitfile)>0) continue;
79 } else if(strncasecmp(cptr, "LP=", 3)==0) {
80 strlcpy(lpfile, cptr+3, FILENAME_MAX); if(strlen(lpfile)>0) continue;
81 }
82 fprintf(stderr, "Error: invalid option '%s'.\n", argv[ai]);
83 return(1);
84 } else break;
85
86 TPCSTATUS status; statusInit(&status);
87 statusSet(&status, __func__, __FILE__, __LINE__, TPCERROR_OK);
88 status.verbose=verbose-3;
89
90 /* Print help or version? */
91 if(help==2) {tpcHtmlUsage(argv[0], info, ""); return(0);}
92 if(help) {tpcPrintUsage(argv[0], info, stdout); return(0);}
93 if(version) {tpcPrintBuild(argv[0], stdout); return(0);}
94
95 /* Process other arguments, starting from the first non-option */
96 if(ai<argc) strlcpy(ptacfile, argv[ai++], FILENAME_MAX);
97 if(ai<argc) strlcpy(ttacfile, argv[ai++], FILENAME_MAX);
98 if(ai<argc) strlcpy(resfile, argv[ai++], FILENAME_MAX);
99 if(ai<argc) {
100 fprintf(stderr, "Error: invalid argument '%s'.\n", argv[ai]);
101 return(1);
102 }
103 /* Did we get all the information that we need? */
104 if(!resfile[0]) {
105 fprintf(stderr, "Error: missing command-line argument; use option --help\n");
106 return(1);
107 }
108
109
110 /* In verbose mode print arguments and options */
111 if(verbose>1) {
112 printf("ptacfile := %s\n", ptacfile);
113 printf("ttacfile := %s\n", ttacfile);
114 printf("resfile := %s\n", resfile);
115 printf("fitfile := %s\n", fitfile);
116 printf("svgfile := %s\n", svgfile);
117 printf("lpfile := %s\n", lpfile);
118 }
119
120
121 /*
122 * Read tissue and input data
123 */
124 if(verbose>1) printf("reading tissue and input data\n");
125 statusSet(&status, __func__, __FILE__, __LINE__, TPCERROR_OK);
126 TAC ptac, ttac0; tacInit(&ptac); tacInit(&ttac0);
127 double fitdur=1.0E+10;
128 if(tacReadModelingData(ttacfile, ptacfile, NULL, NULL, &fitdur, 0,
129 NULL, &ttac0, &ptac, &status)!=TPCERROR_OK) {
130 fprintf(stderr, "Error: %s\n", errorMsg(status.error));
131 tacFree(&ttac0); tacFree(&ptac); return(2);
132 }
133 if(verbose>2) {
134 printf("fileformat := %s\n", tacFormattxt(ttac0.format));
135 printf("tacNr := %d\n", ttac0.tacNr);
136 printf("ttac.sampleNr := %d\n", ttac0.sampleNr);
137 printf("ptac.sampleNr := %d\n", ptac.sampleNr);
138 printf("xunit := %s\n", unitName(ttac0.tunit));
139 printf("yunit := %s\n", unitName(ttac0.cunit));
140 }
141 if(ttac0.isframe==0) {
142 fprintf(stderr, "Error: TTAC file does not contain frame times.\n");
143 tacFree(&ttac0); tacFree(&ptac); return(2);
144 }
145
146
147 /*
148 * Interpolate PTAC to TTAC frame times
149 */
150 if(verbose>1) printf("interpolating PTAC\n");
151 TAC input0; tacInit(&input0); // PTAC mean during PET frames
152 if(tacInterpolate(&ptac, &ttac0, &input0, NULL, NULL, &status)!=TPCERROR_OK) {
153 fprintf(stderr, "Error: %s\n", errorMsg(status.error));
154 tacFree(&ttac0); tacFree(&ptac);
155 tacFree(&input0);
156 return(3);
157 }
158
159 /*
160 * Integrate PTAC to TTAC frame end times
161 */
162 if(verbose>1) printf("integrating PTAC\n");
163 TAC input1; tacInit(&input1); // 1st integral
164 tacDuplicate(&input0, &input1);
165 if(liIntegrateFE(input0.x1, input0.x2, input0.c[0].y, input0.sampleNr, input1.c[0].y, NULL, 0)!=0) {
166 fprintf(stderr, "Error: cannot integrate PTAC.\n");
167 tacFree(&ttac0); tacFree(&ptac);
168 tacFree(&input0); tacFree(&input1);
169 return(3);
170 }
171 /* Original PTAC should not be needed any more */
172 tacFree(&ptac);
173
174 /*
175 * Integrate TTAC to TTAC frame end times
176 */
177 if(verbose>1) printf("integrating TTAC\n");
178 TAC ttac1; tacInit(&ttac1); // 1st integral
179 tacDuplicate(&ttac0, &ttac1);
180 for(int i=0; i<ttac0.tacNr; i++) {
181 if(liIntegrateFE(ttac0.x1, ttac0.x2, ttac0.c[i].y, ttac0.sampleNr, ttac1.c[i].y, NULL, 0)!=0) {
182 fprintf(stderr, "Error: cannot integrate PTAC.\n");
183 tacFree(&ttac0); tacFree(&ttac1);
184 tacFree(&input0); tacFree(&input1);
185 return(3);
186 }
187 }
188
189
190 /*
191 * Allocate memory required by NNLS
192 */
193 if(verbose>1) printf("allocating memory for NNLS\n");
194 int llsq_m=ttac0.sampleNr;
195 int llsq_n=3;
196 double *llsq_mat=(double*)malloc((llsq_n*llsq_m)*sizeof(double));
197 if(llsq_mat==NULL) {
198 fprintf(stderr, "Error: cannot allocate memory for NNLS.\n");
199 tacFree(&ttac0); tacFree(&ttac1);
200 tacFree(&input0); tacFree(&input1);
201 return(5);
202 }
203 double **llsq_a=(double**)malloc(llsq_n*sizeof(double*));
204 if(llsq_a==NULL) {
205 fprintf(stderr, "Error: cannot allocate memory for NNLS.\n");
206 tacFree(&ttac0); tacFree(&ttac1);
207 tacFree(&input0); tacFree(&input1);
208 free(llsq_mat);
209 return(5);
210 }
211 for(int ni=0; ni<llsq_n; ni++) llsq_a[ni]=llsq_mat+ni*llsq_m;
212 double r2, llsq_b[llsq_m], llsq_x[llsq_n], llsq_wp[llsq_n], llsq_zz[llsq_m];
213 int indexp[llsq_n];
214
215
216 /*
217 * Fit each regional TTAC
218 */
219 for(int ti=0; ti<ttac0.tacNr; ti++) {
220
221 if(verbose>1 && ttac0.tacNr>1) {
222 printf("Region %d %s\n", 1+ti, ttac0.c[ti].name); fflush(stdout);}
223
224 /* Setup data matrix A and vector B */
225 for(int mi=0; mi<llsq_m; mi++)
226 llsq_b[mi]=ttac0.c[ti].y[mi];
227 for(int mi=0; mi<llsq_m; mi++) {
228 llsq_mat[mi]=input0.c[0].y[mi]; // Vb
229 if(mi>0) // K1+Vb*k2
230 llsq_mat[mi+llsq_m]=0.5*(input1.c[0].y[mi]+input1.c[0].y[mi-1]);
231 else
232 llsq_mat[mi+llsq_m]=0.5*(input1.c[0].y[mi]+0.0);
233 if(mi>0) // k2
234 llsq_mat[mi+2*llsq_m]=-0.5*(ttac1.c[0].y[mi]+ttac1.c[0].y[mi-1]);
235 else
236 llsq_mat[mi+2*llsq_m]=-0.5*(ttac1.c[0].y[mi]+0.0);
237 }
238 if(verbose>5) {
239 printf("Matrix A and vector B:\n");
240 for(int mi=0; mi<llsq_m; mi++) {
241 printf("%.2e", llsq_a[0][mi]);
242 for(int ni=1; ni<llsq_n; ni++) printf(", %.2e", llsq_a[ni][mi]);
243 printf("; %.3e\n", llsq_b[mi]);
244 }
245 }
246
247 /* Compute NNLS */
248 if(verbose>3) printf("starting NNLS...\n");
249 int ret=nnls(llsq_a, llsq_m, llsq_n, llsq_b, llsq_x, &r2, llsq_wp, llsq_zz, indexp);
250 if(verbose>3) printf(" ... done.\n");
251 if(ret>1) {
252 fprintf(stderr, "Warning: no NNLS solution for %s\n", ttac0.c[ti].name);
253 for(int ni=0; ni<llsq_n; ni++) llsq_x[ni]=0.0;
254 r2=0.0;
255 } else if(ret==1) {
256 fprintf(stderr, "Warning: NNLS iteration max exceeded for %s\n", ttac0.c[ti].name);
257 }
258 if(verbose>4) {
259 printf("solution_vector: %g", llsq_wp[0]);
260 for(int ni=1; ni<llsq_n; ni++) printf(", %g", llsq_wp[ni]);
261 printf("\n");
262 }
263 if(verbose>3) {
264 printf("parameter_vector: %g", llsq_x[0]);
265 for(int ni=1; ni<llsq_n; ni++) printf(", %g", llsq_x[ni]);
266 printf("\n");
267 }
268
269 } // next TAC
270
271 /* Free allocated memory */
272 free(llsq_a); free(llsq_mat);
273
274
275
276 tacFree(&ttac0); tacFree(&ttac1);
277 tacFree(&input0); tacFree(&input1);
278
279 return(0);
280}
281/*****************************************************************************/
282
283/*****************************************************************************/
int liIntegrateFE(double *x1, double *x2, double *y, int nr, double *ie, double *iie, const int verbose)
Linear integration of PET TAC to frame end times.
Definition integrate.c:219
int tacInterpolate(TAC *inp, TAC *xinp, TAC *tac, TAC *itac, TAC *iitac, TPCSTATUS *status)
Interpolate and/or integrate TACs from one TAC structure into a new TAC structure,...
Definition litac.c:141
int nnls(double **a, int m, int n, double *b, double *x, double *rnorm, double *wp, double *zzp, int *indexp)
Definition nnls.c:48
int tpcProcessStdOptions(const char *s, int *print_usage, int *print_version, int *verbose_level)
Definition proginfo.c:47
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
char name[MAX_TACNAME_LEN+1]
Definition tpctac.h:81
double * y
Definition tpctac.h:75
Definition tpctac.h:87
unit cunit
Definition tpctac.h:105
tacformat format
Definition tpctac.h:93
int sampleNr
Definition tpctac.h:89
int isframe
Definition tpctac.h:95
TACC * c
Definition tpctac.h:117
double * x2
Definition tpctac.h:101
unit tunit
Definition tpctac.h:109
double * x1
Definition tpctac.h:99
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
int tacDuplicate(TAC *tac1, TAC *tac2)
Make a duplicate of TAC structure.
Definition tac.c:356
void tacInit(TAC *tac)
Definition tac.c:24
char * tacFormattxt(tacformat c)
Definition tacio.c:98
int tacReadModelingData(const char *tissuefile, const char *inputfile1, const char *inputfile2, const char *inputfile3, double *fitdur, int cutInput, int *fitSampleNr, TAC *tis, TAC *inp, TPCSTATUS *status)
Read tissue and input data for modelling.
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 libtpclinopt.
Header file for libtpcpar.
Header file for library libtpctac.
Header file for libtpctacmod.