TPCCLIB
Loading...
Searching...
No Matches
tacmove.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 "tpcfileutil.h"
17#include "tpcift.h"
18#include "tpccsv.h"
19#include "tpcisotope.h"
20#include "tpctac.h"
21#include "tpctacmod.h"
22/*****************************************************************************/
23
24/*****************************************************************************/
25static char *info[] = {
26 "Move TAC(s) in time with interpolation, keeping the original sample times",
27 "or time frames in TAC file, and cause only minimal bias in AUC.",
28 " ",
29 "Usage: @P [Options] tacfile delay",
30 " ",
31 "Options:",
32 " -opposite",
33 " TACs are moved in opposite direction as specified in parameter file.",
34 " -simple",
35 " Simple linear interpolation is always used; possibly higher AUC bias.",
36 " -stdoptions", // List standard options like --help, -v, etc
37 " ",
38 "Delay time can be given as positive or negative value directly in the command",
39 "line, or as dT or deltaT in a parameter file for certain TACs if file",
40 "contains more than one TAC.",
41 " ",
42 "See also: tactime, tacframe, fitdelay, taccut, simframe, tacadd",
43 " ",
44 "Keywords: TAC, simulation, time delay",
45 0};
46/*****************************************************************************/
47
48/*****************************************************************************/
49/* Turn on the globbing of the command line, since it is disabled by default in
50 mingw-w64 (_dowildcard=0); in MinGW32 define _CRT_glob instead, if necessary;
51 In Unix&Linux wildcard command line processing is enabled by default. */
52/*
53#undef _CRT_glob
54#define _CRT_glob -1
55*/
56int _dowildcard = -1;
57/*****************************************************************************/
58
59/*****************************************************************************/
63int main(int argc, char **argv)
64{
65 int ai, help=0, version=0, verbose=1;
66 char tacfile[FILENAME_MAX], parfile[FILENAME_MAX];
67 int opposite=0;
68 int simple=0;
69 double delay=nan("");
70
71
72 /*
73 * Get arguments
74 */
75 if(argc==1) {tpcPrintUsage(argv[0], info, stderr); return(1);}
76 tacfile[0]=parfile[0]=(char)0;
77 /* Options */
78 for(ai=1; ai<argc; ai++) if(*argv[ai]=='-') {
79 if(tpcProcessStdOptions(argv[ai], &help, &version, &verbose)==0) continue;
80 char *cptr=argv[ai]+1; if(*cptr=='-') cptr++; if(!*cptr) continue;
81 if(strncasecmp(cptr, "OPPOSITE", 2)==0) {
82 opposite=1; continue;
83 } else if(strncasecmp(cptr, "SIMPLE", 4)==0) {
84 simple=1; continue;
85 }
86 fprintf(stderr, "Error: invalid option '%s'.\n", argv[ai]);
87 return(1);
88 } else break; // tac name argument may start with '-'
89
90 TPCSTATUS status; statusInit(&status);
91 statusSet(&status, __func__, __FILE__, __LINE__, TPCERROR_OK);
92 status.verbose=verbose-3;
93
94 /* Print help or version? */
95 if(help==2) {tpcHtmlUsage(argv[0], info, ""); return(0);}
96 if(help) {tpcPrintUsage(argv[0], info, stdout); return(0);}
97 if(version) {tpcPrintBuild(argv[0], stdout); return(0);}
98
99 /* The first argument (non-option) is the file name */
100 if(ai<argc) {strlcpy(tacfile, argv[ai], FILENAME_MAX); ai++;}
101 if(ai<argc) {strlcpy(parfile, argv[ai], FILENAME_MAX); ai++;}
102 else {fprintf(stderr, "Error: missing file name.\n"); return(1);}
103 /* check that there are no extra arguments */
104 if(ai<argc) {fprintf(stderr, "Error: extra command-line argument.\n"); return(1);}
105
106 /* Check that TAC file exists */
107 if(!fileExist(tacfile)) {
108 fprintf(stderr, "Error: file '%s' does not exist.\n", tacfile);
109 return(1);
110 }
111 /* Get delay time or parameter file */
112 if(!fileExist(parfile)) {
113 if(atofCheck(parfile, &delay)==0) {
114 parfile[0]=(char)0;
115 if(delay==0.0) {
116 fprintf(stderr, "Warning: zero delay time; file not modified.\n");
117 return(0);
118 }
119 } else {
120 fprintf(stderr, "Error: invalid argument for delay time: '%s'.\n", parfile);
121 return(1);
122 }
123 }
124
125 /* In verbose mode print arguments and options */
126 if(verbose>1) {
127 printf("tacfile := %s\n", tacfile);
128 if(parfile[0]) printf("parfile := %s\n", parfile);
129 if(isfinite(delay)) printf("delaytime := %g\n", delay);
130 printf("opposite := %d\n", opposite);
131 printf("simple := %d\n", simple);
132 fflush(stdout);
133 }
134
135
136 /*
137 * Read the file
138 */
139 if(verbose>1) printf("reading %s\n", tacfile);
140 TAC tac; tacInit(&tac);
141 if(tacRead(&tac, tacfile, &status)!=TPCERROR_OK) {
142 fprintf(stderr, "Error: %s\n", errorMsg(status.error));
143 tacFree(&tac); return(2);
144 }
145 if(verbose>1) {
146 printf("fileformat := %s\n", tacFormattxt(tac.format));
147 printf("tacNr := %d\n", tac.tacNr);
148 printf("sampleNr := %d\n", tac.sampleNr);
149 if(tac.isframe) printf("frames := yes\n"); else printf("frames := no\n");
150 printf("xunit := %s\n", unitName(tac.tunit));
151 printf("yunit := %s\n", unitName(tac.cunit));
152 fflush(stdout);
153 }
154 if(tacSortByTime(&tac, &status)!=TPCERROR_OK) {
155 fprintf(stderr, "Error: %s\n", errorMsg(status.error));
156 tacFree(&tac); return(2);
157 }
158 /* Fix any gaps and overlap in data if possible and if not then quit with error */
159 {
160 int ret=tacSetXContiguous(&tac);
161 if(ret!=TPCERROR_OK) {
162 fprintf(stderr, "Error: %s\n", errorMsg(ret));
163 tacFree(&tac); return(2);
164 }
165 }
166
167 /* Get and check TAC data range */
168 {
169 double xmin, xmax;
170 if(tacXRange(&tac, &xmin, &xmax)) {
171 fprintf(stderr, "Error: invalid sample range.\n");
172 tacFree(&tac); return(2);
173 }
174 if(verbose>1) printf("x_range: %g - %g\n", xmin, xmax);
175 if(!(xmax>xmin)) {fprintf(stderr, "Warning: check the sample times.\n"); fflush(stderr);}
176 }
177
178 /*
179 * If the parameter file was given, then read it
180 */
181 PAR par; parInit(&par);
182 int dti=0;
183 if(parfile[0]) {
184 if(verbose>1) printf("reading %s\n", parfile);
185 if(parRead(&par, parfile, &status)!=TPCERROR_OK) {
186 fprintf(stderr, "Error: %s\n", errorMsg(status.error));
187 tacFree(&tac); return(3);
188 }
189 if(verbose>2) {
190 printf("fileformat := %s\n", parFormattxt(par.format));
191 printf("parNr := %d\n", par.parNr);
192 printf("tacNr := %d\n", par.tacNr);
193 }
194 /* Determine which parameter is the delay time */
195 if(par.parNr>1) {
196 int n=parSelectParameters(&par, "delayT", 1, NULL);
197 if(n==0) n=parSelectParameters(&par, "dT", 1, NULL);
198 if(n==0) {
199 fprintf(stderr, "Error: cannot find delay time in %s\n", parfile);
200 tacFree(&tac); parFree(&par); return(3);
201 } else if(n>1) {
202 fprintf(stderr, "Error: cannot identify delay time in %s\n", parfile);
203 tacFree(&tac); parFree(&par); return(3);
204 }
205 for(int i=0; i<par.parNr; i++) if(par.n[i].sw) {dti=i; break;}
206 }
207 /* Change time unit if necessary */
208 if(tac.tunit==UNIT_MIN && par.n[dti].unit==UNIT_SEC) {
209 par.n[dti].unit=UNIT_MIN;
210 for(int i=0; i<par.tacNr; i++) par.r[i].p[dti]/=60.0;
211 } else if(tac.tunit==UNIT_SEC && par.n[dti].unit==UNIT_MIN) {
212 par.n[dti].unit=UNIT_SEC;
213 for(int i=0; i<par.tacNr; i++) par.r[i].p[dti]*=60.0;
214 }
215 /* If only one delay time in parameter, then use it for all TACs */
216 if(par.tacNr==1) {
217 delay=par.r[0].p[dti];
218 if(opposite) delay=-delay;
219 if(verbose>1) printf("delaytime := %g\n", delay);
220 }
221 }
222
223
224 /*
225 * Change the sample times
226 */
227 int origframe=tac.isframe; if(simple) tac.isframe=0;
228 if(isfinite(delay)) {
229 /* Common delay time for all TACs */
230 if(tacDelay(&tac, delay, -1, &status)!=TPCERROR_OK) {
231 fprintf(stderr, "Error: cannot move TACs.\n");
232 tacFree(&tac); parFree(&par); return(4);
233 }
234 } else {
235 /* Separate delay time for TACs */
236 for(int i=0; i<tac.tacNr; i++) {
237 /* Try to find matching TAC in parameters data */
238 int pi=-1;
239 int n=parSelectTACs(&par, tac.c[i].name, 1, NULL);
240 if(n==0 && tac.tacNr==par.parNr) {
241 pi=i;
242 } else if(n==1) {
243 for(int j=0; j<par.tacNr; j++) if(par.r[j].sw) {pi=j; break;}
244 } else if(n>1) {
245 for(int j=0; j<par.tacNr; j++) if(par.r[j].sw && j==i) {pi=j; break;}
246 }
247 if(pi<0) {
248 fprintf(stderr, "Error: cannot identify delay time for %s\n", tac.c[i].name);
249 tacFree(&tac); parFree(&par); return(4);
250 }
251 delay=par.r[pi].p[dti]; if(opposite) delay=-delay;
252 if(verbose>3) printf(" Moving %s for %g\n", tac.c[i].name, delay);
253 if(tacDelay(&tac, delay, i, &status)!=TPCERROR_OK) {
254 fprintf(stderr, "Error: cannot move TAC.\n");
255 tacFree(&tac); parFree(&par); return(4);
256 }
257 }
258 }
259 parFree(&par);
260 if(simple) tac.isframe=origframe;
261
262
263 /*
264 * Save the modified data
265 */
266 if(verbose>1) printf("saving modified data in %s\n", tacfile);
267 {
268 FILE *fp; fp=fopen(tacfile, "w");
269 if(fp==NULL) {
270 fprintf(stderr, "Error: cannot open file for writing\n");
271 tacFree(&tac); return(11);
272 }
273 int ret=tacWrite(&tac, fp, TAC_FORMAT_UNKNOWN, 1, &status);
274 fclose(fp);
275 if(ret!=TPCERROR_OK) {
276 fprintf(stderr, "Error: %s\n", errorMsg(status.error));
277 tacFree(&tac); return(12);
278 }
279 }
280 tacFree(&tac);
281
282 return(0);
283}
284/*****************************************************************************/
285
286/*****************************************************************************/
int atofCheck(const char *s, double *v)
Definition decpoint.c:94
int tacDelay(TAC *tac, double dt, int ti, TPCSTATUS *status)
Move TAC y values (concentrations) in time, keeping sample times (x values) intact.
Definition delay.c:29
int fileExist(const char *filename)
Definition filexist.c:17
void parFree(PAR *par)
Definition par.c:75
void parInit(PAR *par)
Definition par.c:25
char * parFormattxt(parformat c)
Definition pario.c:59
int parRead(PAR *par, const char *fname, TPCSTATUS *status)
Definition pario.c:232
int parSelectTACs(PAR *d, const char *region_name, int reset, TPCSTATUS *status)
Definition parselect.c:24
int parSelectParameters(PAR *d, const char *par_name, int reset, TPCSTATUS *status)
Definition parselect.c:120
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
Definition tpcpar.h:100
int format
Definition tpcpar.h:102
int parNr
Definition tpcpar.h:108
int tacNr
Definition tpcpar.h:104
PARR * r
Definition tpcpar.h:114
PARN * n
Definition tpcpar.h:112
int unit
Definition tpcpar.h:86
char sw
Definition tpcpar.h:94
char sw
Definition tpcpar.h:74
double * p
Definition tpcpar.h:64
char name[MAX_TACNAME_LEN+1]
Definition tpctac.h:81
Definition tpctac.h:87
unit cunit
Definition tpctac.h:105
tacformat format
Definition tpctac.h:93
int sampleNr
Definition tpctac.h:89
int isframe
Definition tpctac.h:95
TACC * c
Definition tpctac.h:117
unit tunit
Definition tpctac.h:109
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 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
int tacSetXContiguous(TAC *d)
Set PET TAC frame times contiguous, without even tiny overlap or gaps in between.
Definition tacx.c:1166
int tacXRange(TAC *d, double *xmin, double *xmax)
Get the range of x values (times) in TAC structure.
Definition tacx.c:124
Header file for library libtpccsv.
Header file for library libtpcextensions.
@ UNIT_MIN
minutes
@ UNIT_SEC
seconds
@ TPCERROR_OK
No error.
char * unitName(int unit_code)
Definition units.c:143
Header file for libtpcfileutil.
Header file for library libtpcift.
Header file for library libtpcisotope.
Header file for library libtpctac.
@ TAC_FORMAT_UNKNOWN
Unknown format.
Definition tpctac.h:28
Header file for libtpctacmod.