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

TAC file i/o functions. More...

#include "tpcclibConfig.h"
#include "tpcift.h"
#include "tpcisotope.h"
#include "tpccsv.h"
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include <string.h>
#include "tpctac.h"

Go to the source code of this file.

Functions

char * tacFormattxt (tacformat c)
 
int tacFormatIdentify (const char *s)
 
char * tacDefaultExtension (tacformat c)
 
int tacFormatDetermine (const char *fname, TPCSTATUS *status)
 
int tacFormatWriteSupported (tacformat format)
 
int tacWrite (TAC *tac, FILE *fp, tacformat format, int extra, TPCSTATUS *status)
 
int tacRead (TAC *d, const char *fname, TPCSTATUS *status)
 

Detailed Description

TAC file i/o functions.

Todo
Support reading static ROI data from Carimas (test/carimas_static.txt).

Definition in file tacio.c.

Function Documentation

◆ tacDefaultExtension()

char * tacDefaultExtension ( tacformat c)

Return pointer to default TAC filename extension, including the dot, based on the TAC format code.

Returns
pointer to the filename extension string.
See also
tpcformat, tacFormattxt, tacFormatWriteSupported
Author
Vesa Oikonen
Parameters
cTAC format code.

Definition at line 144 of file tacio.c.

147 {
148 if(c<TAC_FORMAT_UNKNOWN || c>=TAC_FORMAT_LAST) return NULL;
149 return (char*)tac_fn_ext[c];
150}

◆ tacFormatDetermine()

int tacFormatDetermine ( const char * fname,
TPCSTATUS * status )

Determine the format of TAC file.

Note
Not all formats are identified, and identification does not mean that reading the format would be supported.
Returns
the format number, or TAC_FORMAT_UNKNOWN if not identified or in case of an error.
Author
Vesa Oikonen
See also
tacDefaultExtension, tacFormatIdentify, tacFormatWriteSupported
Parameters
fnamePointer to the file name; this string is not modified.
statusPointer to status data; enter NULL if not needed

Definition at line 161 of file tacio.c.

