sifio.c
Go to the documentation of this file.
1 /******************************************************************************
2 
3  Copyright (c) 2005,2006,2009 Turku PET Centre
4 
5  File: sifio.c
6  Description: Functions for reading and writing SIF format files.
7 
8  This library is free software; you can redistribute it and/or
9  modify it under the terms of the GNU Lesser General Public
10  License as published by the Free Software Foundation; either
11  version 2.1 of the License, or (at your option) any later version.
12 
13  This library is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
16  See the GNU Lesser General Public License for more details:
17  http://www.gnu.org/copyleft/lesser.html
18 
19  You should have received a copy of the GNU Lesser General Public License
20  along with this library/program; if not, write to the Free Software
21  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 
23  Turku PET Centre, Turku, Finland, http://www.turkupetcentre.fi
24 
25  Modification history:
26  2005-01-15 Vesa Oikonen
27  First created. Functions from sif.c.
28  2005-01-16 VO
29  studynr and isotope_name were added to SIF structure, and if available,
30  can be read from/written in SIF file.
31  sifRead() mostly rewritten.
32  sifRead() does not calculate SIF weights.
33  2005-04-26 CL
34  Merged libsif to libtpcimgio
35  2005-05-04 Jarkko Johansson
36  Compatibility fix in function strftime().
37  2006-10-31 VO
38  Return value of mktime() is checked.
39  2007-17-07 Harri Merisaari
40  Modified for optional ANSi compatibility
41  2007-09-10 VO
42  Return value of localtime() is checked.
43  2009-04-06 VO
44  sifRead(): SIF file with only two columns is accepted, if that is correctly
45  specified in title line. Comment about weights is corrected.
46  sifWrite(): only frame times are saved if SIF column number tells that
47  prompts and randoms are not available.
48 
49 
50 ******************************************************************************/
51 
52 /*****************************************************************************/
53 #include "include/sif.h"
54 /*****************************************************************************/
55 
56 /*****************************************************************************/
64 int sifRead(
66  char *filename,
68  SIF *data
69 ) {
70  FILE *fp;
71  int i, c, n, frameNr, yy, mm, dd, h, m, s, longest=0;
72  struct tm *st;
73  time_t timet;
74  char *line, *cptr;
75 
76 
77  if(SIF_TEST) printf("sifRead(%s, *sif)\n", filename);
78  if(filename==NULL || data==NULL) return(1);
79  /* Empty data */
80  sifEmpty(data);
81 
82  /* Open file */
83  fp=fopen(filename, "r");
84  if(fp==NULL) {strcpy(siferrmsg, "cannot open file"); return(2);}
85 
86  /* Get the length of the longest line */
87  i=0; while((c=fgetc(fp))!=EOF) {
88  if(c==10) {if(i>longest) longest=i; i=0;} else i++;
89  }
90  if(i>longest) longest=i;
91  rewind(fp); longest+=1;
92  /* and allocate memory for string of that length */
93  line=(char*)malloc((longest+1)*sizeof(char));
94  if(line==NULL) {strcpy(siferrmsg, "out of memory"); fclose(fp); return(3);}
95 
96  /* Read the title line */
97  do {
98  if(fgets(line, longest, fp)==NULL) {
99  strcpy(siferrmsg, "wrong format"); fclose(fp); free(line); return(4);
100  }
101  cptr=strpbrk(line, "\n\r"); if(cptr!=NULL) *cptr='\0';
102  cptr=line+strspn(line, " \t");
103  } while(*cptr=='#' || strlen(cptr)==0);
104  n=sscanf(line, "%d/%d/%d %d:%d:%d %d %d %d %10s %7s",
105  &dd, &mm, &yy, &h, &m, &s, &frameNr, &data->colNr, &data->version,
106  data->studynr, data->isotope_name);
107  if(n<9 || frameNr<1 || data->colNr<2 || data->version!=1) {
108  strcpy(siferrmsg, "wrong filetype"); fclose(fp); free(line); return(5);}
109  timet=time(NULL); st=localtime(&timet);
110  if(st!=NULL) {
111  st->tm_mday=dd; st->tm_mon=mm-1; st->tm_year=yy-1900;
112  st->tm_hour=h; st->tm_min=m; st->tm_sec=s; st->tm_isdst=-1;
113  data->scantime=mktime(st); if(data->scantime==-1) data->scantime=0;
114  } else {
115  data->scantime=0;
116  }
117 
118  /* Allocate memory for data */
119  if(sifSetmem(data, frameNr)) {
120  fclose(fp); free(line); return(6);
121  }
122 
123  /* Read data lines */
124  i=0;
125  while(i<data->frameNr) {
126  do {
127  if(fgets(line, longest, fp)==NULL) {
128  strcpy(siferrmsg, "wrong format"); sifEmpty(data);
129  fclose(fp); free(line); return(8);
130  }
131  cptr=strpbrk(line, "\n\r"); if(cptr!=NULL) *cptr='\0';
132  cptr=line+strspn(line, " \t");
133  /*printf(" i=%d cptr='%s'\n", i, cptr);*/
134  } while(*cptr=='#' || strlen(cptr)==0);
135  n=sscanf(line, "%lf %lf %lf %lf", &data->x1[i], &data->x2[i],
136  &data->prompts[i], &data->randoms[i]);
137  /*
138  printf("i=%d n=%d line='%s'\n", i, n, line);
139  printf(" -> x1=%g x2=%g prompts=%g randoms=%g\n", data->x1[i], data->x2[i],
140  data->prompts[i], data->randoms[i]);
141  */
142  if(n<data->colNr || data->x2[i]<data->x1[i]) {
143  strcpy(siferrmsg, "wrong data format"); sifEmpty(data);
144  fclose(fp); free(line); return(9);
145  }
146  i++;
147  }
148 
149  /* Close file */
150  fclose(fp); free(line);
151 
152  /* Calculate trues */
153  if(data->colNr>=4) for(i=0; i<data->frameNr; i++)
154  data->trues[i]=data->prompts[i]-data->randoms[i];
155  /* Set weights to 1.0 */
156  for(i=0; i<data->frameNr; i++) data->weights[i]=1.0;
157 
158  return(0);
159 }
160 /*****************************************************************************/
161 
162 /*****************************************************************************/
169  SIF *data,
171  char *filename
172 ) {
173  FILE *fp;
174  int i, n;
175  char buf[1024];
176  struct tm *st;
177 
178 
179  if(SIF_TEST) printf("sifWrite(*sif, %s)\n", filename);
180  /* Check data */
181  if(data->frameNr<1) {strcpy(siferrmsg, "no data to save"); return 1;}
182 
183  /* Open file */
184  fp=fopen(filename, "w");
185  if(fp==NULL) {strcpy(siferrmsg, "cannot open file"); return 2;}
186 
187  /* Write title line */
188  st=localtime(&data->scantime);
189  if(st!=NULL) strftime(buf, 1024, "%d/%m/%Y %H:%M:%S", st);
190  else strcpy(buf, "1/1/1900 00:00:00");
191  n=fprintf(fp, "%s %d %d %d", buf, data->frameNr, data->colNr, data->version);
192  if(SIF_TEST)
193  printf("%s %d %d %d\n", buf, data->frameNr, data->colNr, data->version);
194  if(n<7) {strcpy(siferrmsg, "cannot write file"); fclose(fp); return 2;}
195  if(strlen(data->studynr)!=0 || strlen(data->isotope_name)!=0) {
196  /* Write also study number and isotope */
197  if(strlen(data->studynr)==0) fprintf(fp, " .");
198  else fprintf(fp, " %s", data->studynr);
199  if(strlen(data->isotope_name)>0) fprintf(fp, " %s", data->isotope_name);
200  }
201  fprintf(fp, "\n");
202 
203  /* Write data lines */
204  for(i=0; i<data->frameNr; i++) {
205  if(data->colNr>2)
206  n=fprintf(fp, "%.0f %.0f %.0f %.0f\n",
207  data->x1[i], data->x2[i], data->prompts[i], data->randoms[i]);
208  else
209  n=fprintf(fp, "%.0f %.0f\n",
210  data->x1[i], data->x2[i]);
211  if(n<3) {strcpy(siferrmsg, "cannot write file"); fclose(fp); return 3;}
212  }
213 
214  /* Close file */
215  fclose(fp);
216 
217  return 0;
218 }
219 /*****************************************************************************/
220 
221 /*****************************************************************************/
224 void sifPrint(
226  SIF *data
227 ) {
228  int i;
229  char buf[512];
230  struct tm *st;
231 
232  /*printf("Number of frames: %d\n", data->frameNr);*/
233  st=localtime(&data->scantime);
234  if(st!=NULL) strftime(buf, 512, "%Y-%m-%d %H:%M:%S", st);
235  else strcpy(buf, "1900-01-01 00:00:00");
236  printf("Scan time: %s\n", buf);
237  printf("Isotope: %s\n", data->isotope_name);
238  printf("Frame start end Prompts Randoms Trues Weight\n");
239  for(i=0; i<data->frameNr; i++) {
240  printf(" %03d %5.0f %5.0f %10.0f %10.0f %10.0f %8.6f\n", i+1,
241  data->x1[i], data->x2[i], data->prompts[i], data->randoms[i],
242  data->trues[i], data->weights[i]);
243  }
244  return;
245 }
246 /*****************************************************************************/
247 
248 /*****************************************************************************/
249