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 
39 
40 ******************************************************************************/
41 #include <stdio.h>
42 #include <string.h>
43 #include <math.h>
44 #include <stdlib.h>
45 #include <time.h>
46 #include <unistd.h>
47 /*****************************************************************************/
48 #include "libtpcmisc.h"
49 /*****************************************************************************/
50 #include "include/imgio.h"
51 /*****************************************************************************/
52 
53 /*****************************************************************************/
62  FILE *fp,
64  char *parameter,
68  char *value
69 ) {
70  char *cptr, tmp[MAX_MICROPET_LINE_LEN];
71 
72  if(fp==NULL) return -1;
73  if(parameter==NULL || strlen(parameter)<1) return -2;
74  do {
75  if(fgets(tmp, MAX_MICROPET_LINE_LEN-1, fp)==NULL) return 1;
76  if(tmp[0]=='#') continue;
77  if(strncasecmp(tmp, parameter, strlen(parameter))!=0) continue;
78  /* Get parameter value, if one exists */
79  cptr=tmp+strlen(parameter)+1;
80  if(strlen(cptr)>0) {
81  if(value!=0) strcpy(value, cptr);
82  } else {
83  if(value!=0) strcpy(value, "");
84  }
85  /* In any case, we found the parameter */
86  if(MICROPET_TEST>9) printf("%s := %s\n", parameter, value);
87  return 0;
88  } while(1);
89  return 0;
90 }
91 /*****************************************************************************/
92 
93 /*****************************************************************************/
99  char *hdrfile
100 ) {
101  char tmp[MAX_MICROPET_LINE_LEN];
102  FILE *fp;
103  int ret;
104 
105  if(hdrfile==NULL || strlen(hdrfile)<5) return 0;
106  if((fp=fopen(hdrfile, "r"))==NULL) return 0;
107  /* Check that first line starts with '#' */
108  if(fgets(tmp, MAX_MICROPET_LINE_LEN-1, fp)==NULL) {fclose(fp); return 0;}
109  if(tmp[0]!='#') {fclose(fp); return 0;}
110  /* Check that certain header parameters do exist */
111  ret=upetHeaderReadParameter(fp, "version", tmp);
112  if(ret!=0) {fclose(fp); return 0;}
113  ret=upetHeaderReadParameter(fp, "model", tmp);
114  if(ret!=0) {fclose(fp); return 0;}
115  ret=upetHeaderReadParameter(fp, "modality", tmp);
116  if(ret!=0) {fclose(fp); return 0;}
117  fclose(fp);
118  return 1;
119 }
120 /*****************************************************************************/
121 
122 /*****************************************************************************/
129  char *upetname,
133  char *hdrfile,
137  char *imgfile
138 ) {
139  char *cptr, basefile[FILENAME_MAX], temp[FILENAME_MAX];
140 
141  if(upetname==NULL || strlen(upetname)==0) return(0);
142 
143  /* Construct the base file name wo extensions */
144  strcpy(basefile, upetname);
145  cptr=strrchr(basefile, '.');
146  if(cptr!=NULL) {
147  if(strncasecmp(cptr, ".HDR", 4)==0 || strncasecmp(cptr, ".IMG", 4)==0 )
148  *cptr=(char)0;
149  }
150  cptr=strrchr(basefile, '.');
151  if(cptr!=NULL) {
152  if(strncasecmp(cptr, ".IMG", 4)==0 )
153  *cptr=(char)0;
154  }
155 
156  /* Header file exists? */
157  strcpy(temp, basefile); strcat(temp, ".hdr");
158  if(access(temp, 0) == -1) {
159  strcpy(temp, basefile); strcat(temp, ".img.hdr");
160  if(access(temp, 0) == -1) return(0);
161  }
162  /* Is this microPET header file? */
163  if(upetIsHeader(temp)==0) return(0);
164  /* Preserve header filename */
165  if(hdrfile!=NULL) strcpy(hdrfile, temp);
166 
167  /* Image file exists? */
168  strcpy(temp, basefile); strcat(temp, ".img");
169  if(access(temp, 0) == -1) return(0);
170  /* Preserve image filename */
171  if(imgfile!=NULL) strcpy(imgfile, temp);
172 
173  return 1;
174 }
175 /*****************************************************************************/
176 
177 /*****************************************************************************/
182  FILE *fp,
184  int *z,
186  int *x,
188  int *y,
190  int *f
191 ) {
192  char tmp[MAX_MICROPET_LINE_LEN];
193 
194  if(fp==NULL) return 1;
195  *z=*x=*y=0; if(f!=NULL) *f=0;
196  rewind(fp);
197 
198  if(f!=NULL) {
199  if(upetHeaderReadParameter(fp, "total_frames", tmp)!=0) return 11;
200  *f=-1; (void)sscanf(tmp, "%d", f);
201  }
202  if(upetHeaderReadParameter(fp, "x_dimension", tmp)!=0) return 12;
203  *x=-1; (void)sscanf(tmp, "%d", x);
204  if(upetHeaderReadParameter(fp, "y_dimension", tmp)!=0) return 13;
205  *y=-1; (void)sscanf(tmp, "%d", y);
206  if(upetHeaderReadParameter(fp, "z_dimension", tmp)!=0) return 14;
207  *z=-1; (void)sscanf(tmp, "%d", z);
208  if(*z<1 || *x<1 || *y<1) return 2;
209  if(f!=NULL && *f<1) return 2;
210  return 0;
211 }
212 /*****************************************************************************/
213 
214 /*****************************************************************************/
220  FILE *fp,
222  time_t *scant
223 ) {
224  char tmp[MAX_MICROPET_LINE_LEN], tmp2[64], tmp3[64];
225  int n, i;
226  struct tm scanstart={0};
227 
228  if(fp==NULL || scant==NULL) return 1;
229 
230  rewind(fp);
231  if(upetHeaderReadParameter(fp, "scan_time", tmp)!=0) return 2;
232  n=sscanf(tmp, "%s %s %d %d:%d:%d %d", tmp2, tmp3, &scanstart.tm_mday,
233  &scanstart.tm_hour, &scanstart.tm_min, &scanstart.tm_sec, &i);
234  if(n==7) {
235  scanstart.tm_year=i-1900;
236  if(strcasecmp(tmp3, "Jan")==0) scanstart.tm_mon=0;
237  else if(strcasecmp(tmp3, "Feb")==0) scanstart.tm_mon=1;
238  else if(strcasecmp(tmp3, "Mar")==0) scanstart.tm_mon=2;
239  else if(strcasecmp(tmp3, "Apr")==0) scanstart.tm_mon=3;
240  else if(strcasecmp(tmp3, "May")==0) scanstart.tm_mon=4;
241  else if(strcasecmp(tmp3, "Jun")==0) scanstart.tm_mon=5;
242  else if(strcasecmp(tmp3, "Jul")==0) scanstart.tm_mon=6;
243  else if(strcasecmp(tmp3, "Aug")==0) scanstart.tm_mon=7;
244  else if(strcasecmp(tmp3, "Sep")==0) scanstart.tm_mon=8;
245  else if(strcasecmp(tmp3, "Oct")==0) scanstart.tm_mon=9;
246  else if(strcasecmp(tmp3, "Nov")==0) scanstart.tm_mon=10;
247  else if(strcasecmp(tmp3, "Dec")==0) scanstart.tm_mon=11;
248  scanstart.tm_isdst=-1;
249  *scant=mktime(&scanstart); if(*scant<0) return 4;
250  } else return 5;
251 
252  return 0;
253 }
254 /*****************************************************************************/
255 
256 /*****************************************************************************/
263  char *upetname,
265  char *ecatfile,
267  int verbose
268 ) {
269  char upetheader[FILENAME_MAX], upetimage[FILENAME_MAX];
270  int n, ret;
271  int acquisition_mode, data_type;
272  FILE *fph, *fpi;
273  char tmp[MAX_MICROPET_LINE_LEN];
274 
275 
276  if(MICROPET_TEST) printf("\nimgMicropetToEcat7(%s, %s, %d)\n",
277  upetname, ecatfile, verbose);
278  /* Check the arguments */
279  if(upetname==NULL || ecatfile==NULL) return STATUS_FAULT;
280  ret=upetExists(upetname, upetheader, upetimage);
281  if(ret!=1) return STATUS_NOFILE;
282 
283  /*
284  * Open Micropet Header and binary data files
285  */
286  if((fph=fopen(upetheader, "r"))==NULL) return(STATUS_NOHEADERFILE);
287  if((fpi=fopen(upetimage, "rb"))==NULL) {fclose(fph); return(STATUS_NOIMGDATA);}
288 
289 
290  /*
291  * Check that image format is (currently) supported
292  */
293  rewind(fph);
294  if(MICROPET_TEST>1) printf("checking that image format is supported\n");
295  n=-1; if(upetHeaderReadParameter(fph, "file_type", tmp)==0)
296  (void)sscanf(tmp, "%d", &n);
297  if(MICROPET_TEST>2) printf("file_type := %d\n", n);
298  if(n!=5) {fclose(fph); fclose(fpi); return(STATUS_UNSUPPORTED);}
299  acquisition_mode=-1;
300  if(upetHeaderReadParameter(fph, "acquisition_mode", tmp)==0)
301  (void)sscanf(tmp, "%d", &acquisition_mode);
302  if(MICROPET_TEST>2) printf("acquisition_mode := %d\n", acquisition_mode);
303  if(acquisition_mode!=2 && acquisition_mode!=3 && acquisition_mode!=9) {
304  fclose(fph); fclose(fpi); return(STATUS_UNSUPPORTED);}
305  data_type=-1;
306  if(upetHeaderReadParameter(fph, "data_type", tmp)==0)
307  (void)sscanf(tmp, "%d", &data_type);
308  if(MICROPET_TEST>2) printf("data_type := %d\n", data_type);
309  if(data_type!=4 && data_type!=2) {
310  fclose(fph); fclose(fpi); return(STATUS_UNSUPPORTED);}
311 
312  /*
313  * Convert PET or CT image
314  */
315  if(acquisition_mode==2 || acquisition_mode==3)
316  ret=imgMicropetPETToEcat7(fph, fpi, ecatfile, verbose);
317  else if(acquisition_mode==9)
318  ret=imgMicropetCTToEcat7(fph, fpi, ecatfile, verbose);
319  else
320  return(STATUS_UNSUPPORTED);
321  fclose(fph); fclose(fpi);
322  return ret;
323 }
324 /*****************************************************************************/
325 
326 /*****************************************************************************/
334  FILE *fph,
336  FILE *fpi,
338  char *ecatfile,
340  int verbose
341 ) {
342  IMG img;
343  int n, pxlnr, zi, xi, yi, ti, zdim, xdim, ydim, tdim, ret;
344  float *fptr, calibration_factor;
345  char *mdata, *mptr;
346 
347 
348  /* Check input */
349  if(fph==NULL || fpi==NULL || ecatfile==NULL) return STATUS_FAULT;
350 
351  /* Remove existing ECAT file */
352  if(access(ecatfile, 0)!=-1 && remove(ecatfile)!=0) {
353  return(STATUS_CANNOTERASE);
354  }
355 
356  /*
357  * Read image dimensions from header
358  */
359  ret=upetGetImageDimensions(fph, &zdim, &xdim, &ydim, &tdim);
360  if(ret) {return(STATUS_INVALIDHEADER);}
361  if(MICROPET_TEST>1) {
362  printf("z_dim := %d\n", zdim);
363  printf("x_dim := %d\n", xdim);
364  printf("y_dim := %d\n", ydim);
365  printf("t_dim := %d\n", tdim);
366  }
367 
368  /*
369  * Read and write image frame-by-frame
370  */
371  imgInit(&img);
372  /* Allocate memory for one frame */
373  ret=imgAllocate(&img, zdim, ydim, xdim, 1);
374  if(ret) {return(STATUS_NOMEMORY);}
375  /* Fill header with what we now can */
376  ret=imgGetMicropetMainHeader(fph, &img, &calibration_factor);
377  if(ret) {
378  if(MICROPET_TEST) printf("ret := %d\n", ret);
379  imgEmpty(&img); return(STATUS_INVALIDHEADER);
380  }
381  if(MICROPET_TEST) printf("calibration_factor := %g\n", calibration_factor);
382  img._fileFormat=IMG_E7;
383  img.type=IMG_TYPE_IMAGE;
384  studynr_from_fname(ecatfile, img.studyNr);
385  upetScanStart(fph, &img.scanStart);
386  /* Allocate memory for the binary data */
387  pxlnr=xdim*ydim*zdim;
388  mdata=(char*)malloc(pxlnr*sizeof(float)); if(mdata==NULL) {
389  imgEmpty(&img); return(STATUS_NOMEMORY);
390  }
391  /* Frame-by-frame */
392  for(ti=0; ti<tdim; ti++) {
393  if(MICROPET_TEST>3) {printf("ti=%d\n", ti); fflush(stdout);}
394  /* Read frame information from MicroPET header into IMG */
395  ret=imgGetMicropetFrameHeader(fph, &img, ti);
396  if(ret) {
397  if(verbose==0) {fprintf(stdout, "\n"); fflush(stdout);}
398  free(mdata); imgEmpty(&img);
399  return(STATUS_INVALIDHEADER);
400  }
401  /* Read floats */
402  mptr=mdata;
403  if((n=fread(mptr, 4, pxlnr, fpi)) < pxlnr) {
404  if(verbose==0) {fprintf(stdout, "\n"); fflush(stdout);}
405  free(mdata); imgEmpty(&img);
406  return(STATUS_NOMATRIX);
407  }
408  /* Copy floats to IMG */
409  mptr=mdata;
410  for(zi=0; zi<zdim; zi++)
411  for(yi=0; yi<ydim; yi++)
412  for(xi=0; xi<xdim; xi++) {
413  fptr=(float*)mptr;
414  img.m[zi][yi][xi][0]=(*fptr)*img.weight[0]*calibration_factor;
415  mptr+=4;
416  }
417  /* Write frame */
418  ret=imgWriteFrame(ecatfile, ti+1, &img, 0); //printf("ret := %d\n", ret);
419  if(ret!=STATUS_OK) break;
420  if(MICROPET_TEST>1) printf(" frame written.\n");
421  else if(verbose==0) {fprintf(stdout, "."); fflush(stdout);}
422  };
423  free(mdata); imgEmpty(&img);
424  if(verbose==0) {fprintf(stdout, "\n"); fflush(stdout);}
425  if(verbose==0 && ret==STATUS_NOMATRIX) {
426  fprintf(stdout, " %d frame(s) processed.\n", ti);
427  }
428  if(ret!=STATUS_OK && ret!=STATUS_NOMATRIX) {
429  remove(ecatfile); return ret;
430  }
431 
432  return STATUS_OK;
433 }
434 /*****************************************************************************/
435 
436 /*****************************************************************************/
443  FILE *fph,
445  FILE *fpi,
447  char *ecatfile,
449  int verbose
450 ) {
451  IMG img;
452  int n, pxlnr, zi, xi, yi, zdim, xdim, ydim, ret;
453  float f, scale_factor;
454  char *mdata, *mptr;
455  char tmp[MAX_MICROPET_LINE_LEN];
456  short int *si;
457 
458 
459  /* Check input */
460  if(fph==NULL || fpi==NULL || ecatfile==NULL) return STATUS_FAULT;
461 
462  /*
463  * Read image dimensions from header
464  */
465  ret=upetGetImageDimensions(fph, &zdim, &xdim, &ydim, NULL);
466  if(ret) {return(STATUS_INVALIDHEADER);}
467  if(MICROPET_TEST>1) {
468  printf("z_dim := %d\n", zdim);
469  printf("x_dim := %d\n", xdim);
470  printf("y_dim := %d\n", ydim);
471  }
472 
473  /* Read scale factor */
474  rewind(fph);
475  if(upetHeaderReadParameter(fph, "scale_factor", tmp)!=0) {
476  return(STATUS_INVALIDHEADER);}
477  scale_factor=-1; (void)sscanf(tmp, "%f", &scale_factor);
478  if(scale_factor<=0) return(STATUS_INVALIDHEADER);
479  if(MICROPET_TEST>1) {
480  printf("scale_factor := %g\n", scale_factor);
481  }
482 
483  /* Remove existing ECAT file */
484  if(access(ecatfile, 0)!=-1 && remove(ecatfile)!=0) {
485  return(STATUS_CANNOTERASE);
486  }
487 
488  /*
489  * Read and write image
490  */
491  imgInit(&img);
492  /* Allocate memory for one frame */
493  ret=imgAllocate(&img, zdim, ydim, xdim, 1);
494  if(ret) {return(STATUS_NOMEMORY);}
495  /* Fill header with what we now can */
496  ret=imgGetMicropetMainHeader(fph, &img, NULL);
497  if(ret) {
498  if(MICROPET_TEST) printf("ret := %d\n", ret);
499  imgEmpty(&img); return(STATUS_INVALIDHEADER);
500  }
501  img._fileFormat=IMG_E7;
502  img.type=IMG_TYPE_IMAGE;
503  studynr_from_fname(ecatfile, img.studyNr);
504  upetScanStart(fph, &img.scanStart);
505  /* Allocate memory for the binary data */
506  pxlnr=xdim*ydim;
507  mdata=(char*)malloc(pxlnr*sizeof(short int)); if(mdata==NULL) {
508  imgEmpty(&img); return(STATUS_NOMEMORY);
509  }
510  /* Read image data, plane-by-plane */
511  for(zi=0; zi<zdim; zi++) {
512  mptr=mdata;
513  if((n=fread(mptr, 2, pxlnr, fpi)) < pxlnr) {
514  if(verbose==0) {fprintf(stdout, "\n"); fflush(stdout);}
515  free(mdata); imgEmpty(&img);
516  return(STATUS_NOMATRIX);
517  }
518  /* Copy short ints to IMG */
519  mptr=mdata;
520  for(yi=0; yi<ydim; yi++)
521  for(xi=0; xi<xdim; xi++) {
522  si=(short int*)mptr;
523  f=(float)*si*scale_factor;
524  if(f>=0.0) img.m[zi][yi][xi][0]=f; else img.m[zi][yi][xi][0]=0.0;
525  mptr+=2;
526  }
527  if(MICROPET_TEST>1) printf(" plane %d\n", zi+1);
528  else if(verbose==0) {fprintf(stdout, "."); fflush(stdout);}
529  }
530  free(mdata);
531  if(verbose==0) {fprintf(stdout, "\n"); fflush(stdout);}
532  /* Save ECAT 7 image volume */
533  ret=imgWrite(ecatfile, &img);
534  if(ret!=0) {imgEmpty(&img); return(STATUS_CANNOTWRITE);}
535 
536  imgEmpty(&img);
537  return STATUS_OK;
538 }
539 /*****************************************************************************/
540 
541 /*****************************************************************************/
546  FILE *fp,
548  IMG *img,
550  float *calibration_factor
551 ) {
552  char tmp[MAX_MICROPET_LINE_LEN];
553  int n;
554  float f, branching_fraction=1.0;
555 
556 
557  if(fp==NULL) return 1;
558  if(img==NULL) return 2;
559 
560  /* scanner model */
561  rewind(fp);
562  if(upetHeaderReadParameter(fp, "model", tmp)!=0) return 11;
563  n=-1; (void)sscanf(tmp, "%d", &n); if(n<0) return 11;
564  img->scanner=n;
565 
566  /* zoom */
567  rewind(fp);
568  if(upetHeaderReadParameter(fp, "zoom", tmp)!=0) return 11;
569  f=-1; (void)sscanf(tmp, "%f", &f); if(f<0) return 11;
570  img->zoom=f;
571 
572  /* pixel size x */
573  rewind(fp);
574  if(upetHeaderReadParameter(fp, "pixel_size_x", tmp)!=0) return 12;
575  f=-1; (void)sscanf(tmp, "%f", &f); if(f<0) return 12;
576  img->sizex=f;
577 
578  /* pixel size y */
579  rewind(fp);
580  if(upetHeaderReadParameter(fp, "pixel_size_y", tmp)!=0) return 13;
581  f=-1; (void)sscanf(tmp, "%f", &f); if(f<0) return 13;
582  img->sizey=f;
583 
584  /* pixel size z */
585  rewind(fp);
586  if(upetHeaderReadParameter(fp, "pixel_size_z", tmp)!=0) return 14;
587  f=-1; (void)sscanf(tmp, "%f", &f); if(f<0) return 14;
588  img->sizez=f;
589  rewind(fp);
590  if(upetHeaderReadParameter(fp, "transaxial_bin_size", tmp)==0) {
591  f=-1; (void)sscanf(tmp, "%f", &f); if(f>0) img->sizez=10.0*f;
592  }
593 
594  /* isotope halflife */
595  rewind(fp);
596  if(upetHeaderReadParameter(fp, "isotope_half_life", tmp)==0) {
597  f=-1; (void)sscanf(tmp, "%f", &f); if(f<0) return 15;
598  img->isotopeHalflife=f;
599  }
600 
601  /* branching_fraction */
602  rewind(fp);
603  if(upetHeaderReadParameter(fp, "isotope_branching_fraction", tmp)==0) {
604  f=-1; (void)sscanf(tmp, "%f", &f); if(f<0) return 16;
605  branching_fraction=f;
606  }
607 
608  /* decay correction applied */
609  rewind(fp);
610  if(upetHeaderReadParameter(fp, "decay_correction_applied", tmp)==0) {
611  n=-1; (void)sscanf(tmp, "%d", &n); if(n<0) return 17;
612  img->decayCorrected=n;
613  }
614 
615  /* calibration units */
616  rewind(fp);
617  if(upetHeaderReadParameter(fp, "calibration_units", tmp)==0) {
618  n=-1; (void)sscanf(tmp, "%d", &n); if(n<0) return 18;
619  switch(n) {
620  case 1: img->unit=IMGUNIT_NCI_PER_ML; break;
621  case 2: img->unit=IMGUNIT_BQ_PER_ML; break;
622  case 0:
623  default: img->unit=IMGUNIT_UNKNOWN; break;
624  }
625  }
626 
627  /* calibration factor */
628  rewind(fp);
629  if(calibration_factor!=NULL &&
630  upetHeaderReadParameter(fp, "calibration_factor", tmp)==0)
631  {
632  f=-1; (void)sscanf(tmp, "%f", &f); if(f<=0.0) return 19;
633  *calibration_factor=f;
634  if(branching_fraction>0.0) *calibration_factor/=branching_fraction;
635  }
636 
637  /* FOV */
638  rewind(fp);
639  if(upetHeaderReadParameter(fp, "radial_fov", tmp)==0) {
640  f=-1; (void)sscanf(tmp, "%f", &f); if(f<0) return 20;
641  img->transaxialFOV=10.0*f;
642  }
643 
644  return 0;
645 }
646 /*****************************************************************************/
647 
648 /*****************************************************************************/
653  /* File pointer to Concorde/MicroPET header */
654  FILE *fp,
655  /* Pointer to IMG struct, allocated for one frame; frame information is
656  written in frame 0. */
657  IMG *img,
658  /* Frame index [0..tdim-1] */
659  int frame_index
660 ) {
661  char tmp[MAX_MICROPET_LINE_LEN];
662  int n;
663  float f;
664 
665 
666  if(fp==NULL) return 1;
667  if(img==NULL) return 2;
668  if(frame_index<0) return 3;
669 
670  /* Search required frame from the beginning of header file */
671  rewind(fp);
672 
673  /* Find correct frame index */
674  sprintf(tmp, "frame %d", frame_index);
675  if(upetHeaderReadParameter(fp, tmp, tmp)!=0) return 5;
676 
677  /* frame start time */
678  if(upetHeaderReadParameter(fp, "frame_start", tmp)!=0) return 11;
679  n=-1; (void)sscanf(tmp, "%d", &n); if(n<0) return 11;
680  img->start[0]=n;
681 
682  /* frame duration */
683  if(upetHeaderReadParameter(fp, "frame_duration", tmp)!=0) return 12;
684  n=-1; (void)sscanf(tmp, "%d", &n); if(n<0) return 12;
685  img->end[0]=img->start[0]+n;
686  img->mid[0]=0.5*(img->end[0]+img->start[0]);
687 
688  /* scale factor (written in 'weight' since there is no better place) */
689  if(upetHeaderReadParameter(fp, "scale_factor", tmp)!=0) return 13;
690  f=-1; (void)sscanf(tmp, "%f", &f); if(f<0) return 13;
691  img->weight[0]=f;
692 
693  /* decay correction */
694  if(upetHeaderReadParameter(fp, "decay_correction", tmp)!=0) return 14;
695  f=-1; (void)sscanf(tmp, "%f", &f); if(f<0) return 14;
696  img->decayCorrFactor[0]=f;
697 
698  return 0;
699 }
700 /*****************************************************************************/
701 
702 /*****************************************************************************/
708  FILE *fp,
711  SIF *sif
712 ) {
713  char tmp[MAX_MICROPET_LINE_LEN], tmp2[64], tmp3[64];
714  int n, i, ret;
715 
716 
717  if(fp==NULL) return 1;
718  if(sif==NULL) return 2;
719 
720 
721  /* Get frame number */
722  rewind(fp);
723  if(upetHeaderReadParameter(fp, "total_frames", tmp)!=0) return 11;
724  n=-1; (void)sscanf(tmp, "%d", &n); if(n<1) return 11;
725 
726  /* Allocate memory for SIF */
727  ret=sifSetmem(sif, n); if(ret!=0) return 4;
728  sif->frameNr=n;
729  sif->colNr=4;
730  sif->version=1;
731 
732  /* Scan time */
733  upetScanStart(fp, &sif->scantime);
734 
735  /* Isotope */
736  rewind(fp);
737  if(upetHeaderReadParameter(fp, "isotope", tmp)!=0) return 13;
738  strncpy(sif->isotope_name, tmp, 8);
739 
740  /* Frames */
741  for(i=0; i<sif->frameNr; i++) {
742  /* Find correct frame index */
743  sprintf(tmp, "frame %d", i);
744  if(upetHeaderReadParameter(fp, tmp, tmp)!=0) return 21;
745  /* frame start time */
746  if(upetHeaderReadParameter(fp, "frame_start", tmp)!=0) return 22;
747  n=-1; (void)sscanf(tmp, "%d", &n); if(n<0) return 22;
748  sif->x1[i]=n;
749  /* frame duration */
750  if(upetHeaderReadParameter(fp, "frame_duration", tmp)!=0) return 23;
751  n=-1; (void)sscanf(tmp, "%d", &n); if(n<0) return 23;
752  sif->x2[i]=sif->x1[i]+n;
753  /* prompts */
754  if(upetHeaderReadParameter(fp, "prompts", tmp)!=0) return 24;
755  n=-1; (void)sscanf(tmp, "%s %s %d", tmp2, tmp3, &n); if(n<0) return 24;
756  sif->prompts[i]=n;
757  /* delays */
758  if(upetHeaderReadParameter(fp, "delays", tmp)!=0) return 25;
759  n=-1; (void)sscanf(tmp, "%s %s %d", tmp2, tmp3, &n); if(n<0) return 25;
760  sif->randoms[i]=n;
761  /* trues */
762  sif->trues[i]=sif->prompts[i]-sif->randoms[i];
763  }
764  return 0;
765 }
766 /*****************************************************************************/
767 
768 /*****************************************************************************/