Read transmission scan file and blank scan file and calculate the attenuation correction data and the logarithmic correction data.
159 {
160 int ret;
161
162
163 if(status!=NULL) sprintf(status, "invalid filename");
164 if(trafile==NULL || !trafile[0]) return(1);
165 if(blkfile==NULL || !blkfile[0]) return(1);
166 if(norfile==NULL || !blkfile[0]) return(1);
167 if(atnfile==NULL || !atnfile[0]) return(1);
168
169
170
171
172
173 FILE *fptra=NULL, *fpblk=NULL, *fpnor=NULL;
174 if(verbose>0) printf("opening %s\n", trafile);
175 if((fptra=fopen(trafile, "rb")) == NULL) {
176 if(status!=NULL) sprintf(status, "cannot open transmission sinogram");
177 return(2);
178 }
179 if(verbose>0) printf("opening %s\n", blkfile);
180 if((fpblk=fopen(blkfile, "rb")) == NULL) {
181 if(status!=NULL) sprintf(status, "cannot open blank sinogram");
182 fclose(fptra);
183 return(2);
184 }
185 if(verbose>0) printf("opening %s\n", norfile);
186 if((fpnor=fopen(norfile, "rb")) == NULL) {
187 if(status!=NULL) sprintf(status, "cannot open normalization file");
188 fclose(fptra); fclose(fpblk);
189 return(2);
190 }
191
192
193
194
195 if(verbose>1) printf("reading transmission main header\n");
198 if(status!=NULL) sprintf(status, "cannot read transmission main header");
199 fclose(fptra); fclose(fpblk); fclose(fpnor);
200 return(3);
201 }
203 if(verbose>4) printf(
"file_type := %d\n", tra_main_header.
file_type);
204
205 if(verbose>1) printf("reading blank main header\n");
208 if(status!=NULL) sprintf(status, "cannot read blank main header");
209 fclose(fptra); fclose(fpblk); fclose(fpnor);
210 return(3);
211 }
213 if(verbose>4) printf(
"file_type := %d\n", blk_main_header.
file_type);
214
215 if(verbose>1) printf("reading normalization main header\n");
218 if(status!=NULL) sprintf(status, "cannot read blank main header");
219 fclose(fptra); fclose(fpblk); fclose(fpnor);
220 return(3);
221 }
223 if(verbose>4) printf(
"file_type := %d\n", nor_main_header.
file_type);
224
225
228 {
229 if(status!=NULL) sprintf(status, "file is not a sinogram");
230 fclose(fptra); fclose(fpblk); fclose(fpnor);
231 return(3);
232 }
233
234
235 time_t tra_start, blk_start;
238 if(verbose>1) {
239 char buf[32];
240 printf(
"Blank scan start time := %s\n",
ctime_r_int(&blk_start, buf));
241 printf(
"Transmission scan start time := %s\n",
ctime_r_int(&tra_start, buf));
242 }
243 if(decay!=0 && (tra_start==0 || blk_start==0)) {
244 if(status!=NULL) sprintf(status, "missing scan start time");
245 fclose(fptra); fclose(fpblk); fclose(fpnor);
246 return(3);
247 }
248 double start_time_diff=difftime(tra_start, blk_start);
249 if(verbose>1) {printf("scan start time difference := %g\n", start_time_diff);}
250
251
252 double halflife=-1.0;
255 if(verbose>1 && halflife>0.0) {printf("isotope halflife := %g\n", halflife);}
256 if(decay!=0 && halflife<=0.0) {
257 if(status!=NULL) sprintf(status, "missing isotope halflife");
258 fclose(fptra); fclose(fpblk); fclose(fpnor);
259 return(3);
260 }
261
262
263
264
265
266
267 if(verbose>1) printf("reading transmission matrix list\n");
270 if(ret) {
271 if(status!=NULL) sprintf(status, "cannot read sinogram matrix list");
272 fclose(fptra); fclose(fpblk); fclose(fpnor);
273 return(3);
274 }
275
276 if(verbose>1) printf("reading blank matrix list\n");
279 if(ret) {
280 if(status!=NULL) sprintf(status, "cannot read blank matrix list");
282 fclose(fptra); fclose(fpblk); fclose(fpnor);
283 return(3);
284 }
285
286 if(verbose>1) printf("reading normalization matrix list\n");
289 if(ret) {
290 if(status!=NULL) sprintf(status, "cannot read normalization matrix list");
292 fclose(fptra); fclose(fpblk); fclose(fpnor);
293 return(3);
294 }
295
296
298 if(status!=NULL) sprintf(status, "empty matrix list");
301 fclose(fptra); fclose(fpblk); fclose(fpnor);
302 return(3);
303 }
306 {
307 if(status!=NULL) sprintf(status, "invalid matrix list");
310 fclose(fptra); fclose(fpblk); fclose(fpnor);
311 return(3);
312 }
313 if(verbose>3) {
314 printf(
"transmission_matrixNr := %d\n", tra_mlist.
matrixNr);
315 printf(
"blank_matrixNr := %d\n", blk_mlist.
matrixNr);
316 printf(
"normalization_matrixNr := %d\n", nor_mlist.
matrixNr);
317 }
322 {
323 if(status!=NULL) sprintf(status, "different plane numbers");
326 fclose(fptra); fclose(fpblk); fclose(fpnor);
327 return(3);
328 }
329
330
331
332
333 if(verbose>0) printf("writing main header in %s\n", atnfile);
340 FILE *fpatn=NULL;
342 if(fpatn==NULL) {
343 if(status!=NULL) sprintf(status, "cannot write attenuation file\n");
346 fclose(fptra); fclose(fpblk); fclose(fpnor);
347 return(11);
348 }
349
350 FILE *fpimg=NULL;
351 if(imgfile!=NULL && imgfile[0]) {
352 if(verbose>0) printf("writing main header in %s\n", imgfile);
361 if(fpimg==NULL) {
362 if(status!=NULL) sprintf(status, "cannot write transmission image\n");
365 fclose(fptra); fclose(fpblk); fclose(fpnor);
366 remove(atnfile);
367 return(12);
368 }
369 }
370
371
372
373
374
375 if(verbose>0) printf("processing matrices...\n");
376 int cret=0;
377 for(
int mi=0; mi<tra_mlist.
matrixNr; mi++) {
378 if(verbose==1) {fprintf(stdout, "."); fflush(stdout);}
379
380 FILE *lfptra=fptra;
381 FILE *lfpblk=fpblk;
382 FILE *lfpnor=fpnor;
383 FILE *lfpatn=fpatn;
384 FILE *lfpimg=fpimg;
385
390 int dimx, dimy, scnpxlNr=0, imgpxlNr=0, matnum=0, ni=0, bi=0;
391 float *tramat, *blkmat, *normat, f;
392 int ret=0;
393
394
396
397
398 if(verbose>1) printf("reading transmission matrix %d\n", 1+mi);
401 if(ret) {
402 if(status!=NULL)
403 sprintf(status,
"cannot read transmission sinogram matrix %u", tra_mlist.
matdir[mi].
matnum);
404 cret=ret;
405 continue;
406 }
407 if(verbose>2)
408 printf("Matrix: plane %d frame %d gate %d bed %d\n",
410 if(verbose>200) {
412 } else if(verbose>1 && mi==0) {
413 printf("Transmission sinogram dimensions := %d x %d\n",
415 printf("Transmission sinogram frame duration := %g\n",
417 printf("Transmission sinogram dead-time correction := %g\n",
419 }
422 scnpxlNr=dimx*dimy;
423 if(imgDim<2) imgDim=dimx;
424
426 for(int i=0; i<scnpxlNr; i++)
428 }
429
431 if(status!=NULL) sprintf(status, "missing frame duration in transmission sinogram");
432 free(tramat);
433 cret=ret;
434 continue;
435 }
437 for(int i=0; i<scnpxlNr; i++) tramat[i]*=f;
438
439
441 for(ni=0; ni<nor_mlist.
matrixNr; ni++)
443 break;
445 if(status!=NULL)
446 sprintf(status, "cannot find matrix %u in normalization sinogram",
448 free(tramat);
449 cret=ret;
450 continue;
451 }
452
453 if(verbose>1) printf("reading normalization matrix %d\n", 1+ni);
456 if(ret) {
457 if(status!=NULL)
458 sprintf(status,
"cannot read blank sinogram matrix %u", nor_mlist.
matdir[ni].
matnum);
459 free(tramat);
460 cret=ret;
461 continue;
462 }
463 if(verbose>200) {
465 } else if(verbose>1 && mi==0) {
466 printf("Normalization sinogram dimensions := %d x %d\n",
468 printf("Normalization sinogram frame duration := %g\n",
470 printf("Normalization sinogram dead-time correction := %g\n",
472 }
475 {
476 if(status!=NULL) sprintf(status, "incompatible matrix dimensions");
477 free(tramat); free(normat);
478 cret=ret;
479 continue;
480 }
481
482
483 for(int i=0; i<scnpxlNr; i++) tramat[i]*=normat[i];
484
485 if(keepNegat==0)
486 for(int i=0; i<scnpxlNr; i++) if(tramat[i]<0.0) tramat[i]=0.0;
487
488
491 for(bi=0; bi<blk_mlist.
matrixNr; bi++)
493 break;
495 if(status!=NULL)
496 sprintf(status,
"cannot find matrix %u in blank sinogram", blk_mlist.
matdir[bi].
matnum);
497 free(tramat); free(normat);
498 cret=ret;
499 continue;
500 }
501
502 if(verbose>1) printf("reading blank matrix %d\n", 1+bi);
505 if(ret) {
506 if(status!=NULL)
507 sprintf(status,
"cannot read blank sinogram matrix %u", blk_mlist.
matdir[bi].
matnum);
508 free(tramat); free(normat);
509 cret=ret;
510 continue;
511 }
512 if(verbose>200) {
514 } else if(verbose>1 && mi==0) {
515 printf("Blank sinogram dimensions := %d x %d\n",
517 printf("Blank sinogram frame duration := %g\n",
519 printf("Blank sinogram dead-time correction := %g\n",
521 }
524 {
525 if(status!=NULL) sprintf(status, "incompatible matrix dimensions");
526 free(tramat); free(normat); free(blkmat);
527 cret=ret;
528 continue;
529 }
530
532 for(int i=0; i<scnpxlNr; i++)
534 }
535
537 if(status!=NULL) sprintf(status, "missing frame duration in blank sinogram");
538 free(tramat); free(normat); free(blkmat);
539 cret=ret;
540 continue;
541 }
543 for(int i=0; i<scnpxlNr; i++) blkmat[i]*=f;
544
545
546 for(int i=0; i<scnpxlNr; i++) blkmat[i]*=normat[i];
547
548 if(keepNegat==0) for(int i=0; i<scnpxlNr; i++) if(blkmat[i]<0.0) blkmat[i]=0.0;
549
550
551
552
553
554
555
556
557 double dcf=1.0;
558 if(decay!=0) {
560 double t=start_time_diff;
564 if(verbose>1 && mi==0) {
565 printf("frame start time difference := %g\n", t);
566 printf("decay correction factor := %g\n", dcf);
567 }
568 for(int i=0; i<scnpxlNr; i++) tramat[i]*=dcf;
569 }
570
571
572
573 if(verbose>3) printf("setting attenuation sub-header\n");
574 if(mi==0) {
575
587 }
590
591
592 if(lfpimg!=NULL && mi==0) {
593 if(verbose>6) printf("setting transmission image sub-header\n");
594
621 }
622 if(lfpimg!=NULL) {
627 }
628
629
630
631
632
633
634
635
636 if(verbose>1) {printf("matrix reconstruction\n"); fflush(stdout);}
637 imgpxlNr=dimx*dimx;
638 float imgmat[imgpxlNr];
639 ret=
trmrp(blkmat, tramat, dimx, imgmat, 120, 1,
640 dimx, dimy, maskDim, 1.0, beta,
642 1, 1, 0.0, 0.0, 0.0,
643 verbose-6);
644 if(ret) {
645 if(status!=NULL) sprintf(status, "cannot calculate attenuation correction factors");
646 if(verbose>1) printf("trmrp_return_value := %d\n", ret);
647 free(tramat); free(normat); free(blkmat);
648 cret=ret;
649 continue;
650 }
651 if(verbose>1) {
652 for(int i=0; i<imgpxlNr; i++)
653 if(!isfinite(imgmat[i])) {
654 printf(" inf in the image!\n");
655 break;
656 }
657 }
658
659
660
661
662
663
664
665 if(lfpimg!=NULL && imgDim==dimx && zoom==1.0 && shiftX==0.0 && shiftY==0.0 && rotation==0.0) {
666 if(verbose>1) printf("writing transmission image matrix\n");
669 if(ret) {
670 if(status!=NULL) sprintf(status, "cannot write transmission image matrix");
671 if(verbose>1) printf("ret := %d\n", ret);
672 free(tramat); free(normat); free(blkmat);
673 cret=ret;
674 continue;
675 }
676 }
677
678
679
680
681 if(verbose>1) {printf("matrix reprojection\n"); fflush(stdout);}
682 float atnmat[scnpxlNr];
683 ret=
reprojection(imgmat, dimx, dimx, dimy, 1.0, atnmat, verbose-10);
684 if(ret) {
685 if(status!=NULL) sprintf(status, "cannot reproject attenuation correction data");
686 if(verbose>1) printf("trmrp_return_value := %d\n", ret);
687 free(tramat); free(normat); free(blkmat);
688 cret=ret;
689 continue;
690 }
691 if(verbose>1) {
692 for(int i=0; i<scnpxlNr; i++)
693 if(!isfinite(atnmat[i])) {
694 printf(" inf in the log attenuation data!\n");
695 break;
696 }
697 }
698
699
700
701
702 if(verbose>2) {printf("conversion from logarithms\n"); fflush(stdout);}
703#if(0)
705 else f=1.0;
706 for(int i=0; i<scnpxlNr; i++) atnmat[i]=expf(atnmat[i]*f);
707#endif
708 for(int i=0; i<scnpxlNr; i++) atnmat[i]=expf(atnmat[i]);
709 if(verbose>1) {
710 for(int i=0; i<scnpxlNr; i++)
711 if(!isfinite(atnmat[i])) {
712 printf(" inf in the attenuation data!\n");
713 break;
714 }
715 }
716 for(int i=0; i<scnpxlNr; i++) if(!isfinite(atnmat[i])) atnmat[i]=1.0;
717
718
719 if(limit>0) {
720 for(int i=0; i<scnpxlNr; i++) {
721 if(!(atnmat[i]>=1.0)) atnmat[i]=1.0;
722 else if(atnmat[i]>ATN_HI_MAX) atnmat[i]=ATN_HI_MAX;
723 }
724 }
725
726
727
728 if(verbose>1) printf("writing attenuation matrix\n");
731 if(ret) {
732 if(status!=NULL) sprintf(status, "cannot write attenuation matrix");
733 if(verbose>1) printf("ret := %d\n", ret);
734 free(tramat); free(normat); free(blkmat);
735 cret=ret;
736 continue;
737 }
738
739
740
741
742
743
744
745 if(lfpimg!=NULL && (imgDim!=dimx || zoom!=1.0 || shiftX!=0.0 || shiftY!=0.0 || rotation!=0.0)) {
746 if(verbose>1) {printf("transmission matrix reconstruction\n"); fflush(stdout);}
747 imgpxlNr=imgDim*imgDim;
748 float imgmat2[imgpxlNr];
749 ret=
trmrp(blkmat, tramat, imgDim, imgmat2, maxIterNr, osSetNr,
750 dimx, dimy, maskDim, zoom, beta,
752 skipPriorNr, 1, shiftX, shiftY, rotation,
753 verbose-7);
754 if(ret) {
755 if(status!=NULL) sprintf(status, "cannot reconstruct transmission image");
756 if(verbose>1) printf("trmrp_return_value := %d\n", ret);
757 } else {
759 for(int i=0; i<imgpxlNr; i++) imgmat2[i]*=f;
760 if(verbose>1) printf("writing transmission image matrix\n");
763 if(ret) {
764 if(status!=NULL) sprintf(status, "cannot write transmission image matrix");
765 if(verbose>1) printf("ret := %d\n", ret);
766 }
767 }
768 if(ret) {
769 free(tramat); free(normat); free(blkmat);
770 cret=ret;
771 continue;
772 }
773 }
774
775 free(tramat); free(normat); free(blkmat);
776 }
777 if(verbose==1) {fprintf(stdout, "\n"); fflush(stdout);}
778 if(verbose>0) {fprintf(stdout, "done.\n"); fflush(stdout);}
779
780
781 fclose(fpatn); if(fpimg!=NULL) fclose(fpimg);
784 fclose(fptra); fclose(fpblk); fclose(fpnor);
785 if(cret) {remove(atnfile); if(fpimg!=NULL) remove(imgfile);}
786 return(cret);
787}
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]