8#include "tpcclibConfig.h"
22static char *info[] = {
23 "Draw circle in x,y matrix with 1 inside circle and 0 outside of it",
24 "for simple simulations, SW testing, and creating ROI masks.",
25 "Matrix size and circle diameter must be given in pixels.",
27 "Usage: @P [Options] dimension diameter outputfile",
30 " -format=<<TSV>|<CSV>|<float>|<short>>",
31 " Matrix data can be saved as tab separated values (TSV, default),",
32 " comma separated values (CSV), or as binary flat files with either",
33 " floats or short ints.",
34 " -diam2=<2nd diameter>",
35 " If the second diameter is specified, then a ring is created.",
36 " -iring=<value inside hole>",
37 " With option -diam2, the integer value for hole inside ring;",
39 " -segm=<Number of segments>",
40 " Divide circle or ring into given number of segments with increasing",
43 " Write 0 inside the circle or ring, and 1 outside of it.",
44 " Not applicable with options -iring and -segm.",
48 " @P 256 224 circle.txt",
50 " @P -format=float 256 64 circle.bin",
51 " flat2nii circle.bin 256 256 1 1 circle",
53 "See also: flat2nii, asc2flat, simiart, simboxes, simelli, imgadd, imglkup",
55 "Keywords: simulation, image, mask, software testing",
74int main(
int argc,
char **argv)
76 int ai, help=0, version=0, verbose=1;
77 char *cptr, outfile[FILENAME_MAX];
81 double diameter=-1, diameter2=-1;
90 if(argc==1) {
tpcPrintUsage(argv[0], info, stderr);
return(1);}
93 for(ai=1; ai<argc; ai++)
if(*argv[ai]==
'-') {
95 cptr=argv[ai]+1;
if(*cptr==
'-') cptr++;
if(!*cptr)
continue;
96 if(strncasecmp(cptr,
"DIAM2=", 6)==0) {
98 if(!isnan(diameter2) && diameter2>0.0)
continue;
99 }
else if(strncasecmp(cptr,
"SEGM=", 5)==0) {
100 if(
atoiCheck(cptr+5, &segments)==0 && segments>0)
continue;
101 }
else if(strncasecmp(cptr,
"IRING=", 6)==0) {
102 if(
atoiCheck(cptr+6, &iring)==0 && iring>=0)
continue;
103 }
else if(strncasecmp(cptr,
"F=", 2)==0) {
105 if(!strcasecmp(cptr,
"TSV")) {csv_separator=2; output_format=0;
continue;}
106 if(!strcasecmp(cptr,
"CSV")) {csv_separator=0; output_format=0;
continue;}
107 if(!strcasecmp(cptr,
"FLOAT")) {output_format=1;
continue;}
108 if(!strcasecmp(cptr,
"SHORT")) {output_format=2;
continue;}
109 }
else if(strncasecmp(cptr,
"FORMAT=", 7)==0) {
111 if(!strcasecmp(cptr,
"TSV")) {csv_separator=2; output_format=0;
continue;}
112 if(!strcasecmp(cptr,
"CSV")) {csv_separator=0; output_format=0;
continue;}
113 if(!strcasecmp(cptr,
"FLOAT")) {output_format=1;
continue;}
114 if(!strcasecmp(cptr,
"SHORT")) {output_format=2;
continue;}
115 }
else if(strncasecmp(cptr,
"INVERT", 3)==0) {
118 fprintf(stderr,
"Error: invalid option '%s'.\n", argv[ai]);
127 if(help==2) {
tpcHtmlUsage(argv[0], info,
"");
return(0);}
134 fprintf(stderr,
"Error: invalid dimension.\n");
140 if(
atofCheck(argv[ai], &diameter) || diameter<1.0 || diameter==diameter2) {
141 fprintf(stderr,
"Error: invalid diameter.\n");
146 if(ai<argc) {
strlcpy(outfile, argv[ai], FILENAME_MAX); ai++;}
147 if(ai<argc) {fprintf(stderr,
"Error: too many arguments.\n");
return(1);}
151 fprintf(stderr,
"Error: missing command-line argument; use option --help\n");
154 if(invert && iring>0) {
155 fprintf(stderr,
"Error: options invert and iring cannot be combined.\n");
158 if(invert && segments>1) {
159 fprintf(stderr,
"Error: options invert and segm cannot be combined.\n");
164 if(diameter2>0.0 && diameter>diameter2) {
165 double v; v=diameter2; diameter2=diameter; diameter=v;
171 printf(
"outfile := %s\n", outfile);
172 printf(
"dim := %d\n", dim);
173 printf(
"diameter := %g\n", diameter);
174 if(diameter2>0.0) printf(
"diameter2 := %g\n", diameter2);
175 if(segments>1) printf(
"segments := %d\n", segments);
176 if(iring!=0) printf(
"iring := %d\n", iring);
177 printf(
"csv_separator := %d\n", csv_separator);
178 printf(
"output_format := %d\n", output_format);
179 printf(
"invert := %d\n", invert);
187 ilist=(
int*)malloc(dim*dim*
sizeof(
int));
189 fprintf(stderr,
"Error: out of memory.\n");
201 double cx, cy, dx, dy, d, radius;
206 cx=cy=0.5*(double)dim;
207 if((dim%2==0 && i%2==0) || (dim%2!=0 && i%2!=0)) {cx+=0.5; cy+=0.5;}
211 for(y=1; y<=dim; y++)
for(x=1; x<=dim; x++) {
212 dx=cx-(double)x; dy=cy-(double)y;
216 if(segments>1 && (dx!=0.0 || dy!=0.0)) {
217 double ra=M_PI+atan2(dx,dy);
218 int s=1+ra*(double)segments/(2.0*M_PI);
225 if(verbose>10) printf(
"d(%d,%d) := %g\n", x, y, d);
229 double cx, cy, dx, dy, d, radius, radius2;
234 cx=cy=0.5*(double)dim;
235 if((dim%2==0 && i%2==0) || (dim%2!=0 && i%2!=0)) {cx+=0.5; cy+=0.5;}
237 radius=0.5*diameter; radius2=0.5*diameter2;
239 for(y=1; y<=dim; y++)
for(x=1; x<=dim; x++) {
240 dx=cx-(double)x; dy=cy-(double)y;
244 }
else if(d<=radius) {
248 if(segments>1 && (dx!=0.0 || dy!=0.0)) {
249 double ra=M_PI+atan2(dx,dy);
250 int s=1+iring+ra*(double)segments/(2.0*M_PI);
256 if(verbose>10) printf(
"d(%d,%d) := %g\n", x, y, d);
260 fprintf(stderr,
"Error: with these settings all matrix values are 0.\n");
261 free(ilist);
return(4);
266 for(
int i=0; i<dim*dim; i++, lptr++)
if(*lptr==0) *lptr=1;
else *lptr=0;
273 if(output_format==0) {
277 fprintf(stderr,
"Error: out of memory.\n");
278 free(ilist);
return(6);
283 if(x==0 && y>0) ret=
csvPutInt(&csv, *lptr, 1);
288 fprintf(stderr,
"Error: cannot fill CSV data.\n");
289 free(ilist);
csvFree(&csv);
return(7);
294 else if(csv_separator==1) csv.
separator=
';';
295 else if(csv_separator==2) csv.
separator=
'\t';
299 if(strcasecmp(outfile,
"stdout")==0) {
302 fp=fopen(outfile,
"w");
304 fprintf(stderr,
"Error: cannot open file for write.\n");
313 if(verbose>1) printf(
"ret := %d\n", ret);
325 fp=fopen(outfile,
"wb");
327 fprintf(stderr,
"Error: cannot open file for write.\n");
328 free(ilist);
return(10);
332 if(output_format==1) {
334 for(
int i=0; i<dim*dim; i++, lptr++) {
336 if(fwrite(&f,
sizeof(
float), 1, fp) != 1) {
337 fprintf(stderr,
"Error: cannot write in %s\n", outfile);
338 fclose(fp); free(ilist);
return(12);
341 }
else if(output_format==2) {
343 for(i=0; i<dim*dim; i++, lptr++) {
345 if(fwrite(&s,
sizeof(
short int), 1, fp) != 1) {
346 fprintf(stderr,
"Error: cannot write in %s\n", outfile);
347 fclose(fp); free(ilist);
return(12);
351 fclose(fp); free(ilist);
int csvPutInt(CSV *csv, int v, int newline)
int csvAllocate(CSV *csv, int nr)
int csvWrite(CSV *csv, int regular, FILE *fp, TPCSTATUS *status)
double atofVerified(const char *s)
int atofCheck(const char *s, double *v)
int atoiCheck(const char *s, int *v)
int tpcProcessStdOptions(const char *s, int *print_usage, int *print_version, int *verbose_level)
int tpcHtmlUsage(const char *program, char *text[], const char *path)
void tpcPrintBuild(const char *program, FILE *fp)
void tpcPrintUsage(const char *program, char *text[], FILE *fp)
void statusInit(TPCSTATUS *s)
char * errorMsg(tpcerror e)
void statusSet(TPCSTATUS *s, const char *func, const char *srcfile, int srcline, tpcerror error)
size_t strlcpy(char *dst, const char *src, size_t dstsize)
int verbose
Verbose level, used by statusPrint() etc.
tpcerror error
Error code.
Header file for library libtpccsv.
Header file for library libtpcextensions.
Header file for library libtpcift.