micropet.c
Go to the documentation of this file.
1 /*****************************************************************************
2 
3  Copyright (c) 2009,2011 by Turku PET Centre
4 
5  Library: micropet.c
6  Description: Procedures for reading Siemens Inveon images.
7 
8  This program is free software; you can redistribute it and/or modify it under
9  the terms of the GNU General Public License as published by the Free Software
10  Foundation; either version 2 of the License, or (at your option) any later
11  version.
12 
13  This program is distributed in the hope that it will be useful, but WITHOUT
14  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15  FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License along with
18  this program; if not, write to the Free Software Foundation, Inc., 59 Temple
19  Place, Suite 330, Boston, MA 02111-1307 USA.
20 
21  Turku PET Centre hereby disclaims all copyright interest in the program.
22  Juhani Knuuti
23  Director, Professor
24  Turku PET Centre, Turku, Finland, http://www.turkupetcentre.fi/
25 
26  Modification history:
27  2009-02-17 Vesa Oikonen
28  First created.
29  2009-02-25 VO
30  SIF information extraction is removed from imgMicropetToEcat7().
31  New functions imgMicropetPETToEcat7() and imgMicropetCTToEcat7().
32  2009-09-28 VO
33  If transaxial_bin_size is defined, it is used as pixel z size
34  instead of pixel_size_z in imgGetMicropetMainHeader()
35  as requested by M Bucci.
36  2011-01-11 VO
37  Fixed bugs in reading headers and in branching fraction correction.
38  2011-08-12 VO
39  Added more test prints.
40  Works with header version 001.701, in addition to 001.830.
41  Reads also version 001.717 but z pixel size is set to zero.
42  2011-09-13 VO
43  Frame times are read as floats instead of ints.
44 
45 
46 ******************************************************************************/
47 #include <stdio.h>
48 #include <string.h>
49 #include <math.h>
50 #include <stdlib.h>
51 #include <time.h>
52 #include <unistd.h>
53 /*****************************************************************************/
54 #include "libtpcmisc.h"
55 /*****************************************************************************/
56 #include "include/imgio.h"
57 /*****************************************************************************/
58 
59 /*****************************************************************************/
68  FILE *fp,
70  char *parameter,
74  char *value
75 ) {
76  char *cptr, tmp[MAX_MICROPET_LINE_LEN];
77 
78  if(fp==NULL) return -1;
79  if(parameter==NULL || strlen(parameter)<1) return -2;
80  do {
81  if(fgets(tmp, MAX_MICROPET_LINE_LEN-1, fp)==NULL) return 1;
82  if(tmp[0]=='#') continue;
83  if(strncasecmp(tmp, parameter, strlen(parameter))!=0) continue;
84  /* Get parameter value, if one exists */
85  cptr=tmp+strlen(parameter)+1;
86  if(strlen(cptr)>0) {
87  if(value!=0) strcpy(value, cptr);
88  } else {
89  if(value!=0) strcpy(value, "");
90  }
91  /* In any case, we found the parameter */
92  if(MICROPET_TEST>9) printf("%s := %s\n", parameter, value);
93  return 0;
94  } while(1);
95  return 0;
96 }
97 /*****************************************************************************/
98 
99 /*****************************************************************************/
105  char *hdrfile
106 ) {
107  char tmp[MAX_MICROPET_LINE_LEN];
108  FILE *fp;
109  int ret;
110 
111  if(hdrfile==NULL || strlen(hdrfile)<5) return 0;
112  if(MICROPET_TEST>1) printf("\nupetIsHeader(%s)\n", hdrfile);
113  if((fp=fopen(hdrfile, "r"))==NULL) return 0;
114  /* Check that first line starts with '#' */
115  if(fgets(tmp, MAX_MICROPET_LINE_LEN-1, fp)==NULL) {fclose(fp); return 0;}
116  if(tmp[0]!='#') {fclose(fp); return 0;}
117  /* Check that certain header parameters do exist */
118  ret=upetHeaderReadParameter(fp, "version", tmp);
119  if(ret!=0) {fclose(fp); return 0;}
120  ret=upetHeaderReadParameter(fp, "model", tmp);
121  if(ret!=0) {fclose(fp); return 0;}
122  ret=upetHeaderReadParameter(fp, "institution", tmp);
123  if(ret!=0) {fclose(fp); return 0;}
124  fclose(fp);
125  return 1;
126 }
127 /*****************************************************************************/
128 
129 /*****************************************************************************/
136  char *upetname,
140  char *hdrfile,
144  char *imgfile
145 ) {
146  char *cptr, basefile[FILENAME_MAX], temp[FILENAME_MAX];
147 
148  if(upetname==NULL || strlen(upetname)==0) return(0);
149  if(MICROPET_TEST>1) printf("\nupetExists(%s, *str, *str)\n", upetname);
150 
151  /* Construct the base file name wo extensions */
152  strcpy(basefile, upetname);
153  cptr=strrchr(basefile, '.');
154  if(cptr!=NULL) {
155  if(strncasecmp(cptr, ".HDR", 4)==0 || strncasecmp(cptr, ".IMG", 4)==0 )
156  *cptr=(char)0;
157  }
158  cptr=strrchr(basefile, '.');
159  if(cptr!=NULL) {
160  if(strncasecmp(cptr, ".IMG", 4)==0 )
161  *cptr=(char)0;
162  }
163  if(MICROPET_TEST>2) printf("\n basefile := %s\n", basefile);
164 
165  /* Header file exists? */
166  strcpy(temp, basefile); strcat(temp, ".hdr");
167  if(access(temp, 0) == -1) {
168  strcpy(temp, basefile); strcat(temp, ".img.hdr");
169  if(access(temp, 0) == -1) {
170  if(MICROPET_TEST) printf("\n hdr file not found or accessible.\n");
171  return(0);
172  }
173  }
174  /* Is this microPET header file? */
175  if(upetIsHeader(temp)==0) {
176  if(MICROPET_TEST)
177  printf("\n %s was not identified as microPET header file.\n", temp);
178  return(0);
179  }
180  /* Preserve header filename */
181  if(hdrfile!=NULL) strcpy(hdrfile, temp);
182 
183  /* Image file exists? */
184  strcpy(temp, basefile); strcat(temp, ".img");
185  if(access(temp, 0) == -1) {
186  if(MICROPET_TEST) printf("\n %s not found or accessible.\n", temp);
187  return(0);
188  }
189  /* Preserve image filename */
190  if(imgfile!=NULL) strcpy(imgfile, temp);
191 
192  return 1;
193 }
194 /*****************************************************************************/
195 
196 /*****************************************************************************/
201  FILE *fp,
203  int *z,
205  int *x,
207  int *y,
209  int *f
210 ) {
211  char tmp[MAX_MICROPET_LINE_LEN];
212 
213  if(fp==NULL) return 1;
214  *z=*x=*y=0; if(f!=NULL) *f=0;
215  rewind(fp);
216 
217  if(f!=NULL) {
218  if(upetHeaderReadParameter(fp, "total_frames", tmp)!=0) return 11;
219  *f=-1; (void)sscanf(tmp, "%d", f);
220  }
221  if(upetHeaderReadParameter(fp, "x_dimension", tmp)!=0) return 12;
222  *x=-1; (void)sscanf(tmp, "%d", x);
223  if(upetHeaderReadParameter(fp, "y_dimension", tmp)!=0) return 13;
224  *y=-1; (void)sscanf(tmp, "%d", y);
225  if(upetHeaderReadParameter(fp, "z_dimension", tmp)!=0) return 14;
226  *z=-1; (void)sscanf(tmp, "%d", z);
227  if(*z<1 || *x<1 || *y<1) return 2;
228  if(f!=NULL && *f<1) return 2;
229  return 0;
230 }
231 /*****************************************************************************/
232 
233 /*****************************************************************************/
239  FILE *fp,
241  time_t *scant
242 ) {
243  char tmp[MAX_MICROPET_LINE_LEN], tmp2[64], tmp3[64];
244  int n, i;
245  struct tm scanstart={0};
246 
247  if(fp==NULL || scant==NULL) return 1;
248 
249  rewind(fp);
250  if(upetHeaderReadParameter(fp, "scan_time", tmp)!=0) return 2;
251  n=sscanf(tmp, "%s %s %d %d:%d:%d %d", tmp2, tmp3, &scanstart.tm_mday,
252  &scanstart.tm_hour, &scanstart.tm_min, &scanstart.tm_sec, &i);
253  if(n==7) {
254  scanstart.tm_year=i-1900;
255  if(strcasecmp(tmp3, "Jan")==0) scanstart.tm_mon=0;
256  else if(strcasecmp(tmp3, "Feb")==0) scanstart.tm_mon=1;
257  else if(strcasecmp(tmp3, "Mar")==0) scanstart.tm_mon=2;
258  else if(strcasecmp(tmp3, "Apr")==0) scanstart.tm_mon=3;
259  else if(strcasecmp(tmp3, "May")==0) scanstart.tm_mon=4;
260  else if(strcasecmp(tmp3, "Jun")==0) scanstart.tm_mon=5;
261  else if(strcasecmp(tmp3, "Jul")==0) scanstart.tm_mon=6;
262  else if(strcasecmp(tmp3, "Aug")==0) scanstart.tm_mon=7;
263  else if(strcasecmp(tmp3, "Sep")==0) scanstart.tm_mon=8;
264  else if(strcasecmp(tmp3, "Oct")==0) scanstart.tm_mon=9;
265  else if(strcasecmp(tmp3, "Nov")==0) scanstart.tm_mon=10;
266  else if(strcasecmp(tmp3, "Dec")==0) scanstart.tm_mon=11;
267  scanstart.tm_isdst=-1;
268  *scant=mktime(&scanstart); if(*scant<0) return 4;
269  } else return 5;
270 
271  return 0;
272 }
273 /*****************************************************************************/
274 
275 /*****************************************************************************/
282  char *upetname,
284  char *ecatfile,
286  int verbose
287 ) {
288  char upetheader[FILENAME_MAX], upetimage[FILENAME_MAX];
289  int n, ret;
290  int acquisition_mode, data_type;
291  FILE *fph, *fpi;
292  char tmp[MAX_MICROPET_LINE_LEN];
293 
294 
295  if(MICROPET_TEST) printf("\nimgMicropetToEcat7(%s, %s, %d)\n",
296  upetname, ecatfile, verbose);
297  /* Check the arguments */
298  if(upetname==NULL || ecatfile==NULL) return STATUS_FAULT;
299  ret=upetExists(upetname, upetheader, upetimage);
300  if(ret!=1) return STATUS_NOFILE;
301 
302  /*
303  * Open Micropet Header and binary data files
304  */
305  if((fph=fopen(upetheader, "r"))==NULL) return(STATUS_NOHEADERFILE);
306  if((fpi=fopen(upetimage, "rb"))==NULL) {fclose(fph); return(STATUS_NOIMGDATA);}
307 
308 
309  /*
310  * Check that image format is (currently) supported
311  */
312  rewind(fph);
313  if(MICROPET_TEST>1) printf("checking that image format is supported\n");
314  n=-1; if(upetHeaderReadParameter(fph, "file_type", tmp)==0)
315  (void)sscanf(tmp, "%d", &n);
316  if(MICROPET_TEST>2) printf("file_type := %d\n", n);
317  if(n!=5) {fclose(fph); fclose(fpi); return(STATUS_UNSUPPORTED);}
318  acquisition_mode=-1;
319  if(upetHeaderReadParameter(fph, "acquisition_mode", tmp)==0)
320  (void)sscanf(tmp, "%d", &acquisition_mode);
321  if(MICROPET_TEST>2) printf("acquisition_mode := %d\n", acquisition_mode);
322  if(acquisition_mode!=2 && acquisition_mode!=3 && acquisition_mode!=9) {
323  fclose(fph); fclose(fpi); return(STATUS_UNSUPPORTED);}
324  data_type=-1;
325  if(upetHeaderReadParameter(fph, "data_type", tmp)==0)
326  (void)sscanf(tmp, "%d", &data_type);
327  if(MICROPET_TEST>2) printf("data_type := %d\n", data_type);
328  if(data_type!=4 && data_type!=2) {
329  fclose(fph); fclose(fpi); return(STATUS_UNSUPPORTED);}
330 
331  /*
332  * Convert PET or CT image
333  */
334  if(acquisition_mode==2 || acquisition_mode==3)
335  ret=imgMicropetPETToEcat7(fph, fpi, ecatfile, verbose);
336  else if(acquisition_mode==9)
337  ret=imgMicropetCTToEcat7(fph, fpi, ecatfile, verbose);
338  else
339  return(STATUS_UNSUPPORTED);
340  fclose(fph); fclose(fpi);
341  return ret;
342 }
343 /*****************************************************************************/
344 
345 /*****************************************************************************/
353  FILE *fph,
355  FILE *fpi,
357  char *ecatfile,
359  int verbose
360 ) {
361  IMG img;
362  int n, pxlnr, zi, xi, yi, ti, zdim, xdim, ydim, tdim, ret;
363  float *fptr, calibration_factor;
364  char *mdata, *mptr;
365 
366 
367  if(MICROPET_TEST>1) printf("imgMicropetPETToEcat7(*fph, *fpi, %s, %d)\n",
368  ecatfile, verbose);
369  /* Check input */
370  if(fph==NULL || fpi==NULL || ecatfile==NULL) return STATUS_FAULT;
371 
372  /* Remove existing ECAT file */
373  if(access(ecatfile, 0)!=-1 && remove(ecatfile)!=0) {
374  return(STATUS_CANNOTERASE);
375  }
376 
377  /*
378  * Read image dimensions from header
379  */
380  ret=upetGetImageDimensions(fph, &zdim, &xdim, &ydim, &tdim);
381  if(ret) {return(STATUS_INVALIDHEADER);}
382  if(MICROPET_TEST>1) {
383  printf("z_dim := %d\n", zdim);
384  printf("x_dim := %d\n", xdim);
385  printf("y_dim := %d\n", ydim);
386  printf("t_dim := %d\n", tdim);
387  }
388 
389  /*
390  * Read and write image frame-by-frame
391  */
392  imgInit(&img);
393  /* Allocate memory for one frame */
394  ret=imgAllocate(&img, zdim, ydim, xdim, 1);
395  if(ret) {return(STATUS_NOMEMORY);}
396  /* Fill header with what we now can */
397  ret=imgGetMicropetMainHeader(fph, &img, &calibration_factor);
398  if(ret) {
399  if(MICROPET_TEST) printf("ret := %d\n", ret);
400  imgEmpty(&img); return(STATUS_INVALIDHEADER);
401  }
402  if(MICROPET_TEST) printf("calibration_factor := %g\n", calibration_factor);
403  img._fileFormat=IMG_E7;
404  img.type=IMG_TYPE_IMAGE;
405  studynr_from_fname(ecatfile, img.studyNr);
406  upetScanStart(fph, &img.scanStart);
407  /* Allocate memory for the binary data */
408  pxlnr=xdim*ydim*zdim;
409  mdata=(char*)malloc(pxlnr*sizeof(float)); if(mdata==NULL) {
410  imgEmpty(&img); return(STATUS_NOMEMORY);
411  }
412  /* Frame-by-frame */
413  for(ti=0; ti<tdim; ti++) {
414  if(MICROPET_TEST>3) {printf("ti=%d\n", ti); fflush(stdout);}
415  /* Read frame information from MicroPET header into IMG */
416  ret=imgGetMicropetFrameHeader(fph, &img, ti);
417  if(ret) {
418  if(verbose==0) {fprintf(stdout, "\n"); fflush(stdout);}
419  free(mdata); imgEmpty(&img);
420  return(STATUS_INVALIDHEADER);
421  }
422  /* Read floats */
423  mptr=mdata;
424  if((n=fread(mptr, 4, pxlnr, fpi)) < pxlnr) {
425  if(verbose==0) {fprintf(stdout, "\n"); fflush(stdout);}
426  free(mdata); imgEmpty(&img);
427  return(STATUS_NOMATRIX);
428  }
429  /* Copy floats to IMG */
430  mptr=mdata;
431  for(zi=0; zi<zdim; zi++)
432  for(yi=0; yi<ydim; yi++)
433  for(xi=0; xi<xdim; xi++) {
434  fptr=(float*)mptr;
435  img.m[zi][yi][xi][0]=(*fptr)*img.weight[0]*calibration_factor;
436  mptr+=4;
437  }
438  /* Write frame */
439  ret=imgWriteFrame(ecatfile, ti+1, &img, 0); //printf("ret := %d\n", ret);
440  if(ret!=STATUS_OK) break;
441  if(MICROPET_TEST>1) printf(" frame written.\n");
442  else if(verbose==0) {fprintf(stdout, "."); fflush(stdout);}
443  };
444  free(mdata); imgEmpty(&img);
445  if(verbose==0) {fprintf(stdout, "\n"); fflush(stdout);}
446  if(verbose==0 && ret==STATUS_NOMATRIX) {
447  fprintf(stdout, " %d frame(s) processed.\n", ti);
448  }
449  if(ret!=STATUS_OK && ret!=STATUS_NOMATRIX) {
450  remove(ecatfile); return ret;
451  }
452 
453  return STATUS_OK;
454 }
455 /*****************************************************************************/
456 
457 /*****************************************************************************/
464  FILE *fph,
466  FILE *fpi,
468  char *ecatfile,
470  int verbose
471 ) {
472  IMG img;
473  int n, pxlnr, zi, xi, yi, zdim, xdim, ydim, ret;
474  float f, scale_factor;
475  char *mdata, *mptr;
476  char tmp[MAX_MICROPET_LINE_LEN];
477  short int *si;
478 
479 
480  if(MICROPET_TEST>1) printf("imgMicropetCTToEcat7(*fph, *fpi, %s, %d)\n",
481  ecatfile, verbose);
482  /* Check input */
483  if(fph==NULL || fpi==NULL || ecatfile==NULL) return STATUS_FAULT;
484 
485  /*
486  * Read image dimensions from header
487  */
488  ret=upetGetImageDimensions(fph, &zdim, &xdim, &ydim, NULL);
489  if(ret) {return(STATUS_INVALIDHEADER);}
490  if(MICROPET_TEST>1) {
491  printf("z_dim := %d\n", zdim);
492  printf("x_dim := %d\n", xdim);
493  printf("y_dim := %d\n", ydim);
494  }
495 
496  /* Read scale factor */
497  rewind(fph);
498  if(upetHeaderReadParameter(fph, "scale_factor", tmp)!=0) {
499  return(STATUS_INVALIDHEADER);}
500  scale_factor=-1; (void)sscanf(tmp, "%f", &scale_factor);
501  if(scale_factor<=0) return(STATUS_INVALIDHEADER);
502  if(MICROPET_TEST>1) {
503  printf("scale_factor := %g\n", scale_factor);
504  }
505 
506  /* Remove existing ECAT file */
507  if(access(ecatfile, 0)!=-1 && remove(ecatfile)!=0) {
508  return(STATUS_CANNOTERASE);
509  }
510 
511  /*
512  * Read and write image
513  */
514  imgInit(&img);
515  /* Allocate memory for one frame */
516  ret=imgAllocate(&img, zdim, ydim, xdim, 1);
517  if(ret) {return(STATUS_NOMEMORY);}
518  /* Fill header with what we now can */
519  ret=imgGetMicropetMainHeader(fph, &img, NULL);
520  if(ret) {
521  if(MICROPET_TEST) printf("ret := %d\n", ret);
522  imgEmpty(&img); return(STATUS_INVALIDHEADER);
523  }
524  img._fileFormat=IMG_E7;
525  img.type=IMG_TYPE_IMAGE;
526  studynr_from_fname(ecatfile, img.studyNr);
527  upetScanStart(fph, &img.scanStart);
528  /* Allocate memory for the binary data */
529  pxlnr=xdim*ydim;
530  mdata=(char*)malloc(pxlnr*sizeof(short int)); if(mdata==NULL) {
531  imgEmpty(&img); return(STATUS_NOMEMORY);
532  }
533  /* Read image data, plane-by-plane */
534  for(zi=0; zi<zdim; zi++) {
535  mptr=mdata;
536  if((n=fread(mptr, 2, pxlnr, fpi)) < pxlnr) {
537  if(verbose==0) {fprintf(stdout, "\n"); fflush(stdout);}
538  free(mdata); imgEmpty(&img);
539  return(STATUS_NOMATRIX);
540  }
541  /* Copy short ints to IMG */
542  mptr=mdata;
543  for(yi=0; yi<ydim; yi++)
544  for(xi=0; xi<xdim; xi++) {
545  si=(short int*)mptr;
546  f=(float)*si*scale_factor;
547  if(f>=0.0) img.m[zi][yi][xi][0]=f; else img.m[zi][yi][xi][0]=0.0;
548  mptr+=2;
549  }
550  if(MICROPET_TEST>1) printf(" plane %d\n", zi+1);
551  else if(verbose==0) {fprintf(stdout, "."); fflush(stdout);}
552  }
553  free(mdata);
554  if(verbose==0) {fprintf(stdout, "\n"); fflush(stdout);}
555  /* Save ECAT 7 image volume */
556  ret=imgWrite(ecatfile, &img);
557  if(ret!=0) {imgEmpty(&img); return(STATUS_CANNOTWRITE);}
558 
559  imgEmpty(&img);
560  return STATUS_OK;
561 }
562 /*****************************************************************************/
563 
564 /*****************************************************************************/
569  FILE *fp,
571  IMG *img,
573  float *calibration_factor
574 ) {
575  char tmp[MAX_MICROPET_LINE_LEN];
576  int n;
577  float f, branching_fraction=1.0;
578 
579 
580  if(MICROPET_TEST>1) printf("imgGetMicropetMainHeader(*fp, *img, *f)\n");
581  if(fp==NULL) return 1;
582  if(img==NULL) return 2;
583 
584  /* scanner model */
585  rewind(fp);
586  if(MICROPET_TEST>9) printf(" reading 'model'\n");
587  if(upetHeaderReadParameter(fp, "model", tmp)!=0) return 11;
588  n=-1; (void)sscanf(tmp, "%d", &n); if(n<0) return 11;
589  img->scanner=n;
590 
591  /* zoom */
592  rewind(fp);
593  if(MICROPET_TEST>9) printf(" reading 'zoom'\n");
594  if(upetHeaderReadParameter(fp, "zoom", tmp)!=0) return 11;
595  f=-1; (void)sscanf(tmp, "%f", &f); if(f<0) return 11;
596  img->zoom=f;
597 
598 
599  /* pixel size x */
600  rewind(fp);
601  if(MICROPET_TEST>9) printf(" reading 'pixel_size_x'\n");
602  if(upetHeaderReadParameter(fp, "pixel_size_x", tmp)==0) {
603  f=-1; (void)sscanf(tmp, "%f", &f); if(f<0) return 12;
604  } else {
605  rewind(fp);
606  if(MICROPET_TEST>9) printf(" reading 'pixel_size'\n");
607  if(upetHeaderReadParameter(fp, "pixel_size", tmp)!=0) return 12;
608  f=-1; (void)sscanf(tmp, "%f", &f); if(f<0) return 12;
609  f*=10.;
610  }
611  img->sizex=f;
612 
613  /* pixel size y */
614  rewind(fp);
615  if(MICROPET_TEST>9) printf(" reading 'pixel_size_y'\n");
616  if(upetHeaderReadParameter(fp, "pixel_size_y", tmp)==0) {
617  f=-1; (void)sscanf(tmp, "%f", &f); if(f<0) return 13;
618  } else {
619  rewind(fp);
620  if(MICROPET_TEST>9) printf(" reading 'pixel_size'\n");
621  if(upetHeaderReadParameter(fp, "pixel_size", tmp)!=0) return 13;
622  f=-1; (void)sscanf(tmp, "%f", &f); if(f<0) return 12;
623  f*=10.;
624  }
625  img->sizey=f;
626 
627  /* pixel size z; note that this is replaced below by transaxial_bin_size */
628  rewind(fp);
629  if(MICROPET_TEST>9) printf(" reading 'pixel_size_z'\n");
630  if(upetHeaderReadParameter(fp, "pixel_size_z", tmp)==0) {
631  f=-1; (void)sscanf(tmp, "%f", &f); if(f<0) return 14;
632  } else {
633  rewind(fp);
634  if(MICROPET_TEST>9) printf(" reading 'axial_plane_size'\n");
635  if(upetHeaderReadParameter(fp, "axial_plane_size", tmp)!=0) {
636  if(MICROPET_TEST) printf(" cannot find z pixel size\n");
637  f=0.0;
638  } else {
639  f=-1; (void)sscanf(tmp, "%f", &f); if(f<0) return 14;
640  f*=10.;
641  }
642  }
643  img->sizez=f;
644 
645  /* transaxial_bin_size */
646  rewind(fp);
647  if(MICROPET_TEST>9) printf(" reading 'transaxial_bin_size'\n");
648  if(upetHeaderReadParameter(fp, "transaxial_bin_size", tmp)==0) {
649  f=-1; (void)sscanf(tmp, "%f", &f); if(f>0) img->sizez=10.0*f;
650  }
651 
652  /* isotope halflife */
653  rewind(fp);
654  if(MICROPET_TEST>9) printf(" reading 'isotope_half_life'\n");
655  if(upetHeaderReadParameter(fp, "isotope_half_life", tmp)==0) {
656  f=-1; (void)sscanf(tmp, "%f", &f); if(f<0) return 15;
657  img->isotopeHalflife=f;
658  }
659 
660  /* branching_fraction */
661  rewind(fp);
662  if(MICROPET_TEST>9) printf(" reading 'isotope_branching_fraction'\n");
663  if(upetHeaderReadParameter(fp, "isotope_branching_fraction", tmp)==0) {
664  f=-1; (void)sscanf(tmp, "%f", &f); if(f<0) return 16;
665  branching_fraction=f;
666  }
667 
668  /* decay correction applied */
669  rewind(fp);
670  if(MICROPET_TEST>9) printf(" reading 'decay_correction_applied'\n");
671  if(upetHeaderReadParameter(fp, "decay_correction_applied", tmp)==0) {
672  n=-1; (void)sscanf(tmp, "%d", &n); if(n<0) return 17;
673  img->decayCorrected=n;
674  }
675 
676  /* calibration units */
677  rewind(fp);
678  if(MICROPET_TEST>9) printf(" reading 'calibration_units'\n");
679  if(upetHeaderReadParameter(fp, "calibration_units", tmp)==0) {
680  n=-1; (void)sscanf(tmp, "%d", &n); if(n<0) return 18;
681  switch(n) {
682  case 1: img->unit=IMGUNIT_NCI_PER_ML; break;
683  case 2: img->unit=IMGUNIT_BQ_PER_ML; break;
684  case 0:
685  default: img->unit=IMGUNIT_UNKNOWN; break;
686  }
687  }
688 
689  /* calibration factor */
690  rewind(fp);
691  if(MICROPET_TEST>9) printf(" reading 'calibration_factor'\n");
692  if(calibration_factor!=NULL &&
693  upetHeaderReadParameter(fp, "calibration_factor", tmp)==0)
694  {
695  f=-1; (void)sscanf(tmp, "%f", &f); if(f<=0.0) return 19;
696  *calibration_factor=f;
697  if(branching_fraction>0.0) *calibration_factor/=branching_fraction;
698  }
699 
700  /* FOV */
701  rewind(fp);
702  if(MICROPET_TEST>9) printf(" reading 'radial_fov'\n");
703  if(upetHeaderReadParameter(fp, "radial_fov", tmp)==0) {
704  f=-1; (void)sscanf(tmp, "%f", &f); if(f<0) return 20;
705  img->transaxialFOV=10.0*f;
706  }
707 
708  return 0;
709 }
710 /*****************************************************************************/
711 
712 /*****************************************************************************/
717  /* File pointer to Concorde/MicroPET header */
718  FILE *fp,
719  /* Pointer to IMG struct, allocated for one frame; frame information is
720  written in frame 0. */
721  IMG *img,
722  /* Frame index [0..tdim-1] */
723  int frame_index
724 ) {
725  char tmp[MAX_MICROPET_LINE_LEN];
726  float f;
727 
728 
729  if(fp==NULL) return 1;
730  if(img==NULL) return 2;
731  if(frame_index<0) return 3;
732 
733  /* Search required frame from the beginning of header file */
734  rewind(fp);
735 
736  /* Find correct frame index */
737  sprintf(tmp, "frame %d", frame_index);
738  if(upetHeaderReadParameter(fp, tmp, tmp)!=0) return 5;
739 
740  /* frame start time */
741  if(upetHeaderReadParameter(fp, "frame_start", tmp)!=0) return 11;
742  f=-1.0; (void)sscanf(tmp, "%f", &f); if(f<0.0) return 11;
743  img->start[0]=f;
744 
745  /* frame duration */
746  if(upetHeaderReadParameter(fp, "frame_duration", tmp)!=0) return 12;
747  f=-1.0; (void)sscanf(tmp, "%f", &f); if(f<=0.0) return 12;
748  img->end[0]=img->start[0]+f;
749  img->mid[0]=0.5*(img->end[0]+img->start[0]);
750 
751  /* scale factor (written in 'weight' since there is no better place) */
752  if(upetHeaderReadParameter(fp, "scale_factor", tmp)!=0) return 13;
753  f=-1; (void)sscanf(tmp, "%f", &f); if(f<0) return 13;
754  img->weight[0]=f;
755 
756  /* decay correction */
757  if(upetHeaderReadParameter(fp, "decay_correction", tmp)!=0) return 14;
758  f=-1; (void)sscanf(tmp, "%f", &f); if(f<0) return 14;
759  img->decayCorrFactor[0]=f;
760 
761  return 0;
762 }
763 /*****************************************************************************/
764 
765 /*****************************************************************************/
771  FILE *fp,
774  SIF *sif
775 ) {
776  char tmp[MAX_MICROPET_LINE_LEN], tmp2[64], tmp3[64];
777  int n, i, ret;
778 
779 
780  if(fp==NULL) return 1;
781  if(sif==NULL) return 2;
782 
783 
784  /* Get frame number */
785  rewind(fp);
786  if(upetHeaderReadParameter(fp, "total_frames", tmp)!=0) return 11;
787  n=-1; (void)sscanf(tmp, "%d", &n); if(n<1) return 11;
788 
789  /* Allocate memory for SIF */
790  ret=sifSetmem(sif, n); if(ret!=0) return 4;
791  sif->frameNr=n;
792  sif->colNr=4;
793  sif->version=1;
794 
795  /* Scan time */
796  upetScanStart(fp, &sif->scantime);
797 
798  /* Isotope */
799  rewind(fp);
800  if(upetHeaderReadParameter(fp, "isotope", tmp)!=0) return 13;
801  strncpy(sif->isotope_name, tmp, 8);
802 
803  /* Frames */
804  for(i=0; i<sif->frameNr; i++) {
805  /* Find correct frame index */
806  sprintf(tmp, "frame %d", i);
807  if(upetHeaderReadParameter(fp, tmp, tmp)!=0) return 21;
808  /* frame start time */
809  if(upetHeaderReadParameter(fp, "frame_start", tmp)!=0) return 22;
810  n=-1; (void)sscanf(tmp, "%d", &n); if(n<0) return 22;
811  sif->x1[i]=n;
812  /* frame duration */
813  if(upetHeaderReadParameter(fp, "frame_duration", tmp)!=0) return 23;
814  n=-1; (void)sscanf(tmp, "%d", &n); if(n<0) return 23;
815  sif->x2[i]=sif->x1[i]+n;
816  /* prompts */
817  if(upetHeaderReadParameter(fp, "prompts", tmp)!=0) return 24;
818  n=-1; (void)sscanf(tmp, "%s %s %d", tmp2, tmp3, &n); if(n<0) return 24;
819  sif->prompts[i]=n;
820  /* delays */
821  if(upetHeaderReadParameter(fp, "delays", tmp)!=0) return 25;
822  n=-1; (void)sscanf(tmp, "%s %s %d", tmp2, tmp3, &n); if(n<0) return 25;
823  sif->randoms[i]=n;
824  /* trues */
825  sif->trues[i]=sif->prompts[i]-sif->randoms[i];
826  }
827  return 0;
828 }
829 /*****************************************************************************/
830 
831 /*****************************************************************************/
int imgWrite(const char *fname, IMG *img)
Definition: imgfile.c:277
float transaxialFOV
Definition: img.h:204
time_t scantime
Definition: sif.h:38
int upetScanStart(FILE *fp, time_t *scant)
Definition: micropet.c:237
int imgAllocate(IMG *image, int planes, int rows, int columns, int frames)
Definition: img.c:285
void imgEmpty(IMG *image)
Definition: img.c:216
Definition: img.h:156
float sizey
Definition: img.h:210
float * end
Definition: img.h:292
int colNr
Definition: sif.h:42
int imgGetMicropetFrameHeader(FILE *fp, IMG *img, int frame_index)
Definition: micropet.c:716
int imgGetMicropetSIF(FILE *fp, SIF *sif)
Definition: micropet.c:769
float * mid
Definition: img.h:294
int frameNr
Definition: sif.h:40
int upetHeaderReadParameter(FILE *fp, char *parameter, char *value)
Definition: micropet.c:64
float **** m
Definition: img.h:274
double * prompts
Definition: sif.h:54
int sifSetmem(SIF *data, int frameNr)
Definition: sif.c:95
float sizez
Definition: img.h:212
Definition: img.h:118
int imgWriteFrame(const char *fname, int frame_to_write, IMG *img, int frame_index)
Definition: imgfile.c:493
int upetIsHeader(char *hdrfile)
Definition: micropet.c:103
double * randoms
Definition: sif.h:56
int scanner
Definition: img.h:231
int upetGetImageDimensions(FILE *fp, int *z, int *x, int *y, int *f)
Definition: micropet.c:199
float * decayCorrFactor
Definition: img.h:314
float * weight
Definition: img.h:302
Definition: sif.h:36
double * x2
Definition: sif.h:52
#define IMG_E7
Definition: img.h:86
int version
Definition: sif.h:44
int upetExists(char *upetname, char *hdrfile, char *imgfile)
Definition: micropet.c:133
float isotopeHalflife
Definition: img.h:182
double * trues
Definition: sif.h:58
void imgInit(IMG *image)
Definition: img.c:163
#define IMG_TYPE_IMAGE
Definition: img.h:80
int _fileFormat
Definition: img.h:229
int MICROPET_TEST
Definition: micropet.h:20
#define MAX_MICROPET_LINE_LEN
Definition: micropet.h:17
int imgMicropetPETToEcat7(FILE *fph, FILE *fpi, char *ecatfile, int verbose)
Definition: micropet.c:351
float sizex
Definition: img.h:208
char studyNr[MAX_STUDYNR_LEN+1]
Definition: img.h:174
char decayCorrected
Definition: img.h:184
double * x1
Definition: sif.h:50
int imgMicropetToEcat7(char *upetname, char *ecatfile, int verbose)
Definition: micropet.c:280
int imgGetMicropetMainHeader(FILE *fp, IMG *img, float *calibration_factor)
Definition: micropet.c:567
time_t scanStart
Definition: img.h:186
char isotope_name[8]
Definition: sif.h:48
float * start
Definition: img.h:290
char type
Definition: img.h:198
char unit
Definition: img.h:172
int imgMicropetCTToEcat7(FILE *fph, FILE *fpi, char *ecatfile, int verbose)
Definition: micropet.c:462
float zoom
Definition: img.h:200