TPCCLIB
Loading...
Searching...
No Matches
simboxes.c
Go to the documentation of this file.
1
9/*****************************************************************************/
10#include "tpcclibConfig.h"
11/*****************************************************************************/
12#include <stdio.h>
13#include <stdlib.h>
14#include <unistd.h>
15#include <string.h>
16#include <math.h>
17/*****************************************************************************/
18#include "tpcextensions.h"
19#include "tpcift.h"
20#include "tpccsv.h"
21/*****************************************************************************/
22
23/*****************************************************************************/
24static char *info[] = {
25 "Draw x,y,z matrix containing boxes with values starting from 1",
26 "for simple simulations, SW testing, and creating ROI masks.",
27 "Matrix and box x,y-dimension and z-dimension must be given in pixels.",
28 " ",
29 "Usage: @P [Options] matxydim matzdim boxxydim boxzdim outputfile",
30 " ",
31 "Options:",
32 " -format=<<TSV>|<CSV>|<float>|<short>>",
33 " Matrix data can be saved as tab separated values (TSV, default),",
34 " comma separated values (CSV), or as binary flat files with either",
35 " floats or short ints.",
36 " -stdoptions", // List standard options like --help, -v, etc
37 " ",
38 "Example #1:",
39 " @P 128 15 16 1 boxes.txt",
40 "Example #2:",
41 " @P -format=float 128 15 16 1 boxes.bin",
42 " flat2img -scanner=931 boxes.bin boxes.img 15 1 128 128",
43 " ",
44 "See also: flat2img, asc2flat, simcirc, imgshrink, imgadd, imglkup, dft2img",
45 " ",
46 "Keywords: simulation, image, mask, software testing",
47 0};
48/*****************************************************************************/
49
50/*****************************************************************************/
51/* Turn on the globbing of the command line, since it is disabled by default in
52 mingw-w64 (_dowildcard=0); in MinGW32 define _CRT_glob instead, if necessary;
53 In Unix&Linux wildcard command line processing is enabled by default. */
54/*
55#undef _CRT_glob
56#define _CRT_glob -1
57*/
58int _dowildcard = -1;
59/*****************************************************************************/
60
61/*****************************************************************************/
65int main(int argc, char **argv)
66{
67 int ai, help=0, version=0, verbose=1;
68 char *cptr, outfile[FILENAME_MAX];
69 int matxydim, matzdim, boxxydim, boxzdim;
70 int csv_separator=2; // 0=comma, 1=semi-colon, 2=tab, 3=space
71 int output_format=0; // 0=ASCII, 1=float binary, 2=short int binary
72 int ret;
73
74 /*
75 * Get arguments
76 */
77 if(argc==1) {tpcPrintUsage(argv[0], info, stderr); return(1);}
78 matxydim=matzdim=boxxydim=boxzdim=-1;
79 outfile[0]=(char)0;
80 /* Options */
81 for(ai=1; ai<argc; ai++) if(*argv[ai]=='-') {
82 if(tpcProcessStdOptions(argv[ai], &help, &version, &verbose)==0) continue;
83 cptr=argv[ai]+1; if(*cptr=='-') cptr++; if(!*cptr) continue;
84 if(strncasecmp(cptr, "F=", 2)==0) {
85 cptr+=2;
86 if(!strcasecmp(cptr, "TSV")) {csv_separator=2; output_format=0; continue;}
87 if(!strcasecmp(cptr, "CSV")) {csv_separator=0; output_format=0; continue;}
88 if(!strcasecmp(cptr, "FLOAT")) {output_format=1; continue;}
89 if(!strcasecmp(cptr, "SHORT")) {output_format=2; continue;}
90 } else if(strncasecmp(cptr, "FORMAT=", 7)==0) {
91 cptr+=7;
92 if(!strcasecmp(cptr, "TSV")) {csv_separator=2; output_format=0; continue;}
93 if(!strcasecmp(cptr, "CSV")) {csv_separator=0; output_format=0; continue;}
94 if(!strcasecmp(cptr, "FLOAT")) {output_format=1; continue;}
95 if(!strcasecmp(cptr, "SHORT")) {output_format=2; continue;}
96 }
97 fprintf(stderr, "Error: invalid option '%s'.\n", argv[ai]);
98 return(1);
99 } else break; // tac name argument may start with '-'
100
101 TPCSTATUS status; statusInit(&status);
102 statusSet(&status, __func__, __FILE__, __LINE__, TPCERROR_OK);
103 status.verbose=verbose-1;
104
105 /* Print help or version? */
106 if(help==2) {tpcHtmlUsage(argv[0], info, ""); return(0);}
107 if(help) {tpcPrintUsage(argv[0], info, stdout); return(0);}
108 if(version) {tpcPrintBuild(argv[0], stdout); return(0);}
109
110 /* Process other arguments, starting from the first non-option */
111 ret=0;
112 if(ai<argc) {if(atoiCheck(argv[ai++], &matxydim)) ret++;}
113 if(ai<argc) {if(atoiCheck(argv[ai++], &matzdim)) ret++;}
114 if(ai<argc) {if(atoiCheck(argv[ai++], &boxxydim)) ret++;}
115 if(ai<argc) {if(atoiCheck(argv[ai++], &boxzdim)) ret++;}
116 if(ret || matxydim<1 || matzdim<1 || boxxydim>matxydim || boxzdim>matzdim) {
117 fprintf(stderr, "Error: invalid dimension.\n");
118 return(1);
119 }
120 if(ai<argc) {strlcpy(outfile, argv[ai], FILENAME_MAX); ai++;}
121 if(ai<argc) {fprintf(stderr, "Error: too many arguments.\n"); return(1);}
122
123 /* Is something missing or wrong? */
124 if(!outfile[0]) {
125 fprintf(stderr, "Error: missing command-line argument; use option --help\n");
126 return(1);
127 }
128
129
130 /* In verbose mode print arguments and options */
131 if(verbose>1) {
132 printf("outfile := %s\n", outfile);
133 printf("matxydim := %d\n", matxydim);
134 printf("matzdim := %d\n", matzdim);
135 printf("boxxydim := %d\n", boxxydim);
136 printf("boxzdim := %d\n", boxzdim);
137 printf("csv_separator := %d\n", csv_separator);
138 printf("output_format := %d\n", output_format);
139 }
140
141
142 /*
143 * Compute and write ints into CSV or TSV file, if requested
144 */
145 if(output_format==0) {
146 /* Check that size is reasonable */
147 unsigned int size=matzdim*matxydim*matxydim;
148 if(size>150000) {
149 fprintf(stderr, "Error: too much data for text format.\n");
150 return(2);
151 }
152 /* Create the data */
153 int a, b, c, zi, yi, xi, mb=0, mc=0;
154 int mat[matzdim][matxydim][matxydim];
155 for(zi=0; zi<matzdim; zi++) {
156 a=zi/boxzdim;
157 for(yi=0; yi<matxydim; yi++) {
158 b=yi/boxxydim;
159 for(xi=0; xi<matxydim; xi++) {
160 c=xi/boxxydim;
161 mat[zi][yi][xi]= 1 + c + b*(mc+1) + a*(mc+1)*(mb+1);
162 if(verbose>2)
163 printf("mat[%d][%d][%d]=%d (%d %d %d) (%d %d)\n",
164 zi, yi, xi, mat[zi][yi][xi], a, b, c, mb, mc);
165 if(c>mc) mc=c;
166 }
167 if(b>mb) mb=b;
168 }
169 }
170 /* Write the data */
171 int newline, ret;
172 CSV csv; csvInit(&csv);
173 if(csvAllocate(&csv, matzdim*matxydim*matxydim)!=TPCERROR_OK) {
174 fprintf(stderr, "Error: out of memory.\n");
175 return(6);
176 }
177 ret=TPCERROR_OK; newline=0;
178 for(zi=0; zi<matzdim && ret==TPCERROR_OK; zi++) {
179 for(yi=0; yi<matxydim && ret==TPCERROR_OK; yi++) {
180 for(xi=0; xi<matxydim && ret==TPCERROR_OK; xi++) {
181 ret=csvPutInt(&csv, mat[zi][yi][xi], newline); newline=0;
182 }
183 newline=1;
184 }
185 }
186 if(ret!=TPCERROR_OK) {
187 fprintf(stderr, "Error: cannot fill CSV data.\n");
188 csvFree(&csv); return(7);
189 }
190 /* Set the field separator */
191 if(csv_separator==0) csv.separator=',';
192 else if(csv_separator==1) csv.separator=';';
193 else if(csv_separator==2) csv.separator='\t';
194 else csv.separator=' ';
195 /* Open file */
196 FILE *fp;
197 if(strcasecmp(outfile, "stdout")==0) {
198 fp=stdout;
199 } else {
200 fp=fopen(outfile, "w");
201 if(fp==NULL) {
202 fprintf(stderr, "Error: cannot open file for write.\n");
203 csvFree(&csv); return(10);
204 }
205 }
206 /* Write matrix data */
207 ret=csvWrite(&csv, 0, fp, &status);
208 csvFree(&csv); fclose(fp);
209 if(ret!=TPCERROR_OK) {
210 fprintf(stderr, "Error: %s\n", errorMsg(status.error));
211 if(verbose>1) printf("ret := %d\n", ret);
212 return(11);
213 }
214 // We are ready
215 return(0);
216 }
217
218
219 /*
220 * Write matrix data as flat binary file,
221 * calculating values pixel by pixel to prevent out-of-memory errors.
222 */
223 /* Open file */
224 FILE *fp;
225 fp=fopen(outfile, "wb");
226 if(fp==NULL) {
227 fprintf(stderr, "Error: cannot open file for write.\n");
228 return(10);
229 }
230 /* Compute and write data */
231 int a, b, c, mb=0, mc=0, zi, yi, xi;
232 unsigned int mv;
233 float f;
234 unsigned short int s;
235 ret=TPCERROR_OK;
236 for(zi=0; zi<matzdim && ret==TPCERROR_OK; zi++) {
237 a=zi/boxzdim;
238 for(yi=0; yi<matxydim && ret==TPCERROR_OK; yi++) {
239 b=yi/boxxydim;
240 for(xi=0; xi<matxydim && ret==TPCERROR_OK; xi++) {
241 c=xi/boxxydim;
242 mv=1 + c + b*(mc+1) + a*(mc+1)*(mb+1);
243 if(output_format==1) { // binary floats
244 f=(float)mv;
245 if(fwrite(&f, sizeof(float), 1, fp) != 1) ret=TPCERROR_CANNOT_WRITE;
246 } else if(output_format==2) { // binary short int
247 s=(unsigned short int)mv;
248 if(fwrite(&s, sizeof(unsigned short int), 1, fp) != 1)
250 }
251 if(c>mc) mc=c;
252 }
253 if(b>mb) mb=b;
254 }
255 }
256 fclose(fp);
257 if(ret!=TPCERROR_OK) {
258 fprintf(stderr, "Error: cannot write in %s; disk full?\n", outfile);
259 return(12);
260 }
261
262 return(0);
263}
264/*****************************************************************************/
265
266/*****************************************************************************/
void csvInit(CSV *csv)
Definition csv.c:22
int csvPutInt(CSV *csv, int v, int newline)
Definition csv.c:222
int csvAllocate(CSV *csv, int nr)
Definition csv.c:58
void csvFree(CSV *csv)
Definition csv.c:38
int csvWrite(CSV *csv, int regular, FILE *fp, TPCSTATUS *status)
Definition csvio.c:52
int atoiCheck(const char *s, int *v)
Definition intutil.c:25
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 tpccsv.h:36
char separator
Definition tpccsv.h:49
int verbose
Verbose level, used by statusPrint() etc.
tpcerror error
Error code.
Header file for library libtpccsv.
Header file for library libtpcextensions.
@ TPCERROR_OK
No error.
@ TPCERROR_CANNOT_WRITE
Cannot write file.
Header file for library libtpcift.