TPCCLIB
Loading...
Searching...
No Matches
sifcat.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#include <unistd.h>
15/*****************************************************************************/
16#include "tpcextensions.h"
17#include "tpccsv.h"
18#include "tpcift.h"
19#include "tpctac.h"
20/*****************************************************************************/
21
22/*****************************************************************************/
23static char *info[] = {
24 "Catenate the scan information files (SIF) from interrupted PET studies",
25 "into a single SIF file.",
26 " ",
27 "Usage: @P [options] combined_sif sif1 sif2 [sif3]",
28 " ",
29 "Usage: @P [options] filename(s) [isotope code]",
30 " ",
31 "Options:",
32 " -stdoptions", // List standard options like --help, -v, etc
33 " ",
34 "Example:",
35 " @P ub0371dy.sif ub0371dy1.sif ub0371dy2.sif ub0371dy3.sif",
36 " ",
37 "See also: sifisot, taclist, eframe, tacframe, tacweigh, ecatcat",
38 " ",
39 "Keywords: SIF, image, catenate, time",
40 0};
41/*****************************************************************************/
42
43/*****************************************************************************/
44/* Turn on the globbing of the command line, since it is disabled by default in
45 mingw-w64 (_dowildcard=0); in MinGW32 define _CRT_glob instead, if necessary;
46 In Unix&Linux wildcard command line processing is enabled by default. */
47/*
48#undef _CRT_glob
49#define _CRT_glob -1
50*/
51int _dowildcard = -1;
52/*****************************************************************************/
53
54/*****************************************************************************/
55/*
56 * Main
57 */
58int main(int argc, char *argv[])
59{
60 int ai, help=0, version=0, verbose=1;
61 char siffile[FILENAME_MAX], catfile[FILENAME_MAX];
62 int ret, ffi=0, fileNr=0;
63
64
65
66 /*
67 * Get arguments
68 */
69 if(argc==1) {tpcPrintUsage(argv[0], info, stderr); return(1);}
70 siffile[0]=catfile[0]=(char)0;
71 /* Options */
72 for(ai=1; ai<argc; ai++) if(*argv[ai]=='-') {
73 if(tpcProcessStdOptions(argv[ai], &help, &version, &verbose)==0) continue;
74 //cptr=argv[ai]+1; if(*cptr=='-') cptr++; if(!*cptr) continue;
75 fprintf(stderr, "Error: invalid option '%s'\n", argv[ai]);
76 return(1);
77 } else break; // tac name argument may start with '-'
78
79 /* Print help or version? */
80 if(help==2) {tpcHtmlUsage(argv[0], info, ""); return(0);}
81 if(help) {tpcPrintUsage(argv[0], info, stdout); return(0);}
82 if(version) {tpcPrintBuild(argv[0], stdout); return(0);}
83
84 TPCSTATUS status; statusInit(&status);
85 statusSet(&status, __func__, __FILE__, __LINE__, TPCERROR_OK);
86 status.verbose=verbose-1;
87
88 /* Process other arguments, starting from the first non-option */
89 if(ai<argc) {strlcpy(catfile, argv[ai++], FILENAME_MAX);}
90 fileNr=ffi=0;
91 for(; ai<argc; ai++) {
92 if(ffi<1) ffi=ai;
93 fileNr++;
94 }
95 if(fileNr<2) {
96 fprintf(stderr, "Error: missing command-line argument; use option --help\n");
97 return(1);
98 }
99
100 /* In verbose mode print arguments and options */
101 if(verbose>1) {
102 printf("catfile := %s\n", catfile);
103 printf("fileNr := %d\n", fileNr);
104 fflush(stdout);
105 }
106
107 /*
108 * Check that SIF files (except the result SIF file) do exist
109 */
110 for(ai=ffi; ai<argc; ai++) {
111 if(access(argv[ai], 0) == -1) {
112 fprintf(stderr, "Error: file %s not found.\n", argv[ai]);
113 return(2);
114 }
115 }
116 /* Check that output file does not exist */
117 if(access(catfile, 0) != -1) {
118 fprintf(stderr, "Warning: file %s exists.\n", catfile);
119 }
120
121
122 /*
123 * Read the first SIF (as TAC)
124 */
125 TAC tac; tacInit(&tac);
126 strlcpy(siffile, argv[ffi], FILENAME_MAX);
127 if(verbose>1) fprintf(stdout, "reading %s\n", siffile);
128 ret=tacRead(&tac, siffile, &status);
129 if(ret!=TPCERROR_OK) {
130 fprintf(stderr, "Error: %s\n", errorMsg(status.error));
131 if(verbose>1) printf("ret := %d\n", ret);
132 tacFree(&tac); return(4);
133 }
134 if(verbose>2) {
135 printf("fileformat := %s\n", tacFormattxt(tac.format));
136 printf("tacNr := %d\n", tac.tacNr);
137 printf("sampleNr := %d\n", tac.sampleNr);
138 }
139 if(tac.format!=TAC_FORMAT_SIF) {
140 fprintf(stderr, "Error: file is not in SIF format.\n");
141 tacFree(&tac); return(4);
142 }
143 /* Read scan start time */
144 char scan_start_time[256];
145 struct tm scantime1, scantime2;
146 ret=tacGetHeaderScanstarttime(&tac.h, scan_start_time, &status);
147 if(ret==TPCERROR_OK) ret=strDateTimeRead(scan_start_time, &scantime1);
148 if(ret!=0) {
149 if(verbose>0) fprintf(stderr, "Warning: cannot read scan start time.\n");
150 }
151
152 /*
153 * Add the following SIFs to the first one
154 */
155 TAC tac2; tacInit(&tac2);
156 for(ai=ffi+1; ai<argc; ai++) {
157
158 strlcpy(siffile, argv[ai], FILENAME_MAX);
159 if(verbose>1) fprintf(stdout, "reading %s\n", siffile);
160 ret=tacRead(&tac2, siffile, &status);
161 if(ret!=TPCERROR_OK) {
162 fprintf(stderr, "Error: %s\n", errorMsg(status.error));
163 if(verbose>1) printf("ret := %d\n", ret);
164 tacFree(&tac); return(5);
165 }
166 if(verbose>2) {
167 printf("fileformat := %s\n", tacFormattxt(tac2.format));
168 printf("tacNr := %d\n", tac2.tacNr);
169 printf("sampleNr := %d\n", tac2.sampleNr);
170 }
171 if(tac2.format!=TAC_FORMAT_SIF) {
172 fprintf(stderr, "Error: file is not in SIF format.\n");
173 tacFree(&tac); tacFree(&tac2); return(5);
174 }
175 /* Delete extra columns if necessary */
176 if(tac.tacNr<tac2.tacNr) tac2.tacNr=tac.tacNr;
177 /* Allocate more space to the first dataset */
178 ret=tacAllocateMoreSamples(&tac, tac2.sampleNr);
179 if(ret!=0) {
180 fprintf(stderr, "Error: cannot combine SIFs.\n");
181 tacFree(&tac); tacFree(&tac2); return(6);
182 }
183 /* Calculate and correct the difference between scan times (sec) */
184 ret=tacGetHeaderScanstarttime(&tac2.h, scan_start_time, &status);
185 if(ret==TPCERROR_OK) ret=strDateTimeRead(scan_start_time, &scantime2);
186 if(ret!=0) {
187 if(verbose>0) fprintf(stderr, "Warning: cannot read scan start time.\n");
188 } else {
189 double tdif=tmDifference(&scantime2, &scantime1);
190 if(verbose>1 || tdif<0.0)
191 printf("scan_start_time_difference[s] := %g\n", tdif);
192 if(tdif<0.0) fprintf(stderr, "Warning: SIFs in wrong order?\n");
193 for(int i=0; i<tac2.sampleNr; i++) {
194 tac2.x1[i]+=tdif; tac2.x2[i]+=tdif; tac2.x[i]+=tdif;
195 }
196 }
197 /* Add new data to the end of the existing data */
198 for(int i=0; i<tac2.sampleNr; i++) {
199 tac.x1[tac.sampleNr]=tac2.x1[i];
200 tac.x2[tac.sampleNr]=tac2.x2[i];
201 tac.x[tac.sampleNr] =tac2.x[i];
202 for(int j=0; j<tac2.tacNr; j++)
203 tac.c[j].y[tac.sampleNr]=tac2.c[j].y[i];
204 tac.sampleNr++;
205 }
206 tacFree(&tac2);
207 } /* next SIF */
208
209 /* Sort data by increasing frame time, in case SIFs were given
210 in wrong order */
211 tacSortByTime(&tac, &status);
212
213 /*
214 * Save the combined SIF
215 */
216 if(verbose>1) printf("writing %s\n", catfile);
217 FILE *fp; fp=fopen(catfile, "w");
218 if(fp==NULL) {
219 fprintf(stderr, "Error: cannot open file for writing.\n");
220 tacFree(&tac); return(11);
221 }
222 ret=tacWrite(&tac, fp, TAC_FORMAT_SIF, 1, &status);
223 fclose(fp);
224 if(ret!=TPCERROR_OK) {
225 fprintf(stderr, "Error: %s\n", errorMsg(status.error));
226 if(verbose>1) printf("ret := %d\n", ret);
227 tacFree(&tac); return(12);
228 }
229 if(verbose>0) printf("catenated file saved in %s\n", catfile);
230
231 tacFree(&tac);
232
233 return(0);
234}
235/*****************************************************************************/
236
237/*****************************************************************************/
int strDateTimeRead(const char *str, struct tm *date)
Definition datetime.c:350
double tmDifference(struct tm *tm1, struct tm *tm0)
Definition datetime.c:486
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
double * y
Definition tpctac.h:75
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
TACC * c
Definition tpctac.h:117
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 tacAllocateMoreSamples(TAC *tac, int addNr)
Allocate memory for more samples in TAC data.
Definition tac.c:435
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
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
Header file for library libtpccsv.
Header file for library libtpcextensions.
@ TPCERROR_OK
No error.
Header file for library libtpcift.
Header file for library libtpctac.
@ TAC_FORMAT_SIF
Scan information file.
Definition tpctac.h:43