TPCCLIB
Loading...
Searching...
No Matches
tacabss.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/*****************************************************************************/
28 TAC *tac,
30 IFT *hdr,
32 TPCSTATUS *status
33) {
34 int verbose=0; if(status!=NULL) verbose=status->verbose;
35 if(tac==NULL) {
36 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_FAIL);
37 return TPCERROR_FAIL;
38 }
39 tacFree(tac);
40 if(hdr==NULL || hdr->keyNr<2) {
41 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_DATA);
42 return TPCERROR_NO_DATA;
43 }
44 if(verbose>0) {printf("%s()\n", __func__); fflush(stdout);}
45
46 /* Check whether IFT even can contain Allogg data */
47 int ii;
48 /* Find the line '//Heading' */
49 ii=iftSearchValue(hdr, "//Heading", 0);
50 if(ii<0) {
51 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_FORMAT);
53 }
54 /* Find the line '//Data' */
55 ii=iftSearchValue(hdr, "//Data", 0);
56 if(ii<0) {
57 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_FORMAT);
59 }
60 /* Sample data should start after this index (right after title) */
61 if(verbose>3) {
62 printf("found '%s' at ii=%d\n", hdr->item[ii].value, ii);
63 fflush(stdout);
64 }
65 /* Allocate memory for TAC data */
66 int ret;
67 ret=tacAllocate(tac, hdr->keyNr-ii, 8);
68 statusSet(status, __func__, __FILE__, __LINE__, ret);
69 if(ret!=TPCERROR_OK) return(ret);
70 tac->tacNr=8;
71 /* Set basic header information */
73 tac->isframe=1; // Allogg data always contains frame start and end times
74 tac->tunit=UNIT_SEC;
75 tac->cunit=UNIT_COUNTS;
76 /* Set TAC names into TAC struct */
77 strcpy(tac->c[0].name, "Singles");
78 strcpy(tac->c[1].name, "Coincidents");
79 strcpy(tac->c[2].name, "Singles-count-rate");
80 strcpy(tac->c[3].name, "Coincidents-count-rate");
81 strcpy(tac->c[4].name, "Singles-count-rate-DTC");
82 strcpy(tac->c[5].name, "Coincidents-count-rate-DTC");
83 strcpy(tac->c[6].name, "Singles-DTC-decay");
84 strcpy(tac->c[7].name, "Coincidents-DTC-decay");
85
86 /* Find the first line starting with valid date and time */
87 struct tm start_time;
88 ii++;
89 for(; ii<hdr->keyNr; ii++) {
90 if(strDateTimeRead(hdr->item[ii].value, &start_time)==0) break;
91 }
92 if(ii==hdr->keyNr) {
93 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_MISSING_DATA);
95 }
96 /* Save the start time of the first sample to be saved later in TAC header */
97 char scan_start_time[32];
98 if(strftime(scan_start_time, 20, "%Y-%m-%d %H:%M:%S", &start_time)==0) {
99 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_DATETIME);
100 return(TPCERROR_NO_DATETIME);
101 }
102 /* Go through the lines, extracting sample data, and deleting data lines
103 from the header; stop storing sample data after first invalid line */
104 if(verbose>2) {printf(" reading data lines...\n"); fflush(stdout);}
105 int i=0, n, stopped=0;
106 while(ii<hdr->keyNr && i<tac->_sampleNr) {
107 if(stopped) {iftDelete(hdr, ii); continue;}
108 if(hdr->item[ii].value[0]=='#') {ii++; continue;}
109 if(hdr->item[ii].value==NULL) {iftDelete(hdr, ii); continue;}
110 if(strnlen(hdr->item[ii].key, 3)>0) {
111 iftDelete(hdr, ii); stopped=1; continue;
112 }
113 if(strDateTimeRead(hdr->item[ii].value, &start_time)!=0) {
114 iftDelete(hdr, ii); stopped=1; continue;
115 }
116 //printf("reading sample '%s'\n", hdr->item[ii].value+20); fflush(stdout);
117 n=sscanf(hdr->item[ii].value+20, "%lf %lf %lf %lf %lf %lf %lf %lf %lf\n",
118 &tac->x1[i],
119 &tac->c[0].y[i], &tac->c[1].y[i], &tac->c[2].y[i], &tac->c[3].y[i],
120 &tac->c[4].y[i], &tac->c[5].y[i], &tac->c[6].y[i], &tac->c[7].y[i]
121 );
122 if(n==9) i++; else stopped=1;
123 iftDelete(hdr, ii);
124 }
125 tac->sampleNr=i;
126 if(verbose>2) printf(" %d data line(s) read.\n", i);
127 if(i<1) {
128 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_DATA);
129 return(TPCERROR_NO_DATA);
130 }
131
132 /* Calculate frame end and mid times */
133 for(i=0; i<tac->sampleNr-1; i++) {
134 tac->x2[i]=tac->x1[i+1];
135 tac->x[i]=0.5*(tac->x1[i]+tac->x2[i]);
136 }
137 /* last sample */
138 if(tac->sampleNr>1) {
139 tac->x2[i]=tac->x1[i]+(tac->x2[i-1]-tac->x1[i-1]);
140 } else {
141 tac->x2[i]=tac->x1[i]+1.0;
142 }
143 tac->x[i]=0.5*(tac->x1[i]+tac->x2[i]);
144
145 /* Delete more lines from the header */
146 ii=iftSearchValue(hdr, "//Heading", 0); if(ii>=0) iftDelete(hdr, ii);
147 ii=iftSearchValue(hdr, "//Data", 0); if(ii>=0) iftDelete(hdr, ii);
148 ii=iftSearchValue(hdr, "Absolute time", 0); if(ii>=0) iftDelete(hdr, ii);
149 /* Set all header lines to comments */
150 for(ii=0; ii<hdr->keyNr; ii++) hdr->item[ii].comment=1;
151 /* Copy the header contents to TAC (deletes previous contents) */
152 (void)iftDuplicate(hdr, &tac->h);
153 tac->h.type=3;
154 /* Copy study number to the TAC header */
155 ii=iftFindKey(hdr, "Run number", 0);
156 if(ii>=0 && strnlen(hdr->item[ii].value, 5)>0)
157 (void)tacSetHeaderStudynr(&tac->h, hdr->item[ii].value);
158 /* Copy the start time of the first sample to the TAC header */
159 (void)tacSetHeaderScanstarttime(&tac->h, scan_start_time);
160
161
162 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OK);
163 return(TPCERROR_OK);
164}
165/*****************************************************************************/
166
167/*****************************************************************************/
175 TAC *tac,
177 IFT *hdr,
179 TPCSTATUS *status
180) {
181 int verbose=0; if(status!=NULL) verbose=status->verbose;
182 if(tac==NULL) {
183 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_FAIL);
184 return TPCERROR_FAIL;
185 }
186 tacFree(tac);
187 if(hdr==NULL || hdr->keyNr<2) {
188 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_DATA);
189 return TPCERROR_NO_DATA;
190 }
191 if(verbose>0) {printf("%s()\n", __func__); fflush(stdout);}
192
193 /* Check whether IFT even can contain Allogg 1 data */
194 int ii;
195 /* Find a specific key */
196 ii=iftFindKey(hdr, "Discriminators", 0);
197 if(ii<0) {
198 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_FORMAT);
200 }
201
202 /* Find the measurement start date and time, and store for later use */
203 char scan_start_time[32];
204 int n, year, month, day, hour, min, sec;
205 char buf[128];
206 for(ii=0; ii<hdr->keyNr; ii++) {
207 if(strnlen(hdr->item[ii].key, 3)>0 || hdr->item[ii].value==NULL) continue;
208 if(strDateTimeValid(hdr->item[ii].value, scan_start_time)==0) {
209 n=sscanf(scan_start_time, "%d-%d-%d %d:%d:%d",
210 &year, &month, &day, &hour, &min, &sec);
211 } else {
212 n=strnlen(hdr->item[ii].value, 15);
213 if(n<8 || n>10) continue;
214 //printf("ii=%d '%s' '%s'\n", ii, hdr->item[ii].key, hdr->item[ii].value);
215 n=sscanf(hdr->item[ii].value, "%d-%d-%d", &year, &month, &day);
216 }
217 if(n==3 || n==6) break;
218 }
219 if(ii==hdr->keyNr) {
220 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_DATETIME);
221 return(TPCERROR_NO_DATETIME);
222 }
223 //printf("found '%s' at ii=%d\n", hdr->item[ii].value, ii);
224
225 /* Find the measurement start time HHMMSS */
226 for(ii=0; ii<hdr->keyNr; ii++) {
227 if(strnlen(hdr->item[ii].key, 3)>0 || hdr->item[ii].value==NULL) continue;
228 //printf("ii=%d '%s' '%s'\n", ii, hdr->item[ii].key, hdr->item[ii].value);
229 if(strnlen(hdr->item[ii].value, 10)==6) break;
230 }
231 if(ii==hdr->keyNr) {
232 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_DATETIME);
233 return(TPCERROR_NO_DATETIME);
234 }
235 //printf("found '%s' at ii=%d\n", hdr->item[ii].value, ii);
236 strlcpy(buf, hdr->item[ii].value, 128); buf[2]=(char)0; hour=atoi(buf);
237 strlcpy(buf, hdr->item[ii].value+2, 128); buf[2]=(char)0; min=atoi(buf);
238 strlcpy(buf, hdr->item[ii].value+4, 128); buf[2]=(char)0; sec=atoi(buf);
239
240 /* Make date and time string and set abss->startTime */
241 sprintf(scan_start_time, "%04d-%02d-%02d %02d:%02d:%02d",
242 year, month, day, hour, min, sec);
243 if(verbose>11) printf(" scan_start_time := %s\n", buf);
244
245 /* Sample data should start after this index */
246 /* Allocate memory for TAC data */
247 int ret;
248 ret=tacAllocate(tac, hdr->keyNr-ii, 2);
249 statusSet(status, __func__, __FILE__, __LINE__, ret);
250 if(ret!=TPCERROR_OK) return(ret);
251 tac->tacNr=2;
252 /* Set basic header information */
254 tac->isframe=1; // Allogg data always contains frame start and end times
255 tac->tunit=UNIT_SEC;
256 tac->cunit=UNIT_COUNTS;
257 /* Set TAC names into TAC struct */
258 strcpy(tac->c[0].name, "Singles");
259 strcpy(tac->c[1].name, "Coincidents");
260
261 /* Go through the lines, extracting sample data, and deleting data lines
262 from the header */
263 if(verbose>2) printf(" reading data lines...\n");
264 ii++;
265 int i=0;
266 while(ii<hdr->keyNr && i<tac->_sampleNr) {
267 if(strnlen(hdr->item[ii].key, 3)>0 || hdr->item[ii].value==NULL) {
268 iftDelete(hdr, ii); continue;}
269 if(hdr->item[ii].value[0]=='#') {iftDelete(hdr, ii); continue;}
270 n=sscanf(hdr->item[ii].value, "%lf %lf %lf",
271 &tac->x2[i], &tac->c[0].y[i], &tac->c[1].y[i]);
272 if(n==3) i++;
273 iftDelete(hdr, ii);
274 }
275 tac->sampleNr=i;
276 if(verbose>2) printf(" %d data line(s) read.\n", i);
277 if(i<1) {
278 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_DATA);
279 return(TPCERROR_NO_DATA);
280 }
281
282 /* Calculate frame start and mid times */
283 for(i=1; i<tac->sampleNr; i++) {
284 tac->x1[i]=tac->x2[i-1];
285 tac->x[i]=0.5*(tac->x1[i]+tac->x2[i]);
286 }
287 /* first sample */
288 i=0;
289 if(tac->sampleNr>1) {
290 tac->x1[i]=tac->x2[i]-(tac->x2[i+1]-tac->x1[i+1]);
291 } else {
292 tac->x1[i]=0.0;
293 }
294 tac->x[i]=0.5*(tac->x1[i]+tac->x2[i]);
295
296 /* Set all header lines to comments */
297 for(ii=0; ii<hdr->keyNr; ii++) hdr->item[ii].comment=1;
298 /* Copy the header contents to TAC (deletes previous contents) */
299 (void)iftDuplicate(hdr, &tac->h);
300 tac->h.type=3;
301 /* Copy the start time to the TAC header */
302 (void)tacSetHeaderScanstarttime(&tac->h, scan_start_time);
303
304
305 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OK);
306 return(TPCERROR_OK);
307}
308/*****************************************************************************/
309
310/*****************************************************************************/
328 TAC *tac,
330 IFT *hdr,
332 TPCSTATUS *status
333) {
334 int verbose=0; if(status!=NULL) verbose=status->verbose;
335 if(tac==NULL) {
336 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_FAIL);
337 return TPCERROR_FAIL;
338 }
339 tacFree(tac);
340 if(hdr==NULL || hdr->keyNr<2) {
341 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_DATA);
342 return TPCERROR_NO_DATA;
343 }
344 if(verbose>0) {printf("%s()\n", __func__); fflush(stdout);}
345
346 /* Check whether IFT contains Scanditronics (or GEMS) data */
347 int format;
348 if(iftSearchValue(hdr, "AUX", 0)<0 ||
349 iftSearchValue(hdr, "1st detector pair", 0)<0)
350 {
351 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_FORMAT);
353 }
355
356 /* Find the measurement start date, possibly with time; Scanditronics
357 header is not required to contain the date and time, because those are
358 stored as the first column in the sample data. */
359 struct tm start_time; start_time.tm_mday=0;
360 int ii, n;
361 for(ii=0; ii<hdr->keyNr; ii++) {
362 if(strnlen(hdr->item[ii].key, 3)>0) continue;
363 n=strnlen(hdr->item[ii].value, 22);
364 if(n<10 || n>19) continue;
365 //printf("ii=%d '%s' '%s'\n", ii, hdr->item[ii].key, hdr->item[ii].value);
366 if(strDateTimeRead(hdr->item[ii].value, &start_time)!=0) {
367 /* Date and time not found, try only date */
368 if(strDateRead(hdr->item[ii].value, &start_time)!=0) continue;
369 }
370 break;
371 }
372 if(verbose>1) {
373 if(ii==hdr->keyNr) printf(" header does not contain date and time.\n");
374 else printf("found '%s' at ii=%d\n", hdr->item[ii].value, ii);
375 }
376
377 /* Sample data should start after this index */
378 /* Allocate memory for TAC data */
379 int ret;
380 ret=tacAllocate(tac, hdr->keyNr-ii, 7);
381 statusSet(status, __func__, __FILE__, __LINE__, ret);
382 if(ret!=TPCERROR_OK) return(ret);
383 tac->tacNr=7;
384 /* Set basic header information */
385 tac->format=format;
386 tac->isframe=1; // Data always contains frame start and end times
387 tac->tunit=UNIT_SEC;
388 tac->cunit=UNIT_COUNTS;
389 /* Set TAC names into TAC struct */
390 strcpy(tac->c[0].name, "Detector1-Coinc");
391 strcpy(tac->c[1].name, "Detector1-Singl1");
392 strcpy(tac->c[2].name, "Detector1-Singl2");
393 strcpy(tac->c[3].name, "Detector2-Coinc");
394 strcpy(tac->c[4].name, "Detector2-Singl1");
395 strcpy(tac->c[5].name, "Detector2-Singl2");
396 strcpy(tac->c[6].name, "AUX-counts");
397
398 /* Go through the lines, extracting sample data, and deleting data lines
399 from the header */
400 if(verbose>2) printf(" reading data lines...\n");
401 ii++;
402 int i=0, stopped=0;
403 double time_of_day, first_tod=0.0, time_since_start, meas_interval;
404 while(ii<hdr->keyNr && i<tac->_sampleNr) {
405 if(stopped) {iftDelete(hdr, ii); continue;}
406 if(strnlen(hdr->item[ii].key, 3)>0 || hdr->item[ii].value==NULL) {
407 iftDelete(hdr, ii); continue;}
408 if(hdr->item[ii].value[0]=='#') {iftDelete(hdr, ii); continue;}
409 //printf("ii=%d '%s'\n", ii, hdr->item[ii].value);
410 n=sscanf(hdr->item[ii].value, "%lf %lf %lf %lf %lf %lf %lf %lf %lf %lf\n",
411 &time_of_day, &time_since_start, &meas_interval,
412 &tac->c[0].y[i], &tac->c[1].y[i], &tac->c[2].y[i], &tac->c[3].y[i],
413 &tac->c[4].y[i], &tac->c[5].y[i], &tac->c[6].y[i]);
414 //printf(" n=%d\n", n);
415 if(n!=10) {
416 /* first line may contain the protocol; keep it as comment */
417 if(i==0) {ii++; continue;}
418 /* Later occurrence is considered as an error */
419 stopped=1; iftDelete(hdr, ii); continue;
420 }
421 if(time_of_day==0.0 && meas_interval==0.0) {
422 stopped=1; iftDelete(hdr, ii); continue;}
423 if(i==0) first_tod=time_of_day;
424 tac->x1[i]=time_since_start;
425 tac->x2[i]=time_since_start+meas_interval;
426 i++;
427 iftDelete(hdr, ii);
428 }
429 tac->sampleNr=i;
430 if(verbose>2) printf(" %d data line(s) read.\n", i);
431 if(i<1) {
432 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_DATA);
433 return(TPCERROR_NO_DATA);
434 }
435 if(verbose>4) printf(" first_tod := %.1lf\n", first_tod);
436
437 /* Calculate frame mid times */
438 for(i=0; i<tac->sampleNr; i++) tac->x[i]=0.5*(tac->x1[i]+tac->x2[i]);
439
440 /* Read scan start date and time from the first sample */
441 char scan_start_time[32], sampler_start_time[32];
442 time_t tim=(time_t)first_tod;
443 struct tm tmtim;
444 if(localtime_r(&tim, &tmtim)==NULL) {
445 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_DATETIME);
446 return(TPCERROR_NO_DATETIME);
447 }
448 /* Check that also date is here; if not, this is actually GEMS data */
449 if(tmtim.tm_year<73) {
450 if(verbose>0) printf("data is not Scanditronics but GEMS format\n");
451 if(verbose>1 &&
452 strftime(scan_start_time, 32, "%Y-%m-%d %H:%M:%S", &tmtim)!=0) {
453 printf("first_sample_time := %s\n", scan_start_time);
454 }
455 tacFree(tac);
456 return(tacReadGEMS(tac, hdr, status));
457 }
458 /* Set scan_start_time based on the first sample */
459 if(strftime(scan_start_time, 32, "%Y-%m-%d %H:%M:%S", &tmtim)==0) {
460 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_DATETIME);
461 return(TPCERROR_NO_DATETIME);
462 }
463 /* Set sampler_start_time based on the header, or first sample, if header
464 does not contain the time */
465 if(start_time.tm_mday==0) { // header did not contain date and time
466 strcpy(sampler_start_time, scan_start_time);
467 } else {
468 /* If header contains just the date but not the time, then take the time
469 from samples */
470 if(start_time.tm_hour==0 && start_time.tm_min==0 && start_time.tm_sec==0) {
471 start_time.tm_hour=tmtim.tm_hour;
472 start_time.tm_min=tmtim.tm_min;
473 start_time.tm_sec=tmtim.tm_sec;
474 }
475 if(strftime(sampler_start_time, 32, "%Y-%m-%d %H:%M:%S", &start_time)==0)
476 strcpy(sampler_start_time, scan_start_time);
477 }
478
479
480 /* Set all header lines to comments */
481 for(ii=0; ii<hdr->keyNr; ii++) hdr->item[ii].comment=1;
482 /* Copy the header contents to TAC (deletes previous contents) */
483 (void)iftDuplicate(hdr, &tac->h);
484 tac->h.type=3;
485 /* Set the scan start time in the TAC header */
486 (void)tacSetHeaderScanstarttime(&tac->h, scan_start_time);
487 /* Set the sampler start time in the TAC header */
488 if(sampler_start_time[0])
489 (void)iftPut(&tac->h, "sampler_start_time", sampler_start_time, 1, NULL);
490 /* Copy study number to the TAC header */
491 ii=iftFindKey(hdr, "Patient", 0);
492 if(ii>=0 && strnlen(hdr->item[ii].value, 5)>0)
493 (void)tacSetHeaderStudynr(&tac->h, hdr->item[ii].value);
494
495 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OK);
496 return(TPCERROR_OK);
497}
498/*****************************************************************************/
499
500/*****************************************************************************/
518 TAC *tac,
520 IFT *hdr,
522 TPCSTATUS *status
523) {
524 int verbose=0; if(status!=NULL) verbose=status->verbose;
525 if(tac==NULL) {
526 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_FAIL);
527 return TPCERROR_FAIL;
528 }
529 tacFree(tac);
530 if(hdr==NULL || hdr->keyNr<2) {
531 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_DATA);
532 return TPCERROR_NO_DATA;
533 }
534 if(verbose>0) {printf("%s()\n", __func__); fflush(stdout);}
535
536 /* Check whether IFT contains GEMS (or Scanditronics) data */
537 int format;
538 if(iftSearchValue(hdr, "AUX", 0)<0 ||
539 iftSearchValue(hdr, "1st detector pair", 0)<0)
540 {
541 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_FORMAT);
543 }
544 if(iftSearchValue(hdr, "Scanditronics", 0)>=0) {
545 if(verbose>0) printf("data is GEMS but Scanditronics format\n");
546 return(tacReadScanditronics(tac, hdr, status));
547 } else {
549 }
550
551 /* Find the measurement start date, possibly with time;
552 at least the date must be there for calibration. */
553 struct tm start_time;
554 int ii, n;
555 for(ii=0; ii<hdr->keyNr; ii++) {
556 if(strnlen(hdr->item[ii].key, 3)>0) continue;
557 n=strnlen(hdr->item[ii].value, 22);
558 if(n<10 || n>19) continue;
559 //printf("ii=%d '%s' '%s'\n", ii, hdr->item[ii].key, hdr->item[ii].value);
560 if(strDateTimeRead(hdr->item[ii].value, &start_time)!=0) {
561 /* Date and time not found, try only date */
562 if(strDateRead(hdr->item[ii].value, &start_time)!=0) continue;
563 }
564 break;
565 }
566 if(ii==hdr->keyNr) {
567 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_DATETIME);
568 return(TPCERROR_NO_DATETIME);
569 }
570 //printf("found '%s' at ii=%d\n", hdr->item[ii].value, ii);
571
572 /* Sample data should start after this index */
573 /* Allocate memory for TAC data */
574 int ret;
575 ret=tacAllocate(tac, hdr->keyNr-ii, 7);
576 statusSet(status, __func__, __FILE__, __LINE__, ret);
577 if(ret!=TPCERROR_OK) return(ret);
578 tac->tacNr=7;
579 /* Set basic header information */
580 tac->format=format;
581 tac->isframe=1; // Data always contains frame start and end times
582 tac->tunit=UNIT_SEC;
583 tac->cunit=UNIT_COUNTS;
584 /* Set TAC names into TAC struct */
585 strcpy(tac->c[0].name, "Detector1-Coinc");
586 strcpy(tac->c[1].name, "Detector1-Singl1");
587 strcpy(tac->c[2].name, "Detector1-Singl2");
588 strcpy(tac->c[3].name, "Detector2-Coinc");
589 strcpy(tac->c[4].name, "Detector2-Singl1");
590 strcpy(tac->c[5].name, "Detector2-Singl2");
591 strcpy(tac->c[6].name, "AUX-counts");
592
593 /* Go through the lines, extracting sample data, and deleting data lines
594 from the header */
595 if(verbose>2) printf(" reading data lines...\n");
596 ii++;
597 int i=0, stopped=0;
598 double time_of_day, first_tod=0.0, time_since_start, meas_interval;
599 while(ii<hdr->keyNr && i<tac->_sampleNr) {
600 if(stopped) {iftDelete(hdr, ii); continue;}
601 if(strnlen(hdr->item[ii].key, 3)>0 || hdr->item[ii].value==NULL) {
602 iftDelete(hdr, ii); continue;}
603 if(hdr->item[ii].value[0]=='#') {iftDelete(hdr, ii); continue;}
604 //printf("ii=%d '%s'\n", ii, hdr->item[ii].value);
605 n=sscanf(hdr->item[ii].value, "%lf %lf %lf %lf %lf %lf %lf %lf %lf %lf\n",
606 &time_of_day, &time_since_start, &meas_interval,
607 &tac->c[0].y[i], &tac->c[1].y[i], &tac->c[2].y[i], &tac->c[3].y[i],
608 &tac->c[4].y[i], &tac->c[5].y[i], &tac->c[6].y[i]);
609 //printf(" n=%d\n", n);
610 if(n!=10) {
611 /* first line may contain the protocol; keep it as comment */
612 if(i==0) {ii++; continue;}
613 /* Later occurrence is considered as an error */
614 stopped=1; iftDelete(hdr, ii); continue;
615 }
616 if(time_of_day==0.0 && meas_interval==0.0) {
617 stopped=1; iftDelete(hdr, ii); continue;}
618 if(i==0) first_tod=time_of_day;
619 tac->x1[i]=time_since_start;
620 tac->x2[i]=time_since_start+meas_interval;
621 i++;
622 iftDelete(hdr, ii);
623 }
624 tac->sampleNr=i;
625 if(verbose>2) printf(" %d data line(s) read.\n", i);
626 if(i<1) {
627 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_DATA);
628 return(TPCERROR_NO_DATA);
629 }
630 if(verbose>4) printf(" first_tod := %.1lf\n", first_tod);
631
632 /* Calculate frame mid times */
633 for(i=0; i<tac->sampleNr; i++) tac->x[i]=0.5*(tac->x1[i]+tac->x2[i]);
634
635 /* Read scan start time from the first sample, which is used also as
636 sampler start time, if only date was given in the header */
637 char scan_start_time[32], sampler_start_time[32];
638 time_t tim=(time_t)first_tod;
639 struct tm tmtim;
640 if(gmtime_r(&tim, &tmtim)==NULL) {
641 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_DATETIME);
642 return(TPCERROR_NO_DATETIME);
643 }
644 /* Check whether also date is here;
645 if yes, this is actually Scanditronics data */
646 if(tmtim.tm_year>71 || tmtim.tm_mday>1) {
647 if(verbose>0) printf("data is not GEMS but Scanditronics format\n");
648 if(verbose>1 &&
649 strftime(scan_start_time, 32, "%Y-%m-%d %H:%M:%S", &tmtim)!=0) {
650 printf("first_sample_time := %s\n", scan_start_time);
651 }
652 tacFree(tac);
653 return(tacReadScanditronics(tac, hdr, status));
654 }
655 if(start_time.tm_hour==0 && start_time.tm_min==0 && start_time.tm_sec==0) {
656 start_time.tm_hour=tmtim.tm_hour;
657 start_time.tm_min=tmtim.tm_min;
658 start_time.tm_sec=tmtim.tm_sec;
659 n=strftime(sampler_start_time, 32, "%Y-%m-%d %H:%M:%S", &start_time);
660 if(n==0) strcpy(sampler_start_time, "");
661 strcpy(scan_start_time, sampler_start_time);
662 } else {
663 n=strftime(sampler_start_time, 32, "%Y-%m-%d %H:%M:%S", &start_time);
664 if(n==0) strcpy(sampler_start_time, "");
665 start_time.tm_hour=tmtim.tm_hour;
666 start_time.tm_min=tmtim.tm_min;
667 start_time.tm_sec=tmtim.tm_sec;
668 n=strftime(scan_start_time, 32, "%Y-%m-%d %H:%M:%S", &start_time);
669 if(n==0) strcpy(scan_start_time, "");
670 }
671 if(!scan_start_time[0]) {
672 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_DATETIME);
673 return(TPCERROR_NO_DATETIME);
674 }
675
676
677 /* Set all header lines to comments */
678 for(ii=0; ii<hdr->keyNr; ii++) hdr->item[ii].comment=1;
679 /* Copy the header contents to TAC (deletes previous contents) */
680 (void)iftDuplicate(hdr, &tac->h);
681 tac->h.type=3;
682 /* Set the scan start time in the TAC header */
683 (void)tacSetHeaderScanstarttime(&tac->h, scan_start_time);
684 /* Set the sampler start time in the TAC header */
685 if(sampler_start_time[0])
686 (void)iftPut(&tac->h, "sampler_start_time", sampler_start_time, 1, NULL);
687 /* Copy study number to the TAC header */
688 ii=iftFindKey(hdr, "Patient", 0);
689 if(ii>=0 && strnlen(hdr->item[ii].value, 5)>0)
690 (void)tacSetHeaderStudynr(&tac->h, hdr->item[ii].value);
691
692 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OK);
693 return(TPCERROR_OK);
694}
695/*****************************************************************************/
696
697/*****************************************************************************/
int strDateTimeRead(const char *str, struct tm *date)
Definition datetime.c:350
int strDateRead(const char *str, struct tm *date)
Definition datetime.c:378
struct tm * gmtime_r(const time_t *t, struct tm *tm)
Convert time_t to GMT struct tm.
Definition datetime.c:31
int strDateTimeValid(const char *str, char *intdate)
Definition datetime.c:308
struct tm * localtime_r(const time_t *t, struct tm *tm)
Convert time_t to local time in struct tm.
Definition datetime.c:54
int iftPut(IFT *ift, const char *key, const char *value, char comment, TPCSTATUS *status)
Definition ift.c:63
int iftDelete(IFT *ift, int index)
Definition ift.c:206
int iftDuplicate(IFT *ift1, IFT *ift2)
Definition ift.c:236
int iftSearchValue(IFT *ift, const char *s, int start_index)
Definition iftfind.c:114
int iftFindKey(IFT *ift, const char *key, int start_index)
Definition iftfind.c:30
void statusSet(TPCSTATUS *s, const char *func, const char *srcfile, int srcline, tpcerror error)
Definition statusmsg.c:142
size_t strnlen(const char *s, size_t n)
Definition stringext.c:566
size_t strlcpy(char *dst, const char *src, size_t dstsize)
Definition stringext.c:632
char comment
Definition tpcift.h:27
char * value
Definition tpcift.h:37
char * key
Definition tpcift.h:32
Definition tpcift.h:43
IFT_ITEM * item
Definition tpcift.h:57
int type
Definition tpcift.h:51
int keyNr
Definition tpcift.h:47
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: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 tacReadScanditronics(TAC *tac, IFT *hdr, TPCSTATUS *status)
Definition tacabss.c:326
int tacReadGEMS(TAC *tac, IFT *hdr, TPCSTATUS *status)
Definition tacabss.c:516
int tacReadAllogg(TAC *tac, IFT *hdr, TPCSTATUS *status)
Definition tacabss.c:26
int tacReadOldAllogg(TAC *tac, IFT *hdr, TPCSTATUS *status)
Definition tacabss.c:173
int tacSetHeaderScanstarttime(IFT *h, const char *s)
Definition tacift.c:427
int tacSetHeaderStudynr(IFT *h, const char *s)
Definition tacift.c:79
Header file for library libtpccsv.
@ UNIT_COUNTS
counts
@ UNIT_SEC
seconds
@ TPCERROR_NO_DATETIME
File contains no date or time.
@ TPCERROR_FAIL
General error.
@ TPCERROR_INVALID_FORMAT
Invalid file format.
@ TPCERROR_OK
No error.
@ TPCERROR_NO_DATA
File contains no data.
@ TPCERROR_MISSING_DATA
File contains missing values.
Header file for library libtpcift.
Header file for library libtpcisotope.
Header file for library libtpctac.
@ 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