コード例 #1
0
ファイル: img_ana.c プロジェクト: phoboz/volkit
/*!
 * Fill IMG struct header information from Analyze 7.5 database files.
 *  SIF file is read if available. Information concerning separate frames
 *  or planes is not filled though.
 *
 * @param dbname name of Analyze database, may contain filename extension
 * @param img pointer to the initiated IMG data
 * @return errstatus, which is STATUS_OK (0) when call was successful,
 * and >0 in case of an error.
 */
int imgReadAnalyzeHeader(const char *dbname, IMG *img) {
  char hdrfile[FILENAME_MAX], siffile[FILENAME_MAX];
  ANALYZE_DSR ana_header;
  SIF sif;
  double f;
  int ret;

  if(IMG_TEST) printf("\nimgReadAnalyzeHeader(%s, *img)\n", dbname);
  
  /* Check the input */
  if(img==NULL) return STATUS_FAULT;
  if(img->status!=IMG_STATUS_INITIALIZED) return STATUS_FAULT;
  imgSetStatus(img, STATUS_FAULT);
  if(dbname==NULL) return STATUS_FAULT;

  /* Determine the names of hdr and sif files */
  ret=anaDatabaseExists(dbname, hdrfile, NULL, siffile);
  if(ret==0) return STATUS_NOFILE;
  
  /* Read Analyze header file */
  ret=anaReadHeader(hdrfile, &ana_header);
  if(ret!=0) {
    if(IMG_TEST>1) printf("anaReadHeader() return value := %d\n", ret);
    if(ret==1) return STATUS_FAULT;
    else if(ret==2) return STATUS_NOHEADERFILE;
    else return STATUS_UNSUPPORTED;
    return(STATUS_FAULT);
  }
  /* and set IMG contents */
  ret=imgGetAnalyzeHeader(img, &ana_header);
  if(ret!=0) {
    imgSetStatus(img, ret);
    return(ret);
  }

  /* If SIF does not exist, then that's it */
  if(!siffile[0]) {
    imgSetStatus(img, STATUS_OK);
    return STATUS_OK;
  }

  /* SIF is available, so read that too */
  sifInit(&sif); ret=0;
  if(sifRead(siffile, &sif)!=0) return STATUS_OK;
  /* Copy scan time */
  img->scanStart=sif.scantime;
  /* Study number, if not yet defined */
  if(!img->studyNr[0] && strlen(sif.studynr)>1 )
    strncpy(img->studyNr, sif.studynr, MAX_STUDYNR_LEN);
  /* Isotope half-life, if not yet defined */
  f=hlFromIsotope(sif.isotope_name);
  if(img->isotopeHalflife<=0.0 && f>0.0) img->isotopeHalflife=60.0*f;
  sifEmpty(&sif);

  return STATUS_OK;
}
コード例 #2
0
ファイル: img_ana.c プロジェクト: phoboz/volkit
/*!
 * Write one PET frame from IMG data struct into Analyze 7.5 database file.
 *  This function can be called repeatedly to write all frames one at a time
 *  to conserve memory. This function does not write SIF.
 *
 * @param dbname name of file where IMG contents will be written.
 *  If file does not exist, it is created.
 *  Make sure to delete existing file, unless you want to add data
 * @param frame_to_write PET frame number (1..frameNr) which will be written:
 *  If set to 0, frame data will be written to an existing or new PET file as
 *  a new frame, never overwriting existing data.
 *  If >0, then frame data is written as specified frame number, overwriting
 *  any data existing with the same frame number
 * @param img pointer to the IMG data struct
 * @param frame_index IMG frame index (0..dimt-1) which will be written
 * @param fmin minimum pixel value in all frames that will be written;
 *  used only when writing the first frame
 * @param fmax maximum pixel value in all frames that will be written;
 *  used only when writing the first frame
 * @return errstatus, which is STATUS_OK (0) when call was successful,
 * and >0 in case of an error.
 */