166 {
167 int verbose=0; if(status!=NULL) verbose=status->verbose;
168
169 if(fname==NULL || strlen(fname)<1) {
170 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_FAIL);
171 return TAC_FORMAT_UNKNOWN;
172 }
173 if(verbose>1) {printf("%s(%s)\n", __func__, fname); fflush(stdout);}
174 int format=TAC_FORMAT_UNKNOWN;
175
176 /* Open file; note that 'b' is required for fgetpos() and fsetpos() to work correctly */
177 FILE *fp;
178 fp=fopen(fname, "rb");
179 if(fp==NULL) {
180 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_CANNOT_OPEN);
181 return format;
182 }
183
184 /* Binary data? */
185 int ret;
186 size_t fsize=asciiFileSize(fp, &ret);
187 if(verbose>3) {printf(" fsize := %zu\n", fsize); fflush(stdout);}
188 if(fsize<1) {
189 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_DATA);
190 fclose(fp); return format;
191 }
192 if(ret==1) {
193 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_UNSUPPORTED);
194 fclose(fp); return TAC_FORMAT_BINARY;
195 }
196
197 /* Read file to a string */
198 char *data;
199 data=asciiFileRead(fp, NULL, fsize+1); rewind(fp);
200 if(data==NULL) {
201 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_DATA);
202 fclose(fp); return format;
203 }
204 /* Check if one of Inveon formats */
205 if(strncasecmp(data, "#Subject ID,Subject Weight,Subject Sex,Unique Series ID,Series Date,Series Description", 20)==0 ||
206 strncasecmp(data, "#Subject ID;Subject Weight;Subject Sex;Unique Series ID;Series Date;Series Description", 20)==0) {
207 format=TAC_FORMAT_INVEON;
208 }
209
210 /* Read the first non-comment line */
211 int i=0, j;
212 char *cptr, *line=NULL;
213 cptr=data;
214 while((line=strTokenDup(cptr, "\n\r", &j))!=NULL) {
215 if(!asciiCommentLine(line, NULL) && strlen(line)>1) break;
216 free(line); cptr+=j; i++;
217 }
218 free(data);
219 if(line==NULL) {
220 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_FORMAT);
221 fclose(fp); return format;
222 }
223
224 /* Check for identification strings */
225 if(verbose>1) {printf(" checking for magic number\n"); fflush(stdout);}
226 if(strncasecmp(line, "DFT", 3)==0) {
227 format=TAC_FORMAT_DFT;
228 } else if(strncasecmp(line, "cpt", 3)==0) {
229 format=TAC_FORMAT_NCI;
230 } else if(strcmp(line, "directory,file name,num,slice,mean,sd,cov,max,min,pixel,total,group")==0) {
231 format=TAC_FORMAT_QVIEW;
232 } else if(strncmp(line, "PatientName,", 12)==0) {
233 format=TAC_FORMAT_4DM;
234 } else if(strstr(line, " - Time")!=NULL && strstr(line, "(upper bound)")!=NULL &&
235 strstr(line, "(lower bound)")!=NULL && strstr(line, "(standard deviation)")!=NULL) {
236 format=TAC_FORMAT_INVEON;
237 }
238 free(line);
239 if(format!=TAC_FORMAT_UNKNOWN) {
240 if(verbose>0) {printf(" identified as %s file\n", tacFormattxt(format)); fflush(stdout);}
241 fclose(fp); return format;
242 }
243
244 /* Identify certain file name extensions */
245 if(verbose>1) {printf(" checking file name extension\n"); fflush(stdout);}
246 cptr=strrchr(fname, '.'); if(cptr!=NULL) cptr++;
247 if(verbose>1 && cptr!=NULL) printf(" extension := %s\n", cptr);
248 if(strcasecmp(cptr, "IDWC")==0 || strcasecmp(cptr, "IDW")==0) {
249 format=TAC_FORMAT_IDWC;
250 } else if(strcasecmp(cptr, "IF")==0) {
251 format=TAC_FORMAT_IF;
252 } else if(strcasecmp(cptr, "XML")==0) {
253 format=TAC_FORMAT_XML;
254 } else if(strcasecmp(cptr, "SIF")==0) {
255 format=TAC_FORMAT_SIF;
256 } else if(strcasecmp(cptr, "LIS")==0) {
258 } else if(strcasecmp(cptr, "ALG")==0) {
260 }
261 if(format!=TAC_FORMAT_UNKNOWN) {
262 if(verbose>0) {printf(" identified as %s file\n", tacFormattxt(format)); fflush(stdout);}
263 fclose(fp); return format;
264 }
265
266#if(0)
267 /* Try to read as CSV (or TSV) file */
268 int ret;
269 FILE *fp;
270 if(fp==NULL) {
271 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_CANNOT_OPEN);
273 }
274 CSV csv; csvInit(&csv);
275 ret=csvRead(&csv, fp, status);
276
277#endif
278
279
280 fclose(fp);
281 if(verbose>0) {printf(" format not identified\n"); fflush(stdout);}
282 return format;
283}
void csvInit(CSV *csv)
Definition csv.c:22
int csvRead(CSV *csv, FILE *fp, TPCSTATUS *status)
Definition csvio.c:124
char * asciiFileRead(FILE *fp, char *data, size_t maxlen)
int asciiCommentLine(const char *line, int *cont)
size_t asciiFileSize(FILE *fp, int *nonprintable)
void statusSet(TPCSTATUS *s, const char *func, const char *srcfile, int srcline, tpcerror error)
Definition statusmsg.c:142
char * strTokenDup(const char *s1, const char *s2, int *next)
Definition stringext.c:413
Definition tpccsv.h:36
int verbose
Verbose level, used by statusPrint() etc.
char * tacFormattxt(tacformat c)
Definition tacio.c:98
@ TPCERROR_FAIL
General error.
@ TPCERROR_INVALID_FORMAT
Invalid file format.
@ TPCERROR_CANNOT_OPEN
Cannot open file.
@ TPCERROR_UNSUPPORTED
Unsupported file type.
@ TPCERROR_NO_DATA
File contains no data.
@ TAC_FORMAT_IF
Hammersmith input file format.
Definition tpctac.h:40
@ TAC_FORMAT_4DM
4DM TAC format (reading supported)
Definition tpctac.h:50
@ TAC_FORMAT_UNKNOWN
Unknown format.
Definition tpctac.h:28
@ TAC_FORMAT_IDWC
Hammersmith tissue file format.
Definition tpctac.h:39
@ TAC_FORMAT_XML
XML format (supported for writing)
Definition tpctac.h:41
@ TAC_FORMAT_QVIEW
QView CSV TAC format (reading supported)
Definition tpctac.h:48
@ TAC_FORMAT_ABSS_ALLOGG_OLD
ALLOGG ABSS data (old format); reading supported.
Definition tpctac.h:55
@ TAC_FORMAT_DFT
Data format of Turku PET Centre.
Definition tpctac.h:30
@ TAC_FORMAT_ABSS_SCANDITRONICS
Scanditronics ABSS data; reading supported.
Definition tpctac.h:53
@ TAC_FORMAT_BINARY
Binary format (currently not supported)
Definition tpctac.h:57
@ TAC_FORMAT_SIF
Scan information file.
Definition tpctac.h:43
@ TAC_FORMAT_INVEON
Inveon format (reading supported)
Definition tpctac.h:45
@ TAC_FORMAT_NCI
Old Turku PET Centre format.
Definition tpctac.h:32

