TPCCLIB
Loading...
Searching...
No Matches
imglhdv.c
Go to the documentation of this file.
1
10/*****************************************************************************/
11#include "tpcclibConfig.h"
12/*****************************************************************************/
13#include <stdio.h>
14#include <stdlib.h>
15#include <unistd.h>
16#include <string.h>
17#include <math.h>
18#include <time.h>
19/*****************************************************************************/
20#include "libtpccurveio.h"
21#include "libtpcmodext.h"
22#include "libtpcmisc.h"
23#include "libtpcmodel.h"
24#include "libtpcimgio.h"
25#include "libtpcimgp.h"
26/*****************************************************************************/
27#define NNLS_N 4
28#define MAX_MODEL_NR 2
29enum {MODEL_SELECTION_WAIC,
30 MODEL_SELECTION_1, MODEL_SELECTION_2, MODEL_SELECTION_AIC};
31/*****************************************************************************/
32
33/*****************************************************************************/
34static char *info[] = {
35 "Computation of parametric image of distribution volume (DV) from dynamic",
36 "PET image in ECAT, NIfTI, or Analyze format applying one- or two-tissue",
37 "compartmental model with arterial plasma input.",
38 "The compartmental models are transformed to general linear least squares",
39 "functions, which are solved using Lawson-Hanson non-negative least squares",
40 "(NNLS) algorithm (1). DV is estimated directly without division (2, 3, 4).",
41 "Vascular volume is ignored here.",
42 " ",
43 "Dynamic PET image and plasma time-activity curve (PTAC) must be corrected",
44 "for decay to the tracer injection time.",
45 " ",
46 "Usage: @P [Options] ptacfile imgfile dvfile",
47 " ",
48 "Options:",
49 " -1 | -2 | -A | -0",
50 " With options -1 and -2 the one- or two-tissue compartment model can be",
51 " forced for all image voxels; otherwise both models are fitted, and",
52 " with option -A the model is selected based on AIC separately for each",
53 " voxel; by default (or option -0) Akaike weighted average of the model",
54 " parameters (5, 6) are reported.",
55/* " -K1=<filename>",
56 " Programs computes also a K1 image.",
57*/
58 " -m=<filename>",
59 " Programs writes the selected model number (1 or 2, or value between",
60 " 1 and 2 as an image.",
61 " -thr=<threshold%>",
62 " Pixels with AUC less than (threshold/100 x PTAC AUC) are set to zero",
63 " default is 0%",
64 " -end=<Fit end time (min)>",
65 " Use data from 0 to end time; by default, model is fitted to all frames.",
66 " -max=<Max value>",
67 " Upper limit for DV values.",
68 " -stdoptions", // List standard options like --help, -v, etc
69 " ",
70 "The unit of voxel values in the DV image is (ml blood)/(ml tissue).",
71 " ",
72 "Example:",
73 " @P ua3818ap.kbq ua3818dy1.v ua3818dv.v",
74 " ",
75 "References:",
76 "1. Lawson CL & Hanson RJ. Solving least squares problems.",
77 " Prentice-Hall, 1974, ISBN 0-89871-356-0.",
78 "2. Zhou Y, Brasic J, Endres CJ, Kuwabara H, Kimes A, Contoreggi C, Maini A,",
79 " Ernst M, Wong DF. Binding potential image based statistical mapping for",
80 " detection of dopamine release by [11C]raclopride dynamic PET.",
81 " NeuroImage 2002;16(3):S91.",
82 "3. Zhou Y, Brasic JR, Ye W, Dogan AS, Hilton J, Singer HS, Wong DF.",
83 " Quantification of cerebral serotonin binding in normal controls and",
84 " subjects with Tourette's syndrome using [11C]MDL 100,907 and",
85 " (+)[11C]McN 5652 dynamic PET with parametric imaging approach.",
86 " NeuroImage 2004;22(Suppl 2):T98.",
87 "4. Hagelberg N, Aalto S, Kajander J, Oikonen V, Hinkka S, NĂ¥gren K,",
88 " Hietala J, Scheinin H. Alfentanil increases cortical dopamine D2/D3",
89 " receptor binding in healthy subjects. Pain 2004;109:86-93.",
90 "5. Turkheimer FE, Hinz R, Cunningham VJ. On the undecidability among",
91 " kinetic models: from model selection to model averaging. J Cereb Blood",
92 " Flow Metab 2003; 23: 490-498.",
93 "6. Sederholm K. Model averaging with Akaike weights. TPCMOD0016 2003-04-07.",
94 " https://www.turkupetcentre.net/reports/tpcmod0016.pdf",
95 " ",
96 "See also: imgdv, imgbfbp, imgratio, img2tif, logan",
97 " ",
98 "Keywords: image, modelling, distribution volume, Vt, NNLS",
99 0};
100/*****************************************************************************/
101
102/*****************************************************************************/
103/* Turn on the globbing of the command line, since it is disabled by default in
104 mingw-w64 (_dowildcard=0); in MinGW32 define _CRT_glob instead, if necessary;
105 In Unix&Linux wildcard command line processing is enabled by default. */
106/*
107#undef _CRT_glob
108#define _CRT_glob -1
109*/
110int _dowildcard = -1;
111/*****************************************************************************/
112
113/*****************************************************************************/
117int main(int argc, char **argv)
118{
119 int ai, help=0, version=0, verbose=1;
120 char *cptr;
121 char inpfile[FILENAME_MAX], petfile[FILENAME_MAX], dvfile[FILENAME_MAX];
122 char k1file[FILENAME_MAX], modfile[FILENAME_MAX];
123 float calcThreshold=0.0;
124 double upperLimit=-1.0;
125 double fittime=-1.0;
126 int model_selection=MODEL_SELECTION_WAIC;
127 int weight=0;
128 int ret;
129 char tmp[512];
130
131
132 /*
133 * Get arguments
134 */
135 if(argc==1) {tpcPrintUsage(argv[0], info, stderr); return(1);}
136 inpfile[0]=petfile[0]=dvfile[0]=k1file[0]=modfile[0]=(char)0;
137 /* Get options */
138 for(ai=1; ai<argc; ai++) if(*argv[ai]=='-') {
139 if(tpcProcessStdOptions(argv[ai], &help, &version, &verbose)==0) continue;
140 cptr=argv[ai]+1; if(*cptr=='-') cptr++; if(cptr==NULL) continue;
141 if(strcasecmp(cptr, "A")==0) {
142 model_selection=MODEL_SELECTION_AIC; continue;
143 } else if(*cptr=='1') {
144 model_selection=MODEL_SELECTION_1; continue;
145 } else if(*cptr=='2') {
146 model_selection=MODEL_SELECTION_2; continue;
147 } else if(*cptr=='0') {
148 model_selection=MODEL_SELECTION_WAIC; continue;
149 } else if(strncasecmp(cptr, "K1=", 3)==0) {
150 strlcpy(k1file, cptr+3, FILENAME_MAX); continue;
151 } else if(strncasecmp(cptr, "M=", 2)==0) {
152 strlcpy(modfile, cptr+2, FILENAME_MAX); continue;
153 } else if(strncasecmp(cptr, "THR=", 4)==0) {
154 double v; ret=atof_with_check(cptr+4, &v);
155 if(!ret && v>=0.0 && v<=200.0) {calcThreshold=(float)(0.01*v); continue;}
156 } else if(strncasecmp(cptr, "END=", 4)==0) {
157 fittime=atof_dpi(cptr+4); if(fittime>0.0) continue;
158 } else if(*cptr=='w' || *cptr=='W') {
159 weight=1; continue;
160 } else if(strncasecmp(cptr, "MAX=", 4)==0) {
161 upperLimit=atof_dpi(cptr+4); if(upperLimit>0.0) continue;
162 }
163 fprintf(stderr, "Error: invalid option '%s'.\n", argv[ai]);
164 return(1);
165 } else break;
166
167 /* Print help or version? */
168 if(help==2) {tpcHtmlUsage(argv[0], info, ""); return(0);}
169 if(help) {tpcPrintUsage(argv[0], info, stdout); return(0);}
170 if(version) {tpcPrintBuild(argv[0], stdout); return(0);}
171
172 /* Process other arguments, starting from the first non-option */
173 if(ai<argc) strlcpy(inpfile, argv[ai++], FILENAME_MAX);
174 if(ai<argc) strlcpy(petfile, argv[ai++], FILENAME_MAX);
175 if(ai<argc) strlcpy(dvfile, argv[ai++], FILENAME_MAX);
176 if(ai<argc) {fprintf(stderr, "Error: invalid argument '%s'.\n", argv[ai]); return(1);}
177 /* Did we get all the information that we need? */
178 if(!dvfile[0]) {
179 fprintf(stderr, "Error: missing command-line argument; use option --help\n");
180 return(1);
181 }
182 if(strcasecmp(petfile, dvfile)==0 || strcasecmp(petfile, k1file)==0 ||
183 strcasecmp(petfile, modfile)==0 || strcasecmp(inpfile, dvfile)==0)
184 {
185 fprintf(stderr, "Error: check the output filenames.\n");
186 return(1);
187 }
188 /* In verbose mode print arguments and options */
189 if(verbose>1) {
190 printf("inpfile := %s\n", inpfile);
191 printf("petfile := %s\n", petfile);
192 printf("dvfile := %s\n", dvfile);
193 if(k1file[0]) printf("k1file := %s\n", k1file);
194 printf("calcThreshold :=%g\n", calcThreshold);
195 if(upperLimit>0.0) printf("upperLimit := %g\n", upperLimit);
196 printf("weight := %d\n", weight);
197 if(fittime>0.0) printf("required_fittime := %g min\n", fittime);
198 printf("model_selection := %d\n", model_selection);
199 fflush(stdout);
200 }
201 if(verbose>8) IMG_TEST=verbose-8; else IMG_TEST=0;
202
203
204 /*
205 * Read PET image and input TAC
206 */
207 if(verbose>0) printf("reading data files\n");
208 DFT tac; dftInit(&tac);
209 IMG img; imgInit(&img);
210 int dataNr;
212 petfile, NULL, inpfile, NULL, NULL, &fittime, &dataNr, &img,
213 NULL, &tac, 1, stdout, verbose-2, tmp);
214 if(ret!=0) {
215 fprintf(stderr, "Error: %s.\n", tmp);
216 if(verbose>1) printf(" ret := %d\n", ret);
217 return(2);
218 }
219 if(imgNaNs(&img, 1)>0)
220 if(verbose>0) fprintf(stderr, "Warning: missing pixel values.\n");
221 /* Set time unit to min, also for integrals in y2[] */
222 if(tac.timeunit==TUNIT_SEC) {
223 for(int fi=0; fi<tac.frameNr; fi++) tac.voi[0].y2[fi]/=60.0;
224 for(int fi=0; fi<tac.frameNr; fi++) tac.voi[0].y3[fi]/=3600.0;
225 }
226 ret=dftTimeunitConversion(&tac, TUNIT_MIN);
227 if(verbose>1) {
228 printf("fittimeFinal := %g min\n", fittime);
229 printf("dataNr := %d\n", dataNr);
230 }
231 /* Check that image is dynamic */
232 if(dataNr<4) {
233 fprintf(stderr, "Error: too few time frames for fitting.\n");
234 if(verbose>0) imgInfo(&img);
235 imgEmpty(&img); dftEmpty(&tac); return(2);
236 }
237
238
239 /* Add place for tissue TACs too */
240 if(verbose>1) fprintf(stdout, "allocating working memory for pixel TACs\n");
241 ret=dftAddmem(&tac, 1);
242 if(ret) {
243 fprintf(stderr, "Error: cannot allocate memory.\n");
244 if(verbose>0) printf("ret := %d\n", ret);
245 imgEmpty(&img); dftEmpty(&tac); return(3);
246 }
247 strcpy(tac.voi[0].name, "input");
248 strcpy(tac.voi[1].name, "tissue");
249
250
251 /*
252 * Allocate result images, for DV, and for the selected model
253 */
254 if(verbose>1) fprintf(stdout, "allocating memory for parametric image data\n");
255 IMG dvimg; imgInit(&dvimg);
256 IMG mimg; imgInit(&mimg);
257 ret=imgAllocateWithHeader(&dvimg, img.dimz, img.dimy, img.dimx, 1, &img);
258 if(!ret) ret=imgAllocateWithHeader(&mimg, img.dimz, img.dimy, img.dimx, 1, &img);
259 if(ret) {
260 fprintf(stderr, "Error: cannot allocate memory for result image.\n");
261 imgEmpty(&img); dftEmpty(&tac); imgEmpty(&dvimg); imgEmpty(&mimg); return(4);
262 }
263 /* and set the more or less necessary things */
264 dvimg.start[0]=mimg.start[0]=0.0;
265 dvimg.end[0]=mimg.end[0]=60.*fittime;
266 dvimg.unit=CUNIT_ML_PER_ML; /* mL/mL */
267 mimg.unit=CUNIT_UNITLESS;
268
269
270 /*
271 * Allocate memory required by NNLS
272 */
273 if(verbose>1) fprintf(stdout, "allocating memory for NNLS\n");
274 int n, m, nnls_n, nnls_m, nnls_index[NNLS_N];
275 double *nnls_a[NNLS_N], *nnls_b, *nnls_zz, nnls_x[NNLS_N], *nnls_mat,
276 nnls_wp[NNLS_N], *dptr, nnls_rnorm;
277 nnls_n=NNLS_N; nnls_m=dataNr;
278 nnls_mat=(double*)malloc(((nnls_n+2)*nnls_m)*sizeof(double));
279 if(nnls_mat==NULL) {
280 fprintf(stderr, "Error: cannot allocate memory for NNLS.\n");
281 imgEmpty(&img); dftEmpty(&tac); imgEmpty(&dvimg); imgEmpty(&mimg);
282 return(4);
283 }
284 for(n=0, dptr=nnls_mat; n<nnls_n; n++) {nnls_a[n]=dptr; dptr+=nnls_m;}
285 nnls_b=dptr; dptr+=nnls_m; nnls_zz=dptr;
286
287 /* Copy weights if available */
288 /* or set them to frame lengths */
289 if(weight==1 && img.isWeight==0) {
290 for(m=0; m<nnls_m; m++) img.weight[m]=img.end[m]-img.start[m];
291 img.isWeight=1;
292 }
293 /* Compute weights for NNLS */
294 if(img.isWeight) {
295 for(m=0; m<nnls_m; m++) tac.w[m]=img.weight[m];
296 for(m=0; m<nnls_m; m++) {
297 if(tac.w[m]<=1.0e-20) tac.w[m]=0.0; else tac.w[m]=sqrt(tac.w[m]);
298 }
299 }
300
301
302 /*
303 * Compute pixel-by-pixel
304 */
305 /* Determine the threshold */
306 double threshold=calcThreshold*tac.voi[0].y2[dataNr-1];
307 if(verbose>1) printf("threshold_AUC := %g\n", threshold);
308 if(verbose>0) fprintf(stdout, "computing NNLS pixel-by-pixel\n");
309 double f, g;
310 double aic[MAX_MODEL_NR], w[MAX_MODEL_NR], ss[MAX_MODEL_NR], dv[MAX_MODEL_NR];
311 int cm2ok=0;
312 for(int pi=0; pi<img.dimz; pi++) {
313 if(verbose>1) printf("computing plane %d\n", img.planeNumber[pi]);
314 else if(verbose>0) fprintf(stdout, ".");
315 if(verbose>0) fflush(stdout);
316 for(int yi=0; yi<img.dimy; yi++) {
317 for(int xi=0; xi<img.dimx; xi++) {
318 /* Set pixel results to zero */
319 dvimg.m[pi][yi][xi][0]=0.0;
320 mimg.m[pi][yi][xi][0]=0.0;
321 /* Copy and integrate pixel curve */
322 for(int fi=0; fi<tac.frameNr; fi++)
323 tac.voi[1].y[fi]=img.m[pi][yi][xi][fi];
324 ret=petintegral(tac.x1, tac.x2, tac.voi[1].y, tac.frameNr, tac.voi[1].y2, tac.voi[1].y3);
325 if(ret) continue;
326 /* if AUC at the end is less than threshold value, then do nothing */
327 if(tac.voi[1].y2[dataNr-1]<threshold) continue;
328
329 /* Fit two-tissue model, if required */
330 if(model_selection==MODEL_SELECTION_AIC ||
331 model_selection==MODEL_SELECTION_2 ||
332 model_selection==MODEL_SELECTION_WAIC)
333 {
334 nnls_n=4;
335 /* Fill the NNLS data matrix */
336 for(m=0; m<nnls_m; m++) {
337 nnls_a[0][m]=tac.voi[0].y3[m];
338 nnls_a[1][m]=-tac.voi[1].y2[m];
339 nnls_a[2][m]=tac.voi[0].y2[m];
340 nnls_a[3][m]=-tac.voi[1].y[m];
341 nnls_b[m]=tac.voi[1].y3[m];
342 }
343 if(img.isWeight) {
344 for(m=0; m<nnls_m; m++) {
345 nnls_b[m]*=tac.w[m];
346 for(n=0; n<nnls_n; n++) nnls_a[n][m]*=tac.w[m];
347 }
348 }
349 /* NNLS */
350 ret=nnls(nnls_a, nnls_m, nnls_n, nnls_b, nnls_x, &nnls_rnorm,
351 nnls_wp, nnls_zz, nnls_index);
352 if(ret>1) { /* no solution is possible */
353 for(n=0; n<nnls_n; n++) nnls_x[n]=0.0;
354 nnls_rnorm=0.0;
355 } else if(ret==1) { /* max iteration count exceeded */ }
356 /* Get DV as the 1st linear coefficient */
357 dv[1]=nnls_x[0];
358 /* Calculate Sum-of-Squares */
359 for(m=0; m<nnls_m; m++) {
360 nnls_a[0][m]=tac.voi[0].y3[m];
361 nnls_a[1][m]=-tac.voi[1].y2[m];
362 nnls_a[2][m]=tac.voi[0].y2[m];
363 nnls_a[3][m]=-tac.voi[1].y[m];
364 nnls_b[m]=tac.voi[1].y3[m];
365 }
366 if(img.isWeight) {
367 for(m=0; m<nnls_m; m++) {
368 nnls_b[m]*=tac.w[m];
369 for(n=0; n<nnls_n; n++) nnls_a[n][m]*=tac.w[m];
370 }
371 }
372 for(m=0, ss[1]=0.0; m<nnls_m; m++) {
373 for(n=0, f=0.0; n<nnls_n; n++) f+=nnls_x[n]*nnls_a[n][m];
374 g=f; f-=nnls_b[m]; ss[1]+=f*f;
375 if(verbose>17 && pi==img.dimz/2 && yi==img.dimy/3 && xi==img.dimx/3)
376 printf("%10.3f : %e %e - %e = %g\n",
377 tac.x[m], tac.voi[1].y[m], tac.voi[1].y3[m], g, f);
378 }
379 /* Calculate AIC */
380 aic[1]=aicSS(ss[1], nnls_m, nnls_n);
381 if(verbose>15 && pi==img.dimz/2 && yi==img.dimy/3 && xi==img.dimx/3) {
382 for(n=0; n<nnls_n; n++) printf(" p[%d]=%g", n, nnls_x[n]);
383 printf(" -> SS=%g AIC=%g\n", ss[1], aic[1]);
384 }
385 /* Compute how many of the parameters are not zeros */
386 for(n=0, m=nnls_n; n<nnls_n; n++) if(nnls_x[n]<1.0e-10) m--;
387 /* Check if results were ok */
388 if(m==nnls_n) cm2ok=1; else cm2ok=0;
389 } /* done with two-tissue model */
390
391 /* Fit one-tissue model, if required */
392 if(model_selection==MODEL_SELECTION_AIC ||
393 model_selection==MODEL_SELECTION_1 ||
394 model_selection==MODEL_SELECTION_WAIC)
395 {
396 nnls_n=2;
397 /* Fill the NNLS data matrix */
398 for(m=0; m<nnls_m; m++) {
399 nnls_a[0][m]=tac.voi[0].y3[m];
400 nnls_a[1][m]=-tac.voi[1].y2[m];
401 nnls_b[m]=tac.voi[1].y3[m];
402 }
403 if(img.isWeight) {
404 for(m=0; m<nnls_m; m++) {
405 nnls_b[m]*=tac.w[m];
406 for(n=0; n<nnls_n; n++) nnls_a[n][m]*=tac.w[m];
407 }
408 }
409 /* NNLS */
410 ret=nnls(nnls_a, nnls_m, nnls_n, nnls_b, nnls_x, &nnls_rnorm,
411 nnls_wp, nnls_zz, nnls_index);
412 if(ret>1) { /* no solution is possible */
413 for(n=0; n<nnls_n; n++) nnls_x[n]=0.0;
414 nnls_rnorm=0.0;
415 } else if(ret==1) { /* max iteration count exceeded */ }
416 /* Get DV as the 1st linear coefficient */
417 dv[0]=nnls_x[0];
418 /* Calculate Sum-of-Squares */
419 for(m=0; m<nnls_m; m++) {
420 nnls_a[0][m]=tac.voi[0].y3[m];
421 nnls_a[1][m]=-tac.voi[1].y2[m];
422 nnls_b[m]=tac.voi[1].y3[m];
423 }
424 if(img.isWeight) {
425 for(m=0; m<nnls_m; m++) {
426 nnls_b[m]*=tac.w[m];
427 for(n=0; n<nnls_n; n++) nnls_a[n][m]*=tac.w[m];
428 }
429 }
430 for(m=0, ss[0]=0.0; m<nnls_m; m++) {
431 for(n=0, f=0.0; n<nnls_n; n++) f+=nnls_x[n]*nnls_a[n][m];
432 g=f; f-=nnls_b[m]; ss[0]+=f*f;
433 if(verbose>17 && pi==img.dimz/2 && yi==img.dimy/3 && xi==img.dimx/3)
434 printf("%10.3f : %e %e - %e = %g\n",
435 tac.x[m], tac.voi[1].y[m], tac.voi[1].y3[m], g, f);
436 }
437 /* Calculate AIC */
438 aic[0]=aicSS(ss[0], nnls_m, nnls_n);
439 if(verbose>15 && pi==img.dimz/2 && yi==img.dimy/3 && xi==img.dimx/3) {
440 for(n=0; n<nnls_n; n++) printf(" p[%d]=%g", n, nnls_x[n]);
441 printf(" -> SS=%g AIC=%g\n", ss[0], aic[0]);
442 }
443 } /* done with one-tissue model */
444
445 /* Select the model, or calculate average */
446 switch(model_selection) {
447 case MODEL_SELECTION_WAIC:
448 ret=aicWeights(aic, w, 2);
449 if(verbose>14 && pi==img.dimz/2 && yi==img.dimy/3 && xi==img.dimx/3)
450 printf(" Model weights are %g %g\n", w[0], w[1]);
451 /* Compute weighted DV and other 'parameters' */
452 dvimg.m[pi][yi][xi][0]=aicWeightedAvg(w, dv, 2);
453 mimg.m[pi][yi][xi][0]=(float)(1.0*w[0]+2.0*w[1]);
454 if(verbose>13 && pi==img.dimz/2 && yi==img.dimy/3 && xi==img.dimx/3)
455 printf(" DV1=%g DV2=%g -> Weighted DV=%g\n", dv[0], dv[1], dvimg.m[pi][yi][xi][0]);
456 break;
457 case MODEL_SELECTION_1:
458 dvimg.m[pi][yi][xi][0]=dv[0];
459 mimg.m[pi][yi][xi][0]=(float)1.0;
460 break;
461 case MODEL_SELECTION_2:
462 dvimg.m[pi][yi][xi][0]=dv[1];
463 mimg.m[pi][yi][xi][0]=(float)2.0;
464 break;
465 case MODEL_SELECTION_AIC:
466 if(cm2ok && aic[1]<aic[0]) {
467 dvimg.m[pi][yi][xi][0]=dv[1];
468 mimg.m[pi][yi][xi][0]=2.0;
469 } else {
470 dvimg.m[pi][yi][xi][0]=dv[0];
471 mimg.m[pi][yi][xi][0]=1.0;
472 }
473 break;
474 }
475
476 } /* next column */
477 } /* next row */
478 } /* next plane */
479 if(verbose>0) fprintf(stdout, " done.\n");
480 /* No need for NNLS data anymore */
481 free(nnls_mat);
482 /* No need for dynamic image or input data anymore */
483 imgEmpty(&img);
484 dftEmpty(&tac);
485
486
487 /*
488 * Filter the parametric images if required
489 */
490 /* Remove values that are higher than the user-defined limit */
491 if(upperLimit>0.0) {
492 if(verbose>0) fprintf(stdout, "filtering out pixel values exceeding %g\n", upperLimit);
493 imgCutoff(&dvimg, (float)upperLimit, 0);
494 }
495
496
497 /*
498 * Save parametric image
499 */
500 ret=backupExistingFile(dvfile, NULL, tmp); if(ret!=0) {
501 fprintf(stderr, "Error: %s\n", tmp);
502 imgEmpty(&dvimg); imgEmpty(&mimg);
503 return(11);
504 }
505 if(verbose>1) printf("%s\n", tmp);
506 ret=imgWrite(dvfile, &dvimg);
507 if(ret) {
508 fprintf(stderr, "Error: %s\n", dvimg.statmsg);
509 imgEmpty(&dvimg); imgEmpty(&mimg);
510 return(11);
511 }
512 if(verbose>0) fprintf(stdout, "DV image %s saved.\n", dvfile);
513
514 /*
515 * Save selected model as image, if requested
516 */
517 if(modfile[0]) {
518 ret=backupExistingFile(modfile, NULL, tmp); if(ret!=0) {
519 fprintf(stderr, "Error: %s\n", tmp);
520 imgEmpty(&dvimg); imgEmpty(&mimg);
521 return(13);
522 }
523 if(verbose>1) printf("%s\n", tmp);
524 ret=imgWrite(modfile, &mimg);
525 if(ret) {
526 fprintf(stderr, "Error: %s\n", mimg.statmsg);
527 imgEmpty(&dvimg); imgEmpty(&mimg);
528 return(13);
529 }
530 if(verbose>0) fprintf(stdout, "Model selection image %s saved.\n", modfile);
531 }
532
533
534 imgEmpty(&dvimg); imgEmpty(&mimg);
535
536 return(0);
537}
538/*****************************************************************************/
539
540/*****************************************************************************/
double aicWeightedAvg(double *w, double *p, int n)
Definition aic.c:108
int aicWeights(double *aic, double *w, int n)
Definition aic.c:74
double aicSS(double ss, const int n, const int k)
Definition aic.c:20
int backupExistingFile(char *filename, char *backup_ext, char *status)
Definition backup.c:14
int atof_with_check(char *double_as_string, double *result_value)
Definition decpoint.c:107
double atof_dpi(char *str)
Definition decpoint.c:59
void dftInit(DFT *data)
Definition dft.c:38
int dftAddmem(DFT *dft, int voiNr)
Definition dft.c:107
void dftEmpty(DFT *data)
Definition dft.c:20
int dftTimeunitConversion(DFT *dft, int tunit)
Definition dftunit.c:119
int IMG_TEST
Definition img.c:6
void imgInfo(IMG *image)
Definition img.c:359
unsigned long long imgNaNs(IMG *img, int fix)
Definition img.c:658
int imgAllocateWithHeader(IMG *image, int planes, int rows, int columns, int frames, IMG *image_from)
Definition img.c:279
void imgEmpty(IMG *image)
Definition img.c:121
void imgInit(IMG *image)
Definition img.c:60
int imgWrite(const char *fname, IMG *img)
Definition imgfile.c:136
int imgReadModelingData(char *petfile, char *siffile, char *inputfile1, char *inputfile2, char *inputfile3, double *fitdur, int *fitframeNr, IMG *img, DFT *inp, DFT *iinp, int verifypeak, FILE *loginfo, int verbose, char *status)
Definition imginput.c:24
void imgCutoff(IMG *image, float cutoff, int mode)
int petintegral(double *x1, double *x2, double *y, int nr, double *ie, double *iie)
Integrate PET TAC data to frame mid times.
Definition integr.c:771
Header file for libtpccurveio.
Header file for libtpcimgio.
Header file for libtpcimgp.
Header file for libtpcmisc.
int tpcProcessStdOptions(const char *s, int *print_usage, int *print_version, int *verbose_level)
Definition proginfo.c:40
size_t strlcpy(char *dst, const char *src, size_t dstsize)
Definition strext.c:245
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.
int nnls(double **a, int m, int n, double *b, double *x, double *rnorm, double *w, double *zz, int *index)
Definition nnls.c:37
Header file for libtpcmodext.
Voi * voi
int timeunit
double * w
double * x1
double * x2
int frameNr
double * x
unsigned short int dimx
float **** m
char unit
int * planeNumber
float * weight
float * start
unsigned short int dimz
unsigned short int dimy
float * end
const char * statmsg
char isWeight
double * y2
double * y
char name[MAX_REGIONNAME_LEN+1]
double * y3