sifio.c
Go to the documentation of this file.
1 /******************************************************************************
2 
3  Copyright (c) 2005,2006,2009,2011 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  2011-08-13 VO
49  sifWrite() writes frame times with one decimal if rounding would lead to
50  equal times in adjacent frames.
51  sifPrint() prints frame times always with one decimal.
52 
53 
54 ******************************************************************************/
55 
56 /*****************************************************************************/
57 #include "include/sif.h"
58 /*****************************************************************************/
59 
60 /*****************************************************************************/
68 int sifRead(
70  char *filename,
72  SIF *data
73 ) {
74  FILE *fp;
75  int i, c, n, frameNr, yy, mm, dd, h, m, s, longest=0;
76  struct tm *st;
77  time_t timet;
78  char *line, *cptr;
79 
80 
81  if(SIF_TEST) printf("sifRead(%s, *sif)\n", filename);
82  if(filename==NULL || data==NULL) return(1);
83  /* Empty data */
84  sifEmpty(data);
85 
86  /* Open file */
87  fp=fopen(filename, "r");
88  if(fp==NULL) {strcpy(siferrmsg, "cannot open file"); return(2);}
89 
90  /* Get the length of the longest line */
91  i=0; while((c=fgetc(fp))!=EOF) {
92  if(c==10) {if(i>longest) longest=i; i=0;} else i++;
93  }
94  if(i>longest) longest=i;
95  rewind(fp); longest+=1;
96  /* and allocate memory for string of that length */
97  line=(char*)malloc((longest+1)*sizeof(char));
98  if(line==NULL) {strcpy(siferrmsg, "out of memory"); fclose(fp); return(3);}
99 
100  /* Read the title line */
101  do {
102  if(fgets(line, longest, fp)==NULL) {
103  strcpy(siferrmsg, "wrong format"); fclose(fp); free(line); return(4);
104  }
105  cptr=strpbrk(line, "\n\r"); if(cptr!=NULL) *cptr='\0';
106  cptr=line+strspn(line, " \t");
107  } while(*cptr=='#' || strlen(cptr)==0);
108  n=sscanf(line, "%d/%d/%d %d:%d:%d %d %d %d %10s %7s",
109  &dd, &mm, &yy, &h, &m, &s, &frameNr, &data->colNr, &data->version,
110  data->studynr, data->isotope_name);
111  if(n<9 || frameNr<1 || data->colNr<2 || data->version!=1) {
112  strcpy(siferrmsg, "wrong filetype"); fclose(fp); free(line); return(5);}
113  timet=time(NULL); st=localtime(&timet);
114  if(st!=NULL) {
115  st->tm_mday=dd; st->tm_mon=mm-1; st->tm_year=yy-1900;
116  st->tm_hour=h; st->tm_min=m; st->tm_sec=s; st->tm_isdst=-1;
117  data->scantime=mktime(st); if(data->scantime==-1) data->scantime=0;
118  } else {
119  data->scantime=0;
120  }
121 
122  /* Allocate memory for data */
123  if(sifSetmem(data, frameNr)) {
124  fclose(fp); free(line); return(6);
125  }
126 
127  /* Read data lines */
128  i=0;
129  while(i<data->frameNr) {
130  do {
131  if(fgets(line, longest, fp)==NULL) {
132  strcpy(siferrmsg, "wrong format"); sifEmpty(data);
133  fclose(fp); free(line); return(8);
134  }
135  cptr=strpbrk(line, "\n\r"); if(cptr!=NULL) *cptr='\0';
136  cptr=line+strspn(line, " \t");
137  } while(*cptr=='#' || strlen(cptr)==0);
138  n=sscanf(line, "%lf %lf %lf %lf", &data->x1[i], &data->x2[i],
139  &data->prompts[i], &data->randoms[i]);
140  if(n<data->colNr || data->x2[i]<data->x1[i]) {
141  strcpy(siferrmsg, "wrong data format"); sifEmpty(data);
142  fclose(fp); free(line); return(9);
143  }
144  i++;
145  }
146 
147  /* Close file */
148  fclose(fp); free(line);
149 
150  /* Calculate trues */
151  if(data->colNr>=4) for(i=0; i<data->frameNr; i++)
152  data->trues[i]=data->prompts[i]-data->randoms[i];
153  /* Set weights to 1.0 */
154  for(i=0; i<data->frameNr; i++) data->weights[i]=1.0;
155 
156  return(0);
157 }
158 /*****************************************************************************/
159 
160 /*****************************************************************************/
167  SIF *data,
169  char *filename
170 ) {
171  FILE *fp;
172  int i, n, req_decimals=0;
173  char buf[1024];
174  struct tm *st;
175 
176 
177  if(SIF_TEST) printf("sifWrite(*sif, %s)\n", filename);
178  /* Check data */
179  if(data->frameNr<1) {strcpy(siferrmsg, "no data to save"); return 1;}
180 
181  /* Open file */
182  fp=fopen(filename, "w");
183  if(fp==NULL) {strcpy(siferrmsg, "cannot open file"); return 2;}
184 
185  /* Write title line */
186  st=localtime(&data->scantime);
187  if(st!=NULL) strftime(buf, 1024, "%d/%m/%Y %H:%M:%S", st);
188  else strcpy(buf, "1/1/1900 00:00:00");
189  n=fprintf(fp, "%s %d %d %d", buf, data->frameNr, data->colNr, data->version);
190  if(SIF_TEST)
191  printf("%s %d %d %d\n", buf, data->frameNr, data->colNr, data->version);
192  if(n<7) {strcpy(siferrmsg, "cannot write file"); fclose(fp); return 2;}
193  if(strlen(data->studynr)!=0 || strlen(data->isotope_name)!=0) {
194  /* Write also study number and isotope */
195  if(strlen(data->studynr)==0) fprintf(fp, " .");
196  else fprintf(fp, " %s", data->studynr);
197  if(strlen(data->isotope_name)>0) fprintf(fp, " %s", data->isotope_name);
198  }
199  fprintf(fp, "\n");
200 
201  /* Check if frame times need to printed with decimals */
202  for(i=1, req_decimals=0; i<data->frameNr; i++) {
203  if(round(data->x1[i])==round(data->x1[i-1])) {req_decimals=1; break;}
204  if(round(data->x2[i])==round(data->x2[i-1])) {req_decimals=1; break;}
205  }
206 
207  /* Write data lines */
208  for(i=0; i<data->frameNr; i++) {
209  if(req_decimals==0) n=fprintf(fp, "%.0f %.0f", data->x1[i], data->x2[i]);
210  else n=fprintf(fp, "%.1f %.1f", data->x1[i], data->x2[i]);
211  if(n<3) {strcpy(siferrmsg, "cannot write file"); fclose(fp); return 3;}
212  if(data->colNr<=2) n=fprintf(fp, "\n");
213  else n=fprintf(fp, " %.0f %.0f\n", data->prompts[i], data->randoms[i]);
214  if(n<1) {strcpy(siferrmsg, "cannot write file"); fclose(fp); return 3;}
215  }
216 
217  /* Close file */
218  fclose(fp);
219 
220  return 0;
221 }
222 /*****************************************************************************/
223 
224 /*****************************************************************************/
227 void sifPrint(
229  SIF *data
230 ) {
231  int i;
232  char buf[512];
233  struct tm *st;
234 
235  st=localtime(&data->scantime);
236  if(st!=NULL) strftime(buf, 512, "%Y-%m-%d %H:%M:%S", st);
237  else strcpy(buf, "1900-01-01 00:00:00");
238  printf("Scan time: %s\n", buf);
239  printf("Isotope: %s\n", data->isotope_name);
240  printf("Frame start end Prompts Randoms Trues Weight\n");
241  for(i=0; i<data->frameNr; i++) {
242  printf(" %03d %6.1f %6.1f %10.0f %10.0f %10.0f %8.6f\n", i+1,
243  data->x1[i], data->x2[i], data->prompts[i], data->randoms[i],
244  data->trues[i], data->weights[i]);
245  }
246  return;
247 }
248 /*****************************************************************************/
249 
250 /*****************************************************************************/
251 
time_t scantime
Definition: sif.h:38
int sifWrite(SIF *data, char *filename)
Definition: sifio.c:165
int colNr
Definition: sif.h:42
int frameNr
Definition: sif.h:40
double * prompts
Definition: sif.h:54
int sifSetmem(SIF *data, int frameNr)
Definition: sif.c:95
double * randoms
Definition: sif.h:56
int sifRead(char *filename, SIF *data)
Definition: sifio.c:68
Definition: sif.h:36
double * x2
Definition: sif.h:52
char studynr[11]
Definition: sif.h:46
int version
Definition: sif.h:44
double * trues
Definition: sif.h:58
char siferrmsg[128]
Definition: sif.h:33
int SIF_TEST
Definition: sif.h:63
double * x1
Definition: sif.h:50
char isotope_name[8]
Definition: sif.h:48
double * weights
Definition: sif.h:60
void sifPrint(SIF *data)
Definition: sifio.c:227
void sifEmpty(SIF *data)
Definition: sif.c:74