117 float activityConcentration,
130 if(status!=NULL) sprintf(status,
"invalid filename");
131 if(imgName==NULL || !imgName[0])
return(1);
132 if(status!=NULL) sprintf(status,
"invalid efficient plane settings");
133 if(firstplane<1 || firstplane>lastplane)
return(2);
134 if(status!=NULL) sprintf(status,
"invalid mean plane settings");
135 if(startplane<1 || startplane>endplane)
return(3);
136 if(status!=NULL) sprintf(status,
"invalid activity concentration");
141 char hdrFile[FILENAME_MAX];
142 char imgFile[FILENAME_MAX];
143 strlcpy(imgFile, imgName, FILENAME_MAX);
144 strlcpy(hdrFile, imgName, FILENAME_MAX-4);
145 strcat(hdrFile,
".hdr");
146 if(verbose>2) printf(
"reading header in %s\n", hdrFile);
148 ret=
iftRead(&ift, hdrFile, 0, 0);
151 strlcpy(hdrFile, imgName, FILENAME_MAX-4);
152 strcat(hdrFile,
".i.hdr");
153 if(verbose>2) printf(
"reading header in %s\n", hdrFile);
154 ret=
iftRead(&ift, hdrFile, 0, 0);
157 strlcpy(imgFile, imgName, FILENAME_MAX);
158 strcat(imgFile,
".i");
163 if(status!=NULL) sprintf(status,
"cannot read file");
168 int dimx, dimy, dimz;
169 if(
iftGetIntValue(&ift, 0,
"matrix size [1]", &dimx, 0)<0 || dimx<1) {
170 if(status!=NULL) sprintf(status,
"cannot read dimx");
173 if(
iftGetIntValue(&ift, 0,
"matrix size [2]", &dimy, 0)<0 || dimy<1) {
174 if(status!=NULL) sprintf(status,
"cannot read dimy");
177 if(
iftGetIntValue(&ift, 0,
"matrix size [3]", &dimz, 0)<0 || dimz<1) {
178 if(status!=NULL) sprintf(status,
"cannot read dimz");
181 if(verbose>1) printf(
" matrix_size := %d x %d x %d\n", dimx, dimy, dimz);
184 if(status!=NULL) sprintf(status,
"invalid efficient plane settings");
188 if(status!=NULL) sprintf(status,
"invalid mean plane settings");
192 printf(
" Efficient factor set to 0 for %d first planes\n", firstplane-1);
193 printf(
" Efficient factor set to 0 for %d last planes\n", dimz-lastplane);
194 printf(
" Excluding %d first planes from the mean calculation\n", startplane-1);
195 printf(
" Excluding %d last planes from the mean calculation\n", dimz-endplane-1);
199 double xsize, ysize, zsize;
200 if(
iftGetDoubleValue(&ift, 0,
"scaling factor (mm/pixel) [1]", &xsize, 0)<0 || xsize<=0.0) {
201 if(status!=NULL) sprintf(status,
"cannot read x size");
204 if(
iftGetDoubleValue(&ift, 0,
"scaling factor (mm/pixel) [2]", &ysize, 0)<0 || ysize<=0.0) {
205 if(status!=NULL) sprintf(status,
"cannot read y size");
208 if(
iftGetDoubleValue(&ift, 0,
"scaling factor (mm/pixel) [3]", &zsize, 0)<0 || zsize<=0.0) {
209 if(status!=NULL) sprintf(status,
"cannot read z size");
212 if(verbose>1) printf(
" pixel_size := %g x %g x %g\n", xsize, ysize, zsize);
213 if(fabs(xsize-ysize)>0.01) {
214 if(status!=NULL) sprintf(status,
"invalid x and y pixel sizes");
219 ROIradius=75.0/xsize;
220 if(verbose>0) printf(
" ROIradius := %g\n", ROIradius);
224 if(
iftGetDoubleValue(&ift, 0,
"image duration", &scanDuration, 0)<0 || scanDuration<=0.0) {
225 if(status!=NULL) sprintf(status,
"cannot read scan duration");
228 if(verbose>1) printf(
" scanDuration := %g\n", scanDuration);
233 if(status!=NULL) sprintf(status,
"cannot read branching fraction");
240 if(
iftGetDoubleValue(&ift, 0,
"isotope halflife", &halflife, 0)<0 || halflife<=0.0) {
241 if(status!=NULL) sprintf(status,
"cannot read halflife");
244 if(verbose>1) printf(
" halflife := %g\n", halflife);
247 double deadtimeCorFactor;
248 if(
iftGetDoubleValue(&ift, 0,
"Dead time correction factor", &deadtimeCorFactor, 0)<0
249 || deadtimeCorFactor<=0.0) {
250 if(status!=NULL) sprintf(status,
"cannot read dead time");
253 if(verbose>1) printf(
" deadtimeCorFactor := %g\n", deadtimeCorFactor);
258 if(status!=NULL) sprintf(status,
"cannot read span");
261 if(verbose>1) printf(
" span := %d\n", span);
265 i=
iftGetFrom(&ift, 0,
"method of reconstruction used", 0);
266 if(i<0) i=
iftGetFrom(&ift, 0,
"reconstruction method", 0);
268 if(status!=NULL) sprintf(status,
"cannot read reconstruction method");
272 for(i=j=0; i<(int)strlen(buf); i++) {
273 if(buf[i]!=
'/' && buf[i]!=
' ') recMethod[j++]=buf[i];
275 recMethod[j]=(char)0;
276 if(verbose>1) printf(
" reconstruction method := %s\n", recMethod);
280 if(
iftGetIntValue(&ift, 0,
"number of iterations", &numIter, 0)<0) {
283 if(verbose>1) printf(
" numIter := %d\n", numIter);
287 if(
iftGetIntValue(&ift, 0,
"number of subsets", &numSubsets, 0)<0) {
290 if(verbose>1) printf(
" numSubsets := %d\n", numSubsets);
294 if(i<0 || strcasecmp(ift.
item[i].
value,
"float")!=0) {
295 if(status!=NULL) sprintf(status,
"data is not stored as floats");
298 i=
iftGetFrom(&ift, 0,
"number of bytes per pixel", 0);
299 if(i<0 || strcasecmp(ift.
item[i].
value,
"4")!=0) {
300 if(status!=NULL) sprintf(status,
"data is not stored as 4-byte floats");
311 if(verbose>2) printf(
"reading image data in %s\n", imgFile);
313 unsigned int pxlNr, n;
314 pxlNr=dimx*dimy*dimz;
315 img=(
float*)malloc(pxlNr*
sizeof(
float));
317 if(status!=NULL) sprintf(status,
"out of memory");
321 fp=fopen(imgFile,
"rb");
323 if(status!=NULL) sprintf(status,
"cannot open image file");
324 free(img);
return(101);
326 n=fread(img,
sizeof(
float), pxlNr, fp);
329 if(status!=NULL) sprintf(status,
"cannot read image");
330 free(img);
return(102);
334 if(verbose>1) printf(
" swapping bytes\n");
335 for(n=0; n<pxlNr; n++)
swawbip(&img[n],
sizeof(
float));
341 if(verbose>2) printf(
"ROI evaluation (circular, centered, 15 cm diameter)\n");
342 int numpix=0, planenumpix, x, y, z;
345 float ROIsum=0.0, ROIavg;
346 float planesum, xsum, ysum, x0, y0;
347 float planeROIavg[dimz], planeROIsum;
348 for(i=0; i<dimz; i++) planeROIavg[i]=0.0;
351 for(z=0; z<dimz; z++) {
352 planesum=xsum=ysum=0.0;
354 for(y=0; y<dimy; y++) {
355 for(x=0; x<dimx; x++) {
357 xsum+=(float)x*img[j];
358 ysum+=(float)y*img[j];
364 if(!isnormal(x0) || (
int)x0<=0 || (
int)x0>=dimx) x0=0.5*dimx;
365 if(!isnormal(y0) || (
int)y0<=0 || (
int)y0>=dimy) y0=0.5*dimy;
366 if(verbose>3) printf(
" ROIcenter[%d] = (%f/%f)\n", z, x0, y0);
369 for(y=0; y<dimy; y++) {
370 for(x=0; x<dimx; x++) {
371 if(hypotf((
float)x-x0, (
float)y-y0) <= ROIradius) {
374 if((z+1)>=startplane && (z+1)<=endplane) {
383 planeROIavg[z]=planeROIsum/(float)planenumpix;
384 if(verbose>0) printf(
" VOIaverage[%d] := %g\n", z, planeROIavg[z]);
386 ROIavg=ROIsum/(float)numpix;
387 if(verbose>2) printf(
" ROIavg := %g\n", ROIavg);
391 j=k=dimx*dimy*(startplane-1);
392 for(z=startplane; z<endplane; z++) {
393 planesum=xsum=ysum=0.0;
395 for(y=0; y<dimy; y++) {
396 for(x=0; x<dimx; x++) {
398 xsum+=(float)x*img[j];
399 ysum+=(float)y*img[j];
405 for(y=0; y<dimy; y++) {
406 for(x=0; x<dimx; x++) {
407 if(hypotf((
float)x-x0, (
float)y-y0) <= ROIradius) {
408 sqrSum+=(img[k]-ROIavg)*(img[k]-ROIavg);
414 VoISTDV=sqrt(sqrSum/(
double)numpix);
416 fprintf(stdout,
" standard deviation in VoI := %f\n", VoISTDV);
427 if(verbose>2) printf(
"Calculating calibration factor\n");
429 double corROIavg=ROIavg/scanDuration;
433 double dfrac=scanDuration/halflife*log(2);
434 dfrac/=(1.0-exp(-dfrac));
435 if(verbose>0) printf(
" decay correction := %f\n", dfrac);
438 corROIavg*=deadtimeCorFactor;
440 float calibFactor=activityConcentration/corROIavg;
442 fprintf(stdout,
" calibration factor := %e (counts/s)/(Bq/ml)\n",
450 if(verbose>2) printf(
"Writing output file\n");
452 char *cptr, calHdrName[512];
454 if((cptr=strpbrk(buf,
"_-. "))!=NULL) *cptr=
'\0';
455 strcpy(calHdrName, buf);
456 strlcat(calHdrName,
"_", 512);
strlcat(calHdrName, recMethod, 512);
458 sprintf(buf,
"_i%02d", numIter);
strlcat(calHdrName, buf, 512);
460 strlcat(calHdrName,
"_i0", 512);
462 sprintf(buf,
"s%d", numSubsets);
strlcat(calHdrName, buf, 512);
463 sprintf(buf,
"_s%d", span);
strlcat(calHdrName, buf, 512);
464 if(dimx!=256) {sprintf(buf,
"_m%d", dimx);
strlcat(calHdrName, buf, 512);}
465 strlcat(calHdrName,
".cal.hdr", 512);
467 ret=
iftPut(&ift, NULL, imgName,
";", 0);
469 ret=
iftPutDouble(&ift,
"activity concentration used (Bq/ml)",
470 (
double)activityConcentration,
";", 0);
472 sprintf(buf,
"VOI mean from planes %d - %d", startplane, endplane);
473 ret=
iftPut(&ift, NULL, buf,
";", 0);
475 if(ret==0) ret=
iftPutDouble(&ift,
"mean activity concentration in VOI", (
double)ROIavg,
";", 0);
477 if(ret==0) ret=
iftPutDouble(&ift,
"standard deviation in VOI", (
double)VoISTDV,
";", 0);
478 if(ret==0) ret=
iftPutDouble(&ift,
"CV in VOI", (
double)VoISTDV/ROIavg,
";", 0);
481 ret=
iftPutDouble(&ift,
"corrected VOI activity concentration", (
double)corROIavg,
";", 0);
482 if(ret==0) ret=
iftPut(&ift, NULL,
" ", NULL, 0);
483 if(ret==0) ret=
iftPut(&ift, NULL,
"calibration factor in (Bq/cc)/(counts/s)",
";", 0);
484 if(ret==0) ret=
iftPutDouble(&ift,
"calibration factor", (
double)calibFactor, NULL, 0);
485 if(ret==0) ret=
iftPut(&ift, NULL,
" ", NULL, 0);
486 for(j=1; j<=dimz && ret==0; j++) {
487 sprintf(buf,
"efficient factor for plane %d", j-1);
488 if(j<firstplane || j>lastplane)
491 ret=
iftPutDouble(&ift, buf, ROIavg/planeROIavg[j-1], NULL, 0);
494 if(status!=NULL) sprintf(status,
"cannot make calibration file");
498 printf(
"\n--------------------------------------------------\n");
499 printf(
"%s :\n", calHdrName);
500 printf(
"--------------------------------------------------\n");
507 if(status!=NULL) sprintf(status,
"cannot write calibration file");
510 fprintf(stdout,
"\ncalibrations written in %s\n\n", calHdrName);