TPCCLIB
Loading...
Searching...
No Matches
sifio.c
Go to the documentation of this file.
1
4/*****************************************************************************/
5#include "tpcclibConfig.h"
6/*****************************************************************************/
7#include "tpcift.h"
8#include "tpcisotope.h"
9#include "tpccsv.h"
10/*****************************************************************************/
11#include <stdio.h>
12#include <stdlib.h>
13#include <math.h>
14#include <time.h>
15#include <string.h>
16/*****************************************************************************/
17#include "tpctac.h"
18/*****************************************************************************/
19
20/*****************************************************************************/
29 TAC *tac,
31 FILE *fp,
34 int extra,
36 TPCSTATUS *status
37) {
38 int verbose=0; if(status!=NULL) verbose=status->verbose;
39 if(fp==NULL) {
40 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_CANNOT_WRITE);
42 }
43 if(tac==NULL || tac->sampleNr<1) {
44 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_DATA);
45 return TPCERROR_NO_DATA;
46 }
47 if(verbose>0) printf("%s()\n", __func__);
48
49 int fi, ret, n;
50 int m2s=0; // 1=time units converted from min to sec
51
52 /* Scan start time */
53 char scan_start_time[20];
54 ret=tacGetHeaderScanstarttime(&tac->h, scan_start_time, NULL);
55 if(ret==TPCERROR_OK) {
56 int yy, mm, dd, h, m, s;
57 n=sscanf(scan_start_time, "%d-%d-%d %d:%d:%d", &yy, &mm, &dd, &h, &m, &s);
58 if(n==6)
59 sprintf(scan_start_time, "%d/%d/%04d %02d:%02d:%02d", dd, mm, yy, h, m, s);
60 else strcpy(scan_start_time, "1/1/1970 00:00:00");
61 } else { // use default date & time
62 strcpy(scan_start_time, "1/1/1970 00:00:00");
63 }
64 /* Column nr */
65 int colNr=2; // frame start and end times
66 colNr+=tac->tacNr;
67 /* Study number */
68 char studynr[MAX_STUDYNR_LEN+1];
69 ret=tacGetHeaderStudynr(&tac->h, studynr, NULL);
70 if(ret!=TPCERROR_OK) strcpy(studynr, ".");
71 /* Isotope */
73 ret=tacGetHeaderIsotope(&tac->h, isotope, NULL);
74 if(ret!=TPCERROR_OK) strcpy(studynr, "");
75 /* Write header line */
76 n=fprintf(fp, "%s %d %d 1 %s %s\n", scan_start_time, tac->sampleNr, colNr, studynr, isotope);
77 if(n<7) {
78 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_CANNOT_WRITE);
80 }
81
82 /* Convert frame times to seconds because always sec in SIF */
83 if(tac->tunit==UNIT_MIN) {m2s=1; tacXUnitConvert(tac, UNIT_SEC, status);}
84
85 /* Check if frame times need to printed with decimals */
86 int req_decimals=0;
87 for(fi=1; fi<tac->sampleNr; fi++) {
88 if(round(tac->x1[fi])==round(tac->x1[fi-1])) {req_decimals=1; break;}
89 if(round(tac->x2[fi])==round(tac->x2[fi-1])) {req_decimals=1; break;}
90 }
91
92 /* Write data lines */
93 ret=0;
94 for(fi=0; fi<tac->sampleNr; fi++) {
95 if(req_decimals==0) n=fprintf(fp, "%.0f %.0f", tac->x1[fi], tac->x2[fi]);
96 else n=fprintf(fp, "%.1f %.1f", tac->x1[fi], tac->x2[fi]);
97 if(n<3) {ret++; break;}
98 for(int ci=0; ci<tac->tacNr; ci++) {
99 n=fprintf(fp, " %.0f", tac->c[ci].y[fi]);
100 if(n<2) {ret++; break;}
101 }
102 if(ret==0) fprintf(fp, "\n"); else break;
103 }
104 if(ret!=0) {
105 if(m2s!=0) tacXUnitConvert(tac, UNIT_MIN, status);
106 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_CANNOT_WRITE);
108 }
109
110 /* Convert frame times back to min if necessary */
111 if(m2s!=0) tacXUnitConvert(tac, UNIT_MIN, status);
112
113 /* Write extra information */
114 if(extra!=0) {
115 /* do nothing at least for now */
116 }
117
118 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OK);
119 return(TPCERROR_OK);
120}
121/*****************************************************************************/
122
123/*****************************************************************************/
135 TAC *tac,
137 CSV *csv,
140 IFT *hdr,
142 TPCSTATUS *status
143) {
144 int verbose=0; if(status!=NULL) verbose=status->verbose;
145 if(verbose>0) {printf("%s(tac, csv, hdr, status)\n", __func__); fflush(stdout);}
146
147
148
149 if(tac==NULL) {
150 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_FAIL);
151 return TPCERROR_FAIL;
152 }
153 tacFree(tac);
154 if(csv==NULL || csv->row_nr<1 || csv->col_nr<1) {
155 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_DATA);
156 return TPCERROR_NO_DATA;
157 }
158
159 /* Check whether CSV file even can contain SIF data */
160 if(verbose>2) {printf(" checking that CSV contains SIF\n"); fflush(stdout);}
161 int title_item_nr;
162 title_item_nr=csvRowLength(csv, 0);
163 if(title_item_nr==1 && csv->separator!=' ') {
164 if(verbose>1) printf("title_item_nr := %d\n", title_item_nr);
165 if(verbose>2) {printf(" SIF has not space character as column separator; fixing title line\n");}
166 //printf("content='%s'\n", csv->c[0].content);
167 char s1[128]; int n=0;
168 int len=strTokenNCpy(csv->c[0].content, " ,;\t", n+1, s1, 128);
169 if(!(len>0)) {
170 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_FORMAT);
172 }
173 n++; //printf("n=%d s1='%s'\n", n, s1);
174 char s[128];
175 while(strTokenNCpy(csv->c[0].content, " ,;\t", n+1, s, 128)>0) {
176 n++; //printf("n=%d s='%s'\n", n, s);
177 if(n==2) csvPutString(csv, s, 1); else csvPutString(csv, s, 0);
178 }
179 if(n>csv->col_nr) csv->col_nr=n;
180 strcpy(csv->c[0].content, s1);
181 int j=1;
182 for(int i=1+csv->nr-n; i<csv->nr; i++) {
183 //printf("content[%d]='%s'\n", i, csv->c[i].content);
184 csv->c[i].row=0; csv->c[i].col=j; j++;
185 }
186 csv->row_nr--;
187 csvReorg(csv, NULL);
188 title_item_nr=csvRowLength(csv, 0);
189 //csvList(csv, stdout);
190 }
191
192 if(csv->row_nr<2 || title_item_nr<5 ) {
193 if(verbose>1) {printf("title_item_nr := %d\n", title_item_nr); csvList(csv, stdout);}
194 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_FORMAT);
196 }
197
198 int ret;
199
200 /* Allocate memory for TAC data */
201 if(verbose>2) {printf(" allocating memory\n"); fflush(stdout);}
202 ret=tacAllocate(tac, csv->row_nr-1, 3);
203 statusSet(status, __func__, __FILE__, __LINE__, ret);
204 if(ret!=TPCERROR_OK) return ret;
205 /* Set initial SIF data size */
206 tac->tacNr=2;
207 tac->sampleNr=csv->row_nr-1;
208 /* Set basic header information */
210 tac->isframe=1; // SIF always contains frame start and end times
211 tac->tunit=UNIT_SEC;
212 tac->cunit=UNIT_COUNTS;
213
214 /* Set SIF compatible titles into TAC struct */
215 strcpy(tac->c[0].name, "Prompts");
216 strcpy(tac->c[1].name, "Randoms");
217 strcpy(tac->c[2].name, "Trues"); // computed, not saved
218
219 /* Read SIF title line */
220 if(verbose>2) {printf(" reading SIF header\n"); fflush(stdout);}
221 /* scan start time */
222 char sif_scan_start_time[20];
223 ret=0;
224 if(strlen(csv->c[0].content)<11 && strlen(csv->c[1].content)<9) {
225 char temp[20];
226 strcpy(temp, csv->c[0].content); strcat(temp, " ");
227 strcat(temp, csv->c[1].content);
228 if(verbose>4) printf(" datetime := '%s'\n", temp);
229 ret=strDateTimeValid(temp, sif_scan_start_time);
230 if(ret!=0) {
231 if(verbose>1) printf(" invalid SIF date/time (%d).\n", ret);
232 else if(verbose>0) printf(" invalid SIF date/time.\n");
233 if(ret<0) ret=0; // its common that SIF time is 1/1/1970 etc
234 }
235 } else ret=1;
236 if(ret!=0) {
237 if(verbose>2) {
238 printf(" cell0 := '%s'\n", csv->c[0].content);
239 printf(" cell1 := '%s'\n", csv->c[1].content);
240 }
241 tacFree(tac);
242 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_VALUE);
244 }
245 if(verbose>1) printf("sif_scan_start_time := %s\n", sif_scan_start_time);
246 /* Nr of frames */
247 int frameNr;
248 frameNr=atoi(csv->c[2].content);
249 if(verbose>1) printf("sif_frame_nr := %d\n", frameNr);
250 if(frameNr<1 || frameNr>tac->_sampleNr) {
251 tacFree(tac);
252 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_FORMAT);
254 }
255 tac->sampleNr=frameNr;
256 /* Nr of columns */
257 int colNr;
258 colNr=atoi(csv->c[3].content);
259 if(verbose>1) printf("sif_col_nr := %d\n", colNr);
260 if(colNr<2) {
261 tacFree(tac);
262 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_FORMAT);
264 }
265 /* SIF version; forget about it */
266 /* Study number; may be missing */
267 char studynr[MAX_STUDYNR_LEN+1]; studynr[0]='\0';
268 if(title_item_nr>5) {
269 strlcpy(studynr, csv->c[5].content, MAX_STUDYNR_LEN+1);
270 if(strcmp(studynr, ".")==0) strcpy(studynr, "");
271 if(verbose>2) printf("sif_studynr := %s\n", studynr);
272 }
273 /* Isotope; may be missing */
274 char isotope[MAX_ISOTOPE_LEN+1]; strcpy(isotope, "unknown");
275 if(title_item_nr>6) {
276 int isocode;
277 isocode=isotopeIdentify(csv->c[6].content);
278 strcpy(isotope, isotopeName(isocode));
279 }
280 if(verbose>1) printf("sif_isotope := %s\n", isotope);
281
282 /* Read SIF frames */
283 if(verbose>2) {printf(" reading SIF frames\n"); fflush(stdout);}
284 ret=0;
285 int fi, ri, ci;
286 double v;
287 for(fi=0; fi<tac->sampleNr; fi++) {
288 ri=fi+1;
289 /* frame start time */
290 ci=0; v=atofVerified(csvCell(csv, ri, ci));
291 if(isnan(v)) {ret++; break;} else tac->x1[fi]=v;
292 /* frame end time */
293 ci=1; v=atofVerified(csvCell(csv, ri, ci));
294 if(isnan(v)) {ret++; break;} else tac->x2[fi]=v;
295 tac->x[fi]=0.5*(tac->x1[fi]+tac->x2[fi]);
296 /* Prompts, randoms, and trues, maybe missing */
297 tac->c[0].y[fi]=0.0;
298 tac->c[1].y[fi]=0.0;
299 tac->c[2].y[fi]=0.0;
300 if(colNr<3) continue;
301 /* so prompts should be there */
302 ci=2; v=atofVerified(csvCell(csv, ri, ci));
303 if(isnan(v)) {ret++; break;} else tac->c[0].y[fi]=v;
304 if(colNr<4) continue;
305 /* so randoms should be there */
306 ci=3; v=atofVerified(csvCell(csv, ri, ci));
307 if(isnan(v)) {ret++; break;} else tac->c[1].y[fi]=v;
308 /* If trues not available, then trues=prompts-randoms */
309 if(colNr<5) {
310 tac->c[2].y[fi]=tac->c[0].y[fi]-tac->c[1].y[fi];
311 continue;
312 }
313 /* so trues should be there */
314 ci=4; v=atofVerified(csvCell(csv, ri, ci));
315 if(isnan(v)) {ret++; break;} else tac->c[2].y[fi]=v;
316 }
317 if(ret!=0) {
318 tacFree(tac);
319 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_FORMAT);
321 }
322
323 /* Set TAC header */
324 /* Isotope */
325 if(isotopeIdentify(isotope)<=0 && hdr!=NULL) {
326 /* SIF did not contain valid isotope code, get it from argument hdr */
327 ret=tacGetHeaderIsotope(hdr, isotope, NULL);
328 /* and delete it from hdr */
329 if(ret==TPCERROR_OK) tacSetHeaderIsotope(hdr, NULL);
330 }
332 /* Studynumber */
333 if(!studynr[0] && hdr!=NULL) {
334 /* SIF did not contain studynumber, get it from argument hdr */
335 ret=tacGetHeaderStudynr(hdr, studynr, NULL);
336 /* and delete it from hdr */
337 if(ret==TPCERROR_OK) {
338 if(verbose>2) printf("sifhdr_studynr := %s\n", studynr);
339 tacSetHeaderStudynr(hdr, NULL);
340 }
341 }
342 if(studynr[0]) {
343 if(verbose>3) printf("setting TAC studynr to '%s'\n", studynr);
344 tacSetHeaderStudynr(&tac->h, studynr);
345 }
346 /* Scan start time */
347 if(strDateTimeValid(sif_scan_start_time, NULL)<0 && hdr!=NULL) {
348 /* SIF did not contain valid scan start time, get it from argument hdr */
349 ret=tacGetHeaderScanstarttime(hdr, sif_scan_start_time, NULL);
350 /* and delete it from hdr */
351 if(ret==TPCERROR_OK) tacSetHeaderScanstarttime(hdr, NULL);
352 }
353 if(strDateTimeValid(sif_scan_start_time, NULL)==0)
354 tacSetHeaderScanstarttime(&tac->h, sif_scan_start_time);
355
356 if(verbose>4) {printf(" %s() out\n", __func__); fflush(stdout);}
357 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OK);
358 return(TPCERROR_OK);
359}
360/*****************************************************************************/
361
362/*****************************************************************************/
char * csvCell(CSV *csv, int row, int col)
Definition csv.c:358
int csvPutString(CSV *csv, const char *s, int newline)
Definition csv.c:144
int csvReorg(CSV *d, TPCSTATUS *status)
Definition csv.c:503
int csvRowLength(CSV *csv, int row)
Definition csv.c:244
int csvList(CSV *csv, FILE *fp)
Definition csvio.c:27
int strDateTimeValid(const char *str, char *intdate)
Definition datetime.c:308
double atofVerified(const char *s)
Definition decpoint.c:75
char * isotopeName(int isotope_code)
Definition isotope.c:101
int isotopeIdentify(const char *isotope)
Definition isotope.c:145
int tacWriteSIF(TAC *tac, FILE *fp, int extra, TPCSTATUS *status)
Definition sifio.c:26
int tacReadSIF(TAC *tac, CSV *csv, IFT *hdr, TPCSTATUS *status)
Definition sifio.c:129
void statusSet(TPCSTATUS *s, const char *func, const char *srcfile, int srcline, tpcerror error)
Definition statusmsg.c:142
int strTokenNCpy(const char *s1, const char *s2, int i, char *s3, int count)
Definition stringext.c:53
size_t strlcpy(char *dst, const char *src, size_t dstsize)
Definition stringext.c:632
int col
Definition tpccsv.h:28
int row
Definition tpccsv.h:26
char * content
Definition tpccsv.h:30
Definition tpccsv.h:36
int row_nr
Definition tpccsv.h:44
int col_nr
Definition tpccsv.h:46
char separator
Definition tpccsv.h:49
CSV_item * c
Definition tpccsv.h:38
int nr
Definition tpccsv.h:42
Definition tpcift.h:43
char name[MAX_TACNAME_LEN+1]
Definition tpctac.h:81
double * y
Definition tpctac.h:75
Definition tpctac.h:87
double * x
Definition tpctac.h:97
tacformat format
Definition tpctac.h:93
int _sampleNr
Definition tpctac.h:121
int sampleNr
Definition tpctac.h:89
IFT h
Optional (but often useful) header information.
Definition tpctac.h:141
int cunit
Definition tpctac.h:105
int isframe
Definition tpctac.h:95
TACC * c
Definition tpctac.h:117
int tunit
Definition tpctac.h:109
double * x2
Definition tpctac.h:101
double * x1
Definition tpctac.h:99
int tacNr
Definition tpctac.h:91
int verbose
Verbose level, used by statusPrint() etc.
void tacFree(TAC *tac)
Definition tac.c:106
int tacAllocate(TAC *tac, int sampleNr, int tacNr)
Definition tac.c:130
int tacSetHeaderScanstarttime(IFT *h, const char *s)
Definition tacift.c:427
int tacGetHeaderScanstarttime(IFT *h, char *s, TPCSTATUS *status)
Definition tacift.c:372
int tacGetHeaderStudynr(IFT *h, char *s, TPCSTATUS *status)
Definition tacift.c:26
int tacSetHeaderIsotope(IFT *h, const char *s)
Definition tacift.c:341
int tacGetHeaderIsotope(IFT *h, char *s, TPCSTATUS *status)
Definition tacift.c:290
int tacSetHeaderStudynr(IFT *h, const char *s)
Definition tacift.c:79
int tacXUnitConvert(TAC *tac, const int u, TPCSTATUS *status)
Definition tacunits.c:23
Header file for library libtpccsv.
@ UNIT_MIN
minutes
@ UNIT_COUNTS
counts
@ UNIT_SEC
seconds
@ TPCERROR_INVALID_VALUE
Invalid value.
@ TPCERROR_FAIL
General error.
@ TPCERROR_INVALID_FORMAT
Invalid file format.
@ TPCERROR_OK
No error.
@ TPCERROR_NO_DATA
File contains no data.
@ TPCERROR_CANNOT_WRITE
Cannot write file.
#define MAX_STUDYNR_LEN
Define max study number length.
Header file for library libtpcift.
Header file for library libtpcisotope.
#define MAX_ISOTOPE_LEN
Max string length for PET isotope.
Definition tpcisotope.h:41
isotope
Definition tpcisotope.h:50
Header file for library libtpctac.
@ TAC_FORMAT_SIF
Scan information file.
Definition tpctac.h:43