TPCCLIB
Loading...
Searching...
No Matches
ncifile.c
Go to the documentation of this file.
1
7/*****************************************************************************/
8#include "libtpccurveio.h"
9#include <unistd.h>
10/*****************************************************************************/
12#define ROIKBQ_MAX_LINE_LEN 8192
13/*****************************************************************************/
14/* Local functions */
16void roikbq_strip_spaces(char *s);
17void roikbq_move_to_next_line(FILE *fp);
18int roikbq_fgets(FILE *fp, int nr, char *s);
20/*****************************************************************************/
21
22/*****************************************************************************/
28 DFT *dft,
30 char *fname
31) {
32 int ri, fi;
33 char tmp[FILENAME_MAX];
34 FILE *fp;
35
36 /* Check that there is some data to write */
37 if(dft->voiNr<1 || dft->frameNr<1) {
38 strcpy(dfterrmsg, "no data"); return(1);}
39
40 /* Check if file exists; backup, if necessary */
41 if(access(fname, 0) != -1) {
42 strcpy(tmp, fname); strcat(tmp, BACKUP_EXTENSION);
43 if(access(tmp, 0) != -1) remove(tmp);
44 rename(fname, tmp);
45 }
46
47 /* Open output file */
48 if((fp = fopen(fname, "w")) == NULL) {strcpy(dfterrmsg, "cannot open file"); return(2);}
49
50 /* Write title lines */
51
52 /* Write 1st title line (Program name and ROI names) */
53 fprintf(fp, "%-15.15s", "cpt2nci 3");
54 for(ri=0; ri<dft->voiNr; ri++) {
55 fprintf(fp, " %-6.6s", dft->voi[ri].voiname);
56 if(strcmp(dft->voi[ri].hemisphere, ".")==0) fprintf(fp, " %-6.6s", " ");
57 else fprintf(fp, " %-6.6s", dft->voi[ri].hemisphere);
58 }
59 fprintf(fp, "\n");
60
61 /* Write 2nd title line (Study nr and Planes) */
62 fprintf(fp, "%-15.15s", dft->studynr);
63 for(ri=0; ri<dft->voiNr; ri++)
64 fprintf(fp, " %-13.13s", dft->voi[ri].place);
65 fprintf(fp, "\n");
66
67 /* Write 3rd title line (ROI volumes) */
68 fprintf(fp, "%-15.15s", "Time (min)");
69 for(ri=0; ri<dft->voiNr; ri++)
70 fprintf(fp, " %-13.1f", dft->voi[ri].size);
71 fprintf(fp, "\n");
72
73 /* Write times and data of each frame */
74 for(fi=0; fi<dft->frameNr; fi++) {
75 fprintf(fp, "%8.3f ", dft->x[fi]);
76 for(ri=0; ri<dft->voiNr; ri++)
77 if(!isnan(dft->voi[ri].y[fi]))
78 fprintf(fp, " %-13.6e", dft->voi[ri].y[fi]);
79 else
80 fprintf(fp, " . ");
81 fprintf(fp, "\n");
82 }
83
84 /* Close file */
85 fclose(fp);
86
87 return(0);
88}
89/*****************************************************************************/
90
91/*****************************************************************************/
97 char *fname,
99 DFT *dft
100) {
101 FILE *fp;
102 int i, j, k, l, roi_nr=0, frame_nr=0, ret, nr=0;
103 char c, line[ROIKBQ_MAX_LINE_LEN], tmp[25], s1[25], s2[25];
104 double a, b;
105
106
107 /* Check the arguments */
108 if(dft==NULL || fname==NULL) {
109 strcpy(dfterrmsg, "program fault"); return(1);}
110 /* Empty data */
111 dftEmpty(dft);
112
113 /* Open file */
114 fp=fopen(fname, "r");
115 if(fp==NULL) {strcpy(dfterrmsg, "cannot open file"); return(2);}
116
117 /* Check file type */
118 rewind(fp); i=0;
119 while(fgets(line, ROIKBQ_MAX_LINE_LEN-1, fp) != NULL) {
120 roikbq_strip_spaces(line); if(!strlen(line) || line[0]=='#') continue;
121 if(!isalpha((int)line[0])) continue;
122 if(strncasecmp(line, "cpt2nci 3", 9)==0) {i=1; break;}
123 }
124 if(i==0) {strcpy(dfterrmsg, "unsupported file format"); fclose(fp); return(3);}
125
126 /* Get data size */
127 rewind(fp); roi_nr=frame_nr=0;
128 /* read first title line */
129 c=fgetc(fp);
130 if(c=='#') roikbq_move_to_next_line(fp); else ungetc(c, fp);
131 i=roikbq_fgets(fp, 16, tmp);
132 if(i<16) {strcpy(dfterrmsg, "unsupported file format"); fclose(fp); return(3);}
133 while(i>13) {
134 i=roikbq_fgets(fp, 14, tmp); if(i>11 && isalnum((int)tmp[0])) roi_nr++;
135 }
136 /* read two title lines more */
137 roikbq_move_to_next_line(fp); roikbq_move_to_next_line(fp);
138 /* now start reading data lines */
139 do {
140 c=fgetc(fp); if(c==EOF) break; if(c!='\n') frame_nr++;
141 roikbq_move_to_next_line(fp);
142 } while(c!=EOF);
143 if(roi_nr<1 || frame_nr<1) {
144 strcpy(dfterrmsg, "unsupported file format"); fclose(fp); return(3);}
145
146 /* Allocate memory for DFT */
147 ret=dftSetmem(dft, frame_nr, roi_nr);
148 if(ret) {strcpy(dfterrmsg, "out of memory"); fclose(fp); return(4);}
149 dft->_type=1;
150
151 /* Read data */
152 /* Set file pointer to the beginning of first title line */
153 rewind(fp); c=fgetc(fp);
154 if(c=='#') roikbq_move_to_next_line(fp); else ungetc(c, fp);
155 /* Read the names of ROIs and Hemispheres */
156 j=roikbq_fgets(fp, 16, tmp);
157 if(j<16) {strcpy(dfterrmsg, "unsupported file format"); fclose(fp); return(3);}
158 i=0; while (j>13) {
159 j=roikbq_fgets(fp, 14, tmp); if(i>=roi_nr) continue;
160 k=sscanf(tmp, "%s %s", s1, s2); if(k<1) continue;
161 if(k==1) s2[0]='\0';
162 strcpy(dft->voi[dft->voiNr+i].voiname, s1);
163 strcpy(dft->voi[dft->voiNr+i].hemisphere, s2);
164 if(s2[0]!='\0')
165 snprintf(dft->voi[dft->voiNr+i].name, MAX_REGIONNAME_LEN, "%s %s", s1, s2);
166 else
167 snprintf(dft->voi[dft->voiNr+i].name, MAX_REGIONNAME_LEN, "%s .", s1);
168 i++;
169 }
170 nr=i;
171 /* Read the name of place (planes) in 2nd title line */
172 c=fgetc(fp); if(c=='#') roikbq_move_to_next_line(fp); else ungetc(c, fp);
173 j=roikbq_fgets(fp, 16, tmp);
174 if(j<16) {strcpy(dfterrmsg, "unsupported file format"); fclose(fp); return(3);}
175 strncpy(dft->studynr, tmp, 6); dft->studynr[6]=(char)0;
176 roikbq_strip_spaces(dft->studynr);
177 i=0; while(j>13) {
178 j=roikbq_fgets(fp, 14, tmp); if(i>=nr) continue;
179 k=sscanf(tmp, "%s", s1); if(k<1) s1[0]='\0';
180 strcpy(dft->voi[dft->voiNr+i].place, s1);
181 if(s1[0]!='\0') {
182 strcat(dft->voi[dft->voiNr+i].name, " ");
183 strcat(dft->voi[dft->voiNr+i].name, s1);
184 } else strcat(dft->voi[dft->voiNr+i].name, " .");
185 i++;
186 }
187 for(j=i; j<nr; j++) strcpy(dft->voi[dft->voiNr+j].place, "");
188 /* Read the ROI volumes in 3rd title line */
189 c=fgetc(fp); if(c=='#') roikbq_move_to_next_line(fp); else ungetc(c, fp);
190 j=roikbq_fgets(fp, 16, tmp);
191 if(j<16) {strcpy(dfterrmsg, "unsupported file format"); fclose(fp); return(3);}
192 if(strstr(tmp, "Times")) dft->timetype=3;
193 else if(strstr(tmp, "Start")) dft->timetype=1;
194 else if(strstr(tmp, "End")) dft->timetype=2;
195 else dft->timetype=0;
196 if(strstr(tmp, "sec")) dft->timeunit=TUNIT_SEC; else dft->timeunit=TUNIT_MIN;
197 i=0; while(j>13) {
198 j=roikbq_fgets(fp, 14, tmp); if(i>=nr) continue;
199 if(sscanf(tmp, "%lf", &dft->voi[dft->voiNr+i].size)<1)
200 dft->voi[dft->voiNr+i].size=0.;
201 i++;
202 }
203 for(j=i; j<nr; j++) dft->voi[dft->voiNr+j].size=0.;
204 /* Read frame data */
205 k=0; c=fgetc(fp); if(c=='#') roikbq_move_to_next_line(fp); else ungetc(c, fp);
206 while((j=roikbq_fgets(fp, 16, tmp))>15) {
207 if(k>=frame_nr) break;
208 roikbq_strip_spaces(tmp); if(strlen(tmp)==0) continue;
209 if(dft->timetype==0) {
210 dft->x[k]=atof(tmp);
211 dft->x1[k]=dft->x2[k]=nan("");
212 } else if(dft->timetype==3) {
213 sscanf(tmp, "%lf %lf", &a, &b); dft->x1[k]=a; dft->x2[k]=b;
214 dft->x[k]=0.5*(dft->x1[k] + dft->x2[k]);
215 } else if(dft->timetype==1) {
216 dft->x1[k]=dft->x[k]=dft->x2[k]=atof(tmp);
217 } else if(dft->timetype==2) {
218 dft->x2[k]=dft->x[k]=dft->x1[k]=atof(tmp);
219 }
220 if(dft->x[k]<-3.e38) dft->x[k]=nan("");
221 i=0; while(j>13) {
222 j=roikbq_fgets(fp, 14, tmp); if(i>=nr || j<13) continue;
223 roikbq_strip_spaces(tmp);
224 if(!strlen(tmp) || !strcmp(tmp, ".")) dft->voi[dft->voiNr+i].y[k]=nan("");
225 else {
226 dft->voi[dft->voiNr+i].y[k]=atof(tmp);
227 if(dft->voi[dft->voiNr+i].y[k]<-3.e38)
228 dft->voi[dft->voiNr+i].y[k]=nan("");
229 }
230 i++;
231 }
232 for(l=i; l<nr; l++) dft->voi[dft->voiNr+l].y[k]=nan("");
233 k++;
234 c=fgetc(fp); if(c=='#') roikbq_move_to_next_line(fp); else ungetc(c, fp);
235 }
236 for(i=k; i<frame_nr; i++) {
237 dft->x[i]=0.;
238 for(j=dft->voiNr; j<dft->voiNr+nr; j++) dft->voi[j].y[i]=nan("");
239 }
240 /* Set voiNr and frameNr and close the file */
241 dft->voiNr=nr; dft->frameNr=frame_nr; fclose(fp);
242 /* Set data unit based on filename */
243 if(strstr(fname, ".nci")==NULL && strstr(fname, ".NCI")==NULL)
244 strcpy(dft->unit, "kBq/ml");
245 else strcpy(dft->unit, "nCi/ml");
246 /* Set weights in DFT to 1.0 */
247 dft->isweight=0;
248 for(i=0; i<dft->frameNr; i++) dft->w[i]=1.0;
249 /* quit */
250 return(0);
251}
252/*****************************************************************************/
253
254/*****************************************************************************/
255/*
256 * Local functions
257 */
259
260/* Removes spaces (and tabs and newlines etc) from string */
261void roikbq_strip_spaces(char *s)
262{
263 int i, len;
264
265 len=strlen(s);
266 for(i=len-1; i>=0; i--) if(isspace((int)s[i])) s[i]=(char)0; else break;
267 len=i;
268 for(i=0; i<len; i++) if(!isspace((int)s[i])) {if(i>0) strcpy(s, &s[i]); break;}
269}
270
271/* Moves file pointer to the start of next line, which is not a comment line
272 or empty line. */
273void roikbq_move_to_next_line(FILE *fp)
274{
275 char ch;
276
277 do {
278 do {ch=fgetc(fp);} while(ch!=EOF && ch!='\n' && ch!='\r');
279 if(ch!=EOF) ch=fgetc(fp);
280 } while(ch!=EOF && (ch=='\n' || ch=='\r' || ch=='#'));
281 ungetc(ch, fp);
282}
283
284/* Copy max nr characters from text file fp;
285 stops if linefeed or EOF is found, but does not include these,
286 as original fgets does.
287 Returns the actual number of chars read.
288*/
289int roikbq_fgets(FILE *fp, int nr, char *s)
290{
291 int i=0;
292 char ch;
293
294 do {
295 ch=fgetc(fp);
296 if(i<nr && ch!=EOF && ch!='\n' && ch!='\r') {*s++=ch; i++;} else break;
297 } while(i<nr && ch!=EOF && ch!='\n' && ch!='\r');
298 *s='\0';
299 return(i);
300}
302/*****************************************************************************/
303
304/*****************************************************************************/
char dfterrmsg[64]
Definition dft.c:6
int dftSetmem(DFT *data, int frameNr, int voiNr)
Definition dft.c:57
void dftEmpty(DFT *data)
Definition dft.c:20
Header file for libtpccurveio.
#define BACKUP_EXTENSION
#define MAX_REGIONNAME_LEN
Definition libtpcmisc.h:154
int roikbqRead(char *fname, DFT *dft)
Definition ncifile.c:95
int roikbqWrite(DFT *dft, char *fname)
Definition ncifile.c:26
#define ROIKBQ_MAX_LINE_LEN
Definition ncifile.c:12
int _type
int timetype
Voi * voi
int timeunit
char studynr[MAX_STUDYNR_LEN+1]
double * w
double * x1
int voiNr
double * x2
int frameNr
int isweight
double * x
char unit[MAX_UNITS_LEN+1]
double size
char voiname[MAX_REGIONSUBNAME_LEN+1]
double * y
char name[MAX_REGIONNAME_LEN+1]
char hemisphere[MAX_REGIONSUBNAME_LEN+1]
char place[MAX_REGIONSUBNAME_LEN+1]