8#include "tpcclibConfig.h"
53static char *info[] = {
54 "Create a 4D PET image file in NIfTI 1S format, with contents from",
55 "the user-specified TAC file, for software testing.",
56 "Image volume is divided into rectangular cuboids, containing as pixel",
57 "values the regional TAC values.",
58 "Frame times are written in SIF as specified in the TAC file.",
60 "Usage: @P [Options] tacfile xdim ydim zdim imagefile [template]",
62 "If file name for template NIfTI is given, the rectangular cuboids are",
63 "are saved in it, with integer pixel values starting from 1.",
68 "See also: dft2img, flat2img, img2tif, img2dft, simboxes, pxl2mask",
70 "Keywords: image, NIfTI, simulation, software testing",
90int main(
int argc,
char **argv)
92 int ai, help=0, version=0, verbose=1;
93 char tacfile[FILENAME_MAX], dbname[FILENAME_MAX], tname[FILENAME_MAX];
94 int dimx=0, dimy=0, dimz=0;
100 if(argc==1) {
tpcPrintUsage(argv[0], info, stderr);
return(1);}
101 tacfile[0]=dbname[0]=tname[0]=(char)0;
103 for(ai=1; ai<argc; ai++)
if(*argv[ai]==
'-') {
104 char *cptr=argv[ai]+1;
if(*cptr==
'-') cptr++;
if(cptr==NULL)
continue;
106 fprintf(stderr,
"Error: invalid option '%s'.\n", argv[ai]);
115 if(help==2) {
tpcHtmlUsage(argv[0], info,
"");
return(0);}
121 if(ai<argc) {
strlcpy(tacfile, argv[ai], FILENAME_MAX); ai++;}
122 if(ai<argc) {
if(
atoiCheck(argv[ai++], &dimx)) ret++;}
123 if(ai<argc) {
if(
atoiCheck(argv[ai++], &dimy)) ret++;}
124 if(ai<argc) {
if(
atoiCheck(argv[ai++], &dimz)) ret++;}
125 if(ret || dimx<1 || dimy<1 || dimz<1) {
126 fprintf(stderr,
"Error: invalid dimension.\n");
129 if(ai<argc) {
strlcpy(dbname, argv[ai], FILENAME_MAX); ai++;}
130 if(ai<argc) {
strlcpy(tname, argv[ai], FILENAME_MAX); ai++;}
131 if(ai<argc) {fprintf(stderr,
"Error: too many arguments.\n");
return(1);}
135 fprintf(stderr,
"Error: missing command-line argument; use option --help\n");
141 printf(
"tacfile := %s\n", tacfile);
142 printf(
"dbname := %s\n", dbname);
143 if(tname[0]) printf(
"tname := %s\n", tname);
144 printf(
"dimx := %d\n", dimx);
145 printf(
"dimy := %d\n", dimy);
146 printf(
"dimz := %d\n", dimz);
153 if(verbose>1) printf(
"reading %s\n", tacfile);
156 ret=
tacRead(&tac, tacfile, &status);
158 fprintf(stderr,
"Error (%d): %s\n", ret,
errorMsg(status.
error));
163 printf(
"tacNr := %d\n", tac.
tacNr);
164 printf(
"sampleNr := %d\n", tac.
sampleNr);
167 printf(
"isframe := %d\n", tac.
isframe);
172 if(
tacYRange(&tac, -1, &min, &max, NULL, NULL, NULL, NULL)) {
173 fprintf(stderr,
"Error: invalid TAC contents.\n");
177 if(verbose>2) printf(
"min := %g\nmax := %g\n", min, max);
183 if(verbose>1) printf(
"Determine dimensions of rectangular cuboids\n");
184 int rdimx=0, rdimy=0, rdimz=0;
185 int rnx=0, rny=0, rnz=0;
186 if(
simRCDims(tac.
tacNr, dimx, dimy, dimz, &rnx, &rny, &rnz, &rdimx, &rdimy, &rdimz)) {
187 fprintf(stderr,
"Error: incompatible input data.\n");
192 printf(
"%d into %d x %d x %d -> %d x %d x %d (%d x %d x %d)\n",
193 tac.
tacNr, dimx, dimy, dimz, rdimx, rdimy, rdimz, rnx, rny, rnz);
199 if(verbose>1) printf(
"Allocate memory for template xyz matrix\n");
200 size_t pxlNr=(size_t)dimz*dimy*dimx;
202 idata=(
int*)calloc(pxlNr,
sizeof(
int));
204 fprintf(stderr,
"Error: out of memory.\n");
209 if(verbose>1) printf(
"Fill the template\n");
212 int x[2], y[2], z[2];
214 for(
int ri=0; ri<tac.
tacNr; ri++) {
215 x[0]=xi*rdimx; x[1]=x[0]+rdimx-1;
216 y[0]=yi*rdimy; y[1]=y[0]+rdimy-1;
217 z[0]=zi*rdimz; z[1]=z[0]+rdimz-1;
219 printf(
" %s : %d,%d,%d - %d,%d,%d\n", tac.
c[ri].
name, x[0],y[0],z[0], x[1],y[1],z[1]);
220 for(
int cz=z[0]; cz<=z[1]; cz++)
221 for(
int cy=y[0]; cy<=y[1]; cy++)
222 for(
int cx=x[0]; cx<=x[1]; cx++) {
223 size_t pos=((size_t)dimy*dimx)*cz + dimx*cy + cx;
226 xi++;
if(xi==rnx) {xi=0; yi++;
if(yi==rny) {yi=0; zi++;
if(zi==rnz)
break;}}
234 if(verbose>1) printf(
"Fill NIfTI header\n");
250 for(
int i=0; i<8; i++) dsr.
h1.
dim[i]=1;
263 for(
int i=0; i<8; i++) dsr.
h1.
pixdim[i]=0.0;
291 for(
int i=0; i<4; i++) dsr.
h1.
srow_x[i]=0;
292 for(
int i=0; i<4; i++) dsr.
h1.
srow_y[i]=0;
293 for(
int i=0; i<4; i++) dsr.
h1.
srow_z[i]=0;
304 if(verbose>1) printf(
"Make NIfTI file names for the template\n");
305 char hdrfile[FILENAME_MAX], imgfile[FILENAME_MAX];
307 fprintf(stderr,
" Error: invalid NIfTI name %s\n", tname);
312 if(verbose>1) printf(
"Writing template NIfTI header\n");
318 fprintf(stderr,
"Error: cannot write template header.\n");
323 if(verbose>1) printf(
"Writing NIfTI image data\n");
324 FILE *fp=fopen(imgfile,
"r+b");
326 fprintf(stderr,
"Error: cannot open %s for write.\n", imgfile);
333 if(fseeko(fp, (
size_t)dsr.
h1.
vox_offset, SEEK_SET)!=0) {
334 fprintf(stderr,
"Error: invalid file write position.\n");
335 fclose(fp);
tacFree(&tac); free(idata);
341 if(fwrite(idata,
sizeof(
int), pxlNr, fp) != pxlNr) {
342 fprintf(stderr,
"Error: cannot write template matrix.\n");
343 fclose(fp);
tacFree(&tac); free(idata);
349 if(verbose>0) printf(
"written %s\n", imgfile);
355 if(verbose>1) printf(
"Set NIfTI header\n");
368 if(verbose>1) printf(
"Make NIfTI file names\n");
369 char hdrfile[FILENAME_MAX], imgfile[FILENAME_MAX], siffile[FILENAME_MAX];
371 fprintf(stderr,
" Error: invalid NIfTI name %s\n", dbname);
377 if(verbose>1) printf(
"Allocate memory for one xyz matrix\n");
379 fdata=(
float*)calloc(pxlNr,
sizeof(
float));
381 fprintf(stderr,
"Error: out of memory.\n");
389 if(verbose>1) printf(
"Writing NIfTI header\n");
398 fprintf(stderr,
"Error: cannot write header.\n");
399 tacFree(&tac); free(fdata); free(idata);
407 if(verbose>1) printf(
"Writing NIfTI image data\n");
408 FILE *fp=fopen(imgfile,
"r+b");
410 fprintf(stderr,
"Error: cannot open %s for write.\n", imgfile);
411 tacFree(&tac); free(fdata); free(idata);
417 if(fseeko(fp, (
size_t)dsr.
h1.
vox_offset, SEEK_SET)!=0) {
418 fprintf(stderr,
"Error: invalid file write position.\n");
419 fclose(fp);
tacFree(&tac); free(fdata); free(idata);
425 for(
int fi=0; fi<tac.
sampleNr; fi++) {
426 if(verbose>8) printf(
"Writing frame %d\n", 1+fi);
428 memset(fdata, 0, pxlNr*
sizeof(
float));
429 for(
size_t i=0; i<pxlNr; i++) {
430 if(idata[i]==0) fdata[i]=0.0;
431 else fdata[i]=tac.
c[idata[i]-1].
y[fi];
433 if(fwrite(fdata,
sizeof(
float), pxlNr, fp) != pxlNr) {
434 fprintf(stderr,
"Error: cannot write image matrix.\n");
435 fclose(fp);
tacFree(&tac); free(fdata); free(idata);
441 fclose(fp); free(fdata); free(idata);
442 if(verbose>0) printf(
"written %s\n", imgfile);
447 if(verbose>1) printf(
"Making SIF\n");
448 fp=fopen(siffile,
"w");
450 fprintf(stderr,
"Error: cannot write %s\n", siffile);
456 fprintf(stderr,
"Error: cannot write %s\n", siffile);
461 if(verbose>0) printf(
"written %s\n", siffile);
498 if(rnx!=NULL) *rnx=0;
499 if(rny!=NULL) *rny=0;
500 if(rnz!=NULL) *rnz=0;
501 if(rcxdim!=NULL) *rcxdim=0;
502 if(rcydim!=NULL) *rcydim=0;
503 if(rczdim!=NULL) *rczdim=0;
504 if(N<1 || mxdim<1 || mydim<1 || mzdim<1)
return(1);
507 xd=mxdim; yd=mydim; zd=mzdim;
509 long long nx=1, ny=1, nz=1;
510 long long maxn=nx*ny*nz;
512 while(n>0 && (nz<mzdim || ny<mydim || nx<mxdim)) {
514 if(n>0 && nx<mxdim) {
515 nx++; maxn=nx*ny*nz; n=N-maxn;
517 if(n>0 && ny<mydim) {
518 ny++; maxn=nx*ny*nz; n=N-maxn;
520 if(n>0 && nz<mzdim) {
521 nz++; maxn=nx*ny*nz; n=N-maxn;
526 xd/=nx; yd/=ny; zd/=nz;
528 if(rnx!=NULL) *rnx=nx;
529 if(rny!=NULL) *rny=ny;
530 if(rnz!=NULL) *rnz=nz;
531 if(rcxdim!=NULL) *rcxdim=xd;
532 if(rcydim!=NULL) *rcydim=yd;
533 if(rczdim!=NULL) *rczdim=zd;
int fileExist(const char *filename)
int niftiCreateFNames(const char *filename, char *hdrfile, char *imgfile, char *siffile, int fileformat)
int atoiCheck(const char *s, int *v)
int niftiWriteHeader(const char *filename, NIFTI_DSR *dsr, int verbose)
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)
int tacWriteSIF(TAC *tac, FILE *fp, int extra, TPCSTATUS *status)
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)
char name[MAX_TACNAME_LEN+1]
int verbose
Verbose level, used by statusPrint() etc.
tpcerror error
Error code.
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)
int tacRead(TAC *d, const char *fname, TPCSTATUS *status)
char * tacFormattxt(tacformat c)
int tacYRange(TAC *d, int i, double *ymin, double *ymax, int *smin, int *smax, int *imin, int *imax)
Get the range of y values (concentrations) in TAC struct.
Header file for library libtpccsv.
Header file for libtpcdcm.
Header file for libtpcecat.
Header file for library libtpcextensions.
char * unitName(int unit_code)
Header file for library libtpcift.
Header file for libtpcimage.
@ IMG_FORMAT_NIFTI_1S
NIfTI-1 single-file format.
Header file for libtpcnifti.
#define NIFTI_DT_SIGNED_INT
#define NIFTI1_HEADER_SIZE
#define NIFTI_INTENT_NONE
Header file for library libtpctac.