11#include "tpcclibConfig.h"
30 char *foldername,
struct tm *stm,
char *fname,
int verbose
33 char *fname,
double *coef,
int verbose
38static char *info[] = {
39 "Calibrate the activity units in CTI ECAT 931 image/sinogram from ECAT counts",
40 "to kBq/mL using specified calibration file containing the",
41 "MBq/PET_count or uCi/PET_count coefficients for all 15 images planes.",
42 "Images/sinograms which are scanned after Jan-01-1997 are corrected also",
43 "for branching ratio.",
44 "If you want to remove existing image calibration, enter '0' as the name of",
45 "calibration file (not applicable to sinogram).",
46 "With '1' only the branching ratio is corrected (do not apply to old scans).",
47 "If only the name of image/sinogram is given, program gives information",
48 "about current calibration status.",
49 "If the path to calibration files is given, then program will automatically",
50 "search for the last calibration prior to scan date.",
53 "Usage: @P [Options] ecatfile [calibrationfile or path]",
59 " @P a2345dy1.img S:\\Lab\\plasma\\ECAT931\\plane_calibration.dir",
61 "See also: lmhdr, egetstrt, esetstrt, eframe, ecatfbp, ecatmrp",
63 "Keywords: image, ECAT, reconstruction, calibration, branching ratio",
82int main(
int argc,
char **argv)
84 int ai, help=0, version=0, verbose=1;
85 char ecatfile[FILENAME_MAX], calfile[FILENAME_MAX];
100 if(argc==1) {
tpcPrintUsage(argv[0], info, stderr);
return(1);}
101 ecatfile[0]=calfile[0]=(char)0;
103 for(ai=1; ai<argc; ai++)
if(*argv[ai]==
'-') {
104 cptr=argv[ai]+1;
if(*cptr==
'-') cptr++;
if(cptr==NULL)
continue;
106 fprintf(stderr,
"Error: invalid option '%s'.\n", argv[ai]);
111 if(help==2) {
tpcHtmlUsage(argv[0], info,
"");
return(0);}
116 for(; ai<argc; ai++) {
118 strlcpy(ecatfile, argv[ai], FILENAME_MAX);
continue;
119 }
else if(!calfile[0]) {
120 strlcpy(calfile, argv[ai], FILENAME_MAX);
continue;
122 fprintf(stderr,
"Error: invalid argument '%s'.\n", argv[ai]);
128 fprintf(stderr,
"Error: missing command-line argument; try %s --help\n",
135 printf(
"ecatfile := %s\n", ecatfile);
136 if(calfile[0]) printf(
"calfile := %s\n", calfile);
143 if(verbose==1) printf(
"reading %s\n", ecatfile);
144 if(verbose>1) printf(
"opening %s\n", ecatfile);
145 if((fp=fopen(ecatfile,
"r+b")) == NULL) {
146 fprintf(stderr,
"Error: cannot open file %s\n", ecatfile);
153 if(verbose>1) printf(
"reading main header\n");
155 fprintf(stderr,
"Error (%d): cannot read main header.\n", ret);
156 fclose(fp);
return(3);
165 "Error: only ECAT 931 images and sinograms can be calibrated.\n");
166 fclose(fp);
return(3);
174 if(timet==-1 || timet<86400) {
175 fprintf(stderr,
"Error: %s does not contain scan start time.\n", ecatfile);
176 fclose(fp);
return(3);
178 strftime(tmp, 32,
"%Y-%m-%d %H:%M:%S", &stm);
179 fprintf(stdout,
"scan_start_time := %s\n", tmp);
196 if(verbose>1) printf(
"reading matrix list\n");
200 fprintf(stderr,
"Error (%d): cannot read matrix list.\n", ret);
201 fclose(fp);
return(4);
204 fprintf(stderr,
"Error: matrix list is empty.\n");
205 fclose(fp);
return(4);
208 fprintf(stderr,
"Error: check the matrix list.\n");
216 for(
int i=0; i<15; i++) {cal_coef[i]=1.; plane_sw[i]=0;}
218 for(
int j=0; j<mlist.
matrixNr; j++) {
221 if(plane<1 || plane>15 || plane_sw[plane-1])
continue;
226 fprintf(stderr,
"Error: cannot read image subheader.\n");
232 printf(
"Plane Calibration coefficient\n");
233 for(
int i=0; i<15; i++)
if(plane_sw[i]==1)
234 printf(
" %2d %12.5e\n", i+1, cal_coef[i]);
248 if(strcasecmp(calfile,
"0")==0) {
249 if(verbose>0) printf(
"removing calibration.\n");
251 fprintf(stderr,
"Error: cannot clear sinogram calibration.\n");
254 for(
int i=0; i<15; i++) cal_coef[i]=1.0;
256 }
else if(strcasecmp(calfile,
"1")==0) {
257 if(verbose>0) printf(
"removing calibration.\n");
259 fprintf(stderr,
"Warning: cannot clear sinogram calibration.\n");
260 for(
int i=0; i<15; i++) cal_coef[i]=1.0;
262 if(verbose>0) printf(
"correcting for branching ratio.\n");
265 fprintf(stderr,
"Warning: unknown isotope.\n");
266 fprintf(stderr,
"Warning: branching correction not possible.\n");
268 for(
int i=0; i<15; i++) cal_coef[i]*=1.0/bf;
271 if(verbose>1) printf(
"reading calibration coefficients in %s\n", calfile);
273 char fname[FILENAME_MAX];
277 strlcpy(fname, calfile, FILENAME_MAX);
279 if(verbose>0) printf(
"calibrationfile := %s\n", fname);
284 fprintf(stderr,
"Error: cannot read calibrations in %s.\n", calfile);
288 if((cal_coef[4]+cal_coef[10])/2. < 4.0) {
293 for(
int i=0; i<15; i++) cal_coef[i]*=0.037;
295 for(
int i=0; i<15; i++) cal_coef[i]*=1000.;
299 if(verbose>0) printf(
"correcting for branching ratio.\n");
302 fprintf(stderr,
"Warning: unknown isotope.\n");
303 fprintf(stderr,
"Warning: branching correction not possible.\n");
305 for(
int i=0; i<15; i++) cal_coef[i]*=1.0/bf;
310 printf(
"\nNew calibration coefficients:\n");
311 printf(
"Plane Calibration coefficient\n");
312 for(
int i=0; i<15; i++) printf(
" %2d %12.5e\n", i+1, cal_coef[i]);
318 for(
int j=0; j<mlist.
matrixNr; j++) {
321 if(plane<1 || plane>15)
continue;
328 fprintf(stderr,
"Error: cannot read subheader.\n");
344 fprintf(stderr,
"Error: cannot write subheader.\n");
358 fprintf(stderr,
"Error: cannot write main header.\n");
362 printf(
"Calibrations removed.\n");
364 printf(
"Calibrated to kBq/mL with plane coefficients:\n");
365 for(
int i=0; i<15; i++) printf(
" %2d %12.5e\n", i+1, cal_coef[i]);
388 if(verbose>0) printf(
"selectEcat931Calibrationfile('%s', ...)\n", foldername);
389 if(foldername==NULL || stm==NULL || fname==NULL)
return(1);
396 stat(foldername, &fst);
397 if(!S_ISDIR(fst.st_mode)) {
398 if(verbose>1) printf(
" %s is not a directory\n", foldername);
404 dp=opendir(foldername);
if(dp==NULL) {
405 if(verbose>1) printf(
"Error: cannot open directory %s\n", foldername);
411 char year[10], month[10], day[10], cfname[FILENAME_MAX];
413 double tdif, tdif_min=-1.0E30;
415 while((de=readdir(dp))!=NULL) {
416 if(verbose>2) printf(
"d_name='%s'\n", de->d_name);
417 if(de->d_name[0]==
'.')
continue;
418 if(strlen(de->d_name)<6)
continue;
421 strlcpy(month, de->d_name+2, 3);
423 sprintf(buf,
"%s.%s.%s 16:00:00", day, month, year);
426 if(verbose>3) printf(
" %s\n", buf);
429 if(verbose>3) printf(
" sec_difference := %.0f\n", tdif);
431 if(tdif>0.0)
continue;
433 if(tdif>tdif_min) {tdif_min=tdif; strcpy(cfname, de->d_name);}
436 if(tdif_min<-1.0E10 || !cfname[0])
return(3);
437 if(verbose>1) printf(
"selected_file := %s\n", cfname);
440 if(foldername[strlen(foldername)-1]!=
'/')
441 sprintf(fname,
"%s/%s", foldername, cfname);
443 sprintf(fname,
"%s%s", foldername, cfname);
462 if(verbose>0) printf(
"readEcat931Calibrationfile('%s', ...)\n", fname);
463 if(fname==NULL || coef==NULL)
return(1);
467 if(
iftRead(&ift, fname, 0, 0)!=0)
return(2);
473 for(
int i=1; i<=15; i++) {
474 if(verbose>1) printf(
"\t%d\t%s\n", i, ift.
item[i].
value);
476 if(v<=0.0) {
iftEmpty(&ift);
return(5);}
float branchingFraction(int isotope)
int get_datetime(char *str, struct tm *date, int verbose)
time_t timegm(struct tm *tm)
Inverse of gmtime, converting struct tm to time_t.
double tmDifference(struct tm *tm1, struct tm *tm0)
int atof_with_check(char *double_as_string, double *result_value)
int readEcat931Calibrationfile(char *fname, double *coef, int verbose)
int selectEcat931Calibrationfile(char *foldername, struct tm *stm, char *fname, int verbose)
int ecat63ReadMatlist(FILE *fp, MATRIXLIST *ml, int verbose)
void ecat63InitMatlist(MATRIXLIST *mlist)
void ecat63EmptyMatlist(MATRIXLIST *mlist)
int ecat63CheckMatlist(MATRIXLIST *ml)
void mat_numdoc(int matnum, Matval *matval)
void ecat63PrintMainheader(ECAT63_mainheader *h, FILE *fp)
char * ecat63Unit(short int dunit)
int ecat63ReadScanheader(FILE *fp, int blk, ECAT63_scanheader *h, int verbose, char *errmsg)
int ecat63ReadImageheader(FILE *fp, int blk, ECAT63_imageheader *h, int verbose, char *errmsg)
int ecat63ReadMainheader(FILE *fp, ECAT63_mainheader *h)
int ecat63WriteImageheader(FILE *fp, int block, ECAT63_imageheader *h)
int ecat63WriteScanheader(FILE *fp, int block, ECAT63_scanheader *h)
struct tm * ecat63ScanstarttimeToTm(const ECAT63_mainheader *h, struct tm *tm)
Convert scan_start_time in ECAT 6.3 main header into a struct tm.
int ecat63WriteMainheader(FILE *fp, ECAT63_mainheader *h)
char * hlIsotopeCode(int isotope)
double hlFromIsotope(char *isocode)
int hlIsotopeFromHalflife(double halflife)
int iftRead(IFT *ift, char *filename, int is_key_required, int verbose)
Header file for libtpcimgio.
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)
short int calibration_units
short int scan_start_year