TPCCLIB
Loading...
Searching...
No Matches
abssio.c File Reference

Functions for writing raw ABSS data files. More...

#include "tpcclibConfig.h"
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include <string.h>
#include "tpcabss.h"

Go to the source code of this file.

Functions

ABSS_DEVICE abssIdFromFName (const char *fname)
int abssWrite (TAC *d, FILE *fp, TPCSTATUS *status)

Detailed Description

Functions for writing raw ABSS data files.

ABSS raw data read functions are not here but in libtpctac, in order to prevent user from accidentally reading raw ABSS data as input function.

Author
Vesa Oikonen

Definition in file abssio.c.

Function Documentation

◆ abssIdFromFName()

ABSS_DEVICE abssIdFromFName ( const char * fname)

Identify ABSS device based on filename.

Returns
the enum ABSS_DEVICE, which is ABSS_UNKNOWN if format cannot be identified.
See also
tacRead, abssWrite
Parameters
fnameABSS data filename

Definition at line 30 of file abssio.c.

33 {
34 if(fname==NULL || strnlen(fname, 10)<5) return(ABSS_UNKNOWN);
35 /* Get pointer to the extension, starting with the dot */
36 char *cptr=filenameGetExtension(fname);
37 if(cptr==NULL) return(ABSS_UNKNOWN);
38 if(strcasecmp(cptr, ".lis")==0) return(ABSS_SCANDITRONICS);
39 if(strcasecmp(cptr, ".bld")==0) return(ABSS_GEMS);
40 if(strcasecmp(cptr, ".alg")==0) return(ABSS_ALLOGG_OLD);
41 if(strcasecmp(cptr, ".txt")==0) return(ABSS_ALLOGG);
42 return(ABSS_UNKNOWN);
43}
char * filenameGetExtension(const char *s)
Get the last extension of a file name.
Definition filename.c:178
size_t strnlen(const char *s, size_t n)
Definition stringext.c:566

◆ abssWrite()

int abssWrite ( TAC * d,
FILE * fp,
TPCSTATUS * status )

Write ABSS data into file opened for writing.

Returns
enum tpcerror (TPCERROR_OK when successful).
See also
tacRead, tacInit, tacFree, abssIdFromFName
Author
Vesa Oikonen
Parameters
dPointer to ABSS data, stored in TAC struct, contents of which are to be written
fpOutput file pointer
statusPointer to status data; enter NULL if not needed

Definition at line 53 of file abssio.c.

