8#include "tpcclibConfig.h"
28static char *info[] = {
29 "Simulate dynamic PET image of heart. Approach is very simplistic and",
30 "only applicable to software testing and basic simulations:",
31 "only one image plane is produced by default, containing a ring representing",
32 "myocardial muscle surrounding LV cavity.",
34 "Usage: @P [options] tacfile imgfile",
36 "TAC data file must contain the time-activity curves of myocardial muscle,",
37 "blood in LV cavity, and optionally background surrounding the heart.",
38 "Sample times in TAC file are used as time frames of the simulated image.",
41 " -dim=<Image x and y dimension in pixels>",
42 " Set image dimension; by default 128.",
44 " Simulation in 3D (note that computation may take time).",
45 " -pxlsize=<Voxel size (mm)>",
46 " Set image voxel size; by default 1 mm.",
48 " Set image resolution; by default 8 mm.",
49 " -thickness=<Myocardial wall thickness (mm)>",
50 " Set (relaxed) myocardial wall thickness; by default 10 mm.",
51 " -diameter=<Max LV cavity diameter (mm)>",
52 " Set maximal LV cavity diameter; by default 52 mm.",
53 " -diamin=<Min LV cavity diameter (fraction)>",
54 " Set minimum LV cavity diameter as fraction of max diameter;",
56 " -bif=<Image filename>",
57 " Save heart beat phases separately as image planes;",
58 " not applicable with option -3D.",
63 "Example: @P tacs.dat myoc.v",
65 "See also: simiart, fvar4tac, imgfiltg, sim_3tcm, b2t_h2o, imgadd, simcirc",
67 "Keywords: simulation, image, software testing, myocardium, LV",
86int main(
int argc,
char **argv)
88 int ai, help=0, version=0, verbose=1;
89 char tacfile[FILENAME_MAX], imgfile[FILENAME_MAX], biffile[FILENAME_MAX];
91 double pxlsize=1.0, fwhm=8.0;
92 double thickness=10.0, diameter=52.0, diamin=0.62;
94 float zoom=1.41421356;
103 if(argc==1) {
tpcPrintUsage(argv[0], info, stderr);
return(1);}
104 tacfile[0]=imgfile[0]=biffile[0]=(char)0;
107 for(ai=1; ai<argc; ai++)
if(*argv[ai]==
'-') {
110 if(strncasecmp(cptr,
"DIM=", 4)==0) {
111 dim=atoi(cptr+4);
if(dim>4)
continue;
112 }
else if(strcasecmp(cptr,
"3D")==0) {
114 }
else if(strncasecmp(cptr,
"PXLSIZE=", 8)==0) {
116 }
else if(strncasecmp(cptr,
"DIAMETER=", 9)==0) {
118 }
else if(strncasecmp(cptr,
"DIAMIN=", 7)==0) {
119 if(!
atof_with_check(cptr+7, &diamin) && diamin>0.0 && diamin<=1.0)
continue;
120 }
else if(strncasecmp(cptr,
"FWHM=", 5)==0) {
122 }
else if(strncasecmp(cptr,
"THICKNESS=", 10)==0) {
124 }
else if(strncasecmp(cptr,
"BIF=", 4)==0) {
125 strlcpy(biffile, cptr+4, FILENAME_MAX);
if(strlen(biffile)>0)
continue;
127 fprintf(stderr,
"Error: invalid option '%s'.\n", argv[ai]);
132 if(help==2) {
tpcHtmlUsage(argv[0], info,
"");
return(0);}
137 if(ai<argc) {
strlcpy(tacfile, argv[ai++], FILENAME_MAX);}
138 if(ai<argc) {
strlcpy(imgfile, argv[ai++], FILENAME_MAX);}
140 fprintf(stderr,
"Error: invalid argument '%s'.\n", argv[ai]);
145 fprintf(stderr,
"Error: missing command-line argument; use option --help\n");
149 if(dimz>0) dimz=dim;
else dimz=1;
150 if(dimz>1 && biffile[0]) {
151 fprintf(stderr,
"Warning: 3D beating image can not be saved; ignored.\n");
157 printf(
"tacfile := %s\n", tacfile);
158 printf(
"imgfile := %s\n", imgfile);
159 if(biffile[0]) printf(
"biffile := %s\n", biffile);
160 printf(
"dim := %d\n", dim);
161 printf(
"dimz := %d\n", dimz);
162 printf(
"pxlsize := %g\n", pxlsize);
163 printf(
"diameter := %g\n", diameter);
164 printf(
"diamin := %g\n", diamin);
165 printf(
"fwhm := %g\n", fwhm);
167 printf(
"thickness := %g\n", thickness);
175 if(verbose>1) printf(
"reading TACs\n");
177 fprintf(stderr,
"Error in reading '%s': %s\n", tacfile,
dfterrmsg);
181 fprintf(stderr,
"Error: TAC file does not contain necessary TACs.\n");
185 fprintf(stderr,
"Error: TAC file contains more than three TACs.\n");
192 if(verbose>1) printf(
"allocating memory for image data\n");
196 fprintf(stderr,
"Error: cannot allocate memory for image data.\n");
200 if(verbose>1) printf(
"setting image headers\n");
208 for(
int fi=0; fi<tac.
frameNr; fi++) {
211 img.
start[fi]*=60.; img.
end[fi]*=60.; img.
mid[fi]*=60.;
215 for(
int zi=0; zi<dimz; zi++) img.
planeNumber[zi]=1+zi;
221 if(biffile[0] && diamin<1.0) {
222 if(verbose>1) printf(
"allocating memory for heart beat phases image\n");
225 fprintf(stderr,
"Error: cannot allocate memory for image data.\n");
228 for(
int i=0; i<SBFNR; i++) bimg.
planeNumber[i]=1+i;
229 }
else biffile[0]=(char)0;
233 if(verbose>1) printf(
"allocating memory for temp image\n");
236 fprintf(stderr,
"Error: cannot allocate memory for image data.\n");
244 if(verbose>0) printf(
"simulation...\n");
249 double rtfract[SBFNR];
251 rtfract[0]=1.0;
for(
int i=1; i<SBFNR; i++) rtfract[i]=0.0;
253 for(
int i=0; i<SBFNR; i++) rtfract[i]=1.0;
266 double r1inner, r1outer, d1, d2;
267 r1inner=0.5*diameter; r1outer=r1inner+thickness;
269 a=r1outer*r1outer - r1inner*r1inner;
271 d1=2.0*r1outer; d2=2.0*r1inner;
272 a=d1*d1*d1 - d2*d2*d2;
275 if(verbose>2) printf(
"a := %g\n", a);
277 double dI, dO, c_cav, c_myo, c_bkg;
280 for(
int fi=0; fi<img.
dimt; fi++) {
281 if(verbose>1) printf(
"Frame %d/%d\n", 1+fi, img.
dimt);
283 c_myo=tac.
voi[0].
y[fi]; c_cav=tac.
voi[1].
y[fi];
284 if(tac.
voiNr>2) c_bkg=tac.
voi[2].
y[fi];
else c_bkg=0.0;
290 for(
int ri=0; ri<SBFNR; ri++)
if(rtfract[ri]>0.0) {
301 dO=cbrt(a + dI*dI*dI);
305 printf(
"Radius %d/%d\n", 1+ri, SBFNR);
306 printf(
"inner diameter := %g\n", dI);
307 printf(
"outer diameter := %g\n", dO);
308 if(simg.
dimz==1) printf(
"muscle area := %g\n", M_PI*(r*r-f*f));
309 else printf(
"muscle volume := %g\n", M_PI*(dO*dO*dO-dI*dI*dI)/6.0);
313 for(
long long i=0; i<(
long long)simg.
dimx*simg.
dimy*simg.
dimz; i++) simg.
pixel[i]=0.0;
315 ret=
imgSimulateRing(&simg, 0, 0, cx, cy, f, r, c_myo, c_cav, c_bkg, verbose-3);
317 ret=
imgSimulateSphere(&simg, 0, cx, cy, cz, f, r, c_myo, c_cav, c_bkg, verbose-3);
322 for(zi=0; zi<img.
dimz; zi++)
323 for(yi=0; yi<img.
dimy; yi++)
324 for(xi=0; xi<img.
dimx; xi++)
325 img.
m[zi][yi][xi][fi]+=rtfract[ri]*simg.
m[zi][yi][xi][0];
329 for(yi=0; yi<img.
dimy; yi++)
330 for(xi=0; xi<img.
dimx; xi++)
331 bimg.
m[ri][yi][xi][fi]=simg.
m[0][yi][xi][0];
335 dI-=diameter*(1.0-diamin)/(
double)(SBFNR-1);
342 fprintf(stderr,
"Error: cannot simulate image (%d).\n", ret);
348 if(verbose>1) printf(
"averaging heart beat phases\n");
351 for(
int i=0; i<SBFNR; i++)
if(rtfract[i]>0.0) rtsum+=rtfract[i];
352 if(verbose>2) printf(
"rtsum := %g\n", rtsum);
355 fprintf(stderr,
"Error: cannot process simulated image (%d).\n", ret);
364 if(verbose>0) printf(
"simulating resolution effect\n");
378 fprintf(stderr,
"Error: cannot filter simulated image (%d).\n", ret);
379 if(verbose>0) fprintf(stderr,
" %s.\n", tmp);
387 fprintf(stderr,
"Error: cannot filter simulated image (%d).\n", ret);
388 if(verbose>0) fprintf(stderr,
" %s.\n", tmp);
399 if(verbose>1) printf(
"Writing image file %s ...\n", imgfile);
401 fprintf(stderr,
"Error: %s\n", img.
statmsg);
404 if(verbose>0) printf(
"%s written.\n", imgfile);
411 if(verbose>1) printf(
"Writing image file %s ...\n", biffile);
413 fprintf(stderr,
"Error: %s\n", bimg.
statmsg);
416 if(verbose>0) printf(
"%s written.\n", biffile);
int atof_with_check(char *double_as_string, double *result_value)
int dftRead(char *filename, DFT *data)
int imgSimulateSphere(IMG *img, int fi, double cx, double cy, double cz, double r1, double r2, double vr, double vi, double vo, int verbose)
int imgSimulateRing(IMG *img, int fi, int zi, double cx, double cy, double r1, double r2, double vr, double vi, double vo, int verbose)
int imgAllocate(IMG *image, int planes, int rows, int columns, int frames)
int imgAllocateWithHeader(IMG *image, int planes, int rows, int columns, int frames, IMG *image_from)
void imgEmpty(IMG *image)
int imgArithmConst(IMG *img, float operand, char operation, float ulimit, int verbose)
int imgWrite(const char *fname, IMG *img)
int imgGaussianFIRFilter(IMG *img, float xsd, float ysd, float zsd, double tolerance, int verbose)
int imgSetScanner(IMG *img, int scanner_type)
int imgSetUnit(IMG *img, char *unit)
Header file for libtpccurveio.
Header file for libtpcidi.
Header file for libtpcimgio.
Header file for libtpcimgp.
Header file for libtpcmisc.
int tpcProcessStdOptions(const char *s, int *print_usage, int *print_version, int *verbose_level)
size_t strlcpy(char *dst, const char *src, size_t dstsize)
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)
Header file for libtpcmodel.
Header file for libtpcmodext.
char studynr[MAX_STUDYNR_LEN+1]
char unit[MAX_UNITS_LEN+1]
char studyNr[MAX_STUDYNR_LEN+1]