TPCCLIB
Loading...
Searching...
No Matches
parcoll.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 "tpcpar.h"
17/*****************************************************************************/
18
19/*****************************************************************************/
20static char *info[] = {
21 "Collect the contents of parameter files.",
22 " ",
23 "Usage: @P [options] newfile filename(s)",
24 " ",
25 "Options:",
26 " -par=<list>",
27 " List of parameter numbers or names to be copied; all by default.",
28 " -tac=<list>",
29 " List of TAC numbers or names to be copied; all by default.",
30 " -stdoptions", // List standard options like --help, -v, etc
31 " ",
32 "Example:",
33 " @P all.par ut????srtm.res",
34 " ",
35 "See also: paradd, iftedit, parformat, parrenp, parmean, parai, rescoll",
36 " ",
37 "Keywords: parameter, tool, format, CSV, RES, FIT",
38 0};
39/*****************************************************************************/
40
41/*****************************************************************************/
42/* Turn on the globbing of the command line, since it is disabled by default in
43 mingw-w64 (_dowildcard=0); in MinGW32 define _CRT_glob instead, if necessary;
44 In Unix&Linux wildcard command line processing is enabled by default. */
45/*
46#undef _CRT_glob
47#define _CRT_glob -1
48*/
49int _dowildcard = -1;
50/*****************************************************************************/
51
52/*****************************************************************************/
56int main(int argc, char **argv)
57{
58 int ai, help=0, version=0, verbose=1;
59 char newfile[FILENAME_MAX], parfile[FILENAME_MAX];
60 char *pars=NULL, *tacs=NULL; // remember to free allocated memory before exit
61
62
63 /*
64 * Get arguments
65 */
66 if(argc==1) {tpcPrintUsage(argv[0], info, stderr); return(1);}
67 newfile[0]=parfile[0]=(char)0;
68 /* Options */
69 for(ai=1; ai<argc; ai++) if(*argv[ai]=='-') {
70 if(tpcProcessStdOptions(argv[ai], &help, &version, &verbose)==0) continue;
71 char *cptr=argv[ai]+1; if(*cptr=='-') cptr++; if(!*cptr) continue;
72 if(strncasecmp(cptr, "PAR=", 4)==0 && strnlen(cptr, 5)>4) {
73 pars=strdup(cptr+4); continue;
74 } else if(strncasecmp(cptr, "TAC=", 4)==0 && strnlen(cptr, 5)>4) {
75 tacs=strdup(cptr+4); continue;
76 }
77 fprintf(stderr, "Error: invalid option '%s'.\n", argv[ai]);
78 return(1);
79 } else break; // tac name argument may start with '-'
80
81 /* Print help or version? */
82 if(help==2) {tpcHtmlUsage(argv[0], info, ""); free(pars); free(tacs); return(0);}
83 if(help) {tpcPrintUsage(argv[0], info, stdout); free(pars); free(tacs); return(0);}
84 if(version) {tpcPrintBuild(argv[0], stdout); free(pars); free(tacs); return(0);}
85
86 TPCSTATUS status; statusInit(&status);
87 statusSet(&status, __func__, __FILE__, __LINE__, TPCERROR_OK);
88 status.verbose=verbose-3;
89
90 /* Next argument is the name of the collection file */
91 if(ai==argc) {tpcPrintUsage(argv[0], info, stdout); free(pars); free(tacs); return(1);}
92 if(ai<argc) strlcpy(newfile, argv[ai++], FILENAME_MAX);
93 if(ai==argc) {
94 fprintf(stderr, "Error: missing names for data files.\n");
95 free(pars); free(tacs); return(1);
96 }
97
98 /* Next arguments are names of files to collect data from */
99 int fileNr=0, ffi=0;
100 for(; ai<argc; ai++) {
101 if(verbose>2) {printf("file %d: %s\n", 1+fileNr, argv[ai]); fflush(stdout);}
102 if(ffi<1) ffi=ai;
103 fileNr++;
104 }
105 /* Is something missing? */
106 if(fileNr<2) {
107 fprintf(stderr, "Error: missing parameter files.\n");
108 free(pars); free(tacs); return(1);
109 }
110
111 /* In verbose mode print arguments and options */
112 if(verbose>1) {
113 printf("fileNr := %d\n", fileNr);
114 printf("newfile := %s\n", newfile);
115 if(pars!=NULL) printf("pars := '%s'\n", pars);
116 if(tacs!=NULL) printf("tacs := '%s'\n", tacs);
117 fflush(stdout);
118 }
119
120
121 /*
122 * Read all specified files and store the contents
123 */
124 if(verbose>0) {printf("reading %d files\n", fileNr); fflush(stdout);}
125 PAR *parlist=(PAR*)malloc(fileNr*sizeof(PAR));
126 if(parlist==NULL) {
127 fprintf(stderr, "Error: cannot allocate memory.\n"); free(pars); free(tacs); return(2);
128 }
129 int pfileNr=0;
130 for(int fi=0; fi<fileNr; fi++) parInit(parlist+fi);
131 for(int fi=0; fi<fileNr; fi++) {
132 /* Read file */
133 strlcpy(parfile, argv[ffi+fi], FILENAME_MAX);
134 if(verbose>0) {printf("%s\n", parfile); fflush(stdout);}
135 if(verbose>2) printf("index=%d\n", pfileNr);
136 if(parRead(parlist+pfileNr, parfile, &status)) {
137 fprintf(stderr, "Error: %s.\n", errorMsg(status.error));
138 for(int j=0; j<pfileNr; j++) parFree(parlist+j);
139 free(parlist); free(pars); free(tacs); return(2);
140 }
141 if(verbose>1) {
142 printf(" fileformat := %s\n", parFormattxt(parlist[pfileNr].format));
143 printf(" parNr := %d\n", parlist[pfileNr].parNr);
144 printf(" tacNr := %d\n", parlist[pfileNr].tacNr);
145 char *cptr=parIsStudyNr(parlist+pfileNr);
146 if(cptr!=NULL) printf(" studyNr := %s\n", cptr);
147 }
148 /* Make sure that we got study number */
149 if(!parIsStudyNr(parlist+pfileNr)) {
150 char studynr[MAX_STUDYNR_LEN+1];
151 if(studynrFromFilename(parfile, studynr, 1)==0)
152 iftPut(&parlist[pfileNr].h, "studynr", studynr, 0, NULL);
153 }
154 /* Select specified parameters, or all */
155 if(pars==NULL) {
156 /* No parameters specified: select all */
157 parSelectParameters(parlist+pfileNr, NULL, 0, &status);
158 } else {
159 char buf[512];
160 for(int i=0; i<strTokenNr(pars, ",;"); i++) {
161 if(strTokenNCpy(pars, ",;", i+1, buf, 512)<1) continue;
162 parSelectParameters(parlist+pfileNr, buf, 0, &status);
163 }
164 int parNr=parSelectedParameters(parlist+pfileNr);
165 if(parNr==0) {
166 fprintf(stderr, "Warning: specified parameter(s) not found in %s.\n", parfile);
167 parFree(parlist+pfileNr); continue; // do not store data from this file
168 }
169 if(parNr<parlist[pfileNr].parNr) { // delete non-selected parameters
170 int i=parlist[pfileNr].parNr-1;
171 while(i>=0) {
172 if(parlist[pfileNr].n[i].sw==0) parDeletePar(parlist+pfileNr, i);
173 i--;
174 }
175 if(verbose>1) printf(" parNrFinal := %d\n", parlist[pfileNr].parNr);
176 }
177 }
178 /* Select specified TACs, or all */
179 if(tacs==NULL) {
180 /* No TACs specified: select all */
181 parSelectTACs(parlist+pfileNr, NULL, 0, &status);
182 } else {
183 char buf[512];
184 for(int i=0; i<strTokenNr(tacs, ",;"); i++) {
185 if(strTokenNCpy(tacs, ",;", i+1, buf, 512)<1) continue;
186 parSelectTACs(parlist+pfileNr, buf, 0, &status);
187 }
188 int tacNr=parSelectedTACs(parlist+pfileNr);
189 if(tacNr==0) {
190 fprintf(stderr, "Warning: specified TAC(s) not found in %s.\n", parfile);
191 parFree(parlist+pfileNr); continue; // do not store data from this file
192 }
193 if(tacNr<parlist[pfileNr].tacNr) { // delete non-selected parameters
194 int i=parlist[pfileNr].tacNr-1;
195 while(i>=0) {
196 if(parlist[pfileNr].r[i].sw==0) parDeleteTAC(parlist+pfileNr, i);
197 i--;
198 }
199 if(verbose>1) printf(" tacNrFinal := %d\n", parlist[pfileNr].tacNr);
200 }
201 }
202 pfileNr++;
203 } // next file
204 fileNr=pfileNr;
205 /* par and tac strings are not needed later */
206 free(pars); free(tacs);
207 /* Check that we still have data to collect */
208 if(fileNr<2) {
209 fprintf(stderr, "Error: files do not contain specified TACs or parameters.\n");
210 for(int j=0; j<fileNr; j++) parFree(parlist+j);
211 free(parlist); return(3);
212 }
213
214
215 /*
216 * Allocate space for collected parameters
217 */
218 if(verbose>0) {printf("preparing the collection\n"); fflush(stdout);}
219 /* List TAC names */
220 if(verbose>1) {printf("listing TACs\n"); fflush(stdout);}
221 IFT tacnames; iftInit(&tacnames);
222 for(int fi=0; fi<fileNr; fi++)
223 for(int ci=0; ci<parlist[fi].tacNr; ci++)
224 iftPut(&tacnames, parlist[fi].r[ci].name, NULL, 0, NULL);
225 iftDeleteDuplicateKeys(&tacnames, &status);
226 if(verbose>2) {printf("TACs:\n"); iftWrite(&tacnames, stdout, NULL); printf("\n");}
227 /* List parameter names */
228 if(verbose>1) {printf("listing parameters\n"); fflush(stdout);}
229 IFT parnames; iftInit(&parnames);
230 for(int fi=0; fi<fileNr; fi++)
231 for(int pi=0; pi<parlist[fi].parNr; pi++)
232 iftPut(&parnames, parlist[fi].n[pi].name, NULL, 0, NULL);
233 iftDeleteDuplicateKeys(&parnames, &status);
234 if(verbose>2) {printf("Parameters:\n"); iftWrite(&parnames, stdout, NULL); printf("\n");}
235 /* Allocating memory */
236 if(verbose>2) {
237 printf("TACs := %d\n", tacnames.keyNr);
238 printf("Parameters := %d\n", parnames.keyNr);
239 }
240 PAR par; parInit(&par);
241 if(parAllocate(&par, parnames.keyNr, fileNr*tacnames.keyNr)!=TPCERROR_OK) {
242 fprintf(stderr, "Error: cannot allocate memory.\n");
243 iftFree(&tacnames); iftFree(&parnames);
244 for(int j=0; j<fileNr; j++) parFree(parlist+j);
245 free(parlist); return(4);
246 }
247 /* Set the file format */
248 par.format=parFormatFromExtension(newfile);
250 /* Set parameter names */
251 for(int i=0; i<parnames.keyNr; i++)
252 strcpy(par.n[i].name, parnames.item[i].key);
253 par.parNr=parnames.keyNr;
254
255
256
257 /*
258 * Collect parameters
259 */
260 par.tacNr=0;
261 for(int fi=0; fi<fileNr; fi++) {
262 for(int ti=0; ti<tacnames.keyNr; ti++) {
263 /* search this TAC */
264 for(int ri=0; ri<parlist[fi].tacNr; ri++) {
265 if(strcasecmp(parlist[fi].r[ri].name, tacnames.item[ti].key)==0) {
266 /* Copy name */
267 char buf[MAX_TACNAME_LEN+1];
268 char *studynr=parIsStudyNr(parlist+fi);
269 if(studynr) strlcpy(buf, studynr, MAX_TACNAME_LEN);
270 /* if more than one TAC name listed, copy TAC name, too */
271 if(tacnames.keyNr>1) {
272 if(studynr) strlcat(buf, " ", MAX_TACNAME_LEN);
273 strlcat(buf, tacnames.item[ti].key, MAX_TACNAME_LEN);
274 }
275 strlcpy(par.r[par.tacNr].name, buf, MAX_TACNAME_LEN);
276 /* Copy matching parameters */
277 for(int pi=0; pi<parnames.keyNr; pi++) {
278 for(int pj=0; pj<parlist[fi].parNr; pj++)
279 if(strcasecmp(parlist[fi].n[pj].name, parnames.item[pi].key)==0)
280 par.r[par.tacNr].p[pi]=parlist[fi].r[ri].p[pj];
281 }
282 par.tacNr++;
283 }
284 }
285 }
286 }
287
288 /* Free the original data */
289 iftFree(&tacnames); iftFree(&parnames);
290 for(int i=0; i<fileNr; i++) parFree(parlist+i);
291 free(parlist);
292
293
294 /*
295 * Write collected parameter file
296 */
297 if(verbose>1) printf(" saving\n");
298 {
299 FILE *fp=fopen(newfile, "w");
300 if(fp==NULL) {
301 fprintf(stderr, "Error: cannot open file for writing.\n");
302 parFree(&par); return(11);
303 }
304 int ret=parWrite(&par, fp, PAR_FORMAT_UNKNOWN, 1, &status);
305 fclose(fp); parFree(&par);
306 if(ret!=TPCERROR_OK) {
307 fprintf(stderr, "Error: %s\n", errorMsg(status.error));
308 return(12);
309 }
310 if(verbose>0) printf("written %s\n", newfile);
311 }
312
313 return(0);
314}
315/*****************************************************************************/
316
317/*****************************************************************************/
void iftFree(IFT *ift)
Definition ift.c:37
int iftPut(IFT *ift, const char *key, const char *value, char comment, TPCSTATUS *status)
Definition ift.c:63
void iftInit(IFT *ift)
Definition ift.c:21
int iftDeleteDuplicateKeys(IFT *ift, TPCSTATUS *status)
Definition ift.c:348
int iftWrite(IFT *ift, FILE *fp, TPCSTATUS *status)
Definition iftio.c:98
int parDeletePar(PAR *par, int pi)
Definition par.c:478
void parFree(PAR *par)
Definition par.c:75
int parAllocate(PAR *par, int parNr, int tacNr)
Definition par.c:108
char * parIsStudyNr(PAR *par)
Definition par.c:399
void parInit(PAR *par)
Definition par.c:25
int parDeleteTAC(PAR *par, int ti)
Definition par.c:519
char * parFormattxt(parformat c)
Definition pario.c:59
int parWrite(PAR *par, FILE *fp, parformat format, int extra, TPCSTATUS *status)
Definition pario.c:148
int parRead(PAR *par, const char *fname, TPCSTATUS *status)
Definition pario.c:232
int parFormatFromExtension(const char *s)
Definition pario.c:102
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 parSelectedTACs(PAR *d)
Definition parselect.c:100
int parSelectedParameters(PAR *d)
Definition parselect.c:199
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
int strTokenNr(const char *s1, const char *s2)
Definition stringext.c:25
char * strdup(const char *s)
Definition stringext.c:185
size_t strnlen(const char *s, size_t n)
Definition stringext.c:566
int strTokenNCpy(const char *s1, const char *s2, int i, char *s3, int count)
Definition stringext.c:53
size_t strlcpy(char *dst, const char *src, size_t dstsize)
Definition stringext.c:632
size_t strlcat(char *dst, const char *src, size_t dstsize)
Definition stringext.c:592
char * key
Definition tpcift.h:32
Definition tpcift.h:43
IFT_ITEM * item
Definition tpcift.h:57
int keyNr
Definition tpcift.h:47
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
char name[MAX_PARNAME_LEN+1]
Definition tpcpar.h:82
char name[MAX_TACNAME_LEN+1]
Definition tpcpar.h:50
double * p
Definition tpcpar.h:64
int verbose
Verbose level, used by statusPrint() etc.
tpcerror error
Error code.
int studynrFromFilename(const char *fname, char *studynr, int force)
Definition studynr.c:79
Header file for library libtpcextensions.
#define MAX_TACNAME_LEN
Max length of TAC ID name (not including trailing zero).
@ TPCERROR_OK
No error.
#define MAX_STUDYNR_LEN
Define max study number length.
Header file for libtpcpar.
@ PAR_FORMAT_UNKNOWN
Unknown format.
Definition tpcpar.h:28
@ PAR_FORMAT_TSV_UK
UK TSV (point as decimal separator).
Definition tpcpar.h:35