TPCCLIB
Loading...
Searching...
No Matches
imgslope.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 <math.h>
13#include <string.h>
14#include <unistd.h>
15#include <time.h>
16/*****************************************************************************/
17#include "libtpcmisc.h"
18#include "libtpcmodel.h"
19#include "libtpccurveio.h"
20#include "libtpcimgio.h"
21#include "libtpcimgp.h"
22/*****************************************************************************/
23
24/*****************************************************************************/
25static char *info[] = {
26 "Calculate the slope of pixel TACs in dynamic PET image.",
27 "Slope is calculated between given start and end times (min).",
28 "Static image containing the slope value of each pixel TAC is written.",
29 " ",
30 "Usage: @P [Options] imgfile starttime endtime slopefile",
31 " ",
32 "Options:",
33 " -median",
34 " Instead of LSQ regression line, the slope is determined as median",
35 " of slopes between any two data points.",
36 " -sign",
37 " Change the sign of slopes.",
38 " -noneg",
39 " Pixels with negative slope (optionally after sign change) are set",
40 " to zero.",
41 " -stdoptions", // List standard options like --help, -v, etc
42 " ",
43 "See also: imgcalc, imgpeak, imgaumc, imgledif, imgthrs",
44 " ",
45 "Keywords: image, dynamics, input, mask",
46 0};
47/*****************************************************************************/
48
49/*****************************************************************************/
50/* Turn on the globbing of the command line, since it is disabled by default in
51 mingw-w64 (_dowildcard=0); in MinGW32 define _CRT_glob instead, if necessary;
52 In Unix&Linux wildcard command line processing is enabled by default. */
53/*
54#undef _CRT_glob
55#define _CRT_glob -1
56*/
57int _dowildcard = -1;
58/*****************************************************************************/
59
60/*****************************************************************************/
64int main(int argc, char **argv)
65{
66 int ai, help=0, version=0, verbose=1;
67 char imgfile[FILENAME_MAX], slopefile[FILENAME_MAX];
68 double v, tstart=0.0, tstop=0.0;
69 int mode=0; // 0=LSQ, 1=median
70 int sign=0; // 0=natural, 1=changed
71 int noneg=0; // 0=negative values are kept, 1=negative values set to zero
72
73
74 /*
75 * Get arguments
76 */
77 if(argc==1) {tpcPrintUsage(argv[0], info, stderr); return(1);}
78 imgfile[0]=slopefile[0]=(char)0;
79 /* Options */
80 for(ai=1; ai<argc; ai++) if(*argv[ai]=='-') { /* options */
81 char *cptr=argv[ai]+1; if(*cptr=='-') cptr++; if(cptr==NULL) continue;
82 if(tpcProcessStdOptions(argv[ai], &help, &version, &verbose)==0) continue;
83 if(strcasecmp(cptr, "MEDIAN")==0) {
84 mode=1; continue;
85 } else if(strcasecmp(cptr, "SIGN")==0) {
86 sign=1; continue;
87 } else if(strncasecmp(cptr, "NONEGATIVES", 5)==0) {
88 noneg=1; continue;
89 }
90 fprintf(stderr, "Error: invalid option '%s'\n", argv[ai]);
91 return(1);
92 } else break;
93
94 /* Print help or version? */
95 if(help==2) {tpcHtmlUsage(argv[0], info, ""); return(0);}
96 if(help) {tpcPrintUsage(argv[0], info, stdout); return(0);}
97 if(version) {tpcPrintBuild(argv[0], stdout); return(0);}
98
99 /* Process other arguments, starting from the first non-option */
100 if(ai<argc) {strlcpy(imgfile, argv[ai], FILENAME_MAX); ai++;}
101 if(ai<argc && atof_with_check(argv[ai], &v)==0) {tstart=v; ai++;}
102 if(ai<argc && atof_with_check(argv[ai], &v)==0) {tstop=v; ai++;}
103 if(ai<argc) {strlcpy(slopefile, argv[ai], FILENAME_MAX); ai++;}
104 if(ai<argc) {fprintf(stderr, "Error: too many arguments.\n"); return(1);}
105
106 /* Is something missing or wrong? */
107 if(!slopefile[0]) {
108 fprintf(stderr, "Error: missing command-line argument; use option --help\n");
109 return(1);
110 }
111
112 /* In verbose mode print arguments and options */
113 if(verbose>1) {
114 printf("imgfile := %s\n", imgfile);
115 printf("tstart := %g\n", tstart);
116 printf("tstop := %g\n", tstop);
117 printf("slopefile := %s\n", slopefile);
118 printf("mode := %d\n", mode);
119 printf("noneg := %d\n", noneg);
120 fflush(stdout);
121 }
122
123
124 /*
125 * Read dynamic image
126 */
127 if(verbose>0) printf("reading dynamic image %s\n", imgfile);
128 IMG img; imgInit(&img);
129 if(imgRead(imgfile, &img)) {
130 fprintf(stderr, "Error: %s\n", img.statmsg);
131 return(2);
132 }
133 if(verbose>1) {
134 printf("img_dimx := %d\n", img.dimx);
135 printf("img_dimy := %d\n", img.dimy);
136 printf("img_dimz := %d\n", img.dimz);
137 printf("img_dimt := %d\n", img.dimt);
138 fflush(stdout);
139 }
140 if(img.dimt<2) {
141 fprintf(stderr, "Error: %s contains only 1 time frame.\n", imgfile);
142 imgEmpty(&img); return(2);
143 }
144 if(imgNaNs(&img, 1)>0)
145 if(verbose>0) fprintf(stderr, "Warning: missing pixel values.\n");
146
147 /* Check that times are available */
148 if(imgExistentTimes(&img)==0) {
149 fprintf(stderr, "Error: image does not contain frame times.\n");
150 imgEmpty(&img); return(2);
151 }
152
153 /* Check and set time range */
154 if(tstop<1.0E-10) {
155 tstop=img.end[img.dimt-1]/60.0;
156 if(verbose>0) {printf("tstop set to %g min\n", tstop); fflush(stdout);}
157 }
158 tstart*=60.0; tstop*=60.0;
159 /* Get the time range in frame indices */
160 int fstart=img.dimt-1;
161 int fstop=0;
162 for(int i=img.dimt-1; i>=0; i--) if(img.mid[i]>=tstart) fstart=i; else break;
163 for(int i=0; i<img.dimt; i++) if(img.mid[i]<=tstop) fstop=i; else break;
164 if(verbose>1) {
165 printf("fstart := %d\n", fstart);
166 printf("fstop := %d\n", fstop);
167 }
168 int sampleNr=1+fstop-fstart;
169 if(sampleNr<2) {
170 fprintf(stderr, "Error: invalid time range.\n");
171 imgEmpty(&img); return(2);
172 }
173
174
175 /*
176 * Allocate IMG for slope image
177 */
178 if(verbose>1) printf("allocating memory for parametric image\n");
179 IMG sout; imgInit(&sout);
180 if(imgAllocateWithHeader(&sout, img.dimz, img.dimy, img.dimx, 1, &img)) {
181 fprintf(stderr, "Error: cannot allocate IMG data.\n");
182 imgEmpty(&img); return(4);
183 }
184 /* Set the frame time */
185 sout.start[0]=img.start[fstart]; sout.end[0]=img.end[fstop];
186 /* and set the units */
187 sout.unit=CUNIT_UNITLESS;
188
189
190 /*
191 * Compute pixel-by-pixel
192 */
193 {
194 double x[sampleNr], y[sampleNr], a, b;
195 for(int i=0; i<sampleNr; i++) x[i]=img.mid[i+fstart];
196 for(int zi=0; zi<img.dimz; zi++) {
197 for(int yi=0; yi<img.dimy; yi++) for(int xi=0; xi<img.dimx; xi++) {
198 /* Set results to zero */
199 sout.m[zi][yi][xi][0]=0.0;
200 /* Line fit */
201 for(int i=0; i<sampleNr; i++) y[i]=img.m[zi][yi][xi][i+fstart];
202 int ret=0;
203 if(mode==0) {
204 ret=regr_line(x, y, sampleNr, &a, &b);
205 } else {
206 ret=medianline(x, y, sampleNr, &a, &b);
207 }
208 if(sign) a*=-1.0;
209 if(noneg && !(a>=0.0)) a=0.0;
210 if(ret==0) sout.m[zi][yi][xi][0]=60.0*(float)a;
211 }
212 }
213 }
214
215
216 /*
217 * Save the slope data
218 */
219 {
220 if(verbose>1) printf("writing slopes\n");
221 if(imgWrite(slopefile, &sout)) {
222 fprintf(stderr, "Error: %s\n", sout.statmsg);
223 imgEmpty(&img); imgEmpty(&sout);
224 return(11);
225 }
226 if(verbose>0) fprintf(stdout, "Image %s saved.\n", slopefile);
227 }
228
229 imgEmpty(&img); imgEmpty(&sout);
230 return(0);
231}
232/*****************************************************************************/
233
234/*****************************************************************************/
int atof_with_check(char *double_as_string, double *result_value)
Definition decpoint.c:107
int imgExistentTimes(IMG *img)
Definition img.c:613
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 imgRead(const char *fname, IMG *img)
Definition imgfile.c:26
int imgWrite(const char *fname, IMG *img)
Definition imgfile.c:136
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 medianline(double *x, double *y, int nr, double *slope, double *ic)
Definition llsqwt.c:533
int regr_line(double *x, double *y, int n, double *m, double *c)
Definition pearson.c:387
unsigned short int dimx
float **** m
char unit
unsigned short int dimt
float * start
unsigned short int dimz
unsigned short int dimy
float * end
const char * statmsg
float * mid