Read transmission scan file and blank scan file and calculate the attenuation correction data and the logarithmic correction data.
155 {
156 int ret;
157
158
159 if(status!=NULL) sprintf(status, "invalid filename");
160 if(trafile==NULL || !trafile[0]) return(1);
161 if(blkfile==NULL || !blkfile[0]) return(1);
162 if(norfile==NULL || !blkfile[0]) return(1);
163 if(atnfile==NULL || !atnfile[0]) return(1);
164
165
166
167
168
169 FILE *fptra=NULL, *fpblk=NULL, *fpnor=NULL;
170 if(verbose>0) printf("opening %s\n", trafile);
171 if((fptra=fopen(trafile, "rb")) == NULL) {
172 if(status!=NULL) sprintf(status, "cannot open transmission sinogram");
173 return(2);
174 }
175 if(verbose>0) printf("opening %s\n", blkfile);
176 if((fpblk=fopen(blkfile, "rb")) == NULL) {
177 if(status!=NULL) sprintf(status, "cannot open blank sinogram");
178 fclose(fptra);
179 return(2);
180 }
181 if(verbose>0) printf("opening %s\n", norfile);
182 if((fpnor=fopen(norfile, "rb")) == NULL) {
183 if(status!=NULL) sprintf(status, "cannot open normalization file");
184 fclose(fptra); fclose(fpblk);
185 return(2);
186 }
187
188
189
190
191 if(verbose>1) printf("reading transmission main header\n");
194 if(status!=NULL) sprintf(status, "cannot read transmission main header");
195 fclose(fptra); fclose(fpblk); fclose(fpnor);
196 return(3);
197 }
199 if(verbose>4) printf(
"file_type := %d\n", tra_main_header.
file_type);
200
201 if(verbose>1) printf("reading blank main header\n");
204 if(status!=NULL) sprintf(status, "cannot read blank main header");
205 fclose(fptra); fclose(fpblk); fclose(fpnor);
206 return(3);
207 }
209 if(verbose>4) printf(
"file_type := %d\n", blk_main_header.
file_type);
210
211 if(verbose>1) printf("reading normalization main header\n");
214 if(status!=NULL) sprintf(status, "cannot read blank main header");
215 fclose(fptra); fclose(fpblk); fclose(fpnor);
216 return(3);
217 }
219 if(verbose>4) printf(
"file_type := %d\n", nor_main_header.
file_type);
220
221
224 {
225 if(status!=NULL) sprintf(status, "file is not a sinogram");
226 fclose(fptra); fclose(fpblk); fclose(fpnor);
227 return(3);
228 }
229
230
231 time_t tra_start, blk_start;
234 if(verbose>1) {
235 char buf[32];
236 printf(
"Blank scan start time := %s\n",
ctime_r_int(&blk_start, buf));
237 printf(
"Transmission scan start time := %s\n",
ctime_r_int(&tra_start, buf));
238 }
239 if(decay!=0 && (tra_start==0 || blk_start==0)) {
240 if(status!=NULL) sprintf(status, "missing scan start time");
241 fclose(fptra); fclose(fpblk); fclose(fpnor);
242 return(3);
243 }
244 double start_time_diff=difftime(tra_start, blk_start);
245 if(verbose>1) {printf("scan start time difference := %g\n", start_time_diff);}
246
247
248 double halflife=-1.0;
251 if(verbose>1 && halflife>0.0) {printf("isotope halflife := %g\n", halflife);}
252 if(decay!=0 && halflife<=0.0) {
253 if(status!=NULL) sprintf(status, "missing isotope halflife");
254 fclose(fptra); fclose(fpblk); fclose(fpnor);
255 return(3);
256 }
257
258
259
260
261
262
263 if(verbose>1) printf("reading transmission matrix list\n");
266 if(ret) {
267 if(status!=NULL) sprintf(status, "cannot read sinogram matrix list");
268 fclose(fptra); fclose(fpblk); fclose(fpnor);
269 return(3);
270 }
271
272 if(verbose>1) printf("reading blank matrix list\n");
275 if(ret) {
276 if(status!=NULL) sprintf(status, "cannot read blank matrix list");
278 fclose(fptra); fclose(fpblk); fclose(fpnor);
279 return(3);
280 }
281
282 if(verbose>1) printf("reading normalization matrix list\n");
285 if(ret) {
286 if(status!=NULL) sprintf(status, "cannot read normalization matrix list");
288 fclose(fptra); fclose(fpblk); fclose(fpnor);
289 return(3);
290 }
291
292
294 if(status!=NULL) sprintf(status, "empty matrix list");
297 fclose(fptra); fclose(fpblk); fclose(fpnor);
298 return(3);
299 }
302 {
303 if(status!=NULL) sprintf(status, "invalid matrix list");
306 fclose(fptra); fclose(fpblk); fclose(fpnor);
307 return(3);
308 }
309 if(verbose>3) {
310 printf(
"transmission_matrixNr := %d\n", tra_mlist.
matrixNr);
311 printf(
"blank_matrixNr := %d\n", blk_mlist.
matrixNr);
312 printf(
"normalization_matrixNr := %d\n", nor_mlist.
matrixNr);
313 }
318 {
319 if(status!=NULL) sprintf(status, "different plane numbers");
322 fclose(fptra); fclose(fpblk); fclose(fpnor);
323 return(3);
324 }
325
326
327
328
329 if(verbose>0) printf("writing main header in %s\n", atnfile);
336 FILE *fpatn=NULL;
338 if(fpatn==NULL) {
339 if(status!=NULL) sprintf(status, "cannot write attenuation file\n");
342 fclose(fptra); fclose(fpblk); fclose(fpnor);
343 return(11);
344 }
345
346 FILE *fpimg=NULL;
347 if(imgfile!=NULL && imgfile[0]) {
348 if(verbose>0) printf("writing main header in %s\n", imgfile);
357 if(fpimg==NULL) {
358 if(status!=NULL) sprintf(status, "cannot write transmission image\n");
361 fclose(fptra); fclose(fpblk); fclose(fpnor);
362 remove(atnfile);
363 return(12);
364 }
365 }
366
367
368
369
370
371 if(verbose>0) printf("processing matrices...\n");
372 int cret=0;
373 for(
int mi=0; mi<tra_mlist.
matrixNr; mi++) {
374 if(verbose==1) {fprintf(stdout, "."); fflush(stdout);}
375
376 FILE *lfptra=fptra;
377 FILE *lfpblk=fpblk;
378 FILE *lfpnor=fpnor;
379 FILE *lfpatn=fpatn;
380 FILE *lfpimg=fpimg;
381
386 int dimx, dimy, scnpxlNr=0, imgpxlNr=0, matnum=0, ni=0, bi=0;
387 float *tramat, *blkmat, *normat, f;
388 int ret=0;
389
390
392
393
394 if(verbose>1) printf("reading transmission matrix %d\n", 1+mi);
397 if(ret) {
398 if(status!=NULL)
399 sprintf(status,
"cannot read transmission sinogram matrix %u", tra_mlist.
matdir[mi].
matnum);
400 cret=ret;
401 continue;
402 }
403 if(verbose>2)
404 printf("Matrix: plane %d frame %d gate %d bed %d\n",
406 if(verbose>200) {
408 } else if(verbose>1 && mi==0) {
409 printf("Transmission sinogram dimensions := %d x %d\n",
411 printf("Transmission sinogram frame duration := %g\n",
413 printf("Transmission sinogram dead-time correction := %g\n",
415 }
418 scnpxlNr=dimx*dimy;
419 if(imgDim<2) imgDim=dimx;
420
422 for(int i=0; i<scnpxlNr; i++)
424 }
425
427 if(status!=NULL) sprintf(status, "missing frame duration in transmission sinogram");
428 free(tramat);
429 cret=ret;
430 continue;
431 }
433 for(int i=0; i<scnpxlNr; i++) tramat[i]*=f;
434
435
437 for(ni=0; ni<nor_mlist.
matrixNr; ni++)
439 break;
441 if(status!=NULL)
442 sprintf(status, "cannot find matrix %u in normalization sinogram",
444 free(tramat);
445 cret=ret;
446 continue;
447 }
448
449 if(verbose>1) printf("reading normalization matrix %d\n", 1+ni);
452 if(ret) {
453 if(status!=NULL)
454 sprintf(status,
"cannot read blank sinogram matrix %u", nor_mlist.
matdir[ni].
matnum);
455 free(tramat);
456 cret=ret;
457 continue;
458 }
459 if(verbose>200) {
461 } else if(verbose>1 && mi==0) {
462 printf("Normalization sinogram dimensions := %d x %d\n",
464 printf("Normalization sinogram frame duration := %g\n",
466 printf("Normalization sinogram dead-time correction := %g\n",
468 }
471 {
472 if(status!=NULL) sprintf(status, "incompatible matrix dimensions");
473 free(tramat); free(normat);
474 cret=ret;
475 continue;
476 }
477
478
479 for(int i=0; i<scnpxlNr; i++) tramat[i]*=normat[i];
480
481 if(keepNegat==0)
482 for(int i=0; i<scnpxlNr; i++) if(tramat[i]<0.0) tramat[i]=0.0;
483
484
487 for(bi=0; bi<blk_mlist.
matrixNr; bi++)
489 break;
491 if(status!=NULL)
492 sprintf(status,
"cannot find matrix %u in blank sinogram", blk_mlist.
matdir[bi].
matnum);
493 free(tramat); free(normat);
494 cret=ret;
495 continue;
496 }
497
498 if(verbose>1) printf("reading blank matrix %d\n", 1+bi);
501 if(ret) {
502 if(status!=NULL)
503 sprintf(status,
"cannot read blank sinogram matrix %u", blk_mlist.
matdir[bi].
matnum);
504 free(tramat); free(normat);
505 cret=ret;
506 continue;
507 }
508 if(verbose>200) {
510 } else if(verbose>1 && mi==0) {
511 printf("Blank sinogram dimensions := %d x %d\n",
513 printf("Blank sinogram frame duration := %g\n",
515 printf("Blank sinogram dead-time correction := %g\n",
517 }
520 {
521 if(status!=NULL) sprintf(status, "incompatible matrix dimensions");
522 free(tramat); free(normat); free(blkmat);
523 cret=ret;
524 continue;
525 }
526
528 for(int i=0; i<scnpxlNr; i++)
530 }
531
533 if(status!=NULL) sprintf(status, "missing frame duration in blank sinogram");
534 free(tramat); free(normat); free(blkmat);
535 cret=ret;
536 continue;
537 }
539 for(int i=0; i<scnpxlNr; i++) blkmat[i]*=f;
540
541
542 for(int i=0; i<scnpxlNr; i++) blkmat[i]*=normat[i];
543
544 if(keepNegat==0) for(int i=0; i<scnpxlNr; i++) if(blkmat[i]<0.0) blkmat[i]=0.0;
545
546
547
548
549
550
551
552
553 double dcf=1.0;
554 if(decay!=0) {
556 double t=start_time_diff;
560 if(verbose>1 && mi==0) {
561 printf("frame start time difference := %g\n", t);
562 printf("decay correction factor := %g\n", dcf);
563 }
564 for(int i=0; i<scnpxlNr; i++) tramat[i]*=dcf;
565 }
566
567
568
569 if(verbose>3) printf("setting attenuation sub-header\n");
570 if(mi==0) {
571
583 }
586
587
588 if(lfpimg!=NULL && mi==0) {
589 if(verbose>6) printf("setting transmission image sub-header\n");
590
617 }
618 if(lfpimg!=NULL) {
623 }
624
625
626
627
628
629
630
631
632 if(verbose>1) {printf("matrix reconstruction\n"); fflush(stdout);}
633 imgpxlNr=dimx*dimx;
634 float imgmat[imgpxlNr];
635 ret=
trmrp(blkmat, tramat, dimx, imgmat, 120, 1,
636 dimx, dimy, maskDim, 1.0, beta,
638 1, 1, 0.0, 0.0, 0.0,
639 verbose-6);
640 if(ret) {
641 if(status!=NULL) sprintf(status, "cannot calculate attenuation correction factors");
642 if(verbose>1) printf("trmrp_return_value := %d\n", ret);
643 free(tramat); free(normat); free(blkmat);
644 cret=ret;
645 continue;
646 }
647 if(verbose>1) {
648 for(int i=0; i<imgpxlNr; i++)
649 if(!isfinite(imgmat[i])) {
650 printf(" inf in the image!\n");
651 break;
652 }
653 }
654
655
656
657
658
659
660
661 if(lfpimg!=NULL && imgDim==dimx && zoom==1.0 && shiftX==0.0 && shiftY==0.0 && rotation==0.0) {
662 if(verbose>1) printf("writing transmission image matrix\n");
665 if(ret) {
666 if(status!=NULL) sprintf(status, "cannot write transmission image matrix");
667 if(verbose>1) printf("ret := %d\n", ret);
668 free(tramat); free(normat); free(blkmat);
669 cret=ret;
670 continue;
671 }
672 }
673
674
675
676
677 if(verbose>1) {printf("matrix reprojection\n"); fflush(stdout);}
678 float atnmat[scnpxlNr];
679 ret=
reprojection(imgmat, dimx, dimx, dimy, 1.0, atnmat, verbose-10);
680 if(ret) {
681 if(status!=NULL) sprintf(status, "cannot reproject attenuation correction data");
682 if(verbose>1) printf("trmrp_return_value := %d\n", ret);
683 free(tramat); free(normat); free(blkmat);
684 cret=ret;
685 continue;
686 }
687 if(verbose>1) {
688 for(int i=0; i<scnpxlNr; i++)
689 if(!isfinite(atnmat[i])) {
690 printf(" inf in the log attenuation data!\n");
691 break;
692 }
693 }
694
695
696
697
698 if(verbose>2) {printf("conversion from logarithms\n"); fflush(stdout);}
699#if(0)
701 else f=1.0;
702 for(int i=0; i<scnpxlNr; i++) atnmat[i]=expf(atnmat[i]*f);
703#endif
704 for(int i=0; i<scnpxlNr; i++) atnmat[i]=expf(atnmat[i]);
705 if(verbose>1) {
706 for(int i=0; i<scnpxlNr; i++)
707 if(!isfinite(atnmat[i])) {
708 printf(" inf in the attenuation data!\n");
709 break;
710 }
711 }
712 for(int i=0; i<scnpxlNr; i++) if(!isfinite(atnmat[i])) atnmat[i]=1.0;
713
714
715 if(limit>0) {
716 for(int i=0; i<scnpxlNr; i++) {
717 if(!(atnmat[i]>=1.0)) atnmat[i]=1.0;
718 else if(atnmat[i]>ATN_HI_MAX) atnmat[i]=ATN_HI_MAX;
719 }
720 }
721
722
723
724 if(verbose>1) printf("writing attenuation matrix\n");
727 if(ret) {
728 if(status!=NULL) sprintf(status, "cannot write attenuation matrix");
729 if(verbose>1) printf("ret := %d\n", ret);
730 free(tramat); free(normat); free(blkmat);
731 cret=ret;
732 continue;
733 }
734
735
736
737
738
739
740
741 if(lfpimg!=NULL && (imgDim!=dimx || zoom!=1.0 || shiftX!=0.0 || shiftY!=0.0 || rotation!=0.0)) {
742 if(verbose>1) {printf("transmission matrix reconstruction\n"); fflush(stdout);}
743 imgpxlNr=imgDim*imgDim;
744 float imgmat2[imgpxlNr];
745 ret=
trmrp(blkmat, tramat, imgDim, imgmat2, maxIterNr, osSetNr,
746 dimx, dimy, maskDim, zoom, beta,
748 skipPriorNr, 1, shiftX, shiftY, rotation,
749 verbose-7);
750 if(ret) {
751 if(status!=NULL) sprintf(status, "cannot reconstruct transmission image");
752 if(verbose>1) printf("trmrp_return_value := %d\n", ret);
753 } else {
755 for(int i=0; i<imgpxlNr; i++) imgmat2[i]*=f;
756 if(verbose>1) printf("writing transmission image matrix\n");
759 if(ret) {
760 if(status!=NULL) sprintf(status, "cannot write transmission image matrix");
761 if(verbose>1) printf("ret := %d\n", ret);
762 }
763 }
764 if(ret) {
765 free(tramat); free(normat); free(blkmat);
766 cret=ret;
767 continue;
768 }
769 }
770
771 free(tramat); free(normat); free(blkmat);
772 }
773 if(verbose==1) {fprintf(stdout, "\n"); fflush(stdout);}
774 if(verbose>0) {fprintf(stdout, "done.\n"); fflush(stdout);}
775
776
777 fclose(fpatn); if(fpimg!=NULL) fclose(fpimg);
780 fclose(fptra); fclose(fpblk); fclose(fpnor);
781 if(cret) {remove(atnfile); if(fpimg!=NULL) remove(imgfile);}
782 return(cret);
783}
char * ctime_r_int(const time_t *t, char *buf)
Convert calendard time t into a null-terminated string of the form YYYY-MM-DD hh:mm:ss,...
int ecat63CopyMainheader(ECAT63_mainheader *h1, ECAT63_mainheader *h2)
int ecat63ReadMatlist(FILE *fp, MATRIXLIST *ml, int verbose)
void ecat63InitMatlist(MATRIXLIST *mlist)
void ecat63EmptyMatlist(MATRIXLIST *mlist)
int mat_numcod(int frame, int plane, int gate, int data, int bed)
int ecat63CheckMatlist(MATRIXLIST *ml)
void mat_numdoc(int matnum, Matval *matval)
void ecat63PrintMainheader(ECAT63_mainheader *h, FILE *fp)
void ecat63PrintScanheader(ECAT63_scanheader *h, FILE *fp)
int ecat63ReadScanMatrix(FILE *fp, int first_block, int last_block, ECAT63_scanheader *h, float **fdata)
int ecat63ReadMainheader(FILE *fp, ECAT63_mainheader *h)
int ecat63WriteAttn(FILE *fp, int matnum, ECAT63_attnheader *h, void *data)
int ecat63WriteImageMatrix(FILE *fp, int matnum, ECAT63_imageheader *h, float *fdata)
FILE * ecat63Create(const char *fname, ECAT63_mainheader *h)
time_t ecat63Scanstarttime(const ECAT63_mainheader *h)
Get calendar time from ECAT 6.3 main header.
double hl2lambda(double halflife)
double hlLambda2factor(double lambda, double frametime, double framedur)
int trmrp(float *bla, float *tra, int dim, float *image, int iter, int sets, int rays, int views, int maskdim, float zoom, float beta, float axial_fov, float sample_distance, int skip_prior, int osl, float shiftX, float shiftY, float rotation, int verbose)
int reprojection(float *image, int dim, int rays, int views, float bpzoom, float *sinogram, int verbose)
short int calibration_units
char user_process_code[10]