int imgWriteAnalyzeFrame(
  const char *dbname, int frame_to_write, IMG *img, int frame_index,
  float fmin, float fmax
) {
  IMG test_img;
  int ret=0, pxlNr, zi, xi, yi, little;
  FILE *fp;
  short int *sdata=NULL, *sptr;
  char datfile[FILENAME_MAX], hdrfile[FILENAME_MAX], siffile[FILENAME_MAX];
  ANALYZE_DSR dsr;
  float scale_factor=1.0;


  if(IMG_TEST) printf("\nimgWriteAnalyzeFrame(%s, %d, *img, %d, %g, %g)\n",
    dbname, frame_to_write, frame_index, fmin, fmax);

  /*
   *  Check the input 
   */
  if(dbname==NULL) return STATUS_FAULT;
  if(img==NULL) return STATUS_FAULT;
  if(img->status!=IMG_STATUS_OCCUPIED) return STATUS_FAULT;
  if(frame_to_write<0) return STATUS_FAULT;
  if(frame_index<0 || frame_index>=img->dimt) return STATUS_FAULT;
  if(img->_fileFormat!=IMG_ANA_L && img->_fileFormat!=IMG_ANA)
    return STATUS_FAULT;

  /*
   *  If database does not exist, then create it with new header,
   *  and if it does exist, then read and check header information.
   *  Create or edit header to contain correct frame nr.
   *  Determine the global scaling factor.   
   */
  imgInit(&test_img);
  if(anaDatabaseExists(dbname, hdrfile, datfile, siffile)==0) { // not existing

    /* Create database filenames */
    sprintf(hdrfile, "%s.hdr", dbname);
    sprintf(datfile, "%s.img", dbname);
    sprintf(siffile, "%s.sif", dbname);

    /* Set main header */
    imgSetAnalyzeHeader(img, dbname, &dsr, fmin, fmax);
    if(frame_to_write==0) frame_to_write=1;
    dsr.dime.dim[4]=frame_to_write;
    scale_factor=dsr.dime.funused1;
    if(fabs(scale_factor)>1.0E-20) scale_factor=1.0/scale_factor;

    /* Write Analyze header */
    ret=anaWriteHeader(hdrfile, &dsr);
    if(ret && IMG_TEST) printf("anaWriteHeader() := %d\n", ret);
    if(ret) return STATUS_CANTWRITEHEADERFILE;

    /* Remove datafile if necessary */
    if(access(datfile, 0) != -1) remove(datfile);

  } else { /* database does exist */
  
    /* Read header information for checking */
    ret=imgReadAnalyzeHeader(dbname, &test_img);
    if(ret!=0) {imgEmpty(&test_img); return ret;}
    /* Check that file format is the same */
    if(img->_fileFormat!=test_img._fileFormat || img->type!=test_img.type) {
      imgEmpty(&test_img); return STATUS_WRONGFILETYPE;}
    /* Check that matrix sizes are the same */
    if(img->dimz!=test_img.dimz || img->dimx!=test_img.dimx ||
       img->dimy!=test_img.dimy) {
      imgEmpty(&test_img); return STATUS_VARMATSIZE;}
    imgEmpty(&test_img);

    /* Read the header, set new frame number, and write it back */
    /* Get also the scale factor */
    if((ret=anaReadHeader(hdrfile, &dsr))!=0) return STATUS_NOMAINHEADER;
    scale_factor=1.0/dsr.dime.funused1;
    if(frame_to_write==0) frame_to_write=dsr.dime.dim[4]+1;
    if(dsr.dime.dim[4]<frame_to_write) {
      if(dsr.dime.dim[4]+1<frame_to_write) return STATUS_MISSINGMATRIX;
      dsr.dime.dim[4]=frame_to_write;
    }
    if((ret=anaWriteHeader(hdrfile, &dsr))!=0) return STATUS_NOWRITEPERM;
  }
  if(IMG_TEST>2) {
    printf("frame_to_write := %d\n", frame_to_write);
    printf("hdrfile := %s\n", hdrfile);
    printf("datfile := %s\n", datfile);
    printf("siffile := %s\n", siffile);
  }

  /* Allocate memory for matrix short int data (one plane) */
  pxlNr=img->dimx*img->dimy;
  sdata=(short int*)malloc(pxlNr*sizeof(short int));
  if(sdata==NULL) return STATUS_NOMEMORY;

  /* Open datafile, not removing possible old contents */
  if(frame_to_write==1) fp=fopen(datfile, "wb"); else fp=fopen(datfile, "r+b");
  if(fp==NULL) {free(sdata); return STATUS_CANTWRITEIMGFILE;}
  /* Move file pointer to the place of current frame */
  if(fseek(fp, (frame_to_write-1)*pxlNr*img->dimz*sizeof(short int),
           SEEK_SET)!=0) {
    free(sdata); fclose(fp); return STATUS_MISSINGMATRIX;}
  little=little_endian();
  /* Copy, scale and write data plane-by-plane */
  if(anaFlipping()==0) {
    for(zi=0; zi<img->dimz; zi++) {
      sptr=sdata;
     /*printf("plane := %d\n  scale_factor := %g\n", zi+1, scale_factor);*/
      for(yi=img->dimy-1; yi>=0; yi--) for(xi=img->dimx-1; xi>=0; xi--) {
        *sptr=temp_roundf(scale_factor*img->m[zi][yi][xi][frame_index]); sptr++;
      }
      /* Change byte order if necessary */
      sptr=sdata; if(little!=dsr.little) swabip(sptr, pxlNr*sizeof(short int));
      /* Write image data */
      sptr=sdata;
      if(fwrite(sptr, sizeof(short int), pxlNr, fp) != pxlNr) {
        free(sdata); fclose(fp); return STATUS_CANTWRITEIMGFILE;
      }
    }
  } else {
    for(zi=img->dimz-1; zi>=0; zi--) {
      sptr=sdata;
      for(yi=img->dimy-1; yi>=0; yi--) for(xi=img->dimx-1; xi>=0; xi--) {
        *sptr=temp_roundf(scale_factor*img->m[zi][yi][xi][frame_index]); sptr++;
      }
      /* Change byte order if necessary */
      sptr=sdata; if(little!=dsr.little) swabip(sptr, pxlNr*sizeof(short int));
      /* Write image data */
      sptr=sdata;
      if(fwrite(sptr, sizeof(short int), pxlNr, fp) != pxlNr) {
        free(sdata); fclose(fp); return STATUS_CANTWRITEIMGFILE;
      }
    }
  }
  free(sdata);
  fclose(fp);

  return STATUS_OK;
}
コード例 #3
0
ファイル: img_ana.c プロジェクト: phoboz/volkit
/*!
 * Read a specified frame from an Analyze 7.5 database into preallocated IMG
 *  data structure. Analyze database consists of two or three files in the same 
 *  directory: fname.hdr, fname.img, and optionally fname.sif.
 *  IMG header is assumed to be filled correctly before calling this function,
 *  except for information concerning separate planes and this frame,
 *  which is filled here.
 *  If frame does not exist, then and only then STATUS_NOMATRIX is returned.
 *
 * @param fname name of Analyze database from which IMG contents will be read
 * @param frame_to_read frame which will be read [1..frameNr]
 * @param img pointer to the IMG data. Place for the frame must be preallocated
 * @param frame_index IMG frame index [0..dimt-1] where data will be placed
 * @return errstatus, which is STATUS_OK (0) when call was successful,
 * and >0 in case of an error.
 */ 
