9#include "tpcclibConfig.h"
51static char *info[] = {
52 "Create a 4D PET image file in NIfTI 1S format, with contents from",
53 "the user-specified TAC file, for software testing.",
54 "Image volume is divided into rectangular cuboids, containing as pixel",
55 "values the regional TAC values.",
56 "Frame times are written in SIF as specified in the TAC file.",
58 "Usage: @P [Options] tacfile xdim ydim zdim imagefile [template]",
60 "If file name for template NIfTI is given, the rectangular cuboids are",
61 "are saved in it, with integer pixel values starting from 1.",
66 "See also: dft2img, flat2img, img2tif, img2dft, simboxes, pxl2mask",
68 "Keywords: image, NIfTI, simulation, software testing",
88int main(
int argc,
char **argv)
90 int ai, help=0, version=0, verbose=1;
91 char tacfile[FILENAME_MAX], dbname[FILENAME_MAX], tname[FILENAME_MAX];
92 int dimx=0, dimy=0, dimz=0;
97 if(argc==1) {
tpcPrintUsage(argv[0], info, stderr);
return(1);}
98 tacfile[0]=dbname[0]=tname[0]=(char)0;
100 for(ai=1; ai<argc; ai++)
if(*argv[ai]==
'-') {
101 char *cptr=argv[ai]+1;
if(*cptr==
'-') cptr++;
if(cptr==NULL)
continue;
103 fprintf(stderr,
"Error: invalid option '%s'.\n", argv[ai]);
108 if(help==2) {
tpcHtmlUsage(argv[0], info,
"");
return(0);}
113 if(ai<argc) {
strlcpy(tacfile, argv[ai], FILENAME_MAX); ai++;}
114 if(ai<argc) {dimx=atoi(argv[ai++]);}
115 if(ai<argc) {dimy=atoi(argv[ai++]);}
116 if(ai<argc) {dimz=atoi(argv[ai++]);}
117 if(ai<argc) {
strlcpy(dbname, argv[ai], FILENAME_MAX); ai++;}
118 if(ai<argc) {
strlcpy(tname, argv[ai], FILENAME_MAX); ai++;}
119 if(ai<argc) {fprintf(stderr,
"Error: invalid argument '%s'.\n", argv[ai]);
return(1);}
123 if(!dbname[0] || dimz<1) {
124 fprintf(stderr,
"Error: missing command-line argument; try %s --help\n", argv[0]);
130 printf(
"tacfile := %s\n", tacfile);
131 printf(
"dbname := %s\n", dbname);
132 if(tname[0]) printf(
"tname := %s\n", tname);
133 printf(
"dimx := %d\n", dimx);
134 printf(
"dimy := %d\n", dimy);
135 printf(
"dimz := %d\n", dimz);
143 if(verbose>1) printf(
"Reading TAC file %s\n", tacfile);
146 fprintf(stderr,
"Error in reading '%s': %s\n", tacfile,
dfterrmsg);
149 if(verbose>2) printf(
"tacNr := %d\nframeNr := %d\n", dft.
voiNr, dft.
frameNr);
152 if(
dftMinMax(&dft, NULL, NULL, &min, &max)) {
153 fprintf(stderr,
"Error: invalid TAC contents.\n");
157 if(verbose>2) printf(
"min := %g\nmax := %g\n", min, max);
163 if(verbose>1) printf(
"Determine dimensions of rectangular cuboids\n");
164 int rdimx=0, rdimy=0, rdimz=0;
165 int rnx=0, rny=0, rnz=0;
166 if(
simRCDims(dft.
voiNr, dimx, dimy, dimz, &rnx, &rny, &rnz, &rdimx, &rdimy, &rdimz)) {
167 fprintf(stderr,
"Error: incompatible input data.\n");
172 printf(
"%d into %d x %d x %d -> %d x %d x %d (%d x %d x %d)\n",
173 dft.
voiNr, dimx, dimy, dimz, rdimx, rdimy, rdimz, rnx, rny, rnz);
179 if(verbose>1) printf(
"Allocate memory for template xyz matrix\n");
180 size_t pxlNr=(size_t)dimz*dimy*dimx;
182 idata=(
int*)calloc(pxlNr,
sizeof(
int));
184 fprintf(stderr,
"Error: out of memory.\n");
189 if(verbose>1) printf(
"Fill the template\n");
192 int x[2], y[2], z[2];
194 for(
int ri=0; ri<dft.
voiNr; ri++) {
195 x[0]=xi*rdimx; x[1]=x[0]+rdimx-1;
196 y[0]=yi*rdimy; y[1]=y[0]+rdimy-1;
197 z[0]=zi*rdimz; z[1]=z[0]+rdimz-1;
199 printf(
" %s : %d,%d,%d - %d,%d,%d\n", dft.
voi[ri].
name,
200 x[0],y[0],z[0], x[1],y[1],z[1]);
201 for(
int cz=z[0]; cz<=z[1]; cz++)
202 for(
int cy=y[0]; cy<=y[1]; cy++)
203 for(
int cx=x[0]; cx<=x[1]; cx++) {
204 size_t pos=((size_t)dimy*dimx)*cz + dimx*cy + cx;
207 xi++;
if(xi==rnx) {xi=0; yi++;
if(yi==rny) {yi=0; zi++;
if(zi==rnz)
break;}}
215 if(verbose>1) printf(
"Fill NIfTI header\n");
230 for(
int i=0; i<8; i++) dsr.
h.
dim[i]=1;
243 for(
int i=0; i<8; i++) dsr.
h.
pixdim[i]=0.0;
271 for(
int i=0; i<4; i++) dsr.
h.
srow_x[i]=0;
272 for(
int i=0; i<4; i++) dsr.
h.
srow_y[i]=0;
273 for(
int i=0; i<4; i++) dsr.
h.
srow_z[i]=0;
275 strcpy(dsr.
h.
magic,
"n+1");
283 if(verbose>1) printf(
"Make NIfTI file names for the template\n");
284 char hdrfile[FILENAME_MAX], imgfile[FILENAME_MAX];
286 fprintf(stderr,
" Error: invalid NIfTI name %s\n", tname);
291 if(verbose>1) printf(
"Writing template NIfTI header\n");
297 fprintf(stderr,
"Error: cannot write template header.\n");
298 if(verbose>1) fprintf(stderr,
"Status: %s\n", tmp);
303 if(verbose>1) printf(
"Writing NIfTI image data\n");
304 FILE *fp=fopen(imgfile,
"r+b");
306 fprintf(stderr,
"Error: cannot open %s for write.\n", imgfile);
312 if(fseeko(fp, (
size_t)dsr.
h.
vox_offset, SEEK_SET)!=0) {
313 fprintf(stderr,
"Error: invalid file write position.\n");
314 fclose(fp);
dftEmpty(&dft); free(idata);
319 if(fwrite(idata,
sizeof(
int), pxlNr, fp) != pxlNr) {
320 fprintf(stderr,
"Error: cannot write template matrix.\n");
321 fclose(fp);
dftEmpty(&dft); free(idata);
326 if(verbose>0) printf(
"written %s\n", imgfile);
333 if(verbose>1) printf(
"Set NIfTI header\n");
346 if(verbose>1) printf(
"Make NIfTI file names\n");
347 char hdrfile[FILENAME_MAX], imgfile[FILENAME_MAX], siffile[FILENAME_MAX];
349 fprintf(stderr,
" Error: invalid NIfTI name %s\n", dbname);
355 if(verbose>1) printf(
"Allocate memory for one xyz matrix\n");
357 fdata=(
float*)calloc(pxlNr,
sizeof(
float));
359 fprintf(stderr,
"Error: out of memory.\n");
367 if(verbose>1) printf(
"Writing NIfTI header\n");
375 fprintf(stderr,
"Error: cannot write header.\n");
376 if(verbose>1) fprintf(stderr,
"Status: %s\n", tmp);
377 dftEmpty(&dft); free(fdata); free(idata);
385 if(verbose>1) printf(
"Writing NIfTI image data\n");
386 FILE *fp=fopen(imgfile,
"r+b");
388 fprintf(stderr,
"Error: cannot open %s for write.\n", imgfile);
389 dftEmpty(&dft); free(fdata); free(idata);
394 if(fseeko(fp, (
size_t)dsr.
h.
vox_offset, SEEK_SET)!=0) {
395 fprintf(stderr,
"Error: invalid file write position.\n");
396 fclose(fp);
dftEmpty(&dft); free(fdata); free(idata);
401 for(
int fi=0; fi<dft.
frameNr; fi++) {
402 if(verbose>8) printf(
"Writing frame %d\n", 1+fi);
404 memset(fdata, 0, pxlNr*
sizeof(
float));
405 for(
size_t i=0; i<pxlNr; i++) {
406 if(idata[i]==0) fdata[i]=0.0;
407 else fdata[i]=dft.
voi[idata[i]-1].
y[fi];
409 if(fwrite(fdata,
sizeof(
float), pxlNr, fp) != pxlNr) {
410 fprintf(stderr,
"Error: cannot write image matrix.\n");
411 fclose(fp);
dftEmpty(&dft); free(fdata); free(idata);
416 fclose(fp); free(fdata); free(idata);
417 if(verbose>0) printf(
"written %s\n", imgfile);
423 if(verbose>1) printf(
"Making SIF\n");
426 fprintf(stderr,
"Error: cannot allocate memory for SIF data.\n");
442 for(
int fi=0; fi<dft.
frameNr; fi++) {
443 sif.
x1[fi]=dft.
x1[fi];
444 sif.
x2[fi]=dft.
x2[fi];
448 fprintf(stderr,
"Error: cannot write %s\n", siffile);
453 if(verbose>0) printf(
"written %s\n", siffile);
491 if(rnx!=NULL) *rnx=0;
492 if(rny!=NULL) *rny=0;
493 if(rnz!=NULL) *rnz=0;
494 if(rcxdim!=NULL) *rcxdim=0;
495 if(rcydim!=NULL) *rcydim=0;
496 if(rczdim!=NULL) *rczdim=0;
497 if(N<1 || mxdim<1 || mydim<1 || mzdim<1)
return(1);
500 xd=mxdim; yd=mydim; zd=mzdim;
502 long long nx=1, ny=1, nz=1;
503 long long maxn=nx*ny*nz;
505 while(n>0 && (nz<mzdim || ny<mydim || nx<mxdim)) {
507 if(n>0 && nx<mxdim) {
508 nx++; maxn=nx*ny*nz; n=N-maxn;
510 if(n>0 && ny<mydim) {
511 ny++; maxn=nx*ny*nz; n=N-maxn;
513 if(n>0 && nz<mzdim) {
514 nz++; maxn=nx*ny*nz; n=N-maxn;
519 xd/=nx; yd/=ny; zd/=nz;
521 if(rnx!=NULL) *rnx=nx;
522 if(rny!=NULL) *rny=ny;
523 if(rnz!=NULL) *rnz=nz;
524 if(rcxdim!=NULL) *rcxdim=xd;
525 if(rcydim!=NULL) *rcydim=yd;
526 if(rczdim!=NULL) *rczdim=zd;
int dftMinMax(DFT *dft, double *minx, double *maxx, double *miny, double *maxy)
void dftFrametimes(DFT *data)
int dftRead(char *filename, DFT *data)
int dftTimeunitConversion(DFT *dft, int tunit)
Header file for libtpccurveio.
Header file for libtpcimgio.
int sifWrite(SIF *data, char *filename)
int niftiWriteHeader(char *filename, NIFTI_DSR *dsr, int verbose, char *status)
int niftiCreateFNames(const char *filename, char *hdrfile, char *imgfile, char *siffile, int fileformat)
#define NIFTI_DT_SIGNED_INT
#define NIFTI_HEADER_SIZE
int sifSetmem(SIF *data, int frameNr)
#define NIFTI_INTENT_NONE
int niftiRemove(const char *dbname, int fileformat, int verbose)
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 libtpcroi.
char studynr[MAX_STUDYNR_LEN+1]
char studynr[MAX_STUDYNR_LEN+1]
char name[MAX_REGIONNAME_LEN+1]
int simRCDims(const long long N, const int mxdim, const int mydim, const int mzdim, int *rnx, int *rny, int *rnz, int *rcxdim, int *rcydim, int *rczdim)