61 {
62 int verbose=0; if(status!=NULL) verbose=status->verbose;
63 if(verbose>0) {printf("%s()\n", __func__); fflush(stdout);}
64 if(fp==NULL) {
65 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_CANNOT_WRITE);
67 }
68 if(d==NULL || d->sampleNr<1 || d->tacNr<1) {
69 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_DATA);
70 return TPCERROR_NO_DATA;
71 }
72
73 char buf[1024];
74 int ret=TPCERROR_OK;
75
77
78 ret=TPCERROR_OK;
79
80 /* Write the header */
81 int ii;
82 d->h.space_before_eq=0; d->h.space_after_eq=1; /* Set no space before ':' */
83 ii=iftFindKey(&d->h, "Protocol", 0);
84 if(ii>=0) ret=iftWriteItem(&d->h, ii, fp, status);
85 if(ret!=TPCERROR_OK) {
86 statusSet(status, __func__, __FILE__, __LINE__, ret); return(ret);
87 }
88
89 if(tacGetHeaderStudynr(&d->h, buf, NULL)!=TPCERROR_OK) {
90 ii=iftFindKey(&d->h, "Patient", 0);
91 if(ii>=0) strlcpy(buf, d->h.item[ii].value, 256); else strcpy(buf, "");
92 }
93 fprintf(fp, "# Patient: %s\n", buf);
94
95 if(tacGetHeaderIsotope(&d->h, buf, NULL)==TPCERROR_OK) {
96 double hl=isotopeHalflife(isotopeIdentify(buf));
97 if(!isnan(hl)) sprintf(buf, "%f", hl); else strcpy(buf, "");
98 } else {
99 ii=iftFindKey(&d->h, "Isotope half-life", 0);
100 if(ii>=0) strlcpy(buf, d->h.item[ii].value, 256); else strcpy(buf, "");
101 }
102 fprintf(fp, "# Isotope half-life: %s\n", buf);
103
104 fprintf(fp, "# Start Interv 1st detector pair");
105 fprintf(fp, " 2nd detector pair AUX\n");
106 fprintf(fp, "# time time coinc singl1 singl2");
107 fprintf(fp, " coinc singl1 singl2 counts\n");
108
109 ii=iftFindKey(&d->h, "sampler_start_time", 0);
110 if(ii>=0) {
111 fprintf(fp, "# %s\n", d->h.item[ii].value);
112 } else if(tacGetHeaderScanstarttime(&d->h, buf, NULL)==TPCERROR_OK) {
113 fprintf(fp, "# %s\n", buf);
114 }
115
116
117 /* Write the sample data */
118 double sod=0.0; /* Time from start of the day */
119 if(tacGetHeaderScanstarttime(&d->h, buf, NULL)==TPCERROR_OK) {
120 struct tm tmsod;
121 if(!strDateTimeRead(buf, &tmsod))
122 sod=3600.*tmsod.tm_hour+60.*tmsod.tm_min+tmsod.tm_sec;
123 }
124 int i, j;
125 for(i=0; i<d->sampleNr; i++) {
126 fprintf(fp, "%9.1f %9.1f %9.1f", sod+d->x1[i], d->x1[i], d->x2[i]-d->x1[i]);
127 for(j=0; j<7; j++) {
128 if(j<d->tacNr) fprintf(fp, " %7.0f", d->c[j].y[i]);
129 else fprintf(fp, " %7.0f", 0.0);
130 }
131 if(fprintf(fp, "\n")<1) {ret=TPCERROR_CANNOT_WRITE; break;}
132 }
133 if(ret!=TPCERROR_OK) {
134 statusSet(status, __func__, __FILE__, __LINE__, ret); return(ret);
135 }
136
137 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OK);
138 return(TPCERROR_OK);
139 }
140
141
143
144 ret=TPCERROR_OK;
145
146 /* Write the header */
147 fprintf(fp, "# Scanditronics Automated Blood Measurement System\n");
148 int ii;
149 d->h.space_before_eq=0; d->h.space_after_eq=1; /* Set no space before ':' */
150 ii=iftFindKey(&d->h, "Protocol", 0);
151 if(ii>=0) ret=iftWriteItem(&d->h, ii, fp, status);
152 if(ret!=TPCERROR_OK) {
153 statusSet(status, __func__, __FILE__, __LINE__, ret); return(ret);
154 }
155
156 fprintf(fp, "# Start Interv 1st detector pair");
157 fprintf(fp, " 2nd detector pair AUX\n");
158 fprintf(fp, "# time time coinc singl1 singl2");
159 fprintf(fp, " coinc singl1 singl2 counts\n");
160
161 ii=iftFindKey(&d->h, "sampler_start_time", 0);
162 if(ii>=0) {
163 fprintf(fp, "# %s\n", d->h.item[ii].value);
164 } else if(tacGetHeaderScanstarttime(&d->h, buf, NULL)==TPCERROR_OK) {
165 fprintf(fp, "# %s\n", buf);
166 }
167
168
169 /* Write the sample data */
170 time_t t=0.0;
171 if(tacGetHeaderScanstarttime(&d->h, buf, NULL)==TPCERROR_OK) {
172 //printf("scanstarttime=%s\n", buf);
173 struct tm tmsod;
174 if(!strDateTimeRead(buf, &tmsod)) t=mktime(&tmsod);
175 }
176 int i, j;
177 for(i=0; i<d->sampleNr; i++) {
178 fprintf(fp, "%13.1f %9.1f %9.1f",
179 d->x1[i]+(unsigned long int)t, d->x1[i], d->x2[i]-d->x1[i]);
180 for(j=0; j<7; j++) {
181 if(j<d->tacNr) fprintf(fp, " %7.0f", d->c[j].y[i]);
182 else fprintf(fp, " %7.0f", 0.0);
183 }
184 if(fprintf(fp, "\n")<1) {ret=TPCERROR_CANNOT_WRITE; break;}
185 }
186 if(ret!=TPCERROR_OK) {
187 statusSet(status, __func__, __FILE__, __LINE__, ret); return(ret);
188 }
189
190 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OK);
191 return(TPCERROR_OK);
192 }
193
194
196
197 ret=TPCERROR_OK;
198
199 if(d->tacNr<2) {
200 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_DATA);
201 return(TPCERROR_NO_DATA);
202 }
203
204 /* Write the header */
205 fprintf(fp, "# Allogg1\n");
206 int ii;
207 d->h.space_before_eq=0; d->h.space_after_eq=1; /* Set no space before ':' */
208
209 ii=iftFindKey(&d->h, "Protocol", 0);
210 if(ii>=0) ret=iftWriteItem(&d->h, ii, fp, status);
211 if(ret!=TPCERROR_OK) {
212 statusSet(status, __func__, __FILE__, __LINE__, ret); return(ret);
213 }
214
215 ii=iftFindKey(&d->h, "Discriminators", 0);
216 if(ii>=0) ret=iftWriteItem(&d->h, ii, fp, status);
217 if(ret!=TPCERROR_OK) {
218 statusSet(status, __func__, __FILE__, __LINE__, ret); return(ret);
219 }
220
221 if(tacGetHeaderScanstarttime(&d->h, buf, NULL)==TPCERROR_OK) {
222 fprintf(fp, "# %s\n", buf);
223 }
224
225 ii=iftSearchKey(&d->h, "Background", 0);
226 if(ii>=0) ret=iftWriteItem(&d->h, ii, fp, status);
227 if(ret!=TPCERROR_OK) {
228 statusSet(status, __func__, __FILE__, __LINE__, ret); return(ret);
229 }
230
231 /* Start time in format HHMMSS */
232 if(tacGetHeaderScanstarttime(&d->h, buf, NULL)==TPCERROR_OK) {
233 fprintf(fp, "\n%2.2s%2.2s%2.2s\n", buf+11, buf+14, buf+17);
234 } else {
235 fprintf(fp, "\n000000\n");
236 }
237
238 /* Write the sample data */
239 for(int i=0; i<d->sampleNr; i++) {
240 if(fprintf(fp, "%6.1f %5.0f %5.0f\n",
241 d->x2[i], d->c[0].y[i], d->c[1].y[i]) < 10)
242 {
243 ret=TPCERROR_CANNOT_WRITE; break;
244 }
245 }
246 if(ret!=TPCERROR_OK) {
247 statusSet(status, __func__, __FILE__, __LINE__, ret); return(ret);
248 }
249
250 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OK);
251 return(TPCERROR_OK);
252 }
253
254
256
257 if(d->tacNr<2) {
258 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_DATA);
259 return(TPCERROR_NO_DATA);
260 }
261
262 int ii;
263 //d->h.space_before_eq=0; d->h.space_after_eq=1; /* Set no space before ':' */
264 ret=TPCERROR_OK;
265
266 /* Write the background */
267 ii=iftSearchKey(&d->h, "background counts", 0);
268 if(ii>=0 &&
269 fprintf(fp, "%s :\t%s\n", d->h.item[ii].key, d->h.item[ii].value)<10)
270 {
271 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_CANNOT_WRITE);
273 }
274
275 /* Write the header */
276 fprintf(fp, "//Heading\n");
277
278 ii=iftFindKey(&d->h, "System ID", 0);
279 if(ii>=0) fprintf(fp, "%s:\t%s\n", d->h.item[ii].key, d->h.item[ii].value);
280 ii=iftFindKey(&d->h, "User name", 0);
281 if(ii>=0) fprintf(fp, "%s:\t%s\n", d->h.item[ii].key, d->h.item[ii].value);
282 ii=iftFindKey(&d->h, "Run number", 0);
283 if(ii>=0) fprintf(fp, "%s:\t%s\n", d->h.item[ii].key, d->h.item[ii].value);
284 ii=iftFindKey(&d->h, "Patient ID", 0);
285 if(ii>=0) fprintf(fp, "%s:\t%s\n", d->h.item[ii].key, d->h.item[ii].value);
286 ii=iftFindKey(&d->h, "HalfTime", 0);
287 if(ii>=0) fprintf(fp, "%s:\t%s\n", d->h.item[ii].key, d->h.item[ii].value);
288 ii=iftFindKey(&d->h, "Tube length", 0);
289 if(ii>=0) fprintf(fp, "%s:\t%s\n", d->h.item[ii].key, d->h.item[ii].value);
290 ii=iftFindKey(&d->h, "Pump speed", 0);
291 if(ii>=0) fprintf(fp, "%s:\t%s\n", d->h.item[ii].key, d->h.item[ii].value);
292 ii=iftFindKey(&d->h, "DeadTimeSingles", 0);
293 if(ii>=0) fprintf(fp, "%s:\t%s\n", d->h.item[ii].key, d->h.item[ii].value);
294 ii=iftFindKey(&d->h, "DeadTimeCoincidents", 0);
295 if(ii>=0) fprintf(fp, "%s:\t%s\n", d->h.item[ii].key, d->h.item[ii].value);
296 ii=iftFindKey(&d->h, "DiscriminatorSingles", 0);
297 if(ii>=0) fprintf(fp, "%s:\t%s\n", d->h.item[ii].key, d->h.item[ii].value);
298 ii=iftFindKey(&d->h, "DiscriminatorCoincidents", 0);
299 if(ii>=0) fprintf(fp, "%s:\t%s\n", d->h.item[ii].key, d->h.item[ii].value);
300 ii=iftFindKey(&d->h, "EffectivitySingles", 0);
301 if(ii>=0) fprintf(fp, "%s:\t%s\n", d->h.item[ii].key, d->h.item[ii].value);
302 ii=iftFindKey(&d->h, "EffectivityCoincidents", 0);
303 if(ii>=0) fprintf(fp, "%s:\t%s\n", d->h.item[ii].key, d->h.item[ii].value);
304
305 /* Write the data */
306 if(fprintf(fp, "//Data\n")<6) {
307 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_CANNOT_WRITE);
309 }
310 fprintf(fp, "Absolute time\t");
311 fprintf(fp, "Time after start [s]\t");
312 fprintf(fp, "Singles [cnt]\t");
313 fprintf(fp, "Coincidents [cnt]\t");
314 fprintf(fp, "Singles count rate [kBq/ml]\t");
315 fprintf(fp, "Coincidents count rate [kBq/ml]\t");
316 fprintf(fp, "Singles count rate DTC [kBq/ml]\t");
317 fprintf(fp, "Coincidents count rate DTC [kBq/ml]\t");
318 fprintf(fp, "Singles DTC&decay [kBq/ml]\t");
319 fprintf(fp, "Coincidents DTC&decay [kBq/ml]\n");
320 struct tm tmtod;
321 if(tacGetHeaderScanstarttime(&d->h, buf, NULL)==TPCERROR_OK) {
322 //printf("scanstarttime=%s\n", buf);
323 strDateTimeRead(buf, &tmtod);
324 }
325 int i, j;
326 for(i=0; i<d->sampleNr; i++) {
327 if(i>0) tmAdd(d->x1[i]-d->x1[i-1], &tmtod);
328 if(strftime(buf, 32, "%Y-%m-%d %H:%M:%S", &tmtod)==0)
329 strcpy(buf, "1970-01-01 00:00:00");
330 fprintf(fp, "%s\t%.1f\t%.0f\t%.0f",
331 buf, d->x1[i], d->c[0].y[i], d->c[1].y[i]);
332 for(j=2; j<8; j++) {
333 if(j<d->tacNr) fprintf(fp, "\t%.12f", d->c[j].y[i]);
334 else fprintf(fp, "\t%f", 0.0);
335 }
336 if(fprintf(fp, "\n")<1) {ret=TPCERROR_CANNOT_WRITE; break;}
337 }
338 if(ret!=TPCERROR_OK) {
339 statusSet(status, __func__, __FILE__, __LINE__, ret); return(ret);
340 }
341
342 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OK);
343 return(TPCERROR_OK);
344 }
345
346
347 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_UNSUPPORTED);
348 return(TPCERROR_UNSUPPORTED);
349}
int strDateTimeRead(const char *str, struct tm *date)
Definition datetime.c:350
void tmAdd(int s, struct tm *d)
Definition datetime.c:500
int iftSearchKey(IFT *ift, const char *s, int start_index)
Definition iftfind.c:86
int iftFindKey(IFT *ift, const char *key, int start_index)
Definition iftfind.c:30
int iftWriteItem(IFT *ift, int item, FILE *fp, TPCSTATUS *status)
Definition iftio.c:25
double isotopeHalflife(int isotope_code)
Definition isotope.c:62
int isotopeIdentify(const char *isotope)
Definition isotope.c:145
void statusSet(TPCSTATUS *s, const char *func, const char *srcfile, int srcline, tpcerror error)
Definition statusmsg.c:142
size_t strlcpy(char *dst, const char *src, size_t dstsize)
Definition stringext.c:632
char * value
Definition tpcift.h:37
char * key
Definition tpcift.h:32
IFT_ITEM * item
Definition tpcift.h:57
int space_after_eq
Definition tpcift.h:55
int space_before_eq
Definition tpcift.h:53
double * y
Definition tpctac.h:75
tacformat format
Definition tpctac.h:93
int sampleNr
Definition tpctac.h:89
IFT h
Optional (but often useful) header information.
Definition tpctac.h:141
TACC * c
Definition tpctac.h:117
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.
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 tacGetHeaderIsotope(IFT *h, char *s, TPCSTATUS *status)
Definition tacift.c:290
@ TPCERROR_UNSUPPORTED
Unsupported file type.
@ TPCERROR_OK
No error.
@ TPCERROR_NO_DATA
File contains no data.
@ TPCERROR_CANNOT_WRITE
Cannot write file.
@ TAC_FORMAT_ABSS_ALLOGG
ALLOGG ABSS data; reading supported.
Definition tpctac.h:56
@ TAC_FORMAT_ABSS_GEMS
GEMS ABSS data; reading supported.
Definition tpctac.h:54
@ TAC_FORMAT_ABSS_ALLOGG_OLD
ALLOGG ABSS data (old format); reading supported.
Definition tpctac.h:55
@ TAC_FORMAT_ABSS_SCANDITRONICS
Scanditronics ABSS data; reading supported.
Definition tpctac.h:53