TPCCLIB
Loading...
Searching...
No Matches
dftcat.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 <math.h>
14#include <unistd.h>
15#include <string.h>
16/*****************************************************************************/
17#include "libtpcmisc.h"
18#include "libtpccurveio.h"
19/*****************************************************************************/
20
21/*****************************************************************************/
22static char *info[] = {
23 "Catenate the TACs from the second TAC file to the first one, or to a new",
24 "datafile. Sample times or correction for physical decay are not changed.",
25 " ",
26 "Deprecated. Please use taccat instead.",
27 " ",
28 "Usage: @P tacfile1 tacfile2 [catenated_file]",
29 " ",
30 "Options:",
31 " -both | -first | -second | -cut=<time>",
32 " In case of overlapping samples, either samples from both (-both),",
33 " first (-first), or second (-second, default) TAC are saved in",
34 " combined file, or specified cut time is used.",
35 " Cut time can also be given in file with keys 'x' or 'time'.",
36 " -stdoptions", // List standard options like --help, -v, etc
37 " ",
38 "Example:",
39 " @P t455ap_pump.kbq t455ap_manual.kbq t455ap_combined.kbq",
40 " ",
41 "See also: taccat, taccut, tacadd, tactime, inpstart, taccross, tacframe",
42 " ",
43 "Keywords: TAC, input, blood, modelling, tool, simulation",
44 0};
45/*****************************************************************************/
46
47/*****************************************************************************/
48/* Turn on the globbing of the command line, since it is disabled by default in
49 mingw-w64 (_dowildcard=0); in MinGW32 define _CRT_glob instead, if necessary;
50 In Unix&Linux wildcard command line processing is enabled by default. */
51/*
52#undef _CRT_glob
53#define _CRT_glob -1
54*/
55int _dowildcard = -1;
56/*****************************************************************************/
57
58/*****************************************************************************/
62int main(int argc, char **argv)
63{
64 int ai, help=0, version=0, verbose=1;
65 int ret, fi, voi=-1;
66 int useboth=0;
67 int overlap=0;
68 int more_reliable=1; /* In case of overlapping data, which one is
69 considered more reliable: 0=first, or 1=second curve */
70 DFT data1, data2, data3;
71 char *cptr, dfile1[FILENAME_MAX], dfile2[FILENAME_MAX], rfile[FILENAME_MAX];
72 double cut_time=-1.0E+20;
73 int unit1, unit2;
74
75
76 /*
77 * Get arguments
78 */
79 if(argc==1) {tpcPrintUsage(argv[0], info, stderr); return(1);}
80 dfile1[0]=dfile2[0]=rfile[0]=(char)0;
81 dftInit(&data1); dftInit(&data2); dftInit(&data3);
82 /* Options */
83 for(ai=1; ai<argc; ai++) if(*argv[ai]=='-') {
84 cptr=argv[ai]+1; if(*cptr=='-') cptr++; if(cptr==NULL) continue;
85 if(tpcProcessStdOptions(argv[ai], &help, &version, &verbose)==0) continue;
86 if(strncasecmp(cptr, "BOTH", 1)==0) {
87 useboth=1; cut_time=-1.0E+20; continue;
88 } else if(strncasecmp(cptr, "FIRST", 2)==0) {
89 more_reliable=0; useboth=0; continue;
90 } else if(strncasecmp(cptr, "SECOND", 2)==0) {
91 more_reliable=1; useboth=0; continue;
92 } else if(strncasecmp(cptr, "CUT=", 4)==0) {
93 cptr+=4;
94 /* Try as a value first */
95 if(atof_with_check(cptr, &cut_time)==0) {if(cut_time>0.0) continue;}
96 /* Then try as a IFT file */
97 if(access(cptr, 0)!=-1) {
98 IFT ift; iftInit(&ift); ret=iftRead(&ift, cptr, 1, 0);
99 if(ret==0) {
100 if(iftGetDoubleValue(&ift, 0, "x", &cut_time, 0)>=0 && cut_time>0.0) {
101 iftEmpty(&ift); continue;}
102 if(iftGetDoubleValue(&ift, 0, "time", &cut_time, 0)>=0 && cut_time>0.0) {
103 iftEmpty(&ift); continue;}
104 if(iftGetDoubleValue(&ift, 0, "cut", &cut_time, 0)>=0 && cut_time>0.0) {
105 iftEmpty(&ift); continue;}
106 iftEmpty(&ift);
107 }
108 }
109 }
110 fprintf(stderr, "Error: invalid option '%s'.\n", argv[ai]);
111 return(1);
112 } else break;
113
114 /* Print help or version? */
115 if(help==2) {tpcHtmlUsage(argv[0], info, ""); return(0);}
116 if(help) {tpcPrintUsage(argv[0], info, stdout); return(0);}
117 if(version) {tpcPrintBuild(argv[0], stdout); return(0);}
118
119 /* Process other arguments, starting from the first non-option */
120 for(; ai<argc; ai++) {
121 if(!dfile1[0]) {strcpy(dfile1, argv[ai]); continue;}
122 else if(!dfile2[0]) {strcpy(dfile2, argv[ai]); continue;}
123 else if(!rfile[0]) {strcpy(rfile, argv[ai]); continue;}
124 fprintf(stderr, "Error: invalid argument '%s'.\n", argv[ai]);
125 return(1);
126 }
127
128 /* Is something missing? */
129 if(!dfile2[0]) {
130 fprintf(stderr, "Error: missing command-line argument; try %s --help\n",
131 argv[0]);
132 return(1);
133 }
134 /* First file is also output file, if output file was not specified */
135 if(!rfile[0]) strcpy(rfile, dfile1);
136
137 /* In verbose mode print arguments and options */
138 if(verbose>1) {
139 printf("dfile1 := %s\n", dfile1);
140 printf("dfile2 := %s\n", dfile2);
141 printf("rfile := %s\n", rfile);
142 printf("useboth := %d\n", useboth);
143 printf("more_reliable := %d\n", more_reliable);
144 printf("cut_time := %g\n", cut_time);
145 }
146
147
148 /*
149 * Read data
150 */
151 if(verbose>1) printf("reading %s\n", dfile1);
152 if(dftRead(dfile1, &data1)) {
153 fprintf(stderr, "Error in reading '%s': %s\n", dfile1, dfterrmsg);
154 return(2);
155 }
156 if(verbose>2) {
157 printf("voiNr1 := %d\n", data1.voiNr);
158 printf("frameNr1 := %d\n", data1.frameNr);
159 }
160 dftSortByFrame(&data1);
161
162 if(verbose>1) printf("reading %s\n", dfile2);
163 if(dftRead(dfile2, &data2)) {
164 fprintf(stderr, "Error in reading '%s': %s\n", dfile2, dfterrmsg);
165 return(2);
166 }
167 if(verbose>2) {
168 printf("voiNr2 := %d\n", data2.voiNr);
169 printf("frameNr2 := %d\n", data2.frameNr);
170 }
171 dftSortByFrame(&data2);
172
173 /* Check that files have equal nr of regions */
174 if(data1.voiNr!=data2.voiNr) {
175 fprintf(stderr, "Error: different nr of regions.\n");
176 dftEmpty(&data1); dftEmpty(&data2); return(3);
177 }
178
179 /* Check that files have the same time unit */
180 if(data1.timeunit==TUNIT_UNKNOWN || data2.timeunit==TUNIT_UNKNOWN) {
181 fprintf(stderr, "Warning: unknown time units.\n");
182 if(data1.timeunit!=TUNIT_UNKNOWN) data2.timeunit=data1.timeunit;
183 else if(data2.timeunit!=TUNIT_UNKNOWN) data1.timeunit=data2.timeunit;
184 } else {
185 if(data1.timeunit!=data2.timeunit) {
186 fprintf(stderr, "Warning: different time units.\n");
187 if(verbose>0)
188 fprintf(stdout, " converting units '%s' to '%s'\n",
189 petTunit(data2.timeunit), petTunit(data1.timeunit));
190 ret=dftTimeunitConversion(&data2, data1.timeunit);
191 if(ret!=0) {
192 fprintf(stderr, "Error: cannot convert time units.\n");
193 dftEmpty(&data1); dftEmpty(&data2); return(3);
194 }
195 }
196 }
197
198 /* Check that files have the same concentration unit */
199 unit1=dftUnitId(data1.unit);
200 unit2=dftUnitId(data2.unit);
201 if(unit1==CUNIT_UNKNOWN || unit2==CUNIT_UNKNOWN) {
202 fprintf(stderr, "Warning: unknown concentration units.\n");
203 if(unit1!=CUNIT_UNKNOWN) strcpy(data2.unit, data1.unit);
204 else if(unit2!=CUNIT_UNKNOWN) strcpy(data1.unit, data2.unit);
205 } else {
206 if(unit1!=unit2) {
207 fprintf(stderr, "Warning: different concentration units.\n");
208 if(verbose>0)
209 fprintf(stdout, " converting units '%s' to '%s'\n",
210 petCunit(unit2), petCunit(unit1));
211 ret=dftUnitConversion(&data2, unit1);
212 if(ret!=0) {
213 fprintf(stderr, "Error: cannot convert concentration units.\n");
214 dftEmpty(&data1); dftEmpty(&data2); return(3);
215 }
216 }
217 }
218
219 /* Deal with possible overlap */
220 /* Check that start times do not overlap, unless delt with options */
221 ret=0;
222 if(data1.timetype==DFT_TIME_STARTEND) {
223 if(data1.x1[0]>data2.x[0] && useboth==0 && cut_time<0.0) ret=1;
224 } else if(data2.timetype==DFT_TIME_STARTEND) {
225 if(data1.x[0]>data2.x2[0] && useboth==0 && cut_time<0.0) ret=2;
226 } else {
227 if(data1.x[0]>data2.x[0] && useboth==0 && cut_time<0.0) ret=3;
228 }
229 if(ret) {
230 fprintf(stderr, "Error: check datafile times and their order!\n");
231 dftEmpty(&data1); dftEmpty(&data2); return(4);
232 }
233 if(cut_time>=0.0 && data1.x[data1.frameNr-1]>=data2.x[0]) {
234 /* use user-given cut time to solve overlap */
235 if(data1.x[data1.frameNr-1]>=cut_time && data2.x[0]<cut_time) {
236 /* It is necessary to cut from both tacs */
237 if(verbose>1) printf("cutting both TACs at %g\n", cut_time);
238 ret=dftRemoveTimeRange(&data1, data1.x[0]-1.0, cut_time);
239 if(ret==0) ret=dftRemoveTimeRange(&data2, cut_time,
240 data2.x[data2.frameNr-1]+1.0);
241 if(ret!=0) {
242 fprintf(stderr, "Error: invalid cut time.\n");
243 dftEmpty(&data1); dftEmpty(&data2); return(4);
244 }
245 } else if(data2.x[0]<cut_time) {
246 /* 2nd tac will be cut later */
247 more_reliable=0;
248 } else if(data1.x[data1.frameNr-1]>=cut_time) {
249 /* 1st tac will be cut later */
250 more_reliable=1;
251 }
252 }
253 if(data1.x[data1.frameNr-1]>=data2.x[0]) {
254 overlap=1;
255 if(verbose>0 && cut_time<0.0 && useboth==0)
256 fprintf(stderr, "Warning: times in datafiles overlap.\n");
257 if(useboth==0) {
258 /* Overlapping data is not allowed */
259 if(more_reliable==1) { // second tac is more reliable
260 ret=dftRemoveTimeRange(&data1, data1.x[0]-1.0, data2.x[0]-1.0E-10);
261 if(ret!=0 || data1.frameNr==0) {
262 fprintf(stderr, "Error: check datafile times and their order!\n");
263 dftEmpty(&data1); dftEmpty(&data2); return(4);
264 }
265 } else { // first tac is more reliable
266 /* Remove the overlapping part from the second tac */
267 ret=dftRemoveTimeRange(&data2, data1.x[data1.frameNr-1]+1.0E-10,
268 data2.x[data2.frameNr-1]+1.0);
269 if(ret!=0) {
270 fprintf(stderr, "Error: check datafile times and their order!\n");
271 dftEmpty(&data1); dftEmpty(&data2); return(4);
272 }
273 if(data2.frameNr<1)
274 if(verbose>0) fprintf(stderr, "Warning: datafiles overlap fully.\n");
275 }
276 }
277 if(verbose>2) {
278 printf("first_tac_range := %g - %g\n",
279 data1.x[0], data1.x[data1.frameNr-1]);
280 printf("second_tac_range := %g - %g\n",
281 data2.x[0], data2.x[data2.frameNr-1]);
282 }
283 }
284
285
286 /*
287 * Make catenated data
288 */
289 /* Allocate memory for it */
290 if(dftSetmem(&data3, data1.frameNr+data2.frameNr, data1.voiNr)){
291 fprintf(stderr, "Error: cannot allocate memory.\n");
292 dftEmpty(&data1); dftEmpty(&data2); return(5);
293 }
294 data3.frameNr=data1.frameNr+data2.frameNr;
295 data3.voiNr=data1.voiNr;
296 /* Set headers */
297 (void)dftCopymainhdr2(&data1, &data3, 1);
298 (void)dftCopymainhdr2(&data2, &data3, 0); // only missing fields
299 for(voi=0; voi<data1.voiNr; voi++)
300 (void)dftCopyvoihdr(&data1, voi, &data3, voi);
301 if(strlen(data3.studynr)==0) strcpy(data3.studynr, data2.studynr);
302 if(strlen(data3.unit)==0) strcpy(data3.unit, data2.unit);
303 if(data3.timeunit==TUNIT_UNKNOWN) data3.timeunit=data2.timeunit;
304 if(data3._type!=data2._type) {
305 if(data2._type==DFT_FORMAT_STANDARD) data3._type=data2._type;
306 }
308 /* Copy data from first file */
309 for(fi=0; fi<data1.frameNr; fi++) {
310 data3.x[fi]=data1.x[fi];
311 data3.x1[fi]=data1.x1[fi]; data3.x2[fi]=data1.x2[fi];
312 for(voi=0; voi<data1.voiNr; voi++)
313 data3.voi[voi].y[fi]=data1.voi[voi].y[fi];
314 }
315 /* Copy data from second file */
316 for(fi=0; fi<data2.frameNr; fi++) {
317 data3.x[data1.frameNr+fi]=data2.x[fi];
318 data3.x1[data1.frameNr+fi]=data2.x1[fi];
319 data3.x2[data1.frameNr+fi]=data2.x2[fi];
320 for(voi=0; voi<data1.voiNr; voi++)
321 data3.voi[voi].y[data1.frameNr+fi]=data2.voi[voi].y[fi];
322 }
323 /* Turn weights off */
324 data3.isweight=0;
325 /* Sort data by increasing sample time, if necessary */
326 if(overlap && useboth) ret=dftSortByFrame(&data3);
327
328 /* Add comment */
329 dftSetComments(&data3);
330 //strcpy(data3.comments, data.comments);
331 //strcat(data3.comments, data2.comments);
332 strcat(data3.comments, "# catenated\n");
333
334
335 /* Save data */
336 ret=dftWrite(&data3, rfile);
337 if(ret) {
338 fprintf(stderr, "Error (%d) in writing '%s': %s\n", ret, rfile, dfterrmsg);
339 dftEmpty(&data1); dftEmpty(&data2); dftEmpty(&data3);
340 return(11);
341 }
342 if(verbose>0)
343 printf(" %d+%d=%d frames written in %s\n", data1.frameNr, data2.frameNr,
344 data3.frameNr, rfile);
345
346 /* Free memory */
347 dftEmpty(&data1); dftEmpty(&data2); dftEmpty(&data3);
348
349 return(0);
350}
351/*****************************************************************************/
352
353/*****************************************************************************/
int atof_with_check(char *double_as_string, double *result_value)
Definition decpoint.c:107
int dftCopyvoihdr(DFT *dft1, int from, DFT *dft2, int to)
Definition dft.c:623
int dftRemoveTimeRange(DFT *dft, double startT, double endT)
Definition dft.c:1275
void dftInit(DFT *data)
Definition dft.c:38
char dfterrmsg[64]
Definition dft.c:6
void dftSetComments(DFT *dft)
Definition dft.c:1326
int dftSortByFrame(DFT *dft)
Definition dft.c:1169
int dftCopymainhdr2(DFT *dft1, DFT *dft2, int ow)
Definition dft.c:587
int dftSetmem(DFT *data, int frameNr, int voiNr)
Definition dft.c:57
void dftEmpty(DFT *data)
Definition dft.c:20
int dftRead(char *filename, DFT *data)
Definition dftio.c:22
int dftWrite(DFT *data, char *filename)
Definition dftio.c:594
int dftUnitConversion(DFT *dft, int dunit)
Definition dftunit.c:25
int dftTimeunitConversion(DFT *dft, int tunit)
Definition dftunit.c:119
void iftEmpty(IFT *ift)
Definition ift.c:60
void iftInit(IFT *ift)
Definition ift.c:45
int iftRead(IFT *ift, char *filename, int is_key_required, int verbose)
Definition iftfile.c:24
int iftGetDoubleValue(IFT *ift, int si, const char *key, double *value, int verbose)
Definition iftsrch.c:268
Header file for libtpccurveio.
#define DFT_TIME_MIDDLE
#define DFT_FORMAT_STANDARD
#define DFT_TIME_STARTEND
Header file for libtpcmisc.
int tpcProcessStdOptions(const char *s, int *print_usage, int *print_version, int *verbose_level)
Definition proginfo.c:40
char * petCunit(int cunit)
Definition petunits.c:211
char * petTunit(int tunit)
Definition petunits.c:226
int tpcHtmlUsage(const char *program, char *text[], const char *path)
Definition proginfo.c:213
void tpcPrintBuild(const char *program, FILE *fp)
Definition proginfo.c:383
void tpcPrintUsage(const char *program, char *text[], FILE *fp)
Definition proginfo.c:158
int _type
int timetype
Voi * voi
int timeunit
char studynr[MAX_STUDYNR_LEN+1]
double * x1
char comments[_DFT_COMMENT_LEN+1]
int voiNr
double * x2
int frameNr
int isweight
double * x
char unit[MAX_UNITS_LEN+1]
double * y