◆ tacFormatIdentify()

int tacFormatIdentify ( const char * s)

Identify the string representation of the TAC file format.

Returns
enum tacformat, or 0 (enum TAC_FORMAT_UNKNOWN) if not identified.
Author
Vesa Oikonen
See also
tpcformat, tacFormattxt, tacDefaultExtension
Parameters
sTAC format as a string.

Definition at line 113 of file tacio.c.

116 {
117 if(s==NULL || strlen(s)<1) return TAC_FORMAT_UNKNOWN;
118 /* Try if string can be found directly in the table */
119 for(int i=0; i<TAC_FORMAT_LAST; i++) {
120 if(strcasecmp(tac_format[i], s)==0) return i;
121 }
122 /* Format string is not following TPC standard, lets try something else */
123 if( strcasecmp(s, "dat")==0) return TAC_FORMAT_TSV_UK;
124 else if(strcasecmp(s, "txt")==0) return TAC_FORMAT_TSV_UK;
125 else if(strcasecmp(s, "tac")==0) return TAC_FORMAT_PMOD;
126 else if(strcasecmp(s, "bld")==0) return TAC_FORMAT_PMOD;
127 else if(strcasecmp(s, "htm")==0) return TAC_FORMAT_HTML;
128 else if(strcasecmp(s, "csv")==0) return TAC_FORMAT_CSV_UK;
129 else if(strcasecmp(s, "tsv")==0) return TAC_FORMAT_TSV_UK;
130 else if(strcasecmp(s, "lis")==0) return TAC_FORMAT_ABSS_SCANDITRONICS;
131 else if(strcasecmp(s, "alg")==0) return TAC_FORMAT_ABSS_ALLOGG_OLD;
132
133 return TAC_FORMAT_UNKNOWN;
134}
@ TAC_FORMAT_HTML
HTML table format (supported for writing)
Definition tpctac.h:42
@ TAC_FORMAT_TSV_UK
UK TSV (point as decimal separator)
Definition tpctac.h:37
@ TAC_FORMAT_PMOD
PMOD TAC format.
Definition tpctac.h:33
@ TAC_FORMAT_CSV_UK
UK CSV.
Definition tpctac.h:35

◆ tacFormattxt()

char * tacFormattxt ( tacformat c)

Return pointer to TAC file format description with the format code.

Returns
pointer to the TAC file format string.
See also
tpcformat, tacFormatIdentify, tacDefaultExtension
Author
Vesa Oikonen
Parameters
cTAC format code.

Definition at line 98 of file tacio.c.

101 {
102 if(c<TAC_FORMAT_UNKNOWN || c>=TAC_FORMAT_LAST) return NULL;
103 return (char*)tac_format[c];
104}

Referenced by tacFormatDetermine(), tacRead(), and tacWrite().

◆ tacFormatWriteSupported()

int tacFormatWriteSupported ( tacformat format)

Check whether writing of specified TAC format is supported.

Returns
1 if supported, 0 if not.
See also
tacWrite, tacFormatDetermine, tacRead
Parameters
formatFile format code, for example TAC->format.

Definition at line 291 of file tacio.c.

294 {
295 int ret=0;
296 switch(format) {
298 ret=1;
299 break;
300 case TAC_FORMAT_DFT:
301 ret=1;
302 break;
303 case TAC_FORMAT_PMOD:
304 ret=1;
305 break;
310 ret=1;
311 break;
312 case TAC_FORMAT_SIF:
313 ret=1;
314 break;
315 case TAC_FORMAT_XML:
316 ret=1;
317 break;
318 default:
319 ret=0;
320 }
321 return(ret);
322}
@ TAC_FORMAT_CSV_INT
International CSV.
Definition tpctac.h:34
@ TAC_FORMAT_TSV_INT
International TSV (comma as decimal separator)
Definition tpctac.h:36
@ TAC_FORMAT_SIMPLE
x and y's with space delimiters
Definition tpctac.h:29

