TPCCLIB
Loading...
Searching...
No Matches
injdifft.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/*****************************************************************************/
18
19/*****************************************************************************/
20static char *info[] = {
21 "Calculates time difference between zero times of PET scan and blood data.",
22 "Zero times are given in two text files in format",
23 "scan_start_time := YYYY-MM-DD hh:mm:ss, or",
24 "injection_time := YYYY-MM-DD hh:mm:ss.",
25 " ",
26 "The result, time difference (time2-time1 in seconds) will be written in",
27 "stdout or specified file in format",
28 "time_difference := <time2-time1>.",
29 " ",
30 "Usage: @P [Options] timefile1 timefile2 [outputfile]",
31 " ",
32 "Options:",
33 " -min | -sec",
34 " Time difference is written in minutes or in seconds (default).",
35 " -small",
36 " Software ignores time differences of multiples of one hour, that may",
37 " have been caused by wrong time zone or daylight saving setting in",
38 " either of the zero times.",
39 " -stdoptions", // List standard options like --help, -v, etc
40 " ",
41 "Example:",
42 " @P -small s95432dy1.v.ift s95432blo.kbq s95432.dift",
43 " ",
44 "See also: egetstrt, absscal, iftlist, tactime, blotimes, fitdelay",
45 " ",
46 "Keywords: input, header, IFT, tool",
47 0};
48/*****************************************************************************/
49
50/*****************************************************************************/
51/* Turn on the globbing of the command line, since it is disabled by default in
52 mingw-w64 (_dowildcard=0); in MinGW32 define _CRT_glob instead, if necessary;
53 In Unix&Linux wildcard command line processing is enabled by default. */
54/*
55#undef _CRT_glob
56#define _CRT_glob -1
57*/
58int _dowildcard = -1;
59/*****************************************************************************/
60
61/*****************************************************************************/
65int main(int argc, char **argv)
66{
67 int ai, help=0, version=0, verbose=1;
68 int ret, li, time_unit=UNIT_SEC, hastobe_small=0;
69 char iftfile1[FILENAME_MAX], iftfile2[FILENAME_MAX],
70 outfile[FILENAME_MAX];
71 IFT ift1, ift2;
72 char *cptr, value1[256], value2[256];
73 struct tm st1, st2;
74 double tdiff;
75 FILE *fp;
76
77
78 /*
79 * Get arguments
80 */
81 if(argc==1) {tpcPrintUsage(argv[0], info, stderr); return(1);}
82 iftfile1[0]=iftfile2[0]=outfile[0]=(char)0;
83 iftInit(&ift1); iftInit(&ift2);
84 /* Options */
85 for(ai=1; ai<argc; ai++) if(*argv[ai]=='-') {
86 if(tpcProcessStdOptions(argv[ai], &help, &version, &verbose)==0) continue;
87 cptr=argv[ai]+1; if(*cptr=='-') cptr++; if(cptr==NULL) continue;
88 if(strncasecmp(cptr, "MINUTES", 3)==0) {
89 time_unit=UNIT_MIN; continue;
90 } else if(strncasecmp(cptr, "SECONDS", 3)==0) {
91 time_unit=UNIT_SEC; continue;
92 } else if(strncasecmp(cptr, "SMALL", 3)==0) {
93 hastobe_small=1; continue;
94 }
95 fprintf(stderr, "Error: invalid option '%s'.\n", argv[ai]);
96 return(1);
97 } else break; // tac name argument may start with '-'
98
99 TPCSTATUS status; statusInit(&status);
100 statusSet(&status, __func__, __FILE__, __LINE__, TPCERROR_OK);
101 status.verbose=verbose-1;
102
103 /* Print help or version? */
104 if(help==2) {tpcHtmlUsage(argv[0], info, ""); return(0);}
105 if(help) {tpcPrintUsage(argv[0], info, stdout); return(0);}
106 if(version) {tpcPrintBuild(argv[0], stdout); return(0);}
107
108 /* Arguments */
109 for(; ai<argc; ai++) {
110 if(!iftfile1[0]) {
111 strlcpy(iftfile1, argv[ai], FILENAME_MAX); continue;
112 } else if(!iftfile2[0]) {
113 strlcpy(iftfile2, argv[ai], FILENAME_MAX); continue;
114 } else if(!outfile[0]) {
115 strlcpy(outfile, argv[ai], FILENAME_MAX); continue;
116 }
117 fprintf(stderr, "Error: invalid argument '%s'.\n", argv[ai]);
118 return(1);
119 }
120
121 /* Is something missing? */
122 if(!iftfile2[0]) {
123 fprintf(stderr, "Error: missing command-line argument; use option --help\n");
124 return(1);
125 }
126
127 /* In verbose mode print arguments and options */
128 if(verbose>1) {
129 for(ai=0; ai<argc; ai++)
130 printf("%s ", argv[ai]);
131 printf("\n");
132 printf("iftfile1 := %s\n", iftfile1);
133 printf("iftfile2 := %s\n", iftfile2);
134 printf("outfile := %s\n", outfile);
135 printf("time_unit := %d\n", time_unit);
136 printf("hastobe_small := %d\n", hastobe_small);
137 }
138
139
140 /*
141 * Read IFT files
142 */
143 if(verbose>1) printf("reading %s\n", iftfile1);
144 fp=fopen(iftfile1, "r"); if(fp==NULL) {
145 fprintf(stderr, "Error: cannot open file %s\n", iftfile1);
146 iftFree(&ift1); return(2);
147 }
148 ret=iftRead(&ift1, fp, 1, 1, &status); fclose(fp);
149 if(ret) {
150 fprintf(stderr, "Error (%d): %s\n", ret, errorMsg(status.error));
151 iftFree(&ift1); return(2);
152 }
153 if(verbose>2) printf("list1 size: %d item(s)\n", ift1.keyNr);
154
155 if(verbose>1) printf("reading %s\n", iftfile2);
156 fp=fopen(iftfile2, "r"); if(fp==NULL) {
157 fprintf(stderr, "Error: cannot open file %s\n", iftfile2);
158 iftFree(&ift1); iftFree(&ift2); return(2);
159 }
160 ret=iftRead(&ift2, fp, 1, 1, &status); fclose(fp);
161 if(ret) {
162 fprintf(stderr, "Error (%d): %s\n", ret, errorMsg(status.error));
163 iftFree(&ift1); iftFree(&ift2); return(2);
164 }
165 if(verbose>2) printf("list2 size: %d item(s)\n", ift2.keyNr);
166
167
168 /*
169 * Read the two times
170 */
171 if(verbose>1) printf("reading times\n");
172 /* Time #1 */
173 li=iftFindKey(&ift1, "scan_start_time", 0);
174 if(li<0) li=iftFindKey(&ift1, "injection_time", 0);
175 if(li<0) {
176 fprintf(stderr, "Error: %s does not contain required key.\n", iftfile1);
177 iftFree(&ift1); iftFree(&ift2); return(4);
178 }
179 strlcpy(value1, ift1.item[li].value, 256);
180 if(verbose>2) printf("File #1:\n%s := %s\n", ift1.item[li].key, value1);
181 if(strDateTimeRead(value1, &st1)) {
182 fprintf(stderr, "Error: wrong date/time format in %s.\n", iftfile1);
183 iftFree(&ift1); iftFree(&ift2); return(5);
184 }
185 /* Time #2 */
186 li=iftFindKey(&ift2, "scan_start_time", 0);
187 if(li<0) li=iftFindKey(&ift2, "injection_time", 0);
188 if(li<0) {
189 fprintf(stderr, "Error: %s does not contain required key.\n", iftfile2);
190 iftFree(&ift1); iftFree(&ift2); return(4);
191 }
192 strlcpy(value2, ift2.item[li].value, 256);
193 if(verbose>2) printf("File #2:\n%s := %s\n", ift2.item[li].key, value2);
194 if(strDateTimeRead(value2, &st2)) {
195 fprintf(stderr, "Error: wrong date/time format in %s.\n", iftfile2);
196 iftFree(&ift1); iftFree(&ift2); return(5);
197 }
198
199 iftFree(&ift1); iftFree(&ift2);
200
201
202 /*
203 * Calculate the time difference in seconds
204 */
205 tdiff=tmDifference(&st2, &st1);
206 if(verbose>1) printf("tdif=%g s\n", tdiff);
207 /* Ignore differences of multiples of hour that maybe caused by wrong
208 time zone etc (option -small) */
209 if(hastobe_small) {
210 double f;
211 f=tdiff/3600.0; f=(f<0.0)?(int)(f-0.5):(int)(f+0.5);
212 tdiff-=3600.0*f;
213 if(verbose>1)
214 printf("tdif=%g s , when ignoring %g hour(s)\n", tdiff, f);
215 }
216
217
218 /*
219 * Write the result into file or stdout
220 */
221 if(outfile[0]) {
222 fp=fopen(outfile, "w"); if(fp==NULL) {
223 fprintf(stderr, "Error: cannot open %s for writing.\n", outfile);
224 return(11);
225 }
226 } else
227 fp=stdout;
228 /* write */
229 fprintf(fp, "filename1 := %s\n", iftfile1);
230 fprintf(fp, "filename2 := %s\n", iftfile2);
231 if(time_unit==UNIT_SEC) {
232 ret=fprintf(fp, "time_difference := %g [s]\n", tdiff);
233 } else {
234 ret=fprintf(fp, "time_difference := %g [min]\n", tdiff/60.0);
235 }
236 if(outfile[0]) fclose(fp);
237 if(ret<24) {
238 fprintf(stderr, "Error: cannot write into %s\n", outfile);
239 return(12);
240 }
241
242 return(0);
243}
244/*****************************************************************************/
245
246/*****************************************************************************/
int strDateTimeRead(const char *str, struct tm *date)
Definition datetime.c:350
double tmDifference(struct tm *tm1, struct tm *tm0)
Definition datetime.c:486
void iftFree(IFT *ift)
Definition ift.c:37
void iftInit(IFT *ift)
Definition ift.c:21
int iftFindKey(IFT *ift, const char *key, int start_index)
Definition iftfind.c:30
int iftRead(IFT *ift, FILE *fp, int is_key_required, int is_comment_accepted, TPCSTATUS *status)
Definition iftio.c:130
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
char * value
Definition tpcift.h:37
char * key
Definition tpcift.h:32
Definition tpcift.h:43
IFT_ITEM * item
Definition tpcift.h:57
int keyNr
Definition tpcift.h:47
int verbose
Verbose level, used by statusPrint() etc.
tpcerror error
Error code.
Header file for library libtpcextensions.
@ UNIT_MIN
minutes
@ UNIT_SEC
seconds
@ TPCERROR_OK
No error.
Header file for library libtpcift.