TPCCLIB
Loading...
Searching...
No Matches
simiart.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 <unistd.h>
13#include <string.h>
14#include <math.h>
15#include <time.h>
16/*****************************************************************************/
17#include "libtpcmisc.h"
18#include "libtpcmodel.h"
19#include "libtpccurveio.h"
20#include "libtpcimgio.h"
21#include "libtpcimgp.h"
22#include "libtpcmodext.h"
23#include "libtpcidi.h"
24/*****************************************************************************/
25
26/*****************************************************************************/
27static char *info[] = {
28 "Simulate dynamic PET image plane with background activity surrounding",
29 "a circular object that is assumed to be extending across image planes",
30 "such as abdominal aorta. Spill-over and spill-in effects can be simulated",
31 "by Gaussian 2D smoothing, or by using method based on Germano et al ",
32 "JNM 1992; 33: 613-620, which is only valid for vessels with very large",
33 "diameter. To simulate the circular vessel correctly in 2D image matrix use",
34 "the equations in Brix et al Nuklearmedizin 2002;41:184-190 instead;",
35 "however, that would require numerical solution to double integrals",
36 " ",
37 "Usage: @P [Options] bloodfile bkgfile image",
38 " ",
39 "Options:",
40 " -dim=<Image x and y dimension in pixels>",
41 " Set image dimension; by default 128.",
42 " -pxlsize=<Voxel size (mm)>",
43 " Set image voxel size; by default 1 mm.",
44 " -diameter=<Vessel diameter (mm)>",
45 " Set vessel diameter; by default 25 mm; vessel border is simulated",
46 " by simple cutoff, thus diameter should be several pixels.",
47 " -fwhm=<FWHM (mm)>",
48 " Set image resolution; by default 8 mm.",
49 " -xpos=<vessel position (mm)>",
50 " Set vessel distance from centre of image; by default 0 mm;",
51 " negative distance moves vessel to the left, positive to the right.",
52 " -ypos=<vessel position (mm)>",
53 " Set vessel distance from centre of image; by default 0 mm",
54 " negative distance moves vessel upwards, positive downwards.",
55 " -gaussian | -bar | -nopve",
56 " Select the spill-over and spill-in simulation method; by default",
57 " no PVE simulation. ",
58 " -stdoptions", // List standard options like --help, -v, etc
59 " ",
60 "Example 1:",
61 " @P blood.tac background.tac vessel.v",
62 "Example 2:",
63 " @P -fwhm=4.3 -diameter=7 -pxlsize=2.3 blood.tac background.tac vessel.v",
64 " ",
65 "See also: fvar4tac, imgfiltg, imgadd, imgcalc, simcirc, simimyoc, flat2img",
66 " ",
67 "Keywords: simulation, image, software testing, vessel, input",
68 0};
69/*****************************************************************************/
70
71/*****************************************************************************/
72/* Turn on the globbing of the command line, since it is disabled by default in
73 mingw-w64 (_dowildcard=0); in MinGW32 define _CRT_glob instead, if necessary;
74 In Unix&Linux wildcard command line processing is enabled by default. */
75/*
76#undef _CRT_glob
77#define _CRT_glob -1
78*/
79int _dowildcard = -1;
80/*****************************************************************************/
81
82/*****************************************************************************/
86int main(int argc, char **argv)
87{
88 int ai, help=0, version=0, verbose=1;
89 int fi, ret;
90 char blofile[FILENAME_MAX], bkgfile[FILENAME_MAX], imgfile[FILENAME_MAX];
91 char *cptr, tmp[256];
92 int pve_method=-1; // -1=No PVE, 0=Germano, 1=Gaussian
93 int dim=128;
94 double pxlsize=1.0, diameter=25.0, fwhm=8.0, xpos=0.0, ypos=0.0;
95 int scanner_type=SCANNER_HRPLUS;
96 float zoom=1.41421356;
97 DFT tac;
98 IMG img;
99 double cx, cy;
100
101
102
103 /*
104 * Get arguments
105 */
106 if(argc==1) {tpcPrintUsage(argv[0], info, stderr); return(1);}
107 blofile[0]=bkgfile[0]=imgfile[0]=(char)0;
108 /* Get options */
109 for(ai=1; ai<argc; ai++) if(*argv[ai]=='-') {
110 if(tpcProcessStdOptions(argv[ai], &help, &version, &verbose)==0) continue;
111 cptr=argv[ai]+1; if(*cptr=='-') cptr++; if(cptr==NULL) continue;
112 if(strncasecmp(cptr, "DIM=", 4)==0) {
113 if(atoi_with_check(cptr+4, &dim)==0 && dim>4) continue;
114 } else if(strncasecmp(cptr, "PXLSIZE=", 8)==0) {
115 if(atof_with_check(cptr+8, &pxlsize)==0 && pxlsize>0.0) continue;
116 } else if(strncasecmp(cptr, "DIAMETER=", 9)==0) {
117 if(atof_with_check(cptr+9, &diameter)==0 && diameter>0.0) continue;
118 } else if(strncasecmp(cptr, "FWHM=", 5)==0) {
119 if(atof_with_check(cptr+5, &fwhm)==0 && fwhm>0.0) continue;
120 } else if(strncasecmp(cptr, "XPOS=", 5)==0) {
121 if(atof_with_check(cptr+5, &xpos)==0) continue;
122 } else if(strncasecmp(cptr, "YPOS=", 5)==0) {
123 if(atof_with_check(cptr+5, &ypos)==0) continue;
124 } else if(strncasecmp(cptr, "NOPVE", 2)==0) {
125 if(pve_method>=0) {
126 fprintf(stderr, "Error: invalid combination of simulation options.\n");
127 return(1);
128 }
129 pve_method=-1; continue;
130 } else if(strcasecmp(cptr, "BAR")==0) {
131 if(pve_method>=0) {
132 fprintf(stderr, "Error: invalid combination of simulation options.\n");
133 return(1);
134 }
135 pve_method=0; continue;
136 } else if(strcasecmp(cptr, "GAUSSIAN")==0) {
137 if(pve_method>=0) {
138 fprintf(stderr, "Error: invalid combination of simulation options.\n");
139 return(1);
140 }
141 pve_method=1; continue;
142 }
143 fprintf(stderr, "Error: invalid option '%s'.\n", argv[ai]);
144 return(1);
145 } else break;
146
147 /* Print help or version? */
148 if(help==2) {tpcHtmlUsage(argv[0], info, ""); return(0);}
149 if(help) {tpcPrintUsage(argv[0], info, stdout); return(0);}
150 if(version) {tpcPrintBuild(argv[0], stdout); return(0);}
151
152 /* Process other arguments, starting from the first non-option */
153 if(ai<argc) {strlcpy(blofile, argv[ai], FILENAME_MAX); ai++;}
154 if(ai<argc) {strlcpy(bkgfile, argv[ai], FILENAME_MAX); ai++;}
155 if(ai<argc) {strlcpy(imgfile, argv[ai], FILENAME_MAX); ai++;}
156 if(ai<argc) {fprintf(stderr, "Error: too many arguments.\n"); return(1);}
157
158 /* Did we get all the information that we need? */
159 if(!imgfile[0]) {
160 fprintf(stderr, "Error: missing command-line argument; use option --help\n");
161 return(1);
162 }
163
164 /* In verbose mode print arguments and options */
165 if(verbose>1) {
166 printf("blofile := %s\n", blofile);
167 printf("bkgfile := %s\n", bkgfile);
168 printf("imgfile := %s\n", imgfile);
169 printf("dim := %d\n", dim);
170 printf("pxlsize := %g\n", pxlsize);
171 printf("diameter := %g\n", diameter);
172 printf("fwhm := %g\n", fwhm);
173 printf("xpos := %g\n", xpos);
174 printf("ypos := %g\n", ypos);
175 printf("pve_method := %d\n", pve_method);
176 }
177
178
179 /*
180 * Read blood and background TACs
181 */
182 dftInit(&tac);
183 if(verbose>1) printf("reading blood TAC\n");
184 if(dftRead(blofile, &tac)) {
185 fprintf(stderr, "Error in reading '%s': %s\n", blofile, dfterrmsg);
186 return(2);
187 }
188 if(tac.voiNr>1) {
189 fprintf(stderr, "Error: blood data contains more than one curve.\n");
190 dftEmpty(&tac); return(2);
191 }
192 if(verbose>1) printf("reading background TAC\n");
193 ret=dftReadReference(&tac, bkgfile, NULL, NULL, tmp, verbose-4);
194 if(ret<1) {
195 fprintf(stderr, "Error in reading background TAC: %s\n", tmp);
196 dftEmpty(&tac); return(2);
197 }
198 if(ret>1) {
199 fprintf(stderr, "Error: background data contains more than one curve.\n");
200 dftEmpty(&tac); return(2);
201 }
202
203
204 /*
205 * Allocate memory for the image
206 */
207 if(verbose>1) printf("allocating memory for image data\n");
208 imgInit(&img);
209 ret=imgAllocate(&img, 1, dim, dim, tac.frameNr);
210 if(ret!=0) {
211 fprintf(stderr, "Error: cannot allocate memory for image data.\n");
212 dftEmpty(&tac); return(4);
213 }
214 /* Set header information */
215 if(verbose>2) printf("setting image headers\n");
217 imgSetUnit(&img, tac.unit);
218 strcpy(img.studyNr, tac.studynr);
219 img.zoom=zoom;
221 (void)imgSetScanner(&img, scanner_type);
223 img.planeNumber[0]=1;
224 for(fi=0; fi<tac.frameNr; fi++) {
225 img.start[fi]=tac.x1[fi]; img.end[fi]=tac.x2[fi]; img.mid[fi]=tac.x[fi];
226 if(tac.timeunit==TUNIT_MIN) {
227 img.start[fi]*=60.; img.end[fi]*=60.; img.mid[fi]*=60.;}
228 }
229 img.sizex=img.sizey=img.sizez=pxlsize;
230
231
232 /*
233 * Simulate image contents one frame at a time
234 */
235 cx=xpos+0.5*(double)img.dimx*img.sizex;
236 cy=ypos+0.5*(double)img.dimy*img.sizey;
237 if(verbose>2) printf("vessel_pos := %g,%g\n", cx, cy);
238
239 ret=idiSimulateTubeImgPlane(pve_method, &img, 0, cx, cy, 0.5*diameter, fwhm,
240 tac.voi[1].y, tac.voi[0].y);
241 if(ret!=0) {
242 fprintf(stderr, "Error: cannot simulate image (%d).\n", ret);
243 imgEmpty(&img); dftEmpty(&tac);
244 return(8);
245 }
246 if(pve_method==1) {
247 double s=fwhm/2.355;
248 s/=img.sizex;
249 ret=imgGaussianFIRFilter(&img, s, s, 0, 1.0E-06, verbose-3);
250 if(ret!=0) {
251 fprintf(stderr, "Error: cannot simulate PVE (%d).\n", ret);
252 imgEmpty(&img); dftEmpty(&tac);
253 return(9);
254 }
255 }
256 dftEmpty(&tac);
257
258
259 /*
260 * Save image
261 */
262 if(verbose>1) printf("Writing image file %s ...\n", imgfile);
263 if(imgWrite(imgfile, &img)) {
264 fprintf(stderr, "Error: %s\n", img.statmsg);
265 imgEmpty(&img); return(11);
266 }
267 if(verbose>0) printf("%s written\n", imgfile);
268 imgEmpty(&img);
269
270 return(0);
271}
272/*****************************************************************************/
273
274/*****************************************************************************/
int atof_with_check(char *double_as_string, double *result_value)
Definition decpoint.c:107
int atoi_with_check(const char *int_as_string, int *result_value)
Definition decpoint.c:238
void dftInit(DFT *data)
Definition dft.c:38
char dfterrmsg[64]
Definition dft.c:6
void dftEmpty(DFT *data)
Definition dft.c:20
int dftReadReference(DFT *tissue, char *filename, int *filetype, int *ref_index, char *status, int verbose)
Definition dftinput.c:204
int dftRead(char *filename, DFT *data)
Definition dftio.c:22
int imgAllocate(IMG *image, int planes, int rows, int columns, int frames)
Definition img.c:194
void imgEmpty(IMG *image)
Definition img.c:121
void imgInit(IMG *image)
Definition img.c:60
int imgWrite(const char *fname, IMG *img)
Definition imgfile.c:136
int imgGaussianFIRFilter(IMG *img, float xsd, float ysd, float zsd, double tolerance, int verbose)
Definition imgfilter.c:18
int imgSetScanner(IMG *img, int scanner_type)
Definition imgscanner.c:14
int imgSetUnit(IMG *img, char *unit)
Definition imgunits.c:328
Header file for libtpccurveio.
Header file for libtpcidi.
int idiSimulateTubeImgPlane(int simmet, IMG *img, int zi, double cx, double cy, double r, double FWHM, double *cbkg, double *cblo)
Definition vessel.c:143
Header file for libtpcimgio.
#define IMG_UNKNOWN
#define IMG_DC_CORRECTED
#define SCANNER_HRPLUS
#define IMG_TYPE_IMAGE
Header file for libtpcimgp.
Header file for libtpcmisc.
int tpcProcessStdOptions(const char *s, int *print_usage, int *print_version, int *verbose_level)
Definition proginfo.c:40
size_t strlcpy(char *dst, const char *src, size_t dstsize)
Definition strext.c:245
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
Header file for libtpcmodel.
Header file for libtpcmodext.
Voi * voi
int timeunit
char studynr[MAX_STUDYNR_LEN+1]
double * x1
int voiNr
double * x2
int frameNr
double * x
char unit[MAX_UNITS_LEN+1]
float sizex
unsigned short int dimx
char type
char decayCorrection
int _fileFormat
int * planeNumber
float sizey
float * start
unsigned short int dimy
float * end
float zoom
const char * statmsg
char studyNr[MAX_STUDYNR_LEN+1]
float * mid
float sizez
double * y