TPCCLIB
Loading...
Searching...
No Matches
imgdelay.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 "tpccsv.h"
18#include "tpctac.h"
19#include "tpcimage.h"
20#include "tpcli.h"
21#include "tpclinopt.h"
22#include "tpctacmod.h"
23#include "tpctacimg.h"
24/*****************************************************************************/
25
26/*****************************************************************************/
27static char *info[] = {
28 "Make a map of time delay between dynamic PET image and BTAC.",
29 "Reversible one-tissue compartment model with blood volume is applied.",
30 "Positive delay time means that tissue curve is delayed as compared to",
31 "the input curve, and vice versa. Thus, input curve needs to be moved",
32 "by the delay time to match the tissue curve.",
33 " ",
34 "Currently only NIfTI format is supported.",
35 " ",
36 "Usage: @P [options] imgfile btacfile delaymap",
37 " ",
38 "Options:",
39 " -min=<Time (sec)> and -max=<Time (sec)>",
40 " The range of time delays to be tested; by default -10 - +50 s.",
41 " Large range will increase computation time.",
42 " -end=<Fit end time (sec)>",
43 " Use data from 0 to end time; by default, 300 s. End time may need to",
44 " be reduced so that BTAC with negative delay extends to end time.",
45 " -thr=<threshold%>",
46 " Pixels with AUC less than (threshold/100 x BTAC AUC) are set to zero.",
47 " Default is 1%.",
48 " -Vb=<filename>",
49 " Vb map is saved in units mL blood/mL PET volume.",
50 " -K1=<filename>",
51 " K1 map is saved in units mL blood/(min*mL PET volume).",
52 " -k2=<filename>",
53 " Map of k2 is saved in units 1/min.",
54 " -stdoptions", // List standard options like --help, -v, etc
55 " ",
56 "See also: fitdelay, tactime",
57 " ",
58 "Keywords: image, time delay",
59 0};
60/*****************************************************************************/
61
62/*****************************************************************************/
63/* Turn on the globbing of the command line, since it is disabled by default in
64 mingw-w64 (_dowildcard=0); in MinGW32 define _CRT_glob instead, if necessary;
65 In Unix&Linux wildcard command line processing is enabled by default. */
66/*
67#undef _CRT_glob
68#define _CRT_glob -1
69*/
70int _dowildcard = -1;
71/*****************************************************************************/
72
73/*****************************************************************************/
77int main(int argc, char **argv)
78{
79 int ai, help=0, version=0, verbose=1;
80 int ret;
81 char imgfile[FILENAME_MAX], btacfile[FILENAME_MAX], mapfile[FILENAME_MAX];
82 char vbfile[FILENAME_MAX], k1file[FILENAME_MAX], k2file[FILENAME_MAX];
83 double endtime=300.0; // fit end time in seconds
84 double endtimemin=120.0; // shortest fit end time allowed
85 int drange[2]={-10,+50};
86 float calcThreshold=0.01;
87
88
89 /*
90 * Get arguments
91 */
92 if(argc==1) {tpcPrintUsage(argv[0], info, stderr); return(1);}
93 imgfile[0]=btacfile[0]=mapfile[0]=vbfile[0]=k1file[0]=k2file[0]=(char)0;
94 /* Options */
95 for(ai=1; ai<argc; ai++) if(*argv[ai]=='-') {
96 if(tpcProcessStdOptions(argv[ai], &help, &version, &verbose)==0) continue;
97 char *cptr=argv[ai]+1; if(*cptr=='-') cptr++; if(!*cptr) continue;
98 if(strncasecmp(cptr, "END=", 4)==0) {
99 ret=atofCheck(cptr+4, &endtime); if(!ret && endtime>0.0) continue;
100 } else if(strncasecmp(cptr, "MIN=", 4)==0) {
101 if(atoiCheck(cptr+4, &drange[0])==0) continue;
102 } else if(strncasecmp(cptr, "MAX=", 4)==0) {
103 if(atoiCheck(cptr+4, &drange[1])==0) continue;
104 } else if(strncasecmp(cptr, "THR=", 4)==0) {
105 double v; ret=atofCheck(cptr+4, &v);
106 if(!ret && v<100.0) {calcThreshold=(float)(0.01*v); continue;}
107 } else if(strncasecmp(cptr, "K1=", 3)==0) {
108 strlcpy(k1file, cptr+3, FILENAME_MAX); if(strlen(k1file)) continue;
109 } else if(strncasecmp(cptr, "K2=", 3)==0) {
110 strlcpy(k2file, cptr+3, FILENAME_MAX); if(strlen(k2file)) continue;
111 } else if(strncasecmp(cptr, "VB=", 3)==0) {
112 strlcpy(vbfile, cptr+3, FILENAME_MAX); if(strlen(vbfile)) continue;
113 }
114 fprintf(stderr, "Error: invalid option '%s'.\n", argv[ai]);
115 return(1);
116 } else break;
117
118 /* Print help or version? */
119 if(help==2) {tpcHtmlUsage(argv[0], info, ""); return(0);}
120 if(help) {tpcPrintUsage(argv[0], info, stdout); return(0);}
121 if(version) {tpcPrintBuild(argv[0], stdout); return(0);}
122
123 /* Process other arguments, starting from the first non-option */
124 if(ai<argc) strlcpy(imgfile, argv[ai++], FILENAME_MAX);
125 if(ai<argc) strlcpy(btacfile, argv[ai++], FILENAME_MAX);
126 if(ai<argc) strlcpy(mapfile, argv[ai++], FILENAME_MAX);
127 if(ai<argc) {fprintf(stderr, "Error: too many arguments: '%s'.\n", argv[ai]); return(1);}
128 /* Is something missing? */
129 if(!mapfile[0]) {tpcPrintUsage(argv[0], info, stdout); return(1);}
130
131 /* Check options */
132 if(endtime<endtimemin) {
133 fprintf(stderr, "Error: too short fit time set with option -end.\n");
134 return(1);
135 }
136 if(drange[0]>drange[1]) {int i=drange[0]; drange[0]=drange[1]; drange[1]=i;}
137 if((drange[1]-drange[0])>180) {
138 fprintf(stderr, "Error: too wide delay range.\n");
139 return(1);
140 } else if((drange[1]-drange[0])>120) {
141 fprintf(stderr, "Warning: large delay range.\n");
142 } else if((drange[1]-drange[0])<4) {
143 fprintf(stderr, "Error: too short delay range.\n");
144 return(1);
145 }
146
147 /* In verbose mode print arguments and options */
148 if(verbose>1) {
149 printf("imgfile := %s\n", imgfile);
150 printf("btacfile := %s\n", btacfile);
151 printf("mapfile := %s\n", mapfile);
152 printf("endtime := %g s\n", endtime);
153 printf("delay_range := %d - %d s\n", drange[0], drange[1]);
154 printf("threshold := %g\n", calcThreshold);
155 if(vbfile[0]) printf("vbfile := %s\n", vbfile);
156 if(k1file[0]) printf("k1file := %s\n", k1file);
157 if(k2file[0]) printf("k2file := %s\n", k2file);
158 fflush(stdout);
159 }
160
161 TPCSTATUS status; statusInit(&status);
162 statusSet(&status, __func__, __FILE__, __LINE__, TPCERROR_OK);
163 status.verbose=verbose-1;
164
165
166 /*
167 * Read BTAC
168 */
169 if(verbose>1) printf("reading %s\n", btacfile);
170 TAC tac; tacInit(&tac);
171 ret=tacRead(&tac, btacfile, &status);
172 if(ret!=TPCERROR_OK) {
173 fprintf(stderr, "Error: %s (%s)\n", errorMsg(status.error), btacfile);
174 tacFree(&tac); return(2);
175 }
176 if(verbose>2) {
177 printf("fileformat := %s\n", tacFormattxt(tac.format));
178 printf("tacNr := %d\n", tac.tacNr);
179 printf("sampleNr := %d\n", tac.sampleNr);
180 printf("xunit := %s\n", unitName(tac.tunit));
181 printf("yunit := %s\n", unitName(tac.cunit));
182 printf("isframe := %d\n", tac.isframe);
183 fflush(stdout);
184 }
185 /* Make sure that frame mid times are set */
186 tacSetX(&tac, NULL);
187
188
189 /*
190 * Read image data
191 */
192 if(verbose>1) {printf("reading %s\n", imgfile); fflush(stdout);}
193 IMG img; imgInit(&img);
194 ret=imgRead(&img, imgfile, &status);
195 if(ret!=TPCERROR_OK) { // error
196 tacFree(&tac); imgFree(&img);
197 fprintf(stderr, "Error: %s (%s)\n", errorMsg(status.error), imgfile); fflush(stderr);
198 return(2);
199 }
200 if(imgNaNs(&img, 1)>0)
201 if(verbose>0) fprintf(stderr, "Warning: missing pixel values.\n");
202 if(verbose>2) imgContents(&img, stdout);
203 double ixmin, ixmax;
204 if(imgXRange(&img, &ixmin, &ixmax)!=TPCERROR_OK) {
205 fprintf(stderr, "Error: invalid sample times in %s\n", imgfile); fflush(stderr);
206 tacFree(&tac); imgFree(&img); return(2);
207 }
208 if(verbose>1) printf("Image range: %g - %g\n", ixmin, ixmax);
209 /* Refine fit end time */
210 if(ixmax<endtimemin) {
211 fprintf(stderr, "Error: image time range is too short.\n");
212 tacFree(&tac); imgFree(&img); return(2);
213 }
214 if(ixmax<endtime) endtime=ixmax;
215
216 /* If BTAC has no frame start and end times, check if those can be obtained from image */
217 if(tacimgXMatch(&tac, &img)) tacimgXCopy(&tac, &img);
218
219 /* Convert BTAC time units to same as in the image */
220 if(tac.tunit==UNIT_UNKNOWN) {
221 if(verbose>0) fprintf(stderr, "Warning: missing BTAC time units.\n");
222 double bxmin, bxmax;
223 if(tacXRange(&tac, &bxmin, &bxmax)!=TPCERROR_OK) {
224 fprintf(stderr, "Error: invalid sample times in %s\n", btacfile); fflush(stderr);
225 tacFree(&tac); imgFree(&img); return(2);
226 }
227 unit guessedUnit=img.tunit;
228 if(img.tunit==UNIT_SEC && bxmax<0.2*ixmax) guessedUnit=UNIT_MIN;
229 if(img.tunit==UNIT_MIN && bxmax>20.*ixmax) guessedUnit=UNIT_SEC;
230 fprintf(stderr, "Warning: assuming BTAC sample times are in units %s.\n", unitName(guessedUnit));
231 tac.tunit=guessedUnit;
232 }
233 if(tacXUnitConvert(&tac, img.tunit, &status)!=TPCERROR_OK) {
234 fprintf(stderr, "Error: %s (%s)\n", errorMsg(status.error), btacfile); fflush(stderr);
235 tacFree(&tac); imgFree(&img); return(2);
236 }
237 double bxmin, bxmax;
238 if(tacXRange(&tac, &bxmin, &bxmax)!=TPCERROR_OK) {
239 fprintf(stderr, "Error: invalid sample times in %s\n", btacfile); fflush(stderr);
240 tacFree(&tac); imgFree(&img); return(2);
241 }
242 if(verbose>1) printf("BTAC range: %g - %g\n", bxmin, bxmax);
243
244
245 /*
246 * Check time ranges
247 */
248 if(verbose>1) {printf("checking time range\n"); fflush(stdout);}
249 ret=0;
250 if(tac.sampleNr<5) {fprintf(stderr, "Error: BTAC has too few samples.\n"); ret++;}
251 if(img.dimt<5) {fprintf(stderr, "Error: image has too few frames.\n"); ret++;}
252 if(bxmax<endtimemin) {fprintf(stderr, "Error: BTAC time range is too short.\n"); ret++;}
253 if(ixmax<endtimemin) {fprintf(stderr, "Error: image time range is too short.\n"); ret++;}
254 if(drange[0]<0 && bxmax<(endtime+drange[0])) {
255 endtime+=drange[0];
256 if(endtime<endtimemin) {
257 fprintf(stderr, "Error: BTAC does not extend to required end time.\n"); ret++;}
258 }
259 int frameNr=0;
260 for(int i=0; i<img.dimt; i++) if(img.x[i]<=endtime) frameNr++;
261 if(frameNr<5) {fprintf(stderr, "Error: image has too few frames in fit time range.\n"); ret++;}
262 if(ret>0) {tacFree(&tac); imgFree(&img); return(2);}
263
264 /* Calculate threshold value */
265 double thrs=tacAUC(&tac, 0, 0.0, img.x[frameNr-1], NULL);
266 thrs*=calcThreshold;
267
268 /*
269 * Make BTACs moved in time, interpolated and integrated to image frames
270 */
271 if(verbose>1) {printf("moving BTAC\n"); fflush(stdout);}
272 int moveNr=1+(drange[1]-drange[0]);
273 if(verbose>2) printf("frameNr := %d\nmoveNr := %d\n", frameNr, moveNr);
274 TAC dtac; tacInit(&dtac); // Delayed BTACs at PET frames
275 if(tacAllocate(&dtac, frameNr, moveNr)!=TPCERROR_OK) {
276 fprintf(stderr, "Error: cannot allocate memory.\n"); fflush(stderr);
277 tacFree(&tac); imgFree(&img); return(3);
278 }
279 dtac.sampleNr=frameNr;
280 dtac.tacNr=moveNr;
281 dtac.isframe=1;
282 for(int i=0; i<dtac.sampleNr; i++) { // x1 and x2 values are needed later when integrating pixel TAC
283 dtac.x1[i]=img.x1[i]; dtac.x[i]=img.x[i]; dtac.x2[i]=img.x2[i];}
284 TAC ditac; tacInit(&ditac); // Delayed integrated BTACs at PET frames
285 if(tacDuplicate(&dtac, &ditac)!=TPCERROR_OK) {
286 fprintf(stderr, "Error: cannot allocate memory.\n"); fflush(stderr);
287 tacFree(&tac); imgFree(&img); tacFree(&dtac); return(3);
288 }
289 ret=0;
290 if(verbose>1) {printf("integrating moved BTACs\n"); fflush(stdout);}
291 for(int di=0; di<dtac.tacNr; di++) {
292 if(di==0) for(int i=0; i<tac.sampleNr; i++) tac.x[i]+=drange[0]; // do NOT modify x1 or x2
293 else for(int i=0; i<tac.sampleNr; i++) tac.x[i]+=1.0;
294 ret=liInterpolateForPET(tac.x, tac.c[0].y, tac.sampleNr, dtac.x1, dtac.x2,
295 dtac.c[di].y, ditac.c[di].y, NULL, dtac.sampleNr, 3, 1, 0);
296 if(ret) break;
297 }
298 if(ret) {
299 fprintf(stderr, "Error: cannot interpolate delayed BTACs.\n"); fflush(stderr);
300 tacFree(&tac); imgFree(&img); tacFree(&dtac); tacFree(&ditac); return(3);
301 }
302 if(verbose>3) {
303 char *dtacfile="delayed_btacs.dat";
304 printf("writing %s\n", dtacfile);
305 FILE *fp; fp=fopen(dtacfile, "w");
306 if(fp!=NULL) {
307 tacWrite(&dtac, fp, TAC_FORMAT_PMOD, 1, &status);
308 fclose(fp);
309 }
310 char *ditacfile="delayed_btac_integrals.dat";
311 printf("writing %s\n", ditacfile);
312 fp=fopen(ditacfile, "w");
313 if(fp!=NULL) {
314 tacWrite(&ditac, fp, TAC_FORMAT_PMOD, 1, &status);
315 fclose(fp);
316 }
317 }
318
319
320 /*
321 * Allocate memory for delay map
322 */
323 if(verbose>1) {printf("preparing delay map\n"); fflush(stdout);}
324 IMG map; imgInit(&map);
325 if(imgAllocate(&map, img.dimz, img.dimy, img.dimx, 1, &status)!=TPCERROR_OK) {
326 fprintf(stderr, "Error: cannot allocate memory\n"); fflush(stderr);
327 tacFree(&tac); imgFree(&img); tacFree(&dtac); tacFree(&ditac); return(4);
328 }
329 imgCopyHeader(&img, &map);
330 map.cunit=UNIT_SEC;
331
332 /* Allocate memory for Vb and/or K1 images, if requested */
333 IMG vbimg; imgInit(&vbimg);
334 if(vbfile[0]) {
335 if(imgAllocate(&vbimg, map.dimz, map.dimy, map.dimx, 1, &status)!=TPCERROR_OK) {
336 fprintf(stderr, "Error: cannot allocate memory\n"); fflush(stderr);
337 tacFree(&tac); imgFree(&img); tacFree(&dtac); tacFree(&ditac); imgFree(&map); return(4);
338 }
339 imgCopyHeader(&map, &vbimg);
340 vbimg.cunit=UNIT_ML_PER_ML;
341 }
342 IMG k1img; imgInit(&k1img);
343 if(k1file[0]) {
344 if(imgAllocate(&k1img, map.dimz, map.dimy, map.dimx, 1, &status)!=TPCERROR_OK) {
345 fprintf(stderr, "Error: cannot allocate memory\n"); fflush(stderr);
346 tacFree(&tac); imgFree(&img); tacFree(&dtac); tacFree(&ditac); imgFree(&map);
347 imgFree(&vbimg); return(4);
348 }
349 imgCopyHeader(&map, &k1img);
351 }
352 IMG k2img; imgInit(&k2img);
353 if(k2file[0]) {
354 if(imgAllocate(&k2img, map.dimz, map.dimy, map.dimx, 1, &status)!=TPCERROR_OK) {
355 fprintf(stderr, "Error: cannot allocate memory\n"); fflush(stderr);
356 tacFree(&tac); imgFree(&img); tacFree(&dtac); tacFree(&ditac); imgFree(&map);
357 imgFree(&vbimg); imgFree(&k1img); return(4);
358 }
359 imgCopyHeader(&map, &k2img);
360 k2img.cunit=UNIT_PER_MIN;
361 }
362
363
364 /* Allocate matrices for NNLS */
365 if(verbose>1) {printf("allocating memory for NNLS matrices\n"); fflush(stdout);}
366 int llsq_m=dtac.sampleNr;
367 int llsq_n=3;
368 double *llsq_mat=(double*)malloc((llsq_n*llsq_m)*sizeof(double));
369 if(llsq_mat==NULL) {
370 fprintf(stderr, "Error: cannot allocate memory for NNLS.\n");
371 tacFree(&tac); imgFree(&img); tacFree(&dtac); tacFree(&ditac); imgFree(&map);
372 imgFree(&vbimg); imgFree(&k1img); imgFree(&k2img); return(5);
373 }
374 double **llsq_a=(double**)malloc(llsq_n*sizeof(double*));
375 if(llsq_a==NULL) {
376 tacFree(&tac); imgFree(&img); tacFree(&dtac); tacFree(&ditac); imgFree(&map); free(llsq_mat);
377 imgFree(&vbimg); imgFree(&k1img); imgFree(&k2img); return(5);
378 }
379 for(int ni=0; ni<llsq_n; ni++) llsq_a[ni]=llsq_mat+ni*llsq_m;
380 double r2, llsq_b[llsq_m], llsq_x[llsq_n], llsq_wp[llsq_n], llsq_zz[llsq_m];
381 int indexp[llsq_n];
382
383
384 /*
385 * Pixel-by-pixel
386 */
387 long long pxlNr=img.dimx*img.dimy*img.dimz;
388 if(verbose>0) {printf("processing %llu image pixels\n", pxlNr); fflush(stdout);}
389 for(int zi=0; zi<img.dimz; zi++) {
390 if(img.dimz>2 && verbose>0) {fprintf(stdout, "."); fflush(stdout);}
391 for(int yi=0; yi<img.dimy; yi++) for(int xi=0; xi<img.dimx; xi++) {
392 map.m[zi][yi][xi][0]=0.0;
393 if(vbfile[0]) vbimg.m[zi][yi][xi][0]=0.0;
394 if(k1file[0]) k1img.m[zi][yi][xi][0]=0.0;
395 double ttac[llsq_m], ittac[llsq_m];
396 for(int mi=0; mi<llsq_m; mi++) ttac[mi]=img.m[zi][yi][xi][mi];
397 if(liIntegratePET(dtac.x1, dtac.x2, ttac, llsq_m, ittac, NULL, 0)!=0) continue;
398 if(ittac[llsq_m-1]<thrs) continue;
399 int diBest=-1;
400 double r2Best=1.0E+100;
401 double vbBest=0.0, k1Best=0.0, k2Best=0.0;
402 for(int di=0; di<dtac.tacNr; di++) {
403 dtac.c[di].size=1.0E+100; // save r2 in here
404 /* Setup data matrix A and vector B */
405 for(int mi=0; mi<llsq_m; mi++)
406 llsq_b[mi]=img.m[zi][yi][xi][mi]; // TTAC
407 for(int mi=0; mi<llsq_m; mi++) {
408 llsq_mat[mi]=dtac.c[di].y[mi]; // BTAC
409 llsq_mat[mi+llsq_m]=ditac.c[di].y[mi]; // BTAC integral
410 llsq_mat[mi+2*llsq_m]=-ittac[mi]; // TTAC integral
411 }
412#if(0)
413 printf("\nmatrix %d\n", 1+di);
414 for(int mi=0; mi<llsq_m; mi++) printf("%g %g %g %g\n",
415 llsq_b[mi], llsq_mat[mi], llsq_mat[mi+llsq_m], llsq_mat[mi+2*llsq_m]);
416#endif
417 /* Compute NNLS */
418 int ret=nnls(llsq_a, llsq_m, llsq_n, llsq_b, llsq_x, &r2, llsq_wp, llsq_zz, indexp);
419 if(ret>1) continue;
420 dtac.c[di].size=r2; // save r2 in here
421 if(r2<r2Best) {
422 r2Best=r2; diBest=di;
423 vbBest=llsq_x[0];
424 k1Best=llsq_x[1]-llsq_x[0]*llsq_x[2];
425 k2Best=llsq_x[2];
426 }
427 } // next delay
428 if(diBest<0) continue; // not successful, let delay be zero
429 //printf("best r2 := %g\n", dtac.c[diBest].size);
430 map.m[zi][yi][xi][0]=(float)(drange[0]+diBest);
431 if(vbfile[0]) {
432 if(vbBest>1.0) vbBest=1.0;
433 vbimg.m[zi][yi][xi][0]=(float)vbBest;
434 }
435 if(k1file[0]) {
436 k1Best*=60.0; // convert to per min
437 if(k1Best>6.0) k1Best=6.0; else if(k1Best<0.0) k1Best=0.0;
438 k1img.m[zi][yi][xi][0]=(float)k1Best;
439 }
440 if(k2file[0]) {
441 k2Best*=60.0; // convert to per min
442 if(k2Best>10.0) k2Best=10.0;
443 k2img.m[zi][yi][xi][0]=(float)k2Best;
444 }
445#if(0)
446 /* Try to refine delay with r2 weighted average with adjacent delays */
447 if(diBest==0 || diBest==dtac.tacNr-1) continue;
448 float w1=1.0/(1.0E-12+dtac.c[diBest-1].size);
449 float w2=1.0/(1.0E-12+dtac.c[diBest].size);
450 float w3=1.0/(1.0E-12+dtac.c[diBest+1].size);
451 float d=(w1*(float)(diBest-1) + w2*(float)diBest + w3*(float)(diBest+1))/(w1+w2+w3);
452 map.m[zi][yi][xi][0]=(float)drange[0] + d;
453#endif
454 }
455 }
456 if(img.dimz>2 && verbose>0) {fprintf(stdout, "\n"); fflush(stdout);}
457 /* Free NNLS matrix data */
458 free(llsq_a); free(llsq_mat);
459
460
461 /* Dynamic data not needed after this */
462 tacFree(&tac); imgFree(&img); tacFree(&dtac); tacFree(&ditac);
463
464 /*
465 * If Vb, K1, or k2 images were requested, save them
466 */
467 if(vbfile[0]) {
468 if(imgWrite(&vbimg, vbfile, &status)!=TPCERROR_OK)
469 fprintf(stderr, "Error: %s\n", errorMsg(status.error));
470 if(verbose>0) {printf(" %s written.\n", vbfile); fflush(stdout);}
471 }
472 if(k1file[0]) {
473 if(imgWrite(&k1img, k1file, &status)!=TPCERROR_OK)
474 fprintf(stderr, "Error: %s\n", errorMsg(status.error));
475 if(verbose>0) {printf(" %s written.\n", k1file); fflush(stdout);}
476 }
477 if(k2file[0]) {
478 if(imgWrite(&k2img, k2file, &status)!=TPCERROR_OK)
479 fprintf(stderr, "Error: %s\n", errorMsg(status.error));
480 if(verbose>0) {printf(" %s written.\n", k2file); fflush(stdout);}
481 }
482 imgFree(&vbimg); imgFree(&k1img); imgFree(&k2img);
483
484
485 /*
486 * Write the delay map
487 */
488 if(verbose>1) {printf("writing %s\n", mapfile); fflush(stdout);}
489 ret=imgWrite(&map, mapfile, &status);
490 if(ret!=TPCERROR_OK) {
491 fprintf(stderr, "Error: %s\n", errorMsg(status.error)); fflush(stderr);
492 imgFree(&map);
493 return(11);
494 }
495 if(verbose>0) {printf(" %s written.\n", mapfile); fflush(stdout);}
496
497 imgFree(&map);
498
499 return(0);
500}
501/*****************************************************************************/
502
503/*****************************************************************************/
int atofCheck(const char *s, double *v)
Definition decpoint.c:94
void imgContents(IMG *img, FILE *fp)
Definition image.c:293
void imgFree(IMG *img)
Definition image.c:107
unsigned long long imgNaNs(IMG *img, int fix)
Definition image.c:373
void imgInit(IMG *img)
Definition image.c:64
int imgAllocate(IMG *img, const unsigned int dimz, const unsigned int dimy, const unsigned int dimx, const unsigned int dimt, TPCSTATUS *status)
Definition image.c:126
int imgXRange(IMG *img, double *xmin, double *xmax)
Definition image.c:430
int imgCopyHeader(IMG *img1, IMG *img2)
Definition imageheader.c:18
int imgRead(IMG *img, const char *fname, TPCSTATUS *status)
Definition imageio.c:82
int imgWrite(IMG *img, const char *fname, TPCSTATUS *status)
Definition imageio.c:214
int liIntegratePET(double *x1, double *x2, double *y, int nr, double *ie, double *iie, const int verbose)
Calculate PET TAC AUC from start to each time frame, as averages during each frame.
Definition integrate.c:120
int liInterpolateForPET(double *x, double *y, const int nr, double *newx1, double *newx2, double *newy, double *newyi, double *newyii, const int newnr, const int se, const int ee, const int verbose)
Linear TAC interpolation and/or integration to PET frames.
int atoiCheck(const char *s, int *v)
Definition intutil.c:25
double tacAUC(TAC *tac, int ti, double t1, double t2, TPCSTATUS *status)
Calculates TAC AUC from t1 to t2.
Definition litac.c:486
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
Definition tpcimage.h:82
unsigned short int dimx
Definition tpcimage.h:112
float * x1
Definition tpcimage.h:180
unit cunit
Definition tpcimage.h:203
float **** m
Definition tpcimage.h:161
float * x2
Definition tpcimage.h:182
unsigned short int dimt
Definition tpcimage.h:110
unsigned short int dimz
Definition tpcimage.h:116
unsigned short int dimy
Definition tpcimage.h:114
float * x
Definition tpcimage.h:184
unit tunit
Definition tpcimage.h:205
double * y
Definition tpctac.h:75
double size
Definition tpctac.h:71
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
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
int tacAllocate(TAC *tac, int sampleNr, int tacNr)
Definition tac.c:130
void tacInit(TAC *tac)
Definition tac.c:24
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 tacXUnitConvert(TAC *tac, const int u, TPCSTATUS *status)
Definition tacunits.c:23
int tacSetX(TAC *d, TPCSTATUS *status)
Set TAC x values based on x1 and x2 values, or guess x1 and x2 values based on x values.
Definition tacx.c:653
int tacXRange(TAC *d, double *xmin, double *xmax)
Get the range of x values (times) in TAC structure.
Definition tacx.c:124
Header file for library libtpccsv.
Header file for library libtpcextensions.
unit
@ UNIT_MIN
minutes
@ UNIT_ML_PER_ML
mL/mL
@ UNIT_ML_PER_ML_MIN
mL/(mL*min)
@ UNIT_UNKNOWN
Unknown unit.
@ UNIT_SEC
seconds
@ UNIT_PER_MIN
1/min
@ TPCERROR_OK
No error.
char * unitName(int unit_code)
Definition units.c:143
Header file for library libtpcift.
Header file for libtpcimage.
Header file for libtpcli.
Header file for libtpclinopt.
Header file for library libtpctac.
@ TAC_FORMAT_PMOD
PMOD TAC format.
Definition tpctac.h:33
Header file for libtpctacimg.
int tacimgXMatch(TAC *tac, IMG *img)
Definition x.c:17
int tacimgXCopy(TAC *tac, IMG *img)
Definition x.c:74
Header file for libtpctacmod.