sifio.c
Go to the documentation of this file.
00001 /******************************************************************************
00002 
00003   Copyright (c) 2005,2006,2009 Turku PET Centre
00004 
00005   File:        sifio.c
00006   Description: Functions for reading and writing SIF format files.
00007 
00008   This library is free software; you can redistribute it and/or
00009   modify it under the terms of the GNU Lesser General Public
00010   License as published by the Free Software Foundation; either
00011   version 2.1 of the License, or (at your option) any later version.
00012 
00013   This library is distributed in the hope that it will be useful,
00014   but WITHOUT ANY WARRANTY; without even the implied warranty of
00015   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00016   See the GNU Lesser General Public License for more details:
00017   http://www.gnu.org/copyleft/lesser.html
00018 
00019   You should have received a copy of the GNU Lesser General Public License
00020   along with this library/program; if not, write to the Free Software
00021   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 
00022 
00023   Turku PET Centre, Turku, Finland, http://www.turkupetcentre.fi
00024 
00025   Modification history:
00026   2005-01-15 Vesa Oikonen
00027     First created. Functions from sif.c.
00028   2005-01-16 VO
00029     studynr and isotope_name were added to SIF structure, and if available,
00030     can be read from/written in SIF file.
00031     sifRead() mostly rewritten.
00032     sifRead() does not calculate SIF weights.
00033   2005-04-26 CL
00034     Merged libsif to libtpcimgio
00035   2005-05-04 Jarkko Johansson
00036     Compatibility fix in function strftime().
00037   2006-10-31 VO
00038     Return value of mktime() is checked.
00039   2007-17-07 Harri Merisaari
00040     Modified for optional ANSi compatibility
00041   2007-09-10 VO
00042     Return value of localtime() is checked.
00043   2009-04-06 VO
00044     sifRead(): SIF file with only two columns is accepted, if that is correctly
00045     specified in title line. Comment about weights is corrected.
00046     sifWrite(): only frame times are saved if SIF column number tells that
00047     prompts and randoms are not available.
00048 
00049 
00050 ******************************************************************************/
00051 
00052 /*****************************************************************************/
00053 #include "include/sif.h"
00054 /*****************************************************************************/
00055 
00056 /*****************************************************************************/
00064 int sifRead(
00066   char *filename,
00068   SIF *data
00069 ) {
00070   FILE *fp;
00071   int i, c, n, frameNr, yy, mm, dd, h, m, s, longest=0;
00072   struct tm *st;
00073   time_t timet;
00074   char *line, *cptr;
00075 
00076 
00077   if(SIF_TEST) printf("sifRead(%s, *sif)\n", filename);
00078   if(filename==NULL || data==NULL) return(1);
00079   /* Empty data */
00080   sifEmpty(data);
00081 
00082   /* Open file */
00083   fp=fopen(filename, "r");
00084   if(fp==NULL) {strcpy(siferrmsg, "cannot open file"); return(2);}
00085 
00086   /* Get the length of the longest line */
00087   i=0; while((c=fgetc(fp))!=EOF) {
00088     if(c==10) {if(i>longest) longest=i; i=0;} else i++;
00089   }
00090   if(i>longest) longest=i;
00091   rewind(fp); longest+=1;
00092   /* and allocate memory for string of that length */
00093   line=(char*)malloc((longest+1)*sizeof(char));
00094   if(line==NULL) {strcpy(siferrmsg, "out of memory"); fclose(fp); return(3);}
00095 
00096   /* Read the title line */
00097   do {
00098     if(fgets(line, longest, fp)==NULL) {
00099       strcpy(siferrmsg, "wrong format"); fclose(fp); free(line); return(4);
00100     }
00101     cptr=strpbrk(line, "\n\r"); if(cptr!=NULL) *cptr='\0';
00102     cptr=line+strspn(line, " \t");
00103   } while(*cptr=='#' || strlen(cptr)==0);
00104   n=sscanf(line, "%d/%d/%d %d:%d:%d %d %d %d %10s %7s",
00105       &dd, &mm, &yy, &h, &m, &s, &frameNr, &data->colNr, &data->version,
00106       data->studynr, data->isotope_name);
00107   if(n<9 || frameNr<1 || data->colNr<2 || data->version!=1) {
00108     strcpy(siferrmsg, "wrong filetype"); fclose(fp); free(line); return(5);}
00109   timet=time(NULL); st=localtime(&timet);
00110   if(st!=NULL) {
00111     st->tm_mday=dd; st->tm_mon=mm-1; st->tm_year=yy-1900;
00112     st->tm_hour=h; st->tm_min=m; st->tm_sec=s; st->tm_isdst=-1;
00113     data->scantime=mktime(st); if(data->scantime==-1) data->scantime=0;
00114   } else {
00115     data->scantime=0;
00116   }
00117 
00118   /* Allocate memory for data */
00119   if(sifSetmem(data, frameNr)) {
00120     fclose(fp); free(line); return(6);
00121   }
00122 
00123   /* Read data lines */
00124   i=0;
00125   while(i<data->frameNr) {
00126     do {
00127       if(fgets(line, longest, fp)==NULL) {
00128         strcpy(siferrmsg, "wrong format"); sifEmpty(data);
00129         fclose(fp); free(line); return(8);
00130       }
00131       cptr=strpbrk(line, "\n\r"); if(cptr!=NULL) *cptr='\0';
00132       cptr=line+strspn(line, " \t");
00133       /*printf("  i=%d cptr='%s'\n", i, cptr);*/
00134     } while(*cptr=='#' || strlen(cptr)==0);
00135     n=sscanf(line, "%lf %lf %lf %lf", &data->x1[i], &data->x2[i],
00136         &data->prompts[i], &data->randoms[i]);
00137     /*
00138     printf("i=%d n=%d line='%s'\n", i, n, line);
00139     printf(" -> x1=%g x2=%g prompts=%g randoms=%g\n", data->x1[i], data->x2[i],
00140         data->prompts[i], data->randoms[i]);
00141     */
00142     if(n<data->colNr || data->x2[i]<data->x1[i]) { 
00143       strcpy(siferrmsg, "wrong data format"); sifEmpty(data);
00144       fclose(fp); free(line); return(9);
00145     }
00146     i++;
00147   }
00148 
00149   /* Close file */
00150   fclose(fp); free(line);
00151 
00152   /* Calculate trues */
00153   if(data->colNr>=4) for(i=0; i<data->frameNr; i++)
00154     data->trues[i]=data->prompts[i]-data->randoms[i];
00155   /* Set weights to 1.0 */
00156   for(i=0; i<data->frameNr; i++) data->weights[i]=1.0;
00157 
00158   return(0);
00159 }
00160 /*****************************************************************************/
00161 
00162 /*****************************************************************************/
00167 int sifWrite(
00169   SIF *data,
00171   char *filename
00172 ) {
00173   FILE *fp;
00174   int i, n;
00175   char buf[1024];
00176   struct tm *st;
00177 
00178 
00179   if(SIF_TEST) printf("sifWrite(*sif, %s)\n", filename);
00180   /* Check data */
00181   if(data->frameNr<1) {strcpy(siferrmsg, "no data to save"); return 1;}
00182 
00183   /* Open file */
00184   fp=fopen(filename, "w");
00185   if(fp==NULL) {strcpy(siferrmsg, "cannot open file"); return 2;}
00186 
00187   /* Write title line */
00188   st=localtime(&data->scantime);
00189   if(st!=NULL) strftime(buf, 1024, "%d/%m/%Y %H:%M:%S", st);
00190   else strcpy(buf, "1/1/1900 00:00:00");
00191   n=fprintf(fp, "%s %d %d %d", buf, data->frameNr, data->colNr, data->version);
00192   if(SIF_TEST)
00193     printf("%s %d %d %d\n", buf, data->frameNr, data->colNr, data->version);
00194   if(n<7) {strcpy(siferrmsg, "cannot write file"); fclose(fp); return 2;}
00195   if(strlen(data->studynr)!=0 || strlen(data->isotope_name)!=0) {
00196     /* Write also study number and isotope */
00197     if(strlen(data->studynr)==0) fprintf(fp, " .");
00198     else fprintf(fp, " %s", data->studynr);
00199     if(strlen(data->isotope_name)>0) fprintf(fp, " %s", data->isotope_name);
00200   }
00201   fprintf(fp, "\n");
00202 
00203   /* Write data lines */
00204   for(i=0; i<data->frameNr; i++) {
00205     if(data->colNr>2)
00206       n=fprintf(fp, "%.0f %.0f %.0f %.0f\n",
00207         data->x1[i], data->x2[i], data->prompts[i], data->randoms[i]);
00208     else
00209       n=fprintf(fp, "%.0f %.0f\n",
00210         data->x1[i], data->x2[i]);
00211     if(n<3) {strcpy(siferrmsg, "cannot write file"); fclose(fp); return 3;}
00212   }
00213 
00214   /* Close file */
00215   fclose(fp);
00216 
00217   return 0;
00218 }
00219 /*****************************************************************************/
00220 
00221 /*****************************************************************************/
00224 void sifPrint(
00226   SIF *data
00227 ) {
00228   int i;
00229   char buf[512];
00230   struct tm *st;
00231   
00232   /*printf("Number of frames: %d\n", data->frameNr);*/
00233   st=localtime(&data->scantime);
00234   if(st!=NULL) strftime(buf, 512, "%Y-%m-%d %H:%M:%S", st);
00235   else strcpy(buf, "1900-01-01 00:00:00");
00236   printf("Scan time: %s\n", buf);
00237   printf("Isotope: %s\n", data->isotope_name);
00238   printf("Frame start  end     Prompts    Randoms      Trues   Weight\n");
00239   for(i=0; i<data->frameNr; i++) {
00240     printf(" %03d %5.0f %5.0f  %10.0f %10.0f %10.0f %8.6f\n", i+1,
00241       data->x1[i], data->x2[i], data->prompts[i], data->randoms[i],
00242       data->trues[i], data->weights[i]);
00243   }
00244   return;
00245 }
00246 /*****************************************************************************/
00247 
00248 /*****************************************************************************/
00249