TPCCLIB
Loading...
Searching...
No Matches
tacframe.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 <unistd.h>
14#include <string.h>
15#include <math.h>
16/*****************************************************************************/
17#include "tpcextensions.h"
18//#include "tpcift.h"
19#include "tpctac.h"
20/*****************************************************************************/
21
22/*****************************************************************************/
23static char *info[] = {
24 "Print or edit the frame times in regional TAC datafile.",
25 " ",
26 "By default, frame start times and lengths are printed on screen, and",
27 "optionally saved in the SIF (scan information file), if it does not exist.",
28 "If an existing SIF name is specified, the SIF frames are written into",
29 "regional TAC file; also normal TAC file containing frame start and end times",
30 "can be given instead of SIF.",
31 " ",
32 "Usage: @P [options] tacfile sif",
33 " ",
34 "Options:",
35 " -mid",
36 " Frame mid time is written in TAC file instead of frame start and end",
37 " times that are read from SIF. Not effective when writing SIF.",
38 " -stdoptions", // List standard options like --help, -v, etc
39 " ",
40 "Example:",
41 " @P iea567.tac iea567dy.img.sif",
42 " ",
43 "See also: tactime, tacsetx, interpol, taccat, taccut, simframe, tacformat",
44 " ",
45 "Keywords: TAC, SIF, tool, time",
46 0};
47/*****************************************************************************/
48
49/*****************************************************************************/
50/* Turn on the globbing of the command line, since it is disabled by default in
51 mingw-w64 (_dowildcard=0); in MinGW32 define _CRT_glob instead, if necessary;
52 In Unix&Linux wildcard command line processing is enabled by default. */
53/*
54#undef _CRT_glob
55#define _CRT_glob -1
56*/
57int _dowildcard = -1;
58/*****************************************************************************/
59
60/*****************************************************************************/
64int main(int argc, char **argv)
65{
66 int ai, help=0, version=0, verbose=1;
67 int ret;
68 int opMode=1; // 0=change, 1=list but do not save, 2=list and save
69 int isframe=1; // 0=save frame mid times, 1=save frame start and end times
70 char *cptr, tacfile[FILENAME_MAX], siffile[FILENAME_MAX];
71 TAC tac, sif;
72
73
74 /*
75 * Get arguments
76 */
77 if(argc==1) {tpcPrintUsage(argv[0], info, stderr); return(1);}
78 tacInit(&tac); tacInit(&sif);
79 tacfile[0]=siffile[0]=(char)0;
80 /* Options */
81 for(ai=1; ai<argc; ai++) if(*argv[ai]=='-') {
82 if(tpcProcessStdOptions(argv[ai], &help, &version, &verbose)==0) continue;
83 cptr=argv[ai]+1; if(*cptr=='-') cptr++; if(!*cptr) continue;
84 if(strncasecmp(cptr, "MIDDLE", 3)==0) {
85 isframe=0; continue;
86 }
87 fprintf(stderr, "Error: invalid option '%s'\n", argv[ai]);
88 return(1);
89 } else break; // tac name argument may start with '-'
90
91 TPCSTATUS status; statusInit(&status);
92 statusSet(&status, __func__, __FILE__, __LINE__, TPCERROR_OK);
93 status.verbose=verbose-3;
94
95 /* Print help or version? */
96 if(help==2) {tpcHtmlUsage(argv[0], info, ""); return(0);}
97 if(help) {tpcPrintUsage(argv[0], info, stdout); return(0);}
98 if(version) {tpcPrintBuild(argv[0], stdout); return(0);}
99
100 /* Process other arguments, starting from the first non-option */
101 for(; ai<argc; ai++) {
102 if(!tacfile[0]) {
103 strlcpy(tacfile, argv[ai], FILENAME_MAX); continue;
104 } else if(!siffile[0]) {
105 strlcpy(siffile, argv[ai], FILENAME_MAX); continue;
106 }
107 fprintf(stderr, "Error: too many arguments: '%s'.\n", argv[ai]);
108 return(1);
109 }
110
111 /* In verbose mode print arguments and options */
112 if(verbose>1) {
113 printf("tacfile := %s\n", tacfile);
114 printf("siffile := %s\n", siffile);
115 printf("isframe := %d\n", isframe);
116 }
117
118 /* Did we get all the information that we need? */
119 if(!tacfile[0]) {
120 fprintf(stderr, "Error: missing TAC name.\n");
121 return(1);
122 }
123
124 /* Read the TAC file */
125 if(verbose>1) printf("reading %s\n", tacfile);
126 ret=tacRead(&tac, tacfile, &status);
127 if(ret!=TPCERROR_OK) {
128 fprintf(stderr, "Error (%d): %s\n", ret, errorMsg(status.error));
129 tacFree(&tac); return(2);
130 }
131 if(verbose>2) {
132 printf("fileformat := %s\n", tacFormattxt(tac.format));
133 printf("tacNr := %d\n", tac.tacNr);
134 printf("sampleNr := %d\n", tac.sampleNr);
135 printf("tac_frames := %d\n", tac.isframe);
136 }
137 if(tac.tunit==UNIT_UNKNOWN) {
138 if(verbose>=0)
139 fprintf(stdout, "Warning: unknown time unit in %s\n", tacfile);
140 }
141
142 /* If SIF name was given by user, check if it exists */
143 if(siffile[0]) {
144 /* Check if file exists */
145 if(access(siffile, 0) != -1) {
146 opMode=0; /* SIF exists; change frames */
147 } else {
148 opMode=2; /* not existing; so create it */
149 }
150 } else
151 opMode=1; /* SIF not specified; just list frames */
152 if(verbose>2) printf("opMode := %d\n", opMode);
153
154
155 /*
156 * Read new frames from frame file, set frames and save TAC file
157 */
158 if(opMode==0) {
159 if(verbose>1) printf("reading %s\n", siffile);
160 ret=tacRead(&sif, siffile, &status);
161 if(ret!=TPCERROR_OK) {
162 fprintf(stderr, "Error (%d): %s\n", ret, errorMsg(status.error));
163 tacFree(&tac); tacFree(&sif); return(3);
164 }
165 if(verbose>2) {
166 printf("siffileformat := %s\n", tacFormattxt(sif.format));
167 printf("siftacNr := %d\n", sif.tacNr);
168 printf("sifsampleNr := %d\n", sif.sampleNr);
169 printf("sifisframe := %d\n", sif.isframe);
170 }
171 if(sif.tunit==UNIT_UNKNOWN) {
172 if(verbose>=0)
173 fprintf(stdout, "Warning: unknown time unit in %s\n", siffile);
174 }
175 /* Check that frame number is the same */
176 if(tac.sampleNr>sif.sampleNr) {
177 fprintf(stderr, "Error: different frame numbers.\n");
178 tacFree(&tac); tacFree(&sif); return(3);
179 } else if(tac.sampleNr<sif.sampleNr) {
180 fprintf(stderr, "Warning: different frame numbers.\n");
181 }
182 /* Check that frame start and end times are there, if required */
183 if(isframe==1 && sif.isframe==0) {
184 fprintf(stderr, "Error: no frame start and end times in %s\n", siffile);
185 tacFree(&tac); tacFree(&sif); return(3);
186 }
187 /* Convert SIF times to min if necessary */
188 if(tac.tunit==UNIT_MIN && sif.tunit==UNIT_SEC)
189 tacXUnitConvert(&sif, UNIT_MIN, &status);
190 /* Set TAC time units, if not previously known */
191 if(tac.tunit==UNIT_UNKNOWN) tac.tunit=sif.tunit;
192 /* Copy frame times */
193 ret=tacXCopy(&sif, &tac, 0, tac.sampleNr-1);
194 if(ret!=TPCERROR_OK) {
195 fprintf(stderr, "Error: cannot copy frame times.\n");
196 tacFree(&tac); tacFree(&sif); return(4);
197 }
198 tacFree(&sif);
199 /* Set output format */
200 tac.isframe=isframe;
201 if(isframe!=0) {
204 }
206 /* Save edited TAC data */
207 if(verbose>1) printf("writing %s\n", tacfile);
208 FILE *fp; fp=fopen(tacfile, "w");
209 if(fp==NULL) {
210 fprintf(stderr, "Error: cannot open file for writing (%s)\n", tacfile);
211 tacFree(&tac); return(5);
212 }
213 ret=tacWrite(&tac, fp, TAC_FORMAT_UNKNOWN, 1, &status);
214 fclose(fp);
215 if(ret!=TPCERROR_OK) {
216 fprintf(stderr, "Error (%d): %s\n", ret, errorMsg(status.error));
217 tacFree(&tac); return(6);
218 }
219 }
220
221
222 /*
223 * Create SIF file based on TAC file if necessary
224 */
225 if(opMode==2) {
226 if(verbose>1) printf("creating SIF data from regional TAC data\n");
227 /* Set file format */
229 /* Convert time units to sec if necessary */
230 int m2s=0;
231 if(tac.tunit==UNIT_MIN) {tacXUnitConvert(&sif, UNIT_SEC, &status); m2s=1;}
232 /* Check that data contains frame start and end times */
233 if(tac.isframe==0) {
234 if(verbose>2)
235 printf("original data does not contain frame start and end times\n");
236 if(tacSetX(&tac, &status)!=TPCERROR_OK) {
237 fprintf(stderr, "Error: data does not contain valid frame times.\n");
238 tacFree(&tac); return(4);
239 }
240 }
241 tac.isframe=1;
242 /* Set tacNr to zero to save only frame times */
243 int bnr=tac.tacNr; tac.tacNr=0;
244 /* Save edited TAC data as SIF */
245 if(verbose>1) printf("writing %s\n", siffile);
246 FILE *fp; fp=fopen(siffile, "w");
247 if(fp==NULL) {
248 fprintf(stderr, "Error: cannot open file for writing (%s)\n", siffile);
249 tacFree(&tac); return(5);
250 }
251 ret=tacWriteSIF(&tac, fp, 0, &status);
252 fclose(fp);
253 if(ret!=TPCERROR_OK) {
254 fprintf(stderr, "Error (%d): %s\n", ret, errorMsg(status.error));
255 tacFree(&tac); return(6);
256 }
257 tac.tacNr=bnr;
258 if(m2s!=0) tacXUnitConvert(&sif, UNIT_MIN, &status);
259 }
260
261
262 /*
263 * List frame lengths on screen
264 */
265 if(opMode==1 && tac.isframe==0) {
266 fprintf(stderr, "Error: no frame start and end times in %s\n", tacfile);
267 tacFree(&tac); return(9);
268 }
269 if(opMode==1 || verbose>1) {
270 fprintf(stdout, "# Frame start and length\n");
271 for(int fi=0; fi<tac.sampleNr; fi++) {
272 fprintf(stdout, "%g %g\n", tac.x1[fi], tac.x2[fi]-tac.x1[fi]);
273 }
274 }
275
276
277 /* Tell the user what he did */
278 if(verbose>0) {
279 if(opMode==0) {
280 printf("New frames saved in datafile %s\n", tacfile);
281 } else if(opMode==1) {
282 fprintf(stdout, "# %d frames were found in %s\n", tac.sampleNr, tacfile);
283 } else if(opMode==2) {
284 printf("# %d frames were found in %s; saved in %s\n",
285 tac.sampleNr, tacfile, siffile);
286 }
287 }
288
289 tacFree(&tac);
290 return(0);
291}
292/*****************************************************************************/
293
294/*****************************************************************************/
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
int tacWriteSIF(TAC *tac, FILE *fp, int extra, TPCSTATUS *status)
Definition sifio.c:26
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
tacformat format
Definition tpctac.h:93
int sampleNr
Definition tpctac.h:89
int isframe
Definition tpctac.h:95
double * x2
Definition tpctac.h:101
unit tunit
Definition tpctac.h:109
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 tacFormatWriteSupported(tacformat format)
Definition tacio.c:291
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 tacXUnitConvert(TAC *tac, const int u, TPCSTATUS *status)
Definition tacunits.c:23
int tacXCopy(TAC *tac1, TAC *tac2, int i1, int i2)
Definition tacx.c:24
int tacSetX(TAC *d, TPCSTATUS *status)
Set TAC x values based on x1 and x2 values, or guess x1 and x2 values based on x values.
Definition tacx.c:653
Header file for library libtpcextensions.
@ UNIT_MIN
minutes
@ UNIT_UNKNOWN
Unknown unit.
@ UNIT_SEC
seconds
@ TPCERROR_OK
No error.
Header file for library libtpctac.
@ TAC_FORMAT_IFT
Interfile-type data (supported for writing).
Definition tpctac.h:31
@ TAC_FORMAT_UNKNOWN
Unknown format.
Definition tpctac.h:28
@ TAC_FORMAT_PMOD
PMOD TAC format.
Definition tpctac.h:33
@ TAC_FORMAT_SIMPLE
x and y's with space delimiters
Definition tpctac.h:29
@ TAC_FORMAT_DFT
Data format of Turku PET Centre.
Definition tpctac.h:30
@ TAC_FORMAT_SIF
Scan information file.
Definition tpctac.h:43