10#include "tpcclibConfig.h"
25static char *info[] = {
26 "Increase or decrease the sample (frame) times in regional or blood/plasma",
28 "Samples with negative times are not saved by default.",
29 "Time must be given in the same units that are used in the datafile.",
31 "Usage: @P [Options] tacfile [-]time outputfile",
33 "Time can be given as positive or negative value directly in the command",
34 "line, or in an ASCII file which contains a line with the time change value",
35 "in the following format: 'time_difference := time'.",
36 "Alternatively, time specified in that file with 'Ta' or 'start_time' is",
37 "subtracted from sample times.",
41 " Physical decay correction is changed with change in sample times;",
42 " without this option, radioactivity values are not changed.",
43 " Note that this option will provide correct result only if time unit",
44 " setting in datafile is correct.",
46 " If tacfile does not contain the isotope, then decay correction cannot",
47 " applied unless isotope is given with this option.",
48 " Accepted isotope codes are for example F-18, C-11, and O-15.",
49 " Isotope code can also be specified in input file in format",
50 " '# isotope := Isotope'.",
52 " Samples with negative sample times are not removed from output.",
54 " While correction for physical decay is changed with option -decay,",
55 " sample times will not be changed.",
57 " Possible gap between time zero and first sample is filled.",
60 "See also: tacframe, tacdecay, injdifft, tacunit, fitdelay, simdisp, taccut",
62 "Keywords: TAC, modelling, simulation, late scan, input, time delay",
81int main(
int argc,
char **argv)
83 int ai, help=0, version=0, verbose=1;
84 int fi, fj, ri, n, ret;
90 char *cptr, dftfile1[FILENAME_MAX], dftfile2[FILENAME_MAX], tmp[64];
93 double halflife=0.0, lambda, dcf, f;
94 int time_diff_unit=TUNIT_UNKNOWN;
102 if(argc==1) {
tpcPrintUsage(argv[0], info, stderr);
return(1);}
103 dftfile1[0]=dftfile2[0]=isotope[0]=(char)0;
106 for(ai=1; ai<argc; ai++)
if(*argv[ai]==
'-') {
107 cptr=argv[ai]+1;
if(*cptr==
'-') cptr++;
if(cptr==NULL)
continue;
110 if(strcasecmp(cptr,
"DECAY")==0) {
111 change_decay=1;
continue;
112 }
else if(strncasecmp(cptr,
"D=", 2)==0) {
114 cptr+=2;
if(!*cptr)
continue;
117 fprintf(stderr,
"Error: invalid isotope '%s'.\n", cptr);
122 }
else if(strncasecmp(cptr,
"I=", 2)==0) {
124 cptr+=2;
if(!*cptr)
continue;
127 fprintf(stderr,
"Error: invalid isotope '%s'.\n", cptr);
132 }
else if(strncasecmp(cptr,
"KEEPNEGATIVE", 5)==0) {
133 keep_negat=1;
continue;
134 }
else if(strncasecmp(cptr,
"KEEPTIMES", 5)==0) {
135 keep_times=1;
continue;
136 }
else if(strncasecmp(cptr,
"NOGAP", 5)==0) {
137 fill_gap=1;
continue;
139 fprintf(stderr,
"Error: invalid option '%s'.\n", argv[ai]);
144 if(help==2) {
tpcHtmlUsage(argv[0], info,
"");
return(0);}
151 if(access(argv[ai], 0) == -1) {
152 fprintf(stderr,
"Error: file '%s' does not exist.\n", argv[ai]);
155 strcpy(dftfile1, argv[ai]); ai++;
160 ret=
iftRead(&ift, argv[ai], 1);
162 strcpy(tmp,
"scan_start_time_difference");
163 n=
iftGet(&ift, tmp); time_sign=+1;
165 strcpy(tmp,
"time_difference"); n=
iftGet(&ift, tmp); time_sign=+1;
168 strcpy(tmp,
"Ta"); n=
iftGet(&ift, tmp); time_sign=-1;
171 strcpy(tmp,
"start_time"); n=
iftGet(&ift, tmp); time_sign=-1;
175 "Error: keyword for time difference not found in '%s'.\n", argv[ai]);
180 fprintf(stderr,
"Error: invalid format for time in '%s'.\n", argv[ai]);
183 time_diff*=time_sign;
185 if(strstr(ift.
item[n].
value,
"[s]")!=NULL) time_diff_unit=TUNIT_SEC;
186 else if(strstr(ift.
item[n].
value,
"[min]")!=NULL) time_diff_unit=TUNIT_MIN;
190 fprintf(stderr,
"Error: invalid argument for time: '%s'.\n", argv[ai]);
194 if(verbose>1) printf(
"time_diff := %g\n", time_diff);
196 fprintf(stderr,
"Warning: time change is zero.\n");
202 strcpy(dftfile2, argv[ai]);
207 fprintf(stderr,
"Error: invalid argument '%s'.\n", argv[ai]);
213 fprintf(stderr,
"Error: missing command-line argument; try %s --help\n",
218 fprintf(stderr,
"Error: undefined output file name.\n");
223 if(keep_times==1 && change_decay==0) {
225 "Error: change in neither sample times or decay correction were requested.\n");
228 if(keep_times==1) keep_negat=1;
232 printf(
"dftfile1 := %s\n", dftfile1);
233 printf(
"dftfile2 := %s\n", dftfile2);
234 printf(
"time_diff := %g\n", time_diff);
235 printf(
"change_decay := %d\n", change_decay);
236 printf(
"halflife := %g\n", halflife);
237 if(isotope[0]) printf(
"isotope := %s\n", isotope);
238 printf(
"keep_times := %d\n", keep_times);
239 printf(
"keep_negat := %d\n", keep_negat);
240 printf(
"fill_gap := %d\n", fill_gap);
246 if(verbose>1) printf(
"reading %s\n", dftfile1);
248 fprintf(stderr,
"Error in reading '%s': %s\n", dftfile1,
dfterrmsg);
252 printf(
"voiNr := %d\n", dft.
voiNr);
253 printf(
"frameNr := %d\n", dft.
frameNr);
257 if(change_decay && strlen(dft.
isotope)>0) {
260 fprintf(stderr,
"Error: invalid isotope '%s' in '%s'.\n",
267 fprintf(stderr,
"Error: invalid isotope in '%s' or in command line.\n",
277 if(change_decay && halflife<=0.0) {
278 fprintf(stderr,
"Error: isotope not specified.\n");
283 if(isotope[0] && strlen(dft.
isotope)<1) {
287 if(!isotope[0]) strcpy(isotope, dft.
isotope);
288 if(verbose>1) printf(
"isotope := %s\n", isotope);
291 if(halflife>0.0 && dft.
timeunit==TUNIT_SEC) {
294 if(verbose>1) printf(
"halflife := %g\n", halflife);
298 if(time_diff_unit==TUNIT_MIN && dft.
timeunit==TUNIT_SEC) {
299 time_diff*=60.0; time_diff_unit=TUNIT_SEC;
300 }
else if(time_diff_unit==TUNIT_SEC && dft.
timeunit==TUNIT_MIN) {
301 time_diff/=60.0; time_diff_unit=TUNIT_MIN;
303 if(verbose>1) printf(
"final_time_diff := %g\n", time_diff);
309 for(fi=0; fi<dft.
frameNr; fi++) {
310 dft.
x[fi]+=time_diff; dft.
x1[fi]+=time_diff; dft.
x2[fi]+=time_diff;
315 for(fi=0; fi<dft.
frameNr; fi++)
if(dft.
x[fi]>=0.0)
break;
316 n=fi;
if(n>0)
for(fj=fi; fj<dft.
frameNr; fj++) {
317 for(ri=0; ri<dft.
voiNr; ri++) dft.
voi[ri].
y[fj-n]=dft.
voi[ri].
y[fj];
318 dft.
x[fj-n]=dft.
x[fj]; dft.
x1[fj-n]=dft.
x1[fj]; dft.
x2[fj-n]=dft.
x2[fj];
319 dft.
w[fj-n]=dft.
w[fj];
323 fprintf(stderr,
"Error: No positive times left.\n");
334 lambda=
hl2lambda(halflife);
if(time_diff<0.0) lambda=-lambda;
337 printf(
"correction factor for physical decay: %g\n", dcf);
338 for(fi=0; fi<dft.
frameNr; fi++)
for(ri=0; ri<dft.
voiNr; ri++)
339 dft.
voi[ri].
y[fi]*=dcf;
349 struct tm tm_injection;
353 t_injection=
timegm(&tm_injection);
354 if(t_injection<0) ret=-100;
357 fprintf(stderr,
"Error: invalid injection time.\n");
361 if(dft.
timeunit==TUNIT_SEC)
tmAdd(-time_diff, &tm_injection);
362 else if(dft.
timeunit==TUNIT_MIN)
tmAdd(-60.0*time_diff, &tm_injection);
363 snprintf(dft.
injectionTime, 20,
"%.4d-%.2d-%.2d %.2d:%.2d:%.2d",
364 tm_injection.tm_year+1900, tm_injection.tm_mon+1, tm_injection.tm_mday,
365 tm_injection.tm_hour, tm_injection.tm_min, tm_injection.tm_sec);
366 if(verbose>0) printf(
"updated_injectiontime := %s\n", dft.
injectionTime);
373 if(verbose>1) printf(
"checking for initial gap\n");
375 fprintf(stderr,
"Error: invalid injection time.\n");
384 if(verbose>1) printf(
"saving modified data in %s\n", dftfile2);
389 fprintf(stderr,
"Error in writing '%s': %s\n", dftfile2,
dfterrmsg);
395 if(keep_times==0) fprintf(stdout,
"Sample times changed by %g", time_diff);
396 else fprintf(stdout,
"Injection time changed by %g", -time_diff);
397 if(change_decay) fprintf(stdout,
" and values with half-life %g", halflife);
398 fprintf(stdout,
" in %s\n", dftfile2);
int get_datetime(char *str, struct tm *date, int verbose)
time_t timegm(struct tm *tm)
Inverse of gmtime, converting struct tm to time_t.
void tmAdd(int s, struct tm *d)
int atof_with_check(char *double_as_string, double *result_value)
void dftSetComments(DFT *dft)
int dftFillInitialGap(DFT *dft)
int dftRead(char *filename, DFT *data)
int dftWrite(DFT *data, char *filename)
double hl2lambda(double halflife)
double hlLambda2factor(double lambda, double frametime, double framedur)
char * hlCorrectIsotopeCode(char *isocode)
double hlFromIsotope(char *isocode)
int iftRead(IFT *ift, char *filename, int is_key_required, int verbose)
int iftGet(IFT *ift, char *key, int verbose)
Header file for libtpccurveio.
Header file for libtpcmisc.
int tpcProcessStdOptions(const char *s, int *print_usage, int *print_version, int *verbose_level)
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)
Header file for libtpcmodel.
char comments[_DFT_COMMENT_LEN+1]