◆ tacRead()

int tacRead ( TAC * d,
const char * fname,
TPCSTATUS * status )

Read TAC file contents into TAC data structure.

This function reads simple data format (time + data columns), DFT format, PMOD format, Hammersmith formats (IDWC and IF), and some CSV formats.

Author
Vesa Oikonen
Returns
code tpcerror, TPCERROR_OK (0) when successful.
See also
tacInit, tacWrite, tacFormatDetermine, csvRead, iftRead
Parameters
dPointer to initiated TAC struct where TAC data will be written; any old content is deleted.
fnamePointer to the filename; this string is not modified.
statusPointer to status data; enter NULL if not needed.

Definition at line 413 of file tacio.c.

420 {
421 int verbose=0; if(status!=NULL) verbose=status->verbose;
422 if(fname==NULL || strlen(fname)<1 || d==NULL) {
423 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_FAIL);
424 return TPCERROR_FAIL;
425 }
426 if(verbose>1) printf("%s(%s)\n", __func__, fname);
427 int format=TAC_FORMAT_UNKNOWN;
428
429 /* Delete any previous data */
430 tacFree(d);
431
432 /* Open the file */
433 FILE *fp;
434 fp=fopen(fname, "r");
435 if(fp==NULL) {
436 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_CANNOT_OPEN);
438 }
439
440 /* Verify that file does not contain binary data */
441 {
442 int n, binpart;
443 n=asciiFileSize(fp, &binpart);
444 if(verbose>4) printf("file_size := %d\n", n);
445 if(n<2 || binpart!=0) {
446 if(verbose>0) {
447 printf("file_size := %d\n", n);
448 printf("binpart := %d\n", binpart);
449 fflush(stdout);
450 }
451 fclose(fp);
452 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_FORMAT);
454 }
455 }
456
457 /* Try to read the file as CSV file */
458 int ret;
459 CSV csv; csvInit(&csv);
460 rewind(fp);
461 ret=csvRead(&csv, fp, status);
462 fclose(fp);
463 if(ret!=TPCERROR_OK) {csvFree(&csv); return ret;}
464 if(verbose>20) {
465 printf("\n --- CSV contents ---\n");
466 csvWrite(&csv, 0, stdout, status);
467 fflush(stdout);
468 }
469
470 /* Try to identify file format from a magic number in the start */
471 if(verbose>1) printf("checking for magic number\n");
472 if(strncasecmp(csv.c[0].content, "DFT", 3)==0) {
473 format=TAC_FORMAT_DFT;
474 } else if(strncasecmp(csv.c[0].content, "cpt", 3)==0) {
475 format=TAC_FORMAT_NCI;
476 } else if(csv.nr>8 && strcasecmp(csv.c[0].content, "time")==0 &&
477 strcasecmp(csv.c[1].content, "prompt")==0 &&
478 strcasecmp(csv.c[2].content, "delayed")==0 &&
479 strcasecmp(csv.c[3].content, "p_rate")==0) {
481 } else if(strncasecmp(csv.c[0].content, "Time", 4)==0) {
482 format=TAC_FORMAT_PMOD;
483 } else if(strncasecmp(csv.c[0].content, "Start", 5)==0) {
484 format=TAC_FORMAT_PMOD;
485 } else if(strncasecmp(csv.c[0].content, "<?xml version", 6)==0) {
486 format=TAC_FORMAT_XML;
487 } else if(csv.nr>12 && strcasecmp(csv.c[0].content, "directory")==0 &&
488 strcasecmp(csv.c[1].content, "file name")==0 &&
489 strcasecmp(csv.c[2].content, "num")==0 &&
490 strcasecmp(csv.c[3].content, "slice")==0 &&
491 strcasecmp(csv.c[4].content, "mean")==0 &&
492 strcasecmp(csv.c[5].content, "sd")==0 &&
493 strcasecmp(csv.c[6].content, "cov")==0 &&
494 strcasecmp(csv.c[7].content, "max")==0 &&
495 strcasecmp(csv.c[8].content, "min")==0 &&
496 strcasecmp(csv.c[9].content, "pixel")==0 &&
497 strcasecmp(csv.c[10].content, "total")==0 &&
498 strcasecmp(csv.c[11].content, "group")==0) {
499 format=TAC_FORMAT_QVIEW;
500 } else if(csv.nr>10 && strcasecmp(csv.c[0].content, "PatientName")==0 &&
501 strcasecmp(csv.c[2].content, "Patient MRN")==0 ) {
502 format=TAC_FORMAT_4DM;
503 } else if(csv.nr>5 && strstr(csv.c[0].content, " - Time")!=NULL &&
504 strstr(csv.c[2].content, "(upper bound)")!=NULL &&
505 strstr(csv.c[3].content, "(lower bound)")!=NULL &&
506 strstr(csv.c[4].content, "(standard deviation)")!=NULL) {
507 format=TAC_FORMAT_INVEON;
508 } else if(strcasecmp(csv.c[0].content, "TAC")==0) {
509 if(csv.separator=='\t') format=TAC_FORMAT_TSV_UK;
510 else if(csv.separator==',') format=TAC_FORMAT_CSV_INT;
511 else format=TAC_FORMAT_CSV_UK;
512 // CSV subformat may not be strictly correct yet
513 } else if(csv.nr>4 && strcasecmp(csv.c[0].content, "Singles")==0 &&
514 strcasecmp(csv.c[1].content, "Randoms")==0 &&
515 strcasecmp(csv.c[2].content, "Prompts")==0 &&
516 strncasecmp(csv.c[3].content, "Time(ms)", 4)==0) {
517 format=TAC_FORMAT_HRRT_HC;
518 } else if(csvCell(&csv, 1, 0) && strcasecmp(csvCell(&csv, 1, 0), "Num Voxels")==0 )
519 {
521 }
522
523 /* If not identified, then try certain file name extensions. */
524 /* Extension is not always reliable, therefore magic nr is tried first */
525 if(format==TAC_FORMAT_UNKNOWN) {
526 if(verbose>1) printf("checking file name extension\n");
527 char *cptr, *extension;
528 cptr=filenameGetExtension(fname);
529 if(cptr!=NULL && strlen(cptr)>1) extension=strdup(cptr+1);
530 else extension=strdup("");
531 if(verbose>1) printf("extension := '%s'\n", extension);
532 cptr=extension;
533 if(strcasecmp(cptr, "IDWC")==0 || strcasecmp(cptr, "IDW")==0) {
534 format=TAC_FORMAT_IDWC;
535 } else if(strcasecmp(cptr, "IF")==0) {
536 format=TAC_FORMAT_IF;
537 } else if(strcasecmp(cptr, "XML")==0) {
538 format=TAC_FORMAT_XML;
539 } else if(strcasecmp(cptr, "HTML")==0 || strcasecmp(cptr, "HTM")==0) {
540 format=TAC_FORMAT_HTML;
541 } else if(strcasecmp(cptr, "SIF")==0) {
542 format=TAC_FORMAT_SIF;
543 } else if(strcasecmp(cptr, "HC")==0) {
544 format=TAC_FORMAT_HRRT_HC;
545 } else if(strcasecmp(cptr, "R")==0) {
547 }
548 free(extension);
549 }
550
551 /* If still unknown, read all data as IFT */
552 IFT hdr; iftInit(&hdr);
553 if(format==TAC_FORMAT_UNKNOWN) {
554 if(verbose>2) {printf("reading all data in IFT structure\n"); fflush(stdout);}
555 fp=fopen(fname, "r");
556 if(fp!=NULL) {iftRead(&hdr, fp, 0, 1, status); fclose(fp);}
557 }
558 if(format==TAC_FORMAT_UNKNOWN) {
559 /* Try Allogg ABSS */
560 if(iftSearchValue(&hdr, "//Heading", 0)>=0 &&
561 iftSearchValue(&hdr, "//Data", 0)>=0 &&
562 iftFindPair(&hdr, "System ID", "ABSS09282", 0)>=0)
563 {
565 /* Try Scanditronics and GEMS ABSS */
566 } else if(iftSearchValue(&hdr, "AUX", 0)>=0 && iftSearchValue(&hdr, "1st detector pair", 0)>=0) {
567 if(iftSearchValue(&hdr, "Scanditronics", 0)>=0)
569 else
571 } else if(iftFindKey(&hdr, "Discriminators", 0)>=0) { // Try old Allogg
573 /* Try another Inveon format */
574 } else if(iftSearchValue(&hdr, "Subject Weight", 0)>=0 && iftSearchValue(&hdr, "Subject Sex", 0)>=0) {
575 format=TAC_FORMAT_INVEON;
576 }
577 }
578
579 /* Try to identify as Mat file */
580 if(format==TAC_FORMAT_UNKNOWN && csvIsRegular(&csv) && csv.row_nr>1 && csv.col_nr>1) {
581 if(verbose>2) printf("\nRegular CSV, therefore trying Mat file format\n");
582 /* Starting from second row, each first cell should be inside '' */
583 int ok=1; char *c; int len;
584 for(int r=1; r<csv.row_nr; r++) {
585 c=csvCell(&csv, r, 0); if(c==NULL) {ok=0; break;}
586 len=strlen(c); if(len<2) {ok=0; break;} // should be at least ''
587 if(c[0]!='\'' || c[len-1]!='\'') {ok=0; break;}
588 }
589 if(ok) format=TAC_FORMAT_MAT;
590 }
591
592 /* more formats should be identified here */
593 if(format==TAC_FORMAT_UNKNOWN) {
594 if(verbose>10) {
595 printf("\n FORMAT NOT IDENTIFIED \n");
596 printf("\n --- CSV contents ---\n");
597 csvWrite(&csv, 0, stdout, status);
598 fflush(stdout);
599 }
600 }
601
602 /* If not identified, then try to read as simple data */
603 if(format==TAC_FORMAT_UNKNOWN) format=TAC_FORMAT_SIMPLE;
604
605 if(verbose>1) {printf(" file format: %s\n", tacFormattxt(format)); fflush(stdout);}
606
607
608 /* Read the supported formats */
609 /* Certain formats may contain additional header information in comment
610 lines; read comment headers to be added into TAC struct for further
611 processing; ABSS formats use the previously read whole IFT data.
612 Header may not exist, therefore do not worry about errors here.
613 */
614 switch(format) {
616 iftFree(&hdr);
617 fp=fopen(fname, "r");
618 if(fp!=NULL) {iftRead(&hdr, fp, 0, 2, status); fclose(fp);}
619 ret=tacReadSimple(d, &csv, &hdr, status);
620 break;
621 case TAC_FORMAT_DFT:
622 iftFree(&hdr);
623 fp=fopen(fname, "r");
624 if(fp!=NULL) {iftRead(&hdr, fp, 0, 2, status); fclose(fp);}
625 ret=tacReadDFT(d, &csv, &hdr, status);
626 break;
627 case TAC_FORMAT_PMOD:
628 iftFree(&hdr);
629 fp=fopen(fname, "r");
630 if(fp!=NULL) {iftRead(&hdr, fp, 0, 2, status); fclose(fp);}
631 ret=tacReadPMOD(d, &csv, &hdr, status);
632 break;
633 case TAC_FORMAT_QVIEW:
634 ret=tacReadQView(d, &csv, 0, status);
635 break;
636 case TAC_FORMAT_MAT:
637 ret=tacReadMat(d, &csv, status);
638 break;
639 case TAC_FORMAT_4DM:
640 ret=tacRead4DM(d, &csv, status);
641 break;
646 iftFree(&hdr);
647 fp=fopen(fname, "r");
648 if(fp!=NULL) {iftRead(&hdr, fp, 0, 2, status); fclose(fp);}
649 ret=tacReadCSV(d, &csv, &hdr, status);
650 break;
652 ret=tacReadCarimasTxt(d, &csv, status);
653 break;
655 ret=tacReadInveonCSV(d, &csv, status);
656 break;
657 case TAC_FORMAT_SIF:
658 iftFree(&hdr);
659 fp=fopen(fname, "r");
660 if(fp!=NULL) {iftRead(&hdr, fp, 0, 2, status); fclose(fp);}
661 ret=tacReadSIF(d, &csv, &hdr, status);
662 break;
664 ret=tacReadHRRTHC(d, &csv, status);
665 break;
667 ret=tacReadHRPLUSHC(d, &csv, status);
668 break;
670 //iftFree(&hdr);
671 //fp=fopen(fname, "r");
672 //if(fp!=NULL) {iftRead(&hdr, fp, 0, 1, status); fclose(fp);}
673 ret=tacReadAllogg(d, &hdr, status);
674 break;
676 ret=tacReadOldAllogg(d, &hdr, status);
677 break;
679 ret=tacReadScanditronics(d, &hdr, status);
680 break;
682 ret=tacReadGEMS(d, &hdr, status);
683 break;
684 default:
685 /* The rest of formats are not supported */
686 if(verbose>0) printf("identified as %s file\n", tacFormattxt(format));
688 statusSet(status, __func__, __FILE__, __LINE__, ret);
689 }
690 csvFree(&csv); iftFree(&hdr);
691 if(ret!=TPCERROR_OK) {tacFree(d); return(ret);}
692
693 /* Set study number, if not yet set, based on file name */
694 if(verbose>1) printf("checking studynr\n");
695 if(tacGetHeaderStudynr(&d->h, NULL, status)!=TPCERROR_OK) {
696 if(verbose>2) printf("studynr not found in %s\n", fname);
697 char studynr[MAX_STUDYNR_LEN+1];
698 /* Only valid studynr is accepted */
699 ret=studynrFromFilename(fname, studynr, 1);
700 if(ret==0) {
701 if(verbose>2) printf("studynr based on filename: %s\n", studynr);
702 ret=tacSetHeaderStudynr(&d->h, studynr);
703 } else if(verbose>1)
704 fprintf(stderr, "Error: cannot get valid studynr from filename.\n");
705 }
706
707 /* Set y unit, if not yet set, based on file name */
708 if(verbose>1) printf("checking concentration units\n");
709 if(d->cunit==UNIT_UNKNOWN) {
710 d->cunit=unitIdentifyFilename(fname);
711 if(d->cunit!=UNIT_UNKNOWN && verbose>1) {
712 printf("concentration units based on filename := %s\n", unitName(d->cunit)); fflush(stdout);
713 }
714 }
715
716 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OK);
717 return(TPCERROR_OK);
718}
int csvIsRegular(CSV *csv)
Definition csv.c:292
char * csvCell(CSV *csv, int row, int col)
Definition csv.c:358
void csvFree(CSV *csv)
Definition csv.c:38
int csvWrite(CSV *csv, int regular, FILE *fp, TPCSTATUS *status)
Definition csvio.c:52
int tacReadDFT(TAC *tac, CSV *csv, IFT *hdr, TPCSTATUS *status)
Definition dftio.c:300
char * filenameGetExtension(const char *s)
Get the last extension of a file name.
Definition filename.c:178
int tacReadHRPLUSHC(TAC *tac, CSV *csv, TPCSTATUS *status)
Definition hcio.c:114
int tacReadHRRTHC(TAC *tac, CSV *csv, TPCSTATUS *status)
Definition hcio.c:25
void iftFree(IFT *ift)
Definition ift.c:37
void iftInit(IFT *ift)
Definition ift.c:21
int iftSearchValue(IFT *ift, const char *s, int start_index)
Definition iftfind.c:114
int iftFindPair(IFT *ift, const char *key, const char *value, int start_index)
Definition iftfind.c:55
int iftFindKey(IFT *ift, const char *key, int start_index)
Definition iftfind.c:30
int iftRead(IFT *ift, FILE *fp, int is_key_required, int is_comment_accepted, TPCSTATUS *status)
Definition iftio.c:130
int tacReadMat(TAC *tac, CSV *csv, TPCSTATUS *status)
Definition matio.c:25
int tacReadPMOD(TAC *tac, CSV *csv, IFT *hdr, TPCSTATUS *status)
Definition pmodio.c:146
int tacReadQView(TAC *tac, CSV *csv, const int grouponly, TPCSTATUS *status)
Definition qviewio.c:27
int tacReadSIF(TAC *tac, CSV *csv, IFT *hdr, TPCSTATUS *status)
Definition sifio.c:129
int tacReadSimple(TAC *tac, CSV *csv, IFT *hdr, TPCSTATUS *status)
Definition simpleio.c:97
char * strdup(const char *s)
Definition stringext.c:185
char * content
Definition tpccsv.h:30
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
IFT h
Optional (but often useful) header information.
Definition tpctac.h:141
int cunit
Definition tpctac.h:105
int studynrFromFilename(const char *fname, char *studynr, int force)
Definition studynr.c:79
void tacFree(TAC *tac)
Definition tac.c:106
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 tacReadInveonCSV(TAC *tac, CSV *csv, TPCSTATUS *status)
Definition taccsv.c:405
int tacReadCSV(TAC *tac, CSV *csv, IFT *hdr, TPCSTATUS *status)
Definition taccsv.c:212
int tacReadCarimasTxt(TAC *tac, CSV *csv, TPCSTATUS *status)
Definition taccsv.c:631
int tacGetHeaderStudynr(IFT *h, char *s, TPCSTATUS *status)
Definition tacift.c:26
int tacSetHeaderStudynr(IFT *h, const char *s)
Definition tacift.c:79
@ UNIT_UNKNOWN
Unknown unit.
@ TPCERROR_OK
No error.
int unitIdentifyFilename(const char *s)
Definition units.c:311
char * unitName(int unit_code)
Definition units.c:143
#define MAX_STUDYNR_LEN
Define max study number length.
@ TAC_FORMAT_ABSS_ALLOGG
ALLOGG ABSS data; reading supported.
Definition tpctac.h:56
@ TAC_FORMAT_MAT
Matlab matrix TAC format (reading supported)
Definition tpctac.h:49
@ TAC_FORMAT_ABSS_GEMS
GEMS ABSS data; reading supported.
Definition tpctac.h:54
@ TAC_FORMAT_CARIMAS_TXT
Carimas txt format (reading supported)
Definition tpctac.h:47
@ TAC_FORMAT_HRPLUS_HC
HR+ head curve format (reading supported)
Definition tpctac.h:52
@ TAC_FORMAT_HRRT_HC
HRRT head curve format (reading supported)
Definition tpctac.h:51

