10#include "tpcclibConfig.h"
25static char *info[] = {
26 "Simple arithmetic calculations on PET images.",
28 "Usage: @P [Options] file1 operation constant|file2 outputfile",
31 " Operation = +, -, x , :",
32 " Constant = Image 1 is operated with this value.",
36 " All frames in image 1 are processed with the 1st time frame of image 2.",
38 " Upper limit for output pixels (may be necessary in division).",
41 " Save absolute voxel values.",
44 "Image 1 and 2 must be in the same format, and they must have same",
45 "matrix size and plane numbers.",
46 "Data is not interpolated or corrected for physical decay, and thus it is",
47 "on the responsibility of the user to check that PET time frames are similar",
48 "and that physical decay and other corrections are appropriately considered.",
50 "Constant can be given directly as value on the command line, or as name of",
51 "file containing only the value, or value with key 'constant'.",
53 "Input files must not be overwritten with the output file.",
56 " @P a999.flow.img - a1000.flow.img subtr.img",
58 " @P o657dy1.v : 2.34 o657rda.v",
61 "See also: imgdecay, imgunit, eframe, imginv, esplit, imginteg, imgthrs",
63 "Keywords: image, modelling, simulation, tool",
98 if(verbose>1) printf(
"ecatCopyHeadersNoQuant(%s, %s)\n", file1, file2);
99 if(file1==NULL || file2==NULL)
return(1);
106 strcpy(tmp,
"user_process_code");
108 strcpy(tmp,
"ecat_calibration_factor");
112 for(mi=0; mi<ehdr.
nr; mi++) {
113 strcpy(tmp,
"scale_factor");
115 strcpy(tmp,
"image_min");
117 strcpy(tmp,
"image_max");
119 strcpy(tmp,
"scan_min");
121 strcpy(tmp,
"scan_max");
128 if(ret!=0)
return(10+ret);
139int main(
int argc,
char **argv)
141 int ai, help=0, version=0, verbose=1;
143 int allframes_with_one=0;
145 char file1[FILENAME_MAX], file2[FILENAME_MAX], file3[FILENAME_MAX];
150 float opconst=nan(
"");
158 if(argc==1) {
tpcPrintUsage(argv[0], info, stderr);
return(1);}
159 file1[0]=file2[0]=file3[0]=(char)0;
162 for(ai=1; ai<argc; ai++)
if(*argv[ai]==
'-') {
163 cptr=argv[ai]+1;
if(*cptr==
'-') cptr++;
if(cptr==NULL)
continue;
165 if(strcasecmp(cptr,
"FRAMES")==0) {
166 allframes_with_one=1;
continue;
167 }
else if(strncasecmp(cptr,
"MAX=", 4)==0) {
168 ulimit=
atof_dpi(cptr+4);
if(ulimit>0.0)
continue;
169 }
else if(strncasecmp(cptr,
"ABSOLUTES", 3)==0) {
170 absolutes=1;
continue;
172 fprintf(stderr,
"Error: invalid option '%s'\n", argv[ai]);
177 if(help==2) {
tpcHtmlUsage(argv[0], info,
"");
return(0);}
183 if(ai<argc) {
strlcpy(file1, argv[ai], FILENAME_MAX); ai++;}
185 if(strncasecmp(argv[ai],
"DIVISION", 3)==0) {
187 }
else if(strncasecmp(argv[ai],
"MULTIPLICATION", 3)==0) {
189 }
else if(strncasecmp(argv[ai],
"MINUS", 3)==0) {
191 }
else if(strncasecmp(argv[ai],
"PLUS", 3)==0) {
193 }
else if(strlen(argv[ai])==1)
switch(*argv[ai]) {
194 case '+' : operation=
'+';
break;
195 case '-' : operation=
'-';
break;
199 case 'x' : operation=
'*';
break;
201 case ':' : operation=
'/';
break;
203 if(operation==0) {fprintf(stderr,
"Error: invalid operator.\n");
return(1);}
211 if(ret==0) {isvalue=1; opconst=v; allframes_with_one=1;}
212 else strlcpy(file2, argv[ai], FILENAME_MAX);
215 if(ai<argc) {
strlcpy(file3, argv[ai], FILENAME_MAX); ai++;}
216 if(ai<argc) {fprintf(stderr,
"Error: too many arguments.\n");
return(1);}
219 if(!file3[0]) {
tpcPrintUsage(argv[0], info, stdout);
return(1);}
225 for(ai=0; ai<argc; ai++) printf(
"%s ", argv[ai]);
227 printf(
"file1 := %s\n", file1);
228 printf(
"operation := %c\n", operation);
229 if(isvalue) printf(
"value := %g\n", opconst);
230 else printf(
"file2 := %s\n", file2);
231 printf(
"ulimit := %g\n", ulimit);
232 printf(
"absolute_values := %d\n", absolutes);
233 printf(
"allframes_with_one := %d\n", allframes_with_one);
238 if(strcasecmp(file3, file1)==0 || strcasecmp(file3, file2)==0) {
239 fprintf(stderr,
"Error: original file must not be overwritten.\n");
247 if(verbose>0) printf(
"reading image(s)...\n");
250 fprintf(stderr,
"Error in reading %s: %s\n", file1,
imgStatus(ret));
256 fprintf(stderr,
"Error in reading %s: %s\n", file2,
imgStatus(ret));
261 fprintf(stderr,
"Error: non-matching files.\n");
264 if(img1.
zoom!=img2.
zoom) fprintf(stderr,
"Warning: different zoom.\n");
267 if(allframes_with_one==0 && img1.
dimt>1 && img2.
dimt==1) {
269 fprintf(stderr,
"Warning: automatically applying option -frames\n"); fflush(stderr);}
270 allframes_with_one=1;
273 if(allframes_with_one==0 && img1.
dimt!=img2.
dimt) {
274 fprintf(stderr,
"Error: non-matching frame number.\n");
283 if(verbose>0) printf(
"computing");
286 for(fi=0; fi<frame_nr; fi++) {
287 if(verbose>1) printf(
"\n frame %d\n", fi+1);
291 fprintf(stderr,
"\nError in reading %s: %s\n", file1,
imgStatus(ret));
295 if(*file2 && (fi==0 || allframes_with_one==0)) {
296 if(verbose>2) printf(
"\n reading frame %d in file2\n", fi+1);
300 fprintf(stderr,
"\nError in reading %s: %s\n", file2,
imgStatus(ret));
306 if(verbose>2) printf(
"\noperating frame %d\n", fi+1);
308 if(allframes_with_one==0)
309 ret=
imgArithm(&img1, &img2, operation, ulimit, verbose-3);
316 fprintf(stderr,
"Error %d in calculation.\n", ret);
320 if(absolutes &&
imgAbs(&img1)!=0) {
321 fprintf(stderr,
"Error in calculation.\n");
325 if(fi==0) (void)remove(file3);
331 fprintf(stderr,
"\nError in writing %s: %s\n", file3,
imgStatus(ret));
335 if(verbose==1) {fprintf(stdout,
"."); fflush(stdout);}
337 if(verbose==1) printf(
"\n");
340 if(verbose>1) printf(
"copying header information\n");
342 if(verbose>0 && ret!=0) {printf(
"copying headers not successful (%d).\n", ret); fflush(stdout);}
346 if(verbose>0) printf(
"done.\n");
int atof_with_check(char *double_as_string, double *result_value)
double atof_dpi(char *str)
void ehdrEmpty(ECAT_HEADERS *ehdr)
int ecat7WriteHeaders(const char *fname, ECAT_HEADERS *ehdr, int verbose)
void ehdrInitiate(ECAT_HEADERS *ehdr)
int ecat7ReadHeaders(const char *fname, ECAT_HEADERS *ehdr, int verbose)
int iftDeleteItem(IFT *ift, int item, int verbose)
char * iftReadValue(char *filename, char *keystr, int verbose)
int iftGet(IFT *ift, char *key, int verbose)
char * imgStatus(int status_index)
void imgEmpty(IMG *image)
int imgArithm(IMG *img1, IMG *img2, char operation, float ulimit, int verbose)
int imgArithmConst(IMG *img, float operand, char operation, float ulimit, int verbose)
int imgArithmFrame(IMG *img1, IMG *img2, char operation, float ulimit, int verbose)
int ecat7CopyHeadersNoQuant(const char *file1, const char *file2, int verbose)
int imgWriteFrame(const char *fname, int frame_to_write, IMG *img, int frame_index)
int imgReadFrame(const char *fname, int frame_to_read, IMG *img, int frame_index)
int imgReadHeader(const char *fname, IMG *img, int format)
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)
size_t strlcpy(char *dst, const char *src, size_t dstsize)
int tpcHtmlUsage(const char *program, char *text[], const char *path)
void tpcPrintBuild(const char *program, FILE *fp)
void tpcPrintUsage(const char *program, char *text[], FILE *fp)