TPCCLIB
Loading...
Searching...
No Matches
absstime.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 "tpctac.h"
17#include "tpcabss.h"
18/*****************************************************************************/
19
20/*****************************************************************************/
21static char *info[] = {
22 "Correct the sample times in Allogg, Scanditronics, or GEMS ABSS on-line",
23 "blood sampler data file by giving the correct sampling start time in format",
24 "hh:mm:ss. If the new sampling start time is not given, program lists",
25 "information on the current sample times on the screen.",
26 " ",
27 "Use this, if sampling was accidentally started later than the PET scan.",
28 "In old Allogg files the sampler start time is given before the sampler",
29 "data lines in format hhmmss. In new Allogg files individual sample time is",
30 "stored for each sampling frame.",
31 "In Scanditronics data files the correct sampling start time is in the file",
32 "headers; however, in old Scanditronics data files the headers do not contain",
33 "time, but it is read from the first sample data line.",
34 "In GEMS data files the time in file headers is not the sampling start time,",
35 "but time is read from the first sample data line.",
36 "If new sampling time is given and it is different than the current sampling",
37 "start time, then all sample times in the sampler data file are changed.",
38 "Decay correction is not changed.",
39 " ",
40 "Notice that the original data file is overwritten by default.",
41 " ",
42 "Usage: @P [options] abssfile starttime",
43 " ",
44 "Options:",
45 " -o=<filename>",
46 " Name for corrected file; by default the original file is overwritten.",
47 " -stdoptions", // List standard options like --help, -v, etc
48 " ",
49 "Example: List the start times from ABSS data and ECAT image, and",
50 "set the ABSS start time based on the PET scanner start time.",
51 " @P us1328.bld",
52 " egetstrt us1328dy1.v",
53 " @P us1328.bld 13:07:45",
54 " ",
55 "See also: absszero, abssbkg, absscal, abssfch, abssexam, injdifft",
56 " ",
57 "Keywords: input, ABSS, blood, time, physical decay, calibration",
58 0};
59/*****************************************************************************/
60
61/*****************************************************************************/
62/* Turn on the globbing of the command line, since it is disabled by default in
63 mingw-w64 (_dowildcard=0); in MinGW32 define _CRT_glob instead, if necessary;
64 In Unix&Linux wildcard command line processing is enabled by default. */
65/*
66#undef _CRT_glob
67#define _CRT_glob -1
68*/
69int _dowildcard = -1;
70/*****************************************************************************/
71
72/*****************************************************************************/
76int main(int argc, char **argv)
77{
78 int ai, help=0, version=0, verbose=1;
79 char abssfile[FILENAME_MAX], outfile[FILENAME_MAX];
80 char *cptr, startTime[256];
81 int ret;
82
83
84 /*
85 * Get arguments
86 */
87 if(argc==1) {tpcPrintUsage(argv[0], info, stderr); return(1);}
88 abssfile[0]=outfile[0]=startTime[0]=(char)0;
89 /* Options */
90 for(ai=1; ai<argc; ai++) if(*argv[ai]=='-') {
91 if(tpcProcessStdOptions(argv[ai], &help, &version, &verbose)==0) continue;
92 cptr=argv[ai]+1; if(*cptr=='-') cptr++; if(!*cptr) continue;
93 if(strncasecmp(cptr, "O=", 2)==0 && strlen(cptr)>2) {
94 strlcpy(outfile, cptr+2, FILENAME_MAX); continue;
95 }
96 fprintf(stderr, "Error: invalid option '%s'.\n", argv[ai]);
97 return(1);
98 } else break;
99
100 TPCSTATUS status; statusInit(&status);
101 statusSet(&status, __func__, __FILE__, __LINE__, TPCERROR_OK);
102 status.verbose=verbose-3;
103
104 /* Print help or version? */
105 if(help==2) {tpcHtmlUsage(argv[0], info, ""); return(0);}
106 if(help) {tpcPrintUsage(argv[0], info, stdout); return(0);}
107 if(version) {tpcPrintBuild(argv[0], stdout); return(0);}
108
109 /* Process other arguments, starting from the first non-option */
110 if(ai<argc) strlcpy(abssfile, argv[ai++], FILENAME_MAX);
111 if(ai<argc) {
112 if(strTimeValid(argv[ai])==0) {
113 strlcpy(startTime, argv[ai], 9);
114 } else {
115 fprintf(stderr, "Error: invalid time '%s'.\n", argv[ai]);
116 return(1);
117 }
118 ai++;
119 }
120 if(ai<argc) {
121 fprintf(stderr, "Error: invalid argument '%s'.\n", argv[ai]);
122 return(1);
123 }
124 /* Did we get all the information that we need? */
125 if(!abssfile[0]) {
126 fprintf(stderr, "Error: missing command-line argument; use option --help\n");
127 return(1);
128 }
129 if(!outfile[0]) strcpy(outfile, abssfile);
130
131
132 /* In verbose mode print arguments and options */
133 if(verbose>1) {
134 printf("abssfile := %s\n", abssfile);
135 printf("startTime := %s\n", startTime);
136 printf("outfile := %s\n", outfile);
137 fflush(stdout);
138 }
139
140 /*
141 * Read ABSS file
142 */
143 if(verbose>1) printf("reading %s\n", abssfile);
144 TAC abss; tacInit(&abss);
145 ret=tacRead(&abss, abssfile, &status);
146 if(ret!=TPCERROR_OK) {
147 fprintf(stderr, "Error: %s\n", errorMsg(status.error));
148 tacFree(&abss); return(2);
149 }
150 if(verbose>1) {
151 printf("sampleNr := %d\n", abss.sampleNr);
152 }
153 if(verbose>2) {
154 printf("tacNr := %d\n", abss.tacNr);
155 }
156 if(verbose>1 || !startTime[0]) {
157 printf("fileformat := %s\n", tacFormattxt(abss.format));
158 }
159 if(abss.format!=TAC_FORMAT_ABSS_ALLOGG &&
163 {
164 fprintf(stderr, "Error: not valid ABSS format.\n");
165 tacFree(&abss); return(2);
166 }
167 if(verbose>100) abssWrite(&abss, stdout, NULL);
168 if(abss.tacNr<1 || abss.sampleNr<1) {
169 fprintf(stderr, "Error: not valid ABSS format.\n");
170 tacFree(&abss); return(2);
171 }
172
173 /* Print the sampler and sampling start times */
174 char samplerStartTime[128], sampleStartTime[128], zeroTime[128];
175 int ii;
176 ii=iftFindKey(&abss.h, "sampler_start_time", 0);
177 if(ii>=0) {
178 strlcpy(samplerStartTime, abss.h.item[ii].value, 32);
179 if(verbose>1)
180 fprintf(stdout, "sampler_start_time := %s\n", samplerStartTime);
181 } else {
182 strcpy(samplerStartTime, "");
183 }
184 if(tacGetHeaderScanstarttime(&abss.h, sampleStartTime, NULL)!=TPCERROR_OK) {
185 strcpy(sampleStartTime, "");
186 }
187 if(strDateTimeValid(sampleStartTime, NULL)!=0) {
188 fprintf(stderr, "Error: invalid start time in %s\n", abssfile);
189 tacFree(&abss); return(3);
190 }
191 strcpy(zeroTime, sampleStartTime);
192 fprintf(stdout, "zero_time := %8.8s\n", zeroTime+11);
193 if(fabs(abss.x1[0])>0.5) {
194 /* we must compute the time at first sample start */
195 struct tm starttm;
196 if(strDateTimeRead(sampleStartTime, &starttm)==0) {
197 tmAdd(abss.x1[0], &starttm);
198 if(strftime(sampleStartTime, 32, "%Y-%m-%d %H:%M:%S", &starttm)==0)
199 strcpy(sampleStartTime, "");
200 }
201 if(strDateTimeValid(sampleStartTime, NULL)!=0) {
202 fprintf(stderr, "Error: invalid start time in %s\n", abssfile);
203 tacFree(&abss); return(3);
204 }
205 }
206 fprintf(stdout, "date := %10.10s\n", sampleStartTime);
207 fprintf(stdout, "first_sample_time := %8.8s\n", sampleStartTime+11);
208 fflush(stdout);
209
210 /* Print the sampling frame duration */
211 fprintf(stdout, "sample_interval[s] := %g\n", abss.x2[0]-abss.x1[0]);
212 /* Print the total sampling duration */
213 fprintf(stdout, "sampling_time[s] := %g\n",
214 abss.x2[abss.sampleNr-1]-abss.x1[0]);
215 fflush(stdout);
216
217
218 /*
219 * If new start time was not specified, then stop here
220 */
221 if(!startTime[0]) {tacFree(&abss); return(0);}
222
223 /*
224 * If new zero time is not different to the current one, then stop here
225 */
226 struct tm newtm, oldtm;
227 char newZeroTime[128];
228 strlcpy(newZeroTime, zeroTime, 12);
229 strcat(newZeroTime, startTime);
230 if(verbose>3) printf("newZeroTime := %s\n", newZeroTime);
231 if(strDateTimeRead(newZeroTime, &newtm)!=0 ||
232 strDateTimeRead(zeroTime, &oldtm)!=0)
233 {
234 fprintf(stderr, "Error: invalid start times.\n");
235 tacFree(&abss); return(5);
236 }
237 double timeDiff=tmDifference(&newtm, &oldtm);
238 if(verbose>1) {
239 printf("required_start_time_change[s] := %g\n", timeDiff);
240 }
241 if(fabs(timeDiff)<1.0) {
242 fprintf(stdout, "Note: start times are not different; file not changed.\n");
243 tacFree(&abss); return(0);
244 }
245
246
247 /* Change the start time */
248 ret=tacSetHeaderScanstarttime(&abss.h, newZeroTime);
249 if(ret!=TPCERROR_OK) {
250 fprintf(stderr, "Error: cannot set new start time.\n");
251 tacFree(&abss); return(6);
252 }
253
254 /* Change also sample frame times for Allogg 1 */
256 for(int i=0; i<abss.sampleNr; i++) {
257 abss.x[i]-=timeDiff;
258 abss.x1[i]-=timeDiff;
259 abss.x2[i]-=timeDiff;
260 }
261 }
262
263
264
265 /*
266 * Write the modified file
267 */
268 if(verbose>1) {
269 printf("writing corrected data file in %s\n", outfile); fflush(stdout);}
270 FILE *fp;
271 fp=fopen(outfile, "w");
272 if(fp==NULL) {
273 fprintf(stderr, "Error: cannot open file for writing.\n");
274 tacFree(&abss); return(11);
275 }
276 ret=abssWrite(&abss, fp, &status);
277 fclose(fp);
278 if(ret!=TPCERROR_OK) {
279 fprintf(stderr, "Error: %s\n", errorMsg(status.error));
280 tacFree(&abss); return(12);
281 }
282 if(verbose>0) {
283 printf("corrected data written in %s\n", outfile);
284 fflush(stdout);
285 }
286
287 tacFree(&abss);
288 return(0);
289}
290/*****************************************************************************/
291
292/*****************************************************************************/
int abssWrite(TAC *d, FILE *fp, TPCSTATUS *status)
Definition abssio.c:53
int strDateTimeRead(const char *str, struct tm *date)
Definition datetime.c:350
void tmAdd(int s, struct tm *d)
Definition datetime.c:500
int strTimeValid(const char *str)
Definition datetime.c:284
int strDateTimeValid(const char *str, char *intdate)
Definition datetime.c:308
double tmDifference(struct tm *tm1, struct tm *tm0)
Definition datetime.c:486
int iftFindKey(IFT *ift, const char *key, int start_index)
Definition iftfind.c:30
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
IFT_ITEM * item
Definition tpcift.h:57
Definition tpctac.h:87
double * x
Definition tpctac.h:97
tacformat format
Definition tpctac.h:93
int sampleNr
Definition tpctac.h:89
IFT h
Optional (but often useful) header information.
Definition tpctac.h:141
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 tacSetHeaderScanstarttime(IFT *h, const char *s)
Definition tacift.c:427
int tacGetHeaderScanstarttime(IFT *h, char *s, TPCSTATUS *status)
Definition tacift.c:372
int tacRead(TAC *d, const char *fname, TPCSTATUS *status)
Definition tacio.c:413
char * tacFormattxt(tacformat c)
Definition tacio.c:98
Header file for libtpcabss.
Header file for library libtpcextensions.
@ TPCERROR_OK
No error.
Header file for library libtpctac.
@ TAC_FORMAT_ABSS_ALLOGG
ALLOGG ABSS data; reading supported.
Definition tpctac.h:56
@ TAC_FORMAT_ABSS_GEMS
GEMS ABSS data; reading supported.
Definition tpctac.h:54
@ TAC_FORMAT_ABSS_ALLOGG_OLD
ALLOGG ABSS data (old format); reading supported.
Definition tpctac.h:55
@ TAC_FORMAT_ABSS_SCANDITRONICS
Scanditronics ABSS data; reading supported.
Definition tpctac.h:53