TPCCLIB
Loading...
Searching...
No Matches
taccut.c
Go to the documentation of this file.
1
8/*****************************************************************************/
9#include "tpcclibConfig.h"
10/*****************************************************************************/
11#include <stdio.h>
12#include <stdlib.h>
13#include <string.h>
14#include <math.h>
15/*****************************************************************************/
16#include "tpcextensions.h"
17#include "tpctac.h"
18/*****************************************************************************/
19
20/*****************************************************************************/
21static char *info[] = {
22 "Extract specified time interval from PET time-activity curves (TACs).",
23 " ",
24 "Usage: @P [Options] tacfile starttime endtime [outputfile]",
25 " ",
26 "Options:",
27 " -LS | -UptoPeak | -FromPeak | -UptoPeakN | -FromPeakP",
28 " Extract the last sample, samples up to peak, from peak to the end",
29 " up to peak plus one, or from one sample before peak to the end;",
30 " times are not effective with these options.",
31 " -stdoptions", // List standard options like --help, -v, etc
32 " ",
33 "See also: taccat, tactime, tacunit, tacframe, interpol, dftrmovl, imgdelfr",
34 " ",
35 "Keywords: TAC, tool, simulation, time, cropping",
36 0};
37/*****************************************************************************/
38
39/*****************************************************************************/
40/* Turn on the globbing of the command line, since it is disabled by default in
41 mingw-w64 (_dowildcard=0); in MinGW32 define _CRT_glob instead, if necessary;
42 In Unix&Linux wildcard command line processing is enabled by default. */
43/*
44#undef _CRT_glob
45#define _CRT_glob -1
46*/
47int _dowildcard = -1;
48/*****************************************************************************/
49
50/*****************************************************************************/
54int main(int argc, char **argv)
55{
56 int ai, help=0, version=0, verbose=1;
57 int origNr, ret;
58 char dfile1[FILENAME_MAX], dfile2[FILENAME_MAX];
59 TAC tac, tac2;
60 double startT, endT;
61 int calcMode=0; // 0=time range; 1=last sample; 2=up to peak, 3=from peak
62
63 /*
64 * Get arguments
65 */
66 if(argc==1) {tpcPrintUsage(argv[0], info, stderr); return(1);}
67 tacInit(&tac); tacInit(&tac2);
68 dfile1[0]=dfile2[0]=(char)0;
69 startT=endT=nan("");
70 /* Options */
71 for(ai=1; ai<argc; ai++) if(*argv[ai]=='-') {
72 if(tpcProcessStdOptions(argv[ai], &help, &version, &verbose)==0) continue;
73 char *cptr=argv[ai]+1; if(*cptr=='-') cptr++; if(!*cptr) continue;
74 if(strcasecmp(cptr, "LS")==0) {calcMode=1; continue;}
75 if(strcasecmp(cptr, "UPTOPEAK")==0) {calcMode=2; continue;}
76 if(strcasecmp(cptr, "FROMPEAK")==0) {calcMode=3; continue;}
77 if(strcasecmp(cptr, "UPTOPEAKN")==0) {calcMode=4; continue;}
78 if(strcasecmp(cptr, "FROMPEAKP")==0) {calcMode=5; continue;}
79 fprintf(stderr, "Error: invalid option '%s'\n", argv[ai]);
80 return(1);
81 } else break;
82
83 TPCSTATUS status; statusInit(&status);
84 statusSet(&status, __func__, __FILE__, __LINE__, TPCERROR_OK);
85 status.verbose=verbose-1;
86
87 /* Print help or version? */
88 if(help==2) {tpcHtmlUsage(argv[0], info, ""); return(0);}
89 if(help) {tpcPrintUsage(argv[0], info, stdout); return(0);}
90 if(version) {tpcPrintBuild(argv[0], stdout); return(0);}
91
92 /* Process other arguments, starting from the first non-option */
93 if(ai<argc) {strlcpy(dfile1, argv[ai++], FILENAME_MAX);}
94 if(ai<argc) {
95 if(calcMode==0) {
96 if(atofCheck(argv[ai], &startT)!=0) {
97 fprintf(stderr, "Error: invalid start time '%s'.\n", argv[ai]);
98 return(1);
99 }
100 }
101 ai++;
102 }
103 if(ai<argc) {
104 if(calcMode==0) {
105 if(atofCheck(argv[ai], &endT)!=0 || endT<=startT) {
106 fprintf(stderr, "Error: invalid end time '%s'.\n", argv[ai]);
107 return(1);
108 }
109 }
110 ai++;
111 }
112 if(ai<argc) {strlcpy(dfile2, argv[ai++], FILENAME_MAX);}
113 if(ai<argc) {fprintf(stderr, "Error: too many arguments: '%s'.\n", argv[ai]); return(1);}
114
115 /* Check that we got what we need */
116 if(!dfile1[0]) {tpcPrintUsage(argv[0], info, stderr); return(1);}
117 /* Check time range only if it is needed */
118 if(calcMode==0 && (isnan(startT) || isnan(endT) || endT<=startT)) {
119 fprintf(stderr, "Error: invalid time range.\n"); return(1);}
120
121 /* If output file name was not given, then edit the input file */
122 if(!dfile2[0]) strcpy(dfile2, dfile1);
123
124 /* In verbose mode print arguments and options */
125 if(verbose>1) {
126 printf("calcMode := %d\n", calcMode);
127 printf("dfile1 := %s\n", dfile1);
128 printf("dfile2 := %s\n", dfile2);
129 if(!isnan(startT)) printf("startT := %g\n", startT);
130 if(!isnan(endT)) printf("endT := %g\n", endT);
131 }
132
133
134 /*
135 * Read data
136 */
137 if(verbose>1) printf("reading %s\n", dfile1);
138 ret=tacRead(&tac, dfile1, &status);
139 if(ret!=TPCERROR_OK) {
140 fprintf(stderr, "Error: %s\n", errorMsg(status.error));
141 tacFree(&tac); return(2);
142 }
143 if(verbose>1) {
144 printf("fileformat := %s\n", tacFormattxt(tac.format));
145 printf("tacNr := %d\n", tac.tacNr);
146 printf("sampleNr := %d\n", tac.sampleNr);
147 }
148 origNr=tac.sampleNr;
149
150 /* Sort by sample times */
151 if(tacSortByTime(&tac, &status)!=TPCERROR_OK) {
152 fprintf(stderr, "Error: %s\n", errorMsg(status.error));
153 tacFree(&tac); return(3);
154 }
155
156 /*
157 * If peak is to be used, then find it, and get time range based on it
158 */
159 if(calcMode>=2 && calcMode<=5) {
160 int maxi; double maxy;
161 ret=tacYRange(&tac, -1, NULL, &maxy, NULL, &maxi, NULL, NULL);
162 if(ret) {
163 fprintf(stderr, "Error: cannot find TAC peak.\n");
164 tacFree(&tac); return(4);
165 }
166 if(verbose>0) {printf("Peak value %g found at %g\n", maxy, tac.x[maxi]); fflush(stdout);}
167 if(calcMode==2) {
168 startT=-9.9E+30;
169 if(tac.isframe) endT=tac.x2[maxi]; else endT=tac.x[maxi];
170 } else if(calcMode==3) {
171 if(tac.isframe) startT=tac.x1[maxi]; else startT=tac.x[maxi];
172 endT=+9.9E+30;
173 } else if(calcMode==4) {
174 startT=-9.9E+30;
175 if(maxi<tac.sampleNr-1) maxi++;
176 if(tac.isframe) endT=tac.x2[maxi]; else endT=tac.x[maxi];
177 } else if(calcMode==5) {
178 if(maxi>0) maxi--;
179 if(tac.isframe) startT=tac.x1[maxi]; else startT=tac.x[maxi];
180 endT=+9.9E+30;
181 }
182 }
183
184
185 /*
186 * Extract samples
187 */
188 if(calcMode==1) {
189 /* Extract the last sample */
190 ret=tacExtractSamples(&tac, &tac2, tac.sampleNr-1, tac.sampleNr-1);
191 } else {
192 /* Extract samples inside the user-specified time range */
193 ret=tacExtractRange(&tac, &tac2, startT, endT);
194 }
195 if(ret!=TPCERROR_OK) {
196 fprintf(stderr, "Error: invalid range.\n");
197 if(verbose>1) printf("error_msg := %s\n", errorMsg(ret));
198 tacFree(&tac); tacFree(&tac2); return(4);
199 }
200 if(verbose>1) {
201 printf("original_frameNr := %d\n", origNr);
202 printf("final_frameNr := %d\n", tac2.sampleNr);
203 }
204 tacFree(&tac);
205
206 /* If all samples were extracted, and output file name was not given, then do not save output */
207 if(origNr==tac2.sampleNr && strcasecmp(dfile1, dfile2)==0) {
208 if(verbose>0) printf("nothing done.\n");
209 tacFree(&tac2);
210 return(0);
211 }
212
213 /*
214 * Save the extracted TACs
215 */
216 if(verbose>1) printf("writing %s\n", dfile2);
217 FILE *fp; fp=fopen(dfile2, "w");
218 if(fp==NULL) {
219 fprintf(stderr, "Error: cannot open file for writing (%s)\n", dfile2);
220 tacFree(&tac2); return(11);
221 }
222 ret=tacWrite(&tac2, fp, TAC_FORMAT_UNKNOWN, 1, &status);
223 fclose(fp);
224 if(ret!=TPCERROR_OK) {
225 fprintf(stderr, "Error: %s\n", errorMsg(status.error));
226 tacFree(&tac2); return(12);
227 }
228 if(verbose>0) printf("%d sample(s) were extracted.\n", tac2.sampleNr);
229
230 /* Free memory */
231 tacFree(&tac2);
232
233 return(0);
234}
235/*****************************************************************************/
236
237/*****************************************************************************/
int atofCheck(const char *s, double *v)
Definition decpoint.c:94
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 tpctac.h:87
double * x
Definition tpctac.h:97
tacformat format
Definition tpctac.h:93
int sampleNr
Definition tpctac.h:89
int isframe
Definition tpctac.h:95
double * x2
Definition tpctac.h:101
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
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 tacSortByTime(TAC *d, TPCSTATUS *status)
Definition tacorder.c:74
int tacExtractSamples(TAC *d1, TAC *d2, int si, int ei)
Extract the specified sample range from TAC structure.
Definition tacx.c:568
int tacExtractRange(TAC *d1, TAC *d2, double startT, double endT)
Extract the specified time (x) range from TAC structure.
Definition tacx.c:486
int tacYRange(TAC *d, int i, double *ymin, double *ymax, int *smin, int *smax, int *imin, int *imax)
Get the range of y values (concentrations) in TAC struct.
Definition tacy.c:26
Header file for library libtpcextensions.
@ TPCERROR_OK
No error.
Header file for library libtpctac.
@ TAC_FORMAT_UNKNOWN
Unknown format.
Definition tpctac.h:28