micropet.c
Go to the documentation of this file.
00001 /*****************************************************************************
00002 
00003   Copyright (c) 2009,2011 by Turku PET Centre
00004 
00005   Library:      micropet.c
00006   Description:  Procedures for reading Siemens Inveon images.
00007 
00008   This program is free software; you can redistribute it and/or modify it under
00009   the terms of the GNU General Public License as published by the Free Software
00010   Foundation; either version 2 of the License, or (at your option) any later
00011   version.
00012 
00013   This program is distributed in the hope that it will be useful, but WITHOUT
00014   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00015   FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
00016 
00017   You should have received a copy of the GNU General Public License along with
00018   this program; if not, write to the Free Software Foundation, Inc., 59 Temple
00019   Place, Suite 330, Boston, MA 02111-1307 USA.
00020 
00021   Turku PET Centre hereby disclaims all copyright interest in the program.
00022   Juhani Knuuti
00023   Director, Professor
00024   Turku PET Centre, Turku, Finland, http://www.turkupetcentre.fi/
00025 
00026   Modification history:
00027   2009-02-17 Vesa Oikonen
00028              First created.
00029   2009-02-25 VO
00030              SIF information extraction is removed from imgMicropetToEcat7().
00031              New functions imgMicropetPETToEcat7() and imgMicropetCTToEcat7().
00032   2009-09-28 VO
00033              If transaxial_bin_size is defined, it is used as pixel z size
00034              instead of pixel_size_z in imgGetMicropetMainHeader()
00035              as requested by M Bucci.
00036   2011-01-11 VO
00037              Fixed bugs in reading headers and in branching fraction correction.
00038 
00039 
00040 ******************************************************************************/
00041 #include <stdio.h>
00042 #include <string.h>
00043 #include <math.h>
00044 #include <stdlib.h>
00045 #include <time.h>
00046 #include <unistd.h>
00047 /*****************************************************************************/
00048 #include "libtpcmisc.h"
00049 /*****************************************************************************/
00050 #include "include/imgio.h"
00051 /*****************************************************************************/
00052 
00053 /*****************************************************************************/
00058 int upetHeaderReadParameter(
00062   FILE *fp,
00064   char *parameter,
00068   char *value
00069 ) {
00070   char *cptr, tmp[MAX_MICROPET_LINE_LEN];
00071 
00072   if(fp==NULL) return -1;
00073   if(parameter==NULL || strlen(parameter)<1) return -2;
00074   do {
00075     if(fgets(tmp, MAX_MICROPET_LINE_LEN-1, fp)==NULL) return 1;
00076     if(tmp[0]=='#') continue;
00077     if(strncasecmp(tmp, parameter, strlen(parameter))!=0) continue;
00078     /* Get parameter value, if one exists */
00079     cptr=tmp+strlen(parameter)+1;
00080     if(strlen(cptr)>0) {
00081       if(value!=0) strcpy(value, cptr);
00082     } else {
00083       if(value!=0) strcpy(value, "");
00084     }
00085     /* In any case, we found the parameter */
00086     if(MICROPET_TEST>9) printf("%s := %s\n", parameter, value);
00087     return 0;
00088   } while(1);
00089   return 0;
00090 }
00091 /*****************************************************************************/
00092 
00093 /*****************************************************************************/
00097 int upetIsHeader(
00099   char *hdrfile
00100 ) {
00101   char tmp[MAX_MICROPET_LINE_LEN];
00102   FILE *fp;
00103   int ret;
00104 
00105   if(hdrfile==NULL || strlen(hdrfile)<5) return 0;
00106   if((fp=fopen(hdrfile, "r"))==NULL) return 0;
00107   /* Check that first line starts with '#' */
00108   if(fgets(tmp, MAX_MICROPET_LINE_LEN-1, fp)==NULL) {fclose(fp); return 0;}
00109   if(tmp[0]!='#') {fclose(fp); return 0;}
00110   /* Check that certain header parameters do exist */
00111   ret=upetHeaderReadParameter(fp, "version", tmp);
00112   if(ret!=0) {fclose(fp); return 0;}
00113   ret=upetHeaderReadParameter(fp, "model", tmp);
00114   if(ret!=0) {fclose(fp); return 0;}
00115   ret=upetHeaderReadParameter(fp, "modality", tmp);
00116   if(ret!=0) {fclose(fp); return 0;}
00117   fclose(fp);
00118   return 1;
00119 }
00120 /*****************************************************************************/
00121 
00122 /*****************************************************************************/
00126 int upetExists(
00129   char *upetname,
00133   char *hdrfile,
00137   char *imgfile
00138 ) {
00139   char *cptr, basefile[FILENAME_MAX], temp[FILENAME_MAX];
00140 
00141   if(upetname==NULL || strlen(upetname)==0) return(0);
00142 
00143   /* Construct the base file name wo extensions */
00144   strcpy(basefile, upetname);
00145   cptr=strrchr(basefile, '.');
00146   if(cptr!=NULL) {
00147     if(strncasecmp(cptr, ".HDR", 4)==0 || strncasecmp(cptr, ".IMG", 4)==0 )
00148       *cptr=(char)0;
00149   } 
00150   cptr=strrchr(basefile, '.');
00151   if(cptr!=NULL) {
00152     if(strncasecmp(cptr, ".IMG", 4)==0 )
00153       *cptr=(char)0;
00154   }
00155 
00156   /* Header file exists? */
00157   strcpy(temp, basefile); strcat(temp, ".hdr");
00158   if(access(temp, 0) == -1) {
00159     strcpy(temp, basefile); strcat(temp, ".img.hdr");
00160     if(access(temp, 0) == -1) return(0);
00161   }
00162   /* Is this microPET header file? */
00163   if(upetIsHeader(temp)==0) return(0);
00164   /* Preserve header filename */
00165   if(hdrfile!=NULL) strcpy(hdrfile, temp);
00166 
00167   /* Image file exists? */
00168   strcpy(temp, basefile); strcat(temp, ".img");
00169   if(access(temp, 0) == -1) return(0);
00170   /* Preserve image filename */
00171   if(imgfile!=NULL) strcpy(imgfile, temp);
00172 
00173   return 1;
00174 }
00175 /*****************************************************************************/
00176 
00177 /*****************************************************************************/
00180 int upetGetImageDimensions(
00182   FILE *fp,
00184   int *z,
00186   int *x,
00188   int *y,
00190   int *f
00191 ) {
00192   char tmp[MAX_MICROPET_LINE_LEN];
00193 
00194   if(fp==NULL) return 1;
00195   *z=*x=*y=0; if(f!=NULL) *f=0;
00196   rewind(fp);
00197 
00198   if(f!=NULL) {
00199     if(upetHeaderReadParameter(fp, "total_frames", tmp)!=0) return 11;
00200     *f=-1; (void)sscanf(tmp, "%d", f);
00201   }
00202   if(upetHeaderReadParameter(fp, "x_dimension", tmp)!=0) return 12;
00203   *x=-1; (void)sscanf(tmp, "%d", x);
00204   if(upetHeaderReadParameter(fp, "y_dimension", tmp)!=0) return 13;
00205   *y=-1; (void)sscanf(tmp, "%d", y);
00206   if(upetHeaderReadParameter(fp, "z_dimension", tmp)!=0) return 14;
00207   *z=-1; (void)sscanf(tmp, "%d", z);
00208   if(*z<1 || *x<1 || *y<1) return 2;
00209   if(f!=NULL && *f<1) return 2;
00210   return 0;
00211 }
00212 /*****************************************************************************/
00213 
00214 /*****************************************************************************/
00218 int upetScanStart(
00220   FILE *fp,
00222   time_t *scant
00223 ) {
00224   char tmp[MAX_MICROPET_LINE_LEN], tmp2[64], tmp3[64];
00225   int n, i;
00226   struct tm scanstart={0};
00227 
00228   if(fp==NULL || scant==NULL) return 1;
00229 
00230   rewind(fp);
00231   if(upetHeaderReadParameter(fp, "scan_time", tmp)!=0) return 2;
00232   n=sscanf(tmp, "%s %s %d %d:%d:%d %d", tmp2, tmp3, &scanstart.tm_mday,
00233            &scanstart.tm_hour, &scanstart.tm_min, &scanstart.tm_sec, &i);
00234   if(n==7) {
00235     scanstart.tm_year=i-1900;
00236     if(strcasecmp(tmp3, "Jan")==0)      scanstart.tm_mon=0;
00237     else if(strcasecmp(tmp3, "Feb")==0) scanstart.tm_mon=1;
00238     else if(strcasecmp(tmp3, "Mar")==0) scanstart.tm_mon=2;
00239     else if(strcasecmp(tmp3, "Apr")==0) scanstart.tm_mon=3;
00240     else if(strcasecmp(tmp3, "May")==0) scanstart.tm_mon=4;
00241     else if(strcasecmp(tmp3, "Jun")==0) scanstart.tm_mon=5;
00242     else if(strcasecmp(tmp3, "Jul")==0) scanstart.tm_mon=6;
00243     else if(strcasecmp(tmp3, "Aug")==0) scanstart.tm_mon=7;
00244     else if(strcasecmp(tmp3, "Sep")==0) scanstart.tm_mon=8;
00245     else if(strcasecmp(tmp3, "Oct")==0) scanstart.tm_mon=9;
00246     else if(strcasecmp(tmp3, "Nov")==0) scanstart.tm_mon=10;
00247     else if(strcasecmp(tmp3, "Dec")==0) scanstart.tm_mon=11;
00248     scanstart.tm_isdst=-1;
00249     *scant=mktime(&scanstart); if(*scant<0) return 4;
00250   } else return 5;
00251 
00252   return 0;
00253 }
00254 /*****************************************************************************/
00255 
00256 /*****************************************************************************/
00261 int imgMicropetToEcat7(
00263   char *upetname,
00265   char *ecatfile,
00267   int verbose
00268 ) {
00269   char upetheader[FILENAME_MAX], upetimage[FILENAME_MAX];
00270   int n, ret;
00271   int acquisition_mode, data_type;
00272   FILE *fph, *fpi;
00273   char tmp[MAX_MICROPET_LINE_LEN];
00274 
00275 
00276   if(MICROPET_TEST) printf("\nimgMicropetToEcat7(%s, %s, %d)\n",
00277     upetname, ecatfile, verbose);
00278   /* Check the arguments */
00279   if(upetname==NULL || ecatfile==NULL) return STATUS_FAULT;
00280   ret=upetExists(upetname, upetheader, upetimage);
00281   if(ret!=1) return STATUS_NOFILE;
00282 
00283   /*
00284    *  Open Micropet Header and binary data files
00285    */
00286   if((fph=fopen(upetheader, "r"))==NULL) return(STATUS_NOHEADERFILE);
00287   if((fpi=fopen(upetimage, "rb"))==NULL) {fclose(fph); return(STATUS_NOIMGDATA);}
00288 
00289 
00290   /*
00291    *  Check that image format is (currently) supported
00292    */
00293   rewind(fph);
00294   if(MICROPET_TEST>1) printf("checking that image format is supported\n");
00295   n=-1; if(upetHeaderReadParameter(fph, "file_type", tmp)==0)
00296     (void)sscanf(tmp, "%d", &n);
00297   if(MICROPET_TEST>2) printf("file_type := %d\n", n);
00298   if(n!=5) {fclose(fph); fclose(fpi); return(STATUS_UNSUPPORTED);}
00299   acquisition_mode=-1;
00300   if(upetHeaderReadParameter(fph, "acquisition_mode", tmp)==0)
00301     (void)sscanf(tmp, "%d", &acquisition_mode);
00302   if(MICROPET_TEST>2) printf("acquisition_mode := %d\n", acquisition_mode);
00303   if(acquisition_mode!=2 && acquisition_mode!=3 && acquisition_mode!=9) {
00304     fclose(fph); fclose(fpi); return(STATUS_UNSUPPORTED);}
00305   data_type=-1;
00306   if(upetHeaderReadParameter(fph, "data_type", tmp)==0)
00307     (void)sscanf(tmp, "%d", &data_type);
00308   if(MICROPET_TEST>2) printf("data_type := %d\n", data_type);
00309   if(data_type!=4 && data_type!=2) {
00310     fclose(fph); fclose(fpi); return(STATUS_UNSUPPORTED);}
00311 
00312   /*
00313    *  Convert PET or CT image
00314    */
00315   if(acquisition_mode==2 || acquisition_mode==3)
00316     ret=imgMicropetPETToEcat7(fph, fpi, ecatfile, verbose);
00317   else if(acquisition_mode==9)
00318     ret=imgMicropetCTToEcat7(fph, fpi, ecatfile, verbose);
00319   else
00320     return(STATUS_UNSUPPORTED);
00321   fclose(fph); fclose(fpi);
00322   return ret;
00323 }
00324 /*****************************************************************************/
00325 
00326 /*****************************************************************************/
00332 int imgMicropetPETToEcat7(
00334   FILE *fph,
00336   FILE *fpi,
00338   char *ecatfile,
00340   int verbose
00341 ) {
00342   IMG img;
00343   int n, pxlnr, zi, xi, yi, ti, zdim, xdim, ydim, tdim, ret;
00344   float *fptr, calibration_factor;
00345   char *mdata, *mptr;
00346 
00347 
00348   /* Check input */
00349   if(fph==NULL || fpi==NULL || ecatfile==NULL) return STATUS_FAULT;
00350 
00351   /* Remove existing ECAT file */
00352   if(access(ecatfile, 0)!=-1 && remove(ecatfile)!=0) {
00353     return(STATUS_CANNOTERASE);
00354   }
00355 
00356   /*
00357    *  Read image dimensions from header
00358    */
00359   ret=upetGetImageDimensions(fph, &zdim, &xdim, &ydim, &tdim);
00360   if(ret) {return(STATUS_INVALIDHEADER);}
00361   if(MICROPET_TEST>1) {
00362     printf("z_dim := %d\n", zdim);
00363     printf("x_dim := %d\n", xdim);
00364     printf("y_dim := %d\n", ydim);
00365     printf("t_dim := %d\n", tdim);
00366   }
00367 
00368   /*
00369    *  Read and write image frame-by-frame
00370    */
00371   imgInit(&img);
00372   /* Allocate memory for one frame */
00373   ret=imgAllocate(&img, zdim, ydim, xdim, 1);
00374   if(ret) {return(STATUS_NOMEMORY);}
00375   /* Fill header with what we now can */
00376   ret=imgGetMicropetMainHeader(fph, &img, &calibration_factor);
00377   if(ret) {
00378     if(MICROPET_TEST) printf("ret := %d\n", ret);
00379     imgEmpty(&img); return(STATUS_INVALIDHEADER);
00380   }
00381   if(MICROPET_TEST) printf("calibration_factor := %g\n", calibration_factor);
00382   img._fileFormat=IMG_E7;
00383   img.type=IMG_TYPE_IMAGE;
00384   studynr_from_fname(ecatfile, img.studyNr);
00385   upetScanStart(fph, &img.scanStart);
00386   /* Allocate memory for the binary data */
00387   pxlnr=xdim*ydim*zdim;
00388   mdata=(char*)malloc(pxlnr*sizeof(float)); if(mdata==NULL) {
00389     imgEmpty(&img); return(STATUS_NOMEMORY);
00390   }
00391   /* Frame-by-frame */
00392   for(ti=0; ti<tdim; ti++) {
00393     if(MICROPET_TEST>3) {printf("ti=%d\n", ti); fflush(stdout);}
00394     /* Read frame information from MicroPET  header into IMG */
00395     ret=imgGetMicropetFrameHeader(fph, &img, ti);
00396     if(ret) {
00397       if(verbose==0) {fprintf(stdout, "\n"); fflush(stdout);}
00398       free(mdata); imgEmpty(&img);
00399       return(STATUS_INVALIDHEADER);
00400     }
00401     /* Read floats */
00402     mptr=mdata;
00403     if((n=fread(mptr, 4, pxlnr, fpi)) < pxlnr) {
00404       if(verbose==0) {fprintf(stdout, "\n"); fflush(stdout);}
00405       free(mdata); imgEmpty(&img);
00406       return(STATUS_NOMATRIX);
00407     }
00408     /* Copy floats to IMG */
00409     mptr=mdata;
00410     for(zi=0; zi<zdim; zi++)
00411       for(yi=0; yi<ydim; yi++)
00412         for(xi=0; xi<xdim; xi++) {
00413           fptr=(float*)mptr;
00414           img.m[zi][yi][xi][0]=(*fptr)*img.weight[0]*calibration_factor;
00415           mptr+=4;
00416         }
00417     /* Write frame */
00418     ret=imgWriteFrame(ecatfile, ti+1, &img, 0); //printf("ret := %d\n", ret);
00419     if(ret!=STATUS_OK) break;
00420     if(MICROPET_TEST>1) printf("    frame written.\n");
00421     else if(verbose==0) {fprintf(stdout, "."); fflush(stdout);}
00422   };
00423   free(mdata); imgEmpty(&img);
00424   if(verbose==0) {fprintf(stdout, "\n"); fflush(stdout);}
00425   if(verbose==0 && ret==STATUS_NOMATRIX) {
00426     fprintf(stdout, "  %d frame(s) processed.\n", ti);
00427   }
00428   if(ret!=STATUS_OK && ret!=STATUS_NOMATRIX) {
00429     remove(ecatfile); return ret;
00430   }
00431 
00432   return STATUS_OK;
00433 }
00434 /*****************************************************************************/
00435 
00436 /*****************************************************************************/
00441 int imgMicropetCTToEcat7(
00443   FILE *fph,
00445   FILE *fpi,
00447   char *ecatfile,
00449   int verbose
00450 ) {
00451   IMG img;
00452   int n, pxlnr, zi, xi, yi, zdim, xdim, ydim, ret;
00453   float f, scale_factor;
00454   char *mdata, *mptr;
00455   char tmp[MAX_MICROPET_LINE_LEN];
00456   short int *si;
00457 
00458 
00459   /* Check input */
00460   if(fph==NULL || fpi==NULL || ecatfile==NULL) return STATUS_FAULT;
00461 
00462   /*
00463    *  Read image dimensions from header
00464    */
00465   ret=upetGetImageDimensions(fph, &zdim, &xdim, &ydim, NULL);
00466   if(ret) {return(STATUS_INVALIDHEADER);}
00467   if(MICROPET_TEST>1) {
00468     printf("z_dim := %d\n", zdim);
00469     printf("x_dim := %d\n", xdim);
00470     printf("y_dim := %d\n", ydim);
00471   }
00472 
00473   /* Read scale factor */
00474   rewind(fph);
00475   if(upetHeaderReadParameter(fph, "scale_factor", tmp)!=0) {
00476     return(STATUS_INVALIDHEADER);}
00477   scale_factor=-1; (void)sscanf(tmp, "%f", &scale_factor);
00478   if(scale_factor<=0) return(STATUS_INVALIDHEADER);
00479   if(MICROPET_TEST>1) {
00480     printf("scale_factor := %g\n", scale_factor);
00481   }
00482 
00483   /* Remove existing ECAT file */
00484   if(access(ecatfile, 0)!=-1 && remove(ecatfile)!=0) {
00485     return(STATUS_CANNOTERASE);
00486   }
00487 
00488   /*
00489    *  Read and write image
00490    */
00491   imgInit(&img);
00492   /* Allocate memory for one frame */
00493   ret=imgAllocate(&img, zdim, ydim, xdim, 1);
00494   if(ret) {return(STATUS_NOMEMORY);}
00495   /* Fill header with what we now can */
00496   ret=imgGetMicropetMainHeader(fph, &img, NULL);
00497   if(ret) {
00498     if(MICROPET_TEST) printf("ret := %d\n", ret);
00499     imgEmpty(&img); return(STATUS_INVALIDHEADER);
00500   }
00501   img._fileFormat=IMG_E7;
00502   img.type=IMG_TYPE_IMAGE;
00503   studynr_from_fname(ecatfile, img.studyNr);
00504   upetScanStart(fph, &img.scanStart);
00505   /* Allocate memory for the binary data */
00506   pxlnr=xdim*ydim;
00507   mdata=(char*)malloc(pxlnr*sizeof(short int)); if(mdata==NULL) {
00508     imgEmpty(&img); return(STATUS_NOMEMORY);
00509   }
00510   /* Read image data, plane-by-plane */
00511   for(zi=0; zi<zdim; zi++) {
00512     mptr=mdata;
00513     if((n=fread(mptr, 2, pxlnr, fpi)) < pxlnr) {
00514       if(verbose==0) {fprintf(stdout, "\n"); fflush(stdout);}
00515       free(mdata); imgEmpty(&img);
00516       return(STATUS_NOMATRIX);
00517     }
00518     /* Copy short ints to IMG */
00519     mptr=mdata;
00520     for(yi=0; yi<ydim; yi++)
00521       for(xi=0; xi<xdim; xi++) {
00522         si=(short int*)mptr;
00523         f=(float)*si*scale_factor;
00524         if(f>=0.0) img.m[zi][yi][xi][0]=f; else img.m[zi][yi][xi][0]=0.0;
00525         mptr+=2;
00526       }
00527     if(MICROPET_TEST>1) printf("   plane %d\n", zi+1);
00528     else if(verbose==0) {fprintf(stdout, "."); fflush(stdout);}
00529   }
00530   free(mdata);
00531   if(verbose==0) {fprintf(stdout, "\n"); fflush(stdout);}
00532   /* Save ECAT 7 image volume */
00533   ret=imgWrite(ecatfile, &img);
00534   if(ret!=0) {imgEmpty(&img); return(STATUS_CANNOTWRITE);}
00535 
00536   imgEmpty(&img);
00537   return STATUS_OK;
00538 }
00539 /*****************************************************************************/
00540 
00541 /*****************************************************************************/
00544 int imgGetMicropetMainHeader(
00546   FILE *fp,
00548   IMG *img,
00550   float *calibration_factor
00551 ) {
00552   char tmp[MAX_MICROPET_LINE_LEN];
00553   int n;
00554   float f, branching_fraction=1.0;
00555 
00556 
00557   if(fp==NULL) return 1;
00558   if(img==NULL) return 2;
00559 
00560   /* scanner model */
00561   rewind(fp);
00562   if(upetHeaderReadParameter(fp, "model", tmp)!=0) return 11;
00563   n=-1; (void)sscanf(tmp, "%d", &n); if(n<0) return 11;
00564   img->scanner=n;
00565 
00566   /* zoom */
00567   rewind(fp);
00568   if(upetHeaderReadParameter(fp, "zoom", tmp)!=0) return 11;
00569   f=-1; (void)sscanf(tmp, "%f", &f); if(f<0) return 11;
00570   img->zoom=f;
00571 
00572   /* pixel size x */
00573   rewind(fp);
00574   if(upetHeaderReadParameter(fp, "pixel_size_x", tmp)!=0) return 12;
00575   f=-1; (void)sscanf(tmp, "%f", &f); if(f<0) return 12;
00576   img->sizex=f;
00577 
00578   /* pixel size y */
00579   rewind(fp);
00580   if(upetHeaderReadParameter(fp, "pixel_size_y", tmp)!=0) return 13;
00581   f=-1; (void)sscanf(tmp, "%f", &f); if(f<0) return 13;
00582   img->sizey=f;
00583 
00584   /* pixel size z */
00585   rewind(fp);
00586   if(upetHeaderReadParameter(fp, "pixel_size_z", tmp)!=0) return 14;
00587   f=-1; (void)sscanf(tmp, "%f", &f); if(f<0) return 14;
00588   img->sizez=f;
00589   rewind(fp);
00590   if(upetHeaderReadParameter(fp, "transaxial_bin_size", tmp)==0) {
00591     f=-1; (void)sscanf(tmp, "%f", &f); if(f>0) img->sizez=10.0*f;
00592   }
00593 
00594   /* isotope halflife */
00595   rewind(fp);
00596   if(upetHeaderReadParameter(fp, "isotope_half_life", tmp)==0) {
00597     f=-1; (void)sscanf(tmp, "%f", &f); if(f<0) return 15;
00598     img->isotopeHalflife=f;
00599   }
00600 
00601   /* branching_fraction */
00602   rewind(fp);
00603   if(upetHeaderReadParameter(fp, "isotope_branching_fraction", tmp)==0) {
00604     f=-1; (void)sscanf(tmp, "%f", &f); if(f<0) return 16;
00605     branching_fraction=f;
00606   }
00607 
00608   /* decay correction applied */
00609   rewind(fp);
00610   if(upetHeaderReadParameter(fp, "decay_correction_applied", tmp)==0) {
00611     n=-1; (void)sscanf(tmp, "%d", &n); if(n<0) return 17;
00612     img->decayCorrected=n;
00613   }
00614 
00615   /* calibration units */
00616   rewind(fp);
00617   if(upetHeaderReadParameter(fp, "calibration_units", tmp)==0) {
00618     n=-1; (void)sscanf(tmp, "%d", &n); if(n<0) return 18;
00619     switch(n) {
00620       case 1: img->unit=IMGUNIT_NCI_PER_ML; break;
00621       case 2: img->unit=IMGUNIT_BQ_PER_ML; break;
00622       case 0:
00623       default: img->unit=IMGUNIT_UNKNOWN; break;
00624     }
00625   }
00626 
00627   /* calibration factor */
00628   rewind(fp);
00629   if(calibration_factor!=NULL &&
00630      upetHeaderReadParameter(fp, "calibration_factor", tmp)==0)
00631   {
00632     f=-1; (void)sscanf(tmp, "%f", &f); if(f<=0.0) return 19;
00633     *calibration_factor=f;
00634     if(branching_fraction>0.0) *calibration_factor/=branching_fraction;
00635   }
00636 
00637   /* FOV */
00638   rewind(fp);
00639   if(upetHeaderReadParameter(fp, "radial_fov", tmp)==0) {
00640     f=-1; (void)sscanf(tmp, "%f", &f); if(f<0) return 20;
00641     img->transaxialFOV=10.0*f;
00642   }
00643 
00644   return 0;
00645 }
00646 /*****************************************************************************/
00647 
00648 /*****************************************************************************/
00652 int imgGetMicropetFrameHeader(
00653   /* File pointer to Concorde/MicroPET header */
00654   FILE *fp,
00655   /* Pointer to IMG struct, allocated for one frame; frame information is
00656      written in frame 0. */
00657   IMG *img,
00658   /* Frame index [0..tdim-1] */
00659   int frame_index
00660 ) {
00661   char tmp[MAX_MICROPET_LINE_LEN];
00662   int n;
00663   float f;
00664 
00665 
00666   if(fp==NULL) return 1;
00667   if(img==NULL) return 2;
00668   if(frame_index<0) return 3;
00669 
00670   /* Search required frame from the beginning of header file */
00671   rewind(fp);
00672 
00673   /* Find correct frame index */
00674   sprintf(tmp, "frame %d", frame_index);
00675   if(upetHeaderReadParameter(fp, tmp, tmp)!=0) return 5;
00676 
00677   /* frame start time */
00678   if(upetHeaderReadParameter(fp, "frame_start", tmp)!=0) return 11;
00679   n=-1; (void)sscanf(tmp, "%d", &n); if(n<0) return 11;
00680   img->start[0]=n;
00681 
00682   /* frame duration */
00683   if(upetHeaderReadParameter(fp, "frame_duration", tmp)!=0) return 12;
00684   n=-1; (void)sscanf(tmp, "%d", &n); if(n<0) return 12;
00685   img->end[0]=img->start[0]+n;
00686   img->mid[0]=0.5*(img->end[0]+img->start[0]);
00687 
00688   /* scale factor (written in 'weight' since there is no better place) */
00689   if(upetHeaderReadParameter(fp, "scale_factor", tmp)!=0) return 13;
00690   f=-1; (void)sscanf(tmp, "%f", &f); if(f<0) return 13;
00691   img->weight[0]=f;
00692 
00693   /* decay correction */
00694   if(upetHeaderReadParameter(fp, "decay_correction", tmp)!=0) return 14;
00695   f=-1; (void)sscanf(tmp, "%f", &f); if(f<0) return 14;
00696   img->decayCorrFactor[0]=f;
00697 
00698   return 0;
00699 }
00700 /*****************************************************************************/
00701 
00702 /*****************************************************************************/
00706 int imgGetMicropetSIF(
00708   FILE *fp,
00711   SIF *sif
00712 ) {
00713   char tmp[MAX_MICROPET_LINE_LEN], tmp2[64], tmp3[64];
00714   int n, i, ret;
00715 
00716 
00717   if(fp==NULL) return 1;
00718   if(sif==NULL) return 2;
00719 
00720 
00721   /* Get frame number */
00722   rewind(fp);
00723   if(upetHeaderReadParameter(fp, "total_frames", tmp)!=0) return 11;
00724   n=-1; (void)sscanf(tmp, "%d", &n); if(n<1) return 11;
00725 
00726   /* Allocate memory for SIF */
00727   ret=sifSetmem(sif, n); if(ret!=0) return 4;
00728   sif->frameNr=n;
00729   sif->colNr=4;
00730   sif->version=1;
00731 
00732   /* Scan time */
00733   upetScanStart(fp, &sif->scantime);
00734 
00735   /* Isotope */
00736   rewind(fp);
00737   if(upetHeaderReadParameter(fp, "isotope", tmp)!=0) return 13;
00738   strncpy(sif->isotope_name, tmp, 8);
00739 
00740   /* Frames */
00741   for(i=0; i<sif->frameNr; i++) {
00742     /* Find correct frame index */
00743     sprintf(tmp, "frame %d", i);
00744     if(upetHeaderReadParameter(fp, tmp, tmp)!=0) return 21;
00745     /* frame start time */
00746     if(upetHeaderReadParameter(fp, "frame_start", tmp)!=0) return 22;
00747     n=-1; (void)sscanf(tmp, "%d", &n); if(n<0) return 22;
00748     sif->x1[i]=n;
00749     /* frame duration */
00750     if(upetHeaderReadParameter(fp, "frame_duration", tmp)!=0) return 23;
00751     n=-1; (void)sscanf(tmp, "%d", &n); if(n<0) return 23;
00752     sif->x2[i]=sif->x1[i]+n;
00753     /* prompts */
00754     if(upetHeaderReadParameter(fp, "prompts", tmp)!=0) return 24;
00755     n=-1; (void)sscanf(tmp, "%s %s %d", tmp2, tmp3, &n); if(n<0) return 24;
00756     sif->prompts[i]=n;
00757     /* delays */
00758     if(upetHeaderReadParameter(fp, "delays", tmp)!=0) return 25;
00759     n=-1; (void)sscanf(tmp, "%s %s %d", tmp2, tmp3, &n); if(n<0) return 25;
00760     sif->randoms[i]=n;
00761     /* trues */
00762     sif->trues[i]=sif->prompts[i]-sif->randoms[i];
00763   }
00764   return 0;
00765 }
00766 /*****************************************************************************/
00767 
00768 /*****************************************************************************/