TPCCLIB
Loading...
Searching...
No Matches
dftavg.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 <string.h>
15/*****************************************************************************/
16#include "libtpcmisc.h"
17#include "libtpccurveio.h"
18/*****************************************************************************/
19
20/*****************************************************************************/
21static char *info[] = {
22 "Calculate a volume weighted average TAC of specified regions in a TAC file.",
23 " ",
24 "Usage: @P [options] tacfile [tacid(s)]",
25 " ",
26 "Options:",
27 " -rm",
28 " Remove the original TACs after averaging.",
29 " -hem[isphere]",
30 " Average of hemispheres (dx and sin as the 2nd name field).",
31 " -stdoptions", // List standard options like --help, -v, etc
32 " ",
33 "Example 1: Average TAC of all TACs named as 'cer':",
34 " @P b123.dat cer",
35 " ",
36 "Example 2: Average TACs over planes of all regions separately;",
37 " remove the original TACs with option -rm.",
38 " @P -rm b123.dat",
39 " ",
40 "Example 3: Average of TAC numbers 4, 6 and 7:",
41 " @P b123.dat 4 6 7",
42 " ",
43 "Example 4: Average of hemispheres (dx and sin) of all regions separately;",
44 " remove the original TACs with option -rm.",
45 " @P -hemisphere -rm b123.dat",
46 " ",
47 "See also: taclist, tacdel, dftrmdpl, tacadd, avgttac, taccalc, tacmean",
48 " ",
49 "Keywords: TAC, modelling, tool, ROI, average",
50 0};
51/*****************************************************************************/
52
53/*****************************************************************************/
54/* Turn on the globbing of the command line, since it is disabled by default in
55 mingw-w64 (_dowildcard=0); in MinGW32 define _CRT_glob instead, if necessary;
56 In Unix&Linux wildcard command line processing is enabled by default. */
57/*
58#undef _CRT_glob
59#define _CRT_glob -1
60*/
61int _dowildcard = -1;
62/*****************************************************************************/
63
64/*****************************************************************************/
68int main(int argc, char **argv)
69{
70 int ai, help=0, version=0, verbose=1;
71 int fi, ri, rj;
72 int n, voi, ret, rmOrig=0, hemisphere=0, tacnamenr=0, operation=0;
73 DFT dft;
74 char *cptr, dfile[FILENAME_MAX];
75
76
77 /*
78 * Get arguments
79 */
80 if(argc==1) {tpcPrintUsage(argv[0], info, stderr); return(1);}
81 dfile[0]=(char)0;
82 dftInit(&dft);
83 /* Options */
84 for(ai=1; ai<argc; ai++) if(*argv[ai]=='-') {
85 cptr=argv[ai]+1; if(*cptr=='-') cptr++; if(cptr==NULL) continue;
86 if(tpcProcessStdOptions(argv[ai], &help, &version, &verbose)==0) continue;
87 if(strncasecmp(cptr, "HEMISPHERE", 3)==0) {
88 hemisphere=1; continue;
89 } else if(strcasecmp(cptr, "RM")==0 || strcasecmp(cptr, "DEL")==0) {
90 rmOrig=1; continue;
91 }
92 fprintf(stderr, "Error: invalid option %s\n", argv[ai]);
93 return(1);
94 } else break;
95
96 /* Print help or version? */
97 if(help==2) {tpcHtmlUsage(argv[0], info, ""); return(0);}
98 if(help) {tpcPrintUsage(argv[0], info, stdout); return(0);}
99 if(version) {tpcPrintBuild(argv[0], stdout); return(0);}
100
101 /* Process other arguments, starting from the first non-option */
102 for(; ai<argc; ai++) {
103 /* The first 'non-option' argument is the datafile */
104 if(!dfile[0]) {strcpy(dfile, argv[ai]); continue;}
105 /* The following ones are the TAC names */
106 if(tacnamenr==0) tacnamenr=ai;
107 }
108
109 /* Is something missing? */
110 if(!dfile[0]) {
111 fprintf(stderr, "Error: missing command-line argument; use option --help\n");
112 return(1);
113 }
114 /* decide what to do */
115 if(hemisphere>0) {
116 operation=1; /* separate avg over hemispheres for each region */
117 } else if(tacnamenr==0) {
118 operation=0; /* separate avg over planes for each region */
119 } else {
120 operation=2; /* avg of specified TACs */
121 }
122
123
124 /* In verbose mode print arguments and options */
125 if(verbose>1) {
126 printf("tacfile := %s\n", dfile);
127 printf("rmOrig := %d\n", rmOrig);
128 printf("hemisphere := %d\n", hemisphere);
129 printf("operation := %d\n", operation);
130 if(tacnamenr>0) {
131 printf("TACs :=");
132 for(ai=tacnamenr; ai<argc; ai++)
133 if(*argv[ai]!='-') printf(" '%s'", argv[ai]);
134 printf("\n");
135 }
136 }
137
138
139 /*
140 * Read TAC file
141 */
142 if(verbose>1) printf("reading %s\n", dfile);
143 if(dftRead(dfile, &dft)) {
144 fprintf(stderr, "Error in reading '%s': %s\n", dfile, dfterrmsg);
145 return(2);
146 }
147 if(verbose>1) {
148 printf(" tacNr := %d\n", dft.voiNr);
149 printf(" sampleNr := %d\n", dft.frameNr);
150 }
151
152 /*
153 * Find the TACs which are to be averaged with each other
154 */
155 /* first 'deselect' all */
156 for(ri=0; ri<dft.voiNr; ri++)
157 dft.voi[ri].sw=dft.voi[ri].sw2=dft.voi[ri].sw3=-1;
158 n=0;
159 if(operation==0) {
160 /* For each region, find the corresponding TACs with the same voiname */
161 /* and hemisphere */
162 for(ri=0; ri<dft.voiNr; ri++) {
163 /* not if already selected */
164 if(dft.voi[ri].sw2>=0) continue;
165 /* not if this is not a single plane */
166 if(strncasecmp(dft.voi[ri].place, "Pl", 2)) continue;
167 /* this is the first and it gets its own tac nr */
168 dft.voi[ri].sw2=ri; dft.voi[ri].sw3=1; n++;
169 /* then search the following tacs */
170 for(rj=ri+1; rj<dft.voiNr; rj++) {
171 /* not if already selected */
172 if(dft.voi[rj].sw2>=0) continue;
173 /* not if this is not a single plane */
174 if(strncasecmp(dft.voi[rj].place, "Pl", 2)) continue;
175 /* if voiname and hemisphere do match, then set the tac nr */
176 if(!strcasecmp(dft.voi[ri].voiname, dft.voi[rj].voiname) &&
177 !strcasecmp(dft.voi[ri].hemisphere, dft.voi[rj].hemisphere)) {
178 dft.voi[rj].sw2=ri;
179 dft.voi[ri].sw3++;
180 }
181 }
182 }
183 if(n<=0) {
184 fprintf(stderr, "Warning: no planes were found.\n");
185 dftEmpty(&dft); return(0);
186 }
187 } else if(operation==1) {
188 /* Find the dx&sin of separate regions */
189 /* Select the specified regions, or all if none was specified */
190 if(tacnamenr>0) {
191 for(ai=tacnamenr; ai<argc; ai++) if(*argv[ai]!='-') {
192 /* check if number was given; if not then find the names */
193 voi=atoi(argv[ai])-1;
194 if(voi>=0 && voi<dft.voiNr) dft.voi[voi].sw=1;
195 else dftSelect(&dft, argv[ai]);
196 }
197 } else {
198 for(ri=0; ri<dft.voiNr; ri++) dft.voi[ri].sw=1;
199 }
200 /* Set sw=1 if dx, sw=2 if sin, and deselect if something else */
201 for(ri=0; ri<dft.voiNr; ri++) if(dft.voi[ri].sw) {
202 /* check for dx and sin */
203 if(!strcasecmp(dft.voi[ri].hemisphere, "dx")) dft.voi[ri].sw=1;
204 else if(!strcasecmp(dft.voi[ri].hemisphere, "sin")) dft.voi[ri].sw=2;
205 else if(!strcasecmp(dft.voi[ri].hemisphere, "right")) dft.voi[ri].sw=1;
206 else if(!strcasecmp(dft.voi[ri].hemisphere, "left")) dft.voi[ri].sw=2;
207 else if(!strcasecmp(dft.voi[ri].hemisphere, "r")) dft.voi[ri].sw=1;
208 else if(!strcasecmp(dft.voi[ri].hemisphere, "l")) dft.voi[ri].sw=2;
209 else if(!strcasecmp(dft.voi[ri].place, "dx")) dft.voi[ri].sw=1;
210 else if(!strcasecmp(dft.voi[ri].place, "sin")) dft.voi[ri].sw=2;
211 else if(!strcasecmp(dft.voi[ri].place, "right")) dft.voi[ri].sw=1;
212 else if(!strcasecmp(dft.voi[ri].place, "left")) dft.voi[ri].sw=2;
213 else if(!strcasecmp(dft.voi[ri].place, "r")) dft.voi[ri].sw=1;
214 else if(!strcasecmp(dft.voi[ri].place, "l")) dft.voi[ri].sw=2;
215 else dft.voi[ri].sw=0;
216 }
217 /* Find the corresponding sin for each dx */
218 for(ri=n=0; ri<dft.voiNr; ri++) if(dft.voi[ri].sw==1) { /* loop for dx's */
219 if(dft.voi[ri].sw2>=0) continue;
220 for(rj=0; rj<dft.voiNr; rj++) if(dft.voi[rj].sw==2) { /* loop for sin's */
221 if(dft.voi[rj].sw2>=0) continue;
222 /* check for region name and plane */
223 if(strcasecmp(dft.voi[ri].voiname, dft.voi[rj].voiname)) continue;
224 if(strcasecmp(dft.voi[ri].place, dft.voi[rj].place)
225 && strcasecmp(dft.voi[ri].hemisphere, dft.voi[rj].hemisphere))
226 continue;
227 /* ok, this is a match */
228 if(ri<rj) dft.voi[ri].sw2=dft.voi[rj].sw2=ri;
229 else dft.voi[ri].sw2=dft.voi[rj].sw2=rj;
230 dft.voi[ri].sw3=2; n++;
231 }
232 }
233 if(n<1) {
234 fprintf(stderr, "Error: no hemispheres to average were found.\n");
235 dftEmpty(&dft); return(2);
236 }
237 } else {
238 /* Find all TACs that match the specified names / numbers */
239 for(ai=tacnamenr; ai<argc; ai++) if(*argv[ai]!='-') {
240 /* check if number was given; if not then find the names */
241 voi=atoi(argv[ai])-1;
242 if(voi>=0 && voi<dft.voiNr) {
243 dft.voi[voi].sw2=1; n=1;
244 } else {
245 n=dftSelect(&dft, argv[ai]);
246 for(ri=0; ri<dft.voiNr; ri++) if(dft.voi[ri].sw) dft.voi[ri].sw2=1;
247 }
248 }
249 for(ri=0, rj=-1; ri<dft.voiNr; ri++) if(dft.voi[ri].sw2==1) {
250 if(rj<0) {rj=ri; dft.voi[ri].sw3=0;}
251 dft.voi[ri].sw2=rj; dft.voi[rj].sw3++;
252 }
253 n=dft.voi[rj].sw3;
254 if(n<=0) {
255 fprintf(stderr, "Error: region '%s' not found.\n", argv[ai]);
256 dftEmpty(&dft); return(2);
257 }
258 }
259 if(verbose>1) {
260 printf("%d average TACs will be produced.\n", n);
261 for(ri=0; ri<dft.voiNr; ri++) if(dft.voi[ri].sw3>=0) {
262 printf("Calculate avg from %d TACs:\n", dft.voi[ri].sw3);
263 printf(" %s %s %s %f\n", dft.voi[ri].voiname, dft.voi[ri].hemisphere,
264 dft.voi[ri].place, dft.voi[ri].size);
265 for(rj=ri+1; rj<dft.voiNr; rj++) if(dft.voi[ri].sw2==dft.voi[rj].sw2)
266 printf(" %s %s %s %f\n", dft.voi[rj].voiname, dft.voi[rj].hemisphere,
267 dft.voi[rj].place, dft.voi[rj].size);
268 }
269 }
270
271 /*
272 * Calculate average TACs
273 */
274 /* Allocate memory for new TACs */
275 if(dftAddmem(&dft, n)) {
276 fprintf(stderr, "Error in reallocating memory.\n");
277 dftEmpty(&dft); return(3);
278 }
279 /* One average TAC at a time */
280 /* find the first tac to be averaged */
281 for(ri=0; ri<dft.voiNr; ri++) if(dft.voi[ri].sw2==ri) {
282 /* tell the user what we are doing */
283 if(verbose>0) {
284 printf(" averaging TACs:\n");
285 printf(" %-6.6s %-6.6s %-6.6s %g\n", dft.voi[ri].voiname,
286 dft.voi[ri].hemisphere, dft.voi[ri].place, dft.voi[ri].size);
287 }
288 /* start the summing with the first tac */
289 if(dft.voi[ri].size>0) {
290 dft.voi[dft.voiNr].size=dft.voi[ri].size;
291 for(fi=0; fi<dft.frameNr; fi++)
292 dft.voi[dft.voiNr].y[fi]=dft.voi[ri].size*dft.voi[ri].y[fi];
293 } else {
294 dft.voi[dft.voiNr].size=1.0;
295 for(fi=0; fi<dft.frameNr; fi++)
296 dft.voi[dft.voiNr].y[fi]=dft.voi[ri].y[fi];
297 }
298 /* copy the names to start with something */
299 strcpy(dft.voi[dft.voiNr].voiname, dft.voi[ri].voiname);
300 strcpy(dft.voi[dft.voiNr].hemisphere, dft.voi[ri].hemisphere);
301 if(dft.voi[ri].sw3>1) strcpy(dft.voi[dft.voiNr].place, dft.voi[ri].place);
302 else strcpy(dft.voi[dft.voiNr].place, "All");
303 /* Sum all tacs with the same number */
304 for(rj=ri+1; rj<dft.voiNr; rj++) if(dft.voi[rj].sw2==ri) {
305 if(verbose>0)
306 printf(" %-6.6s %-6.6s %-6.6s %g\n", dft.voi[rj].voiname,
307 dft.voi[rj].hemisphere, dft.voi[rj].place, dft.voi[rj].size);
308 if(dft.voi[rj].size>0) {
309 dft.voi[dft.voiNr].size+=dft.voi[rj].size;
310 for(fi=0; fi<dft.frameNr; fi++)
311 dft.voi[dft.voiNr].y[fi]+=dft.voi[rj].size*dft.voi[rj].y[fi];
312 } else {
313 dft.voi[dft.voiNr].size+=1.0;
314 for(fi=0; fi<dft.frameNr; fi++)
315 dft.voi[dft.voiNr].y[fi]+=dft.voi[rj].y[fi];
316 }
317 /* let the names be if they are the same */
318 if(strcasecmp(dft.voi[dft.voiNr].voiname, dft.voi[rj].voiname))
319 strcpy(dft.voi[dft.voiNr].voiname, "");
320 if(strcasecmp(dft.voi[dft.voiNr].hemisphere, dft.voi[rj].hemisphere))
321 strcpy(dft.voi[dft.voiNr].hemisphere, "");
322 if(strcasecmp(dft.voi[dft.voiNr].place, dft.voi[rj].place))
323 strcpy(dft.voi[dft.voiNr].place, "");
324 }
325 /* divide with sum size / number */
326 for(fi=0; fi<dft.frameNr; fi++)
327 dft.voi[dft.voiNr].y[fi]/=dft.voi[dft.voiNr].size;
328 if(dft.voi[ri].size<=0) dft.voi[dft.voiNr].size=0.0;
329 /* set names for the avg tac (if common names were not found) */
330 if(!strcmp(dft.voi[dft.voiNr].voiname, ""))
331 strcpy(dft.voi[dft.voiNr].voiname, "Mean");
332 if(!strcmp(dft.voi[dft.voiNr].place, ""))
333 strcpy(dft.voi[dft.voiNr].place, "All");
334 /* make long name */
336 dft.voi[dft.voiNr].voiname, dft.voi[dft.voiNr].hemisphere, dft.voi[dft.voiNr].place, '-');
337 /* set switches */
338 dft.voi[dft.voiNr].sw=0; dft.voi[dft.voiNr].sw2=-1;
339 /* tell user what we did */
340 if(verbose>0)
341 printf(" -> %-6.6s %-6.6s %-6.6s %g\n",
342 dft.voi[dft.voiNr].voiname, dft.voi[dft.voiNr].hemisphere,
343 dft.voi[dft.voiNr].place, dft.voi[dft.voiNr].size);
344 /* next region */
345 dft.voiNr++;
346 }
347
348 /*
349 * Remove those original tacs which were averaged
350 */
351 if(rmOrig) {
352 ri=dft.voiNr-1; n=dft.voiNr;
353 while(ri>=0) {
354 if(dft.voi[ri].sw2>=0) {
355 if((ret=dftDelete(&dft, ri))) {
356 fprintf(stderr, "Error (%d) in deleting TAC.\n", ret);
357 dftEmpty(&dft); return(5);
358 }
359 }
360 ri--;
361 }
362 n-=dft.voiNr;
363 if(n>0 && verbose>0)
364 printf("%d TAC(s) are deleted; backup is in %s.bak\n", n, dfile);
365 }
366 if(verbose>9) dftPrint(&dft);
367
368 /*
369 * Save the TACs
370 */
371 if(verbose>1) printf("writing %s\n", dfile);
372 if(dftWrite(&dft, dfile)) {
373 fprintf(stderr, "Error in writing '%s': %s\n", dfile, dfterrmsg);
374 dftEmpty(&dft); return(11);
375 }
376 if(verbose>0) printf("%s written.\n", dfile);
377
378
379 /*
380 * Free memory
381 */
382 dftEmpty(&dft);
383
384 return(0);
385}
386/*****************************************************************************/
387
388/*****************************************************************************/
void dftInit(DFT *data)
Definition dft.c:38
char dfterrmsg[64]
Definition dft.c:6
int dftAddmem(DFT *dft, int voiNr)
Definition dft.c:107
int dftDelete(DFT *dft, int voi)
Definition dft.c:538
void dftEmpty(DFT *data)
Definition dft.c:20
int dftSelect(DFT *data, char *name)
Definition dft.c:239
int dftRead(char *filename, DFT *data)
Definition dftio.c:22
void dftPrint(DFT *data)
Definition dftio.c:538
int dftWrite(DFT *data, char *filename)
Definition dftio.c:594
Header file for libtpccurveio.
Header file for libtpcmisc.
int tpcProcessStdOptions(const char *s, int *print_usage, int *print_version, int *verbose_level)
Definition proginfo.c:40
int rnameCatenate(char *rname, int max_rname_len, char *name1, char *name2, char *name3, char space)
Definition rname.c:189
#define MAX_REGIONNAME_LEN
Definition libtpcmisc.h:154
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
Voi * voi
int voiNr
int frameNr
double size
char voiname[MAX_REGIONSUBNAME_LEN+1]
char sw
double * y
char name[MAX_REGIONNAME_LEN+1]
char hemisphere[MAX_REGIONSUBNAME_LEN+1]
char sw2
char sw3
char place[MAX_REGIONSUBNAME_LEN+1]