Referenced by imgReadNifti(), imgWriteNifti(), tacReadModelingData(), tacReadModelingInput(), and tacReadReference().

◆ tacWrite()

int tacWrite ( TAC * tac,
FILE * fp,
tacformat format,
int extra,
TPCSTATUS * status )

Write TAC data into specified file in specified format.

Precondition
Before using this, you may want to call tacFormatWriteSupported().
Returns
enum tpcerror (TPCERROR_OK when successful).
Author
Vesa Oikonen
See also
tacRead, tacFree, tacFormatWriteSupported
Parameters
tacPointer to TAC structure, contents of which are to be written.
fpOutput file pointer.
formatFile format code; enter TAC_FORMAT_UNKNOWN to write data in the format specified inside TAC structure.
extraWrite (1) or do not write (0) also extra header fields found in IFT; not effective with SIF.
statusPointer to status data; enter NULL if not needed.

Definition at line 332 of file tacio.c.

345 {
346 int verbose=0; if(status!=NULL) verbose=status->verbose;
347 if(fp==NULL) {
348 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_CANNOT_WRITE);
350 }
351 if(tac==NULL || tac->tacNr<1 || tac->sampleNr<1) {
352 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_DATA);
353 return TPCERROR_NO_DATA;
354 }
355
356 /* Determine and verify the write format */
357 if(format<=TAC_FORMAT_UNKNOWN || format>=TAC_FORMAT_LAST)
358 format=tac->format;
359 if(format<=TAC_FORMAT_UNKNOWN || format>=TAC_FORMAT_LAST) {
360 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_FORMAT);
362 }
363 if(verbose>0) {
364 printf("%s():\n", __func__);
365 printf("writing %d TACs and %d samples in %s format\n",
366 tac->tacNr, tac->sampleNr, tacFormattxt(format));
367 }
368
369 /* Write file */
370 /* Update tacFormatWriteSupported() if you add/remove formats! */
371 int ret;
372 switch(format) {
374 ret=tacWriteSimple(tac, fp, extra, status);
375 break;
376 case TAC_FORMAT_DFT:
377 ret=tacWriteDFT(tac, fp, extra, status);
378 break;
379 case TAC_FORMAT_PMOD:
380 ret=tacWritePMOD(tac, fp, extra, status);
381 break;
386 ret=tacWriteCSV(tac, fp, extra, format, status);
387 break;
388 case TAC_FORMAT_SIF:
389 ret=tacWriteSIF(tac, fp, 0, status);
390 break;
391 case TAC_FORMAT_XML:
392 ret=tacWriteXML(tac, fp, status);
393 break;
394 default:
396 }
397
398 /* Quit */
399 statusSet(status, __func__, __FILE__, __LINE__, ret);
400 return(ret);
401}
int tacWriteDFT(TAC *tac, FILE *fp, int extra, TPCSTATUS *status)
Definition dftio.c:119
int tacWritePMOD(TAC *tac, FILE *fp, int extra, TPCSTATUS *status)
Definition pmodio.c:26
int tacWriteSIF(TAC *tac, FILE *fp, int extra, TPCSTATUS *status)
Definition sifio.c:26
int tacWriteSimple(TAC *tac, FILE *fp, int extra, TPCSTATUS *status)
Definition simpleio.c:26
tacformat format
Definition tpctac.h:93
int sampleNr
Definition tpctac.h:89
int tacNr
Definition tpctac.h:91
int tacWriteCSV(TAC *tac, FILE *fp, int extra, tacformat format, TPCSTATUS *status)
Definition taccsv.c:26
int tacWriteXML(TAC *tac, FILE *fp, TPCSTATUS *status)
Definition tacxmlio.c:26
@ TPCERROR_CANNOT_WRITE
Cannot write file.

Referenced by imgWriteNifti().