int imgReadAnalyzeFrame(
  const char *fname, int frame_to_read, IMG *img, int frame_index
) {
  FILE *fp;
  int ret, pi, xi, yi;
  float *fdata=NULL, *fptr;
  ANALYZE_DSR dsr;
  char datfile[FILENAME_MAX], hdrfile[FILENAME_MAX], siffile[FILENAME_MAX];
  SIF sif;


  if(IMG_TEST) printf("\nimgReadAnalyzeFrame(%s, %d, *img, %d)\n",
    fname, frame_to_read, frame_index);
    
  /* Check the input */
  if(img==NULL) return STATUS_FAULT;
  if(img->status!=IMG_STATUS_OCCUPIED) return STATUS_FAULT;
  if(fname==NULL) return STATUS_FAULT;
  if(frame_index<0 || frame_index>img->dimt-1) return STATUS_FAULT;
  if(frame_to_read<1) return STATUS_FAULT;
  imgSetStatus(img, STATUS_FAULT);
  
  /* Determine the names of hdr, data and sif files */
  ret=anaDatabaseExists(fname, hdrfile, datfile, siffile);
  if(ret==0) return STATUS_NOFILE;

  /* Read Analyze header file */
  ret=anaReadHeader(hdrfile, &dsr);
  if(ret!=0) {
    if(ret==1) return STATUS_FAULT;
    else if(ret==2) return STATUS_NOHEADERFILE;
    else return STATUS_UNSUPPORTED;
    return(STATUS_FAULT);
  }

  /* Open image datafile */
  if(IMG_TEST>2) fprintf(stdout, "reading image data %s\n", datfile);
  if((fp=fopen(datfile, "rb")) == NULL) return STATUS_NOIMGDATA;

  /* Allocate memory for one image frame */
  fdata=malloc(img->dimx*img->dimy*img->dimz*sizeof(float));
  if(fdata==NULL) {fclose(fp); return STATUS_NOMEMORY;}

  /* Read the required image frame */
  fptr=fdata;
  ret=anaReadImagedata(fp, &dsr, frame_to_read, fptr);
  fclose(fp);
  if(ret==3) {free(fdata); return STATUS_NOMATRIX;} /* no more frames */
  if(ret!=0) {free(fdata); return STATUS_UNSUPPORTED;}

  /* Copy pixel values to IMG */
  fptr=fdata;
  if(anaFlipping()==0) { /* no flipping in z-direction */
    for(pi=0; pi<img->dimz; pi++)
      for(yi=img->dimy-1; yi>=0; yi--)
        for(xi=img->dimx-1; xi>=0; xi--)
          img->m[pi][yi][xi][frame_index]=*fptr++;
  } else {
    for(pi=img->dimz-1; pi>=0; pi--)
      for(yi=img->dimy-1; yi>=0; yi--)
        for(xi=img->dimx-1; xi>=0; xi--)
          img->m[pi][yi][xi][frame_index]=*fptr++;
  }
  free(fdata);

  /* Set decay correction factor to zero */
  img->decayCorrFactor[frame_index]=0.0;

  imgSetStatus(img, STATUS_OK); /* If the rest is failed, no problem */

  /* 
   *  Try to read frame time information from SIF file
   */
  sifInit(&sif);
  if(sifRead(siffile, &sif)!=0) return STATUS_OK;
  /* Frame information */
  if(sif.frameNr>=frame_to_read) {
    img->start[frame_index]=sif.x1[frame_to_read-1];
    img->end[frame_index]=sif.x2[frame_to_read-1];
    img->mid[frame_index]=0.5*(img->start[frame_index]+img->end[frame_index]);
    img->prompts[frame_index]=sif.prompts[frame_to_read-1];
    img->randoms[frame_index]=sif.randoms[frame_to_read-1];
  }
  sifEmpty(&sif);

  return STATUS_OK;
}
コード例 #4
0
ファイル: img_ana.c プロジェクト: phoboz/volkit
/*!
 * Read Analyze 7.5 image.
 *   Analyze database name must be given with path. Image and header files
 *   with .img and .hdr extensions must exist. Also SIF file with .sif
 *   extension is used, if it exists.
 *   anaFlipping() determines whether image is flipped in z-direction;
 *   image is always flipped in x,y-directions.
 *
 * @param dbname Analyze database name with path, with or without extension
 * @param img Pointer to initialized IMG structure
 * @return 0 if ok, and otherwise IMG status code; sets IMG->statmsg
 *  in case of error.
 */
int imgReadAnalyze(const char *dbname, IMG *img) {
  FILE *fp;
  int ret, fi, pi, xi, yi;
  float *fdata=NULL, *fptr;
  ANALYZE_DSR dsr;
  char datfile[FILENAME_MAX], hdrfile[FILENAME_MAX], siffile[FILENAME_MAX];
  int dimNr, dimx, dimy, dimz=1, dimt=1, pxlNr=0;
  SIF sif;


  if(IMG_TEST) printf("imgReadAnalyze(%s, *img)\n", dbname);

  /* Check the arguments */
  imgSetStatus(img, STATUS_OK);
  if(img==NULL || img->status!=IMG_STATUS_INITIALIZED) {
    imgSetStatus(img, STATUS_FAULT); return(2);}
  if(dbname==NULL || !dbname[0]) {imgSetStatus(img, STATUS_FAULT); return(1);}
  
  /* Make the image and header filenames */
  ret=anaExistsNew(dbname, hdrfile, datfile, siffile);
  if(ret==0) {imgSetStatus(img, STATUS_NOHEADERFILE); return(3);}
  if(ret==1 && IMG_TEST>0) printf("no SIF found for %s\n", dbname); 

  /* Read Analyze header file */
  ret=anaReadHeader(hdrfile, &dsr);
  if(ret) {
    if(ret==1) imgSetStatus(img, STATUS_FAULT);
    else if(ret==2) imgSetStatus(img, STATUS_NOHEADERFILE);
    else imgSetStatus(img, STATUS_UNSUPPORTED);
    return(3);
  }
  if(IMG_TEST) anaPrintHeader(&dsr, stdout);

  /* Open image datafile */
  if(IMG_TEST) fprintf(stdout, "reading image data %s\n", datfile);
  if((fp=fopen(datfile, "rb")) == NULL) {
    imgSetStatus(img, STATUS_NOIMGDATA); return(5);}

  /* Prepare IMG for Analyze image */
  /* Get the image dimensions from header */
  dimNr=dsr.dime.dim[0];
  if(dimNr<2) {fclose(fp); imgSetStatus(img, STATUS_INVALIDHEADER); return(4);}
  dimx=dsr.dime.dim[1]; dimy=dsr.dime.dim[2];
  if(dimNr>2) {dimz=dsr.dime.dim[3]; if(dimNr>3) dimt=dsr.dime.dim[4];}
  pxlNr=dimx*dimy*dimz;
  if(pxlNr<1) {fclose(fp); imgSetStatus(img, STATUS_INVALIDHEADER); return(4);}
  /* Allocate memory for IMG */
  ret=imgAllocate(img, dimz, dimy, dimx, dimt);
  if(ret) {fclose(fp); imgSetStatus(img, STATUS_NOMEMORY); return(11);}
  /* Copy information from Analyze header */
  img->type=IMG_TYPE_IMAGE;
  strncpy(img->studyNr, dsr.hist.patient_id, MAX_STUDYNR_LEN);
  if(strcmp(img->studyNr, ".")==0) strcpy(img->studyNr, "");
  strcpy(img->patientName, dsr.hist.patient_id);
  img->sizex=dsr.dime.pixdim[1];
  img->sizey=dsr.dime.pixdim[2];
  img->sizez=dsr.dime.pixdim[3];
  /*if(dsr.dime.funused2>1.E-5) img->zoom=dsr.dime.funused2;*/
  if(dsr.dime.funused3>1.E-5) img->isotopeHalflife=dsr.dime.funused3;
  for(pi=0; pi<dimz; pi++) img->planeNumber[pi]=pi+1;
  if(dsr.little) img->_fileFormat=IMG_ANA_L; else img->_fileFormat=IMG_ANA;
  /* Decay correction */
  if(strstr(dsr.hist.descrip, "Decay corrected.")!=NULL)
    img->decayCorrection=IMG_DC_CORRECTED;
  else if(strstr(dsr.hist.descrip, "No decay correction.")!=NULL)
    img->decayCorrection=IMG_DC_NONCORRECTED;
  else
    img->decayCorrection=IMG_DC_CORRECTED; // just assumed so

  /* Allocate memory for one image frame */
  fdata=malloc(pxlNr*sizeof(float));
  if(fdata==NULL) {fclose(fp); imgSetStatus(img, STATUS_NOMEMORY); return(12);}

  /* Read one image frame at a time */
  for(fi=0; fi<dimt; fi++) {
    fptr=fdata;
    ret=anaReadImagedata(fp, &dsr, fi+1, fptr);
    if(ret) {
      free(fdata); fclose(fp); imgSetStatus(img, STATUS_NOIMGDATA); return(7);}
    /* Copy pixel values to IMG */
    fptr=fdata;
    if(anaFlipping()==0) { /* no flipping in z-direction */
      for(pi=0; pi<img->dimz; pi++)
        for(yi=dimy-1; yi>=0; yi--)
          for(xi=dimx-1; xi>=0; xi--)
            img->m[pi][yi][xi][fi]=*fptr++;
    } else {
      for(pi=dimz-1; pi>=0; pi--)
        for(yi=dimy-1; yi>=0; yi--)
          for(xi=dimx-1; xi>=0; xi--)
            img->m[pi][yi][xi][fi]=*fptr++;
    }
  } /* next frame */
  free(fdata);
  fclose(fp);
  
  /* Try to read frame time information from SIF file */
  /* Check if SIF file is found */
  if(siffile[0]) {
    if(IMG_TEST) printf("reading SIF file %s\n", siffile);
    if(access(siffile, 0) == -1) {
      if(IMG_TEST) printf(" No SIF file; therefore unknown frame times.\n");
      return(0);
    }
  }
  /* If found, then read it */
  sifInit(&sif); ret=sifRead(siffile, &sif);
  if(ret) {imgSetStatus(img, STATUS_NOSIFDATA); return(21);}

  /* Copy SIF contents */
  ret=sif2img(&sif, img, 1, 1, 1, IMG_TEST-2);
  sifEmpty(&sif);
  if(ret!=0) {imgSetStatus(img, STATUS_WRONGSIFDATA); return(22);}
  
  return(0);
}
コード例 #5
0
ファイル: analyze.c プロジェクト: jbpoline/compile_ecat2ana
/** Check if specified filename is a Analyze file. 
\return Returns 0 if it is not, 1 if it is, and both image and header is found,
    and 2, if sif file is found too.
 */
int anaExistsNew(
  /** Filename, either header file, image file, or base name without extensions.
   *  this string is never modified. */
  const char *filename,
  /** If filename refers to a Analyze file, then header filename will be
     written in this char pointer (space needs to allocated by caller);
     NULL if not needed. */
  char *hdrfile,
  /** If filename refers to a Analyze file, then image filename will be
     written in this char pointer (space needs to allocated by caller);
     NULL if not needed. */
  char *imgfile,
  /** If filename refers to a Analyze file, and if SIF exists, then SIF filename
     will be written in this char pointer (space needs to allocated by caller);
     NULL if not needed. */
  char *siffile
) {
  char *cptr, basefile[FILENAME_MAX], temp[FILENAME_MAX];
  ANALYZE_DSR h;
  int ret;

  if(filename==NULL || strlen(filename)==0) return(0);
  if(ANALYZE_TEST>1) printf("\nanaExistsNew(%s, *str, *str, *str)\n", filename);

  /* Construct the base file name wo extensions */
  strcpy(basefile, filename);
  cptr=strrchr(basefile, '.');
  if(cptr!=NULL) {
    if(strncasecmp(cptr, ".HDR", 4)==0 || strncasecmp(cptr, ".IMG", 4)==0 )
      *cptr=(char)0;
  } 
  cptr=strrchr(basefile, '.');
  if(cptr!=NULL) {
    if(strncasecmp(cptr, ".IMG", 4)==0 )
      *cptr=(char)0;
  }
  if(ANALYZE_TEST>2) printf("\n  basefile := %s\n", basefile);

  /* Header file exists? */
  strcpy(temp, basefile); strcat(temp, ".hdr");
  if(access(temp, 0) == -1) {
    strcpy(temp, basefile); strcat(temp, ".img.hdr");
    if(access(temp, 0) == -1) {
      if(ANALYZE_TEST) printf("\n  hdr file not found or accessible.\n");
      return(0);
    }
  }
  /* Is this Analyze header file? */
  if((ret=anaReadHeader(temp, &h))!=0) {
    if(ANALYZE_TEST) {
      printf("\n  %s was not identified as Analyze header file (%d).\n",
        temp, ret);
    }
    return(0);
  }
  /* Preserve header filename */
  if(hdrfile!=NULL) strcpy(hdrfile, temp);

  /* Image file exists? */
  strcpy(temp, basefile); strcat(temp, ".img");
  if(access(temp, 0) == -1) {
    if(ANALYZE_TEST) printf("\n  %s not found or accessible.\n", temp);
    return(0);
  }
  /* Preserve image filename */
  if(imgfile!=NULL) strcpy(imgfile, temp);

  /* SIF exists? */
  strcpy(temp, basefile); strcat(temp, ".sif");
  if(access(temp, 0) == -1) {
    strcpy(temp, basefile); strcat(temp, ".img.sif");
    if(access(temp, 0) == -1) {
      if(ANALYZE_TEST) printf("\n  SIF not found or accessible.\n");
     if(siffile!=NULL) strcpy(siffile, "");
      return(1); // but otherwise ok
    }
  }
  /* Preserve SIF filename */
  if(siffile!=NULL) strcpy(siffile, temp);
  return(2);
}