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

Contains I/O functions for DFT files. More...

#include "libtpccurveio.h"
#include <unistd.h>

Go to the source code of this file.

Functions

int dftRead (char *filename, DFT *data)
 
int dftFormat (char *fname)
 
int dftType (FILE *fp)
 
void dftPrint (DFT *data)
 
int dftWrite (DFT *data, char *filename)
 
int dftWriteHTML (DFT *dft, char *fname, int orientation)
 
int dftWriteXHTML11_doctype (FILE *fp)
 
int dftWriteXHTML11_head (FILE *fp, char *author_name)
 
int dft_fill_hdr_from_IFT (DFT *dft, IFT *ift)
 
int dftGetPmodTitle (DFT *dft, char *title_line)
 

Variables

int DFT_NR_OF_DECIMALS = 3
 

Detailed Description

Contains I/O functions for DFT files.

Author
Vesa Oikonen
Bug
Line length cannot be larger than max int value, but this is not taken into consideration. This may limit the curve number in some systems.

Definition in file dftio.c.

Function Documentation

◆ dft_fill_hdr_from_IFT()

int dft_fill_hdr_from_IFT ( DFT * dft,
IFT * ift )

Read certain keys from IFT and set DFT fields accordingly.

Returns
Returns the nr of identified keys.
Parameters
dftPointer to allocated DFT struct where information will be written
iftPointer to IFT struct from where information is retrieved

Definition at line 971 of file dftio.c.

976 {
977 int ki, ri, ok_nr=0, ret;
978 char keystr[256], *cptr;
979
980 //printf("dft_fill_hdr_from_IFT()\n");
981
982 /* Check for study number */
983 strcpy(keystr, "studynr"); ki=iftGet(ift, keystr, 0);
984 if(ki==-1) {strcpy(keystr, "study number"); ki=iftGet(ift, keystr, 0);}
985 if(ki==-1) {strcpy(keystr, "study_number"); ki=iftGet(ift, keystr, 0);}
986 if(ki>=0) {
987 strlcpy(dft->studynr, ift->item[ki].value, MAX_STUDYNR_LEN);
988 ok_nr++;
989 }
990
991 /* Check for time unit */
992 strcpy(keystr, "timeunit"); ki=iftGet(ift, keystr, 0);
993 if(ki==-1) {strcpy(keystr, "time unit"); ki=iftGet(ift, keystr, 0);}
994 if(ki==-1) {strcpy(keystr, "time_unit"); ki=iftGet(ift, keystr, 0);}
995 if(ki==-1) {strcpy(keystr, "Time units"); ki=iftGet(ift, keystr, 0);}
996 if(ki>=0) {
997 ret=petTunitId(ift->item[ki].value);
998 if(ret>=0 && ret!=TUNIT_UNKNOWN) {dft->timeunit=ret; ok_nr++;}
999 }
1000
1001 /* Check for sample unit */
1002 strcpy(keystr, "unit"); ki=iftGet(ift, keystr, 0);
1003 if(ki==-1) {strcpy(keystr, "Activity units"); ki=iftGet(ift, keystr, 0);}
1004 if(ki>=0) {
1005 strncpy(dft->unit, ift->item[ki].value, 12); dft->unit[12]=(char)0;
1006 ok_nr++;
1007 }
1008
1009 /* Check for region names */
1010 ri=0;
1011 do {
1012 strcpy(keystr, "voiname"); ki=iftGetNth(ift, keystr, ri+1, 0);
1013 if(ki>=0) {
1014 strncpy(dft->voi[ri].name, ift->item[ki].value, MAX_REGIONNAME_LEN);
1015 dft->voi[ri].name[MAX_REGIONNAME_LEN]=(char)0;
1016 rnameSplit(ift->item[ki].value, dft->voi[ri].voiname,
1017 dft->voi[ri].hemisphere, dft->voi[ri].place, MAX_REGIONSUBNAME_LEN);
1018 }
1019 ri++; ok_nr++;
1020 } while(ki>=0 && ri<dft->_voidataNr);
1021
1022 /* Check for region volumes */
1023 strcpy(keystr, "sizes"); ki=iftGet(ift, keystr, 0);
1024 if(ki==-1) {strcpy(keystr, "volumes"); ki=iftGet(ift, keystr, 0);}
1025 if(ki>=0 && strlen(ift->item[ki].value)) {
1026 ri=0; cptr=strtok(ift->item[ki].value, " ;\t");
1027 while(cptr!=NULL && ri<dft->_voidataNr) {
1028 if(strcmp(cptr, ".")==0) {ri++; continue;}
1029 dft->voi[ri++].size=atof_dpi(cptr);
1030 cptr=strtok(NULL, " ;\t");
1031 }
1032 ok_nr++;
1033 }
1034
1035 /* Check for the name of radiopharmaceutical */
1036 strcpy(keystr, "radiopharmaceutical"); ki=iftGet(ift, keystr, 0);
1037 if(ki>=0 && strlen(ift->item[ki].value)) {
1038 strncpy(dft->radiopharmaceutical, ift->item[ki].value, 31);
1039 dft->radiopharmaceutical[31]=(char)0;
1040 ok_nr++;
1041 }
1042
1043 /* Check for isotope name */
1044 strcpy(keystr, "isotope"); ki=iftGet(ift, keystr, 0);
1045 if(ki>=0 && strlen(ift->item[ki].value)) {
1046 strncpy(dft->isotope, ift->item[ki].value, 6); dft->isotope[6]=(char)0;
1047 ok_nr++;
1048 }
1049
1050 /* Check if there is anything about correction for physical decay */
1051 strcpy(keystr, "decay_correction"); ki=iftGet(ift, keystr, 0);
1052 if(ki==-1) {strcpy(keystr, "decay correction"); ki=iftGet(ift, keystr, 0);}
1053 if(ki>=0 && strlen(ift->item[ki].value)) {
1054 if(strncasecmp(ift->item[ki].value, "Yes", 1)==0) {
1055 dft->decayCorrected=DFT_DECAY_CORRECTED; ok_nr++;
1056 } else if(strncasecmp(ift->item[ki].value, "No", 1)==0) {
1058 }
1059 }
1060
1061 /* Check for injection time */
1062 strcpy(keystr, "injection time"); ki=iftGet(ift, keystr, 0);
1063 if(ki==-1) {strcpy(keystr, "injection_time"); ki=iftGet(ift, keystr, 0);}
1064 if(ki>=0 && strlen(ift->item[ki].value)) {
1065 /* check if time is in correct format; otherwise try to correct it */
1066 if(ift->item[ki].value[4]=='-' && ift->item[ki].value[7]=='-' &&
1067 ift->item[ki].value[13]==':' && ift->item[ki].value[16]==':') {
1068 strncpy(dft->injectionTime, ift->item[ki].value, 19);
1069 dft->injectionTime[19]=(char)0; ok_nr++;
1070 } else if(ift->item[ki].value[2]=='.' && ift->item[ki].value[5]=='.' &&
1071 ift->item[ki].value[13]==':' && ift->item[ki].value[16]==':') {
1072 sprintf(dft->injectionTime, "%4.4s-%2.2s-%2.2s %8.8s",
1073 ift->item[ki].value+6, ift->item[ki].value+3, ift->item[ki].value,
1074 ift->item[ki].value+11);
1075 ok_nr++;
1076 }
1077 }
1078
1079 /* Check for scan start time */
1080 strcpy(keystr, "scan start time"); ki=iftGet(ift, keystr, 0);
1081 if(ki==-1) {strcpy(keystr, "scan_start_time"); ki=iftGet(ift, keystr, 0);}
1082 if(ki==-1) {strcpy(keystr, "scan_start"); ki=iftGet(ift, keystr, 0);}
1083 if(ki==-1) {strcpy(keystr, "scan start"); ki=iftGet(ift, keystr, 0);}
1084 if(ki>=0 && strlen(ift->item[ki].value)) {
1085 /* check if time is in correct format; otherwise try to correct it */
1086 if(ift->item[ki].value[4]=='-' && ift->item[ki].value[7]=='-' &&
1087 ift->item[ki].value[13]==':' && ift->item[ki].value[16]==':') {
1088 strncpy(dft->scanStartTime, ift->item[ki].value, 19);
1089 dft->scanStartTime[19]=(char)0; ok_nr++;
1090 } else if(ift->item[ki].value[2]=='.' && ift->item[ki].value[5]=='.' &&
1091 ift->item[ki].value[13]==':' && ift->item[ki].value[16]==':') {
1092 sprintf(dft->scanStartTime, "%4.4s-%2.2s-%2.2s %8.8s",
1093 ift->item[ki].value+6, ift->item[ki].value+3, ift->item[ki].value,
1094 ift->item[ki].value+11);
1095 ok_nr++;
1096 }
1097 }
1098
1099 return(ok_nr);
1100}
double atof_dpi(char *str)
Definition decpoint.c:59
int iftGet(IFT *ift, char *key, int verbose)
Definition iftsrch.c:15
int iftGetNth(IFT *ift, char *key, int n, int verbose)
Definition iftsrch.c:48
#define DFT_DECAY_NOTCORRECTED
#define DFT_DECAY_CORRECTED
int rnameSplit(char *rname, char *name1, char *name2, char *name3, int max_name_len)
Definition rname.c:14
#define MAX_REGIONNAME_LEN
Definition libtpcmisc.h:154
size_t strlcpy(char *dst, const char *src, size_t dstsize)
Definition strext.c:245
#define MAX_STUDYNR_LEN
Definition libtpcmisc.h:163
int petTunitId(const char *timeunit)
Definition petunits.c:187
#define MAX_REGIONSUBNAME_LEN
Definition libtpcmisc.h:158
char scanStartTime[20]
char decayCorrected
Voi * voi
int timeunit
char studynr[MAX_STUDYNR_LEN+1]
char injectionTime[20]
char isotope[8]
char unit[MAX_UNITS_LEN+1]
char radiopharmaceutical[32]
IFT_KEY_AND_VALUE * item
Definition libtpcmisc.h:279
double size
char voiname[MAX_REGIONSUBNAME_LEN+1]
char name[MAX_REGIONNAME_LEN+1]
char hemisphere[MAX_REGIONSUBNAME_LEN+1]
char place[MAX_REGIONSUBNAME_LEN+1]

Referenced by dftRead().

◆ dftFormat()

int dftFormat ( char * fname)

Determine the type of DFT file. This will replace dftType().

Note that only some of formats are currently identified, and identification does not mean that dftRead() supports the format.

Returns
Returns DFT_FORMAT_UNKNOWN or other format id defined in dft.h.
See also
dftRead, dftWrite
Parameters
fnamePointer to file name; this string is not modified.

Definition at line 422 of file dftio.c.

425 {
426 if(CSV_TEST>0) {printf("%s('%s')\n", __func__, fname); fflush(stdout);}
427
428 FILE *fp;
429 char tmp[256];
430 int c;
431
432
433 /* Open file */
434 fp=fopen(fname, "r"); if(fp==NULL) return DFT_FORMAT_UNKNOWN;
435
436 /* Binary data? */
437 while((c=fgetc(fp))!=EOF) {
438 if(isalnum(c) || isspace(c) || isgraph(c)) continue;
439 if(c>=160) continue;
440 if(CSV_TEST>1) {printf(" invalid character %d\n", c); fflush(stdout);}
441 fclose(fp); return DFT_FORMAT_UNKNOWN;
442 }
443 rewind(fp);
444
445 /* File with one title line without comment mark? */
446 while(fgets(tmp, 10, fp) != NULL) {if(strlen(tmp)) break;}
447 if(strncasecmp(tmp, "Time[", 5)==0) {fclose(fp); return DFT_FORMAT_PMOD;}
448 if(strncasecmp(tmp, "Start[", 6)==0) {fclose(fp); return DFT_FORMAT_PMOD;}
449 if(strcasestr(tmp, "Start\tEnd\t")!=NULL) {fclose(fp); return DFT_FORMAT_PMOD;}
450 rewind(fp);
451
452 /* Read the first line that is not empty or comment line */
453 while(fgets(tmp, 32, fp) != NULL) {
454 if(strlen(tmp)==0) continue;
455 if(tmp[0]=='#') continue;
456 if(strncmp(tmp, "//", 2)==0) continue;
457 break;
458 }
459 rewind(fp);
460
461 /* Check for identification strings */
462 if(strncasecmp(tmp, "DFT", 3)==0) {fclose(fp); return DFT_FORMAT_STANDARD;}
463 else if(strncasecmp(tmp, "FIT1", 3)==0) {fclose(fp); return DFT_FORMAT_FIT;}
464 else if(strncasecmp(tmp, "cpt", 3)==0) {fclose(fp); return DFT_FORMAT_NCI;}
465
466 /* Identify certain file name extensions */
467 if(fncasematch(fname, "*.idwc")==1 || fncasematch(fname, "*.idw")==1) {
468 fclose(fp); return DFT_FORMAT_IDWC;}
469 if(fncasematch(fname, "*.if")==1) {fclose(fp); return DFT_FORMAT_IF;}
470
471 fclose(fp);
472
473 /* Try to read as CSV */
474 CSV csv; csvInit(&csv);
475 if(csvRead(&csv, fname)==0) {
476 int format=DFT_FORMAT_UNKNOWN;
477 if(csv.separator==';') format=DFT_FORMAT_CSV_INT;
478 else if(csv.separator==',') format=DFT_FORMAT_CSV_UK;
479 else if(csv.separator=='\t') {
480 int i, commas=0, dots=0;
481 for(i=0; i<csv.nr; i++) {
482 if(strchr(csv.c[i].content, ',')!=NULL) commas++;
483 else if(strchr(csv.c[i].content, '.')!=NULL) dots++;
484 }
485 if(dots>commas) format=DFT_FORMAT_CSV_UK; else format=DFT_FORMAT_CSV_INT;
486 }
487 if(CSV_TEST>1) printf(" format=%d\n", format);
488 csvEmpty(&csv);
489 if(format!=DFT_FORMAT_UNKNOWN) return(format);
490 }
491
492 return DFT_FORMAT_PLAIN;
493}
int CSV_TEST
Definition csv.c:6
void csvInit(CSV *csv)
Definition csv.c:13
void csvEmpty(CSV *csv)
Definition csv.c:24
int csvRead(CSV *csv, char *fname)
Definition csv.c:42
int fncasematch(const char *fname, const char *key)
Definition filename.c:100
#define DFT_FORMAT_PMOD
#define DFT_FORMAT_CSV_INT
#define DFT_FORMAT_CSV_UK
#define DFT_FORMAT_STANDARD
#define DFT_FORMAT_IF
#define DFT_FORMAT_FIT
#define DFT_FORMAT_IDWC
#define DFT_FORMAT_NCI
#define DFT_FORMAT_PLAIN
#define DFT_FORMAT_UNKNOWN
char * strcasestr(const char *haystack, const char *needle)
Definition strext.c:279
char * content
char separator
CSV_item * c

Referenced by dftRead(), dftReadinput(), and dftReadReference().

◆ dftGetPmodTitle()

int dftGetPmodTitle ( DFT * dft,
char * title_line )

Read single title line from PMOD files and set DFT fields accordingly. Alternatively, reads the number of regions in PMOD title line.

Returns
Returns 0 if title contents were successfully saved in DFT struct; if pointer to DFT struct is not specified, then the number of regions is returned.
Parameters
dftPointer to allocated DFT struct where information will be written; Enter NULL, if only the nr of regions is to be returned.
title_linePointer to string containing the title line; string is not modified

Definition at line 1109 of file dftio.c.

1115 {
1116 //printf("dftGetPmodTitle()\n");
1117 //printf(" '%s'\n", title_line);
1118 //if(dft==NULL) printf(" dft=NULL\n");
1119
1120 int ti=0, ri, ret, tabs=0, timetype=DFT_TIME_MIDDLE;
1121 char *cptr, *cptr2, rname[MAX_REGIONNAME_LEN+1];
1122 char unit[MAX_UNITS_LEN+1], separs[8];
1123
1124 /* Check the input */
1125 if(strlen(title_line)<1) return 1;
1126
1127 /* Count the nr of tabs in title line */
1128 cptr=title_line; while(*cptr) {if(*cptr=='\t') tabs++; cptr++;}
1129 /* If tabs found, then do not use space as field separator */
1130 if(tabs>0) strcpy(separs, "\t\n\r"); else strcpy(separs, " \t\n\r");
1131
1132 /* Make a copy of title line */
1133 char ntl[1+strlen(title_line)], *tl;
1134 strcpy(ntl, title_line); tl=ntl;
1135 cptr=strtok(tl, separs); if(cptr==NULL) return 2;
1136 ti=ri=0;
1137 while(cptr!=NULL) {
1138 if(ti==0) {
1139 if(strlen(cptr)>6 && strncasecmp(cptr, "Time[", 5)==0) {
1140 strncpy(unit, cptr+5, MAX_UNITS_LEN); unit[MAX_UNITS_LEN]=(char)0;
1141 cptr2=strchr(unit, ']'); if(cptr2!=NULL) *cptr2=(char)0;
1142 if(dft!=NULL) dft->timeunit=petTunitId(unit);
1143 timetype=DFT_TIME_MIDDLE;
1144 } else if(strlen(cptr)>6 && strncasecmp(cptr, "start[", 6)==0) {
1145 strncpy(unit, cptr+6, MAX_UNITS_LEN); unit[MAX_UNITS_LEN]=(char)0;
1146 cptr2=strchr(unit, ']'); if(cptr2!=NULL) *cptr2=(char)0;
1147 if(dft!=NULL) dft->timeunit=petTunitId(unit);
1148 timetype=DFT_TIME_STARTEND;
1149 }
1150 } else if(ti==1 && timetype==DFT_TIME_STARTEND) {
1151 if(strlen(cptr)>5 && strncasecmp(cptr, "end[", 4)==0) {
1152 strncpy(unit, cptr+4, MAX_UNITS_LEN); unit[MAX_UNITS_LEN]=(char)0;
1153 cptr2=strchr(unit, ']'); if(cptr2!=NULL) *cptr2=(char)0;
1154 ret=petCunitId(unit);
1155 if(ret!=CUNIT_UNKNOWN && dft!=NULL) strcpy(dft->unit, petCunit(ret));
1156 }
1157 } else {
1158 // get tac name
1159 strncpy(rname, cptr, MAX_REGIONNAME_LEN);
1160 rname[MAX_REGIONNAME_LEN]=(char)0;
1161 cptr2=strchr(rname, '['); if(cptr2!=NULL) *cptr2=(char)0;
1162 while((cptr2=strchr(rname, '_'))!=NULL) *cptr2=' ';
1163 if(dft!=NULL && ri<dft->_voidataNr) strcpy(dft->voi[ri].name, rname);
1164 // get unit
1165 cptr2=strchr(cptr, '[');
1166 if(cptr2!=NULL) {
1167 strncpy(unit, cptr2+1, MAX_UNITS_LEN); unit[MAX_UNITS_LEN]=(char)0;
1168 cptr2=strchr(unit, ']'); if(cptr2!=NULL) *cptr2=(char)0;
1169 ret=petCunitId(unit);
1170 if(ret!=CUNIT_UNKNOWN && dft!=NULL) strcpy(dft->unit, petCunit(ret));
1171 }
1172 ri++;
1173 }
1174 ti++;
1175 cptr=strtok(NULL, separs);
1176 }
1177 if(dft==NULL) {
1178 return(ri);
1179 }
1180
1181 dft->timetype=timetype;
1182
1183 //for(int i=0; i<dft->_voidataNr; i++) printf(" '%s'\n", dft->voi[i].name);
1184
1185 /* Split ROI names */
1186 ti=ri;
1187 for(ri=0; ri<ti; ri++)
1188 rnameSplit(dft->voi[ri].name, dft->voi[ri].voiname,
1189 dft->voi[ri].hemisphere, dft->voi[ri].place, MAX_REGIONSUBNAME_LEN);
1190
1191 return(0);
1192}
#define DFT_TIME_MIDDLE
#define DFT_TIME_STARTEND
int petCunitId(const char *unit)
Definition petunits.c:74
char * petCunit(int cunit)
Definition petunits.c:211
#define MAX_UNITS_LEN
Definition libtpcmisc.h:95
int timetype

Referenced by dftRead().

◆ dftPrint()

void dftPrint ( DFT * data)

Prints to stdout the contents of DFT data structure. Mainly for testing purposes.

See also
dftWrite

Definition at line 538 of file dftio.c.

539{
540 int voi, frame;
541
542 printf("Number of curves: %d Number of data points: %d\n",
543 data->voiNr, data->frameNr);
544 printf("Study: '%s' Unit: '%s'\n", data->studynr, data->unit);
545 printf("Time unit and type: %d %d\n", data->timeunit, data->timetype);
546 if(strlen(data->radiopharmaceutical))
547 printf("Radiopharmaceutical: %s\n", data->radiopharmaceutical);
548 if(strlen(data->isotope)) printf("Isotope: %s\n", data->isotope);
549 if(strlen(data->scanStartTime))
550 printf("Scan start time: %s\n", data->scanStartTime);
551 if(strlen(data->injectionTime))
552 printf("Injection time: %s\n", data->injectionTime);
554 printf("Corrected for physical decay: yes\n");
556 printf("Corrected for physical decay: no\n");
557 printf("_datasize = %d\n", data->_dataSize);
558 for(voi=0; voi<data->voiNr; voi++) {
559 if(strlen(data->voi[voi].name)>0)
560 printf("\nROI name: '%s' Size: %g\n",
561 data->voi[voi].name, data->voi[voi].size);
562 else
563 printf("\nROI name: '%s' '%s' '%s' Size: %g\n",
564 data->voi[voi].voiname, data->voi[voi].hemisphere, data->voi[voi].place,
565 data->voi[voi].size);
566 for(frame=0; frame<data->frameNr; frame++) {
567 printf("%03d: %11.3e %11.3e %11.3e %11.3e %11.3e %11.3e\n",
568 frame+1, data->x[frame], data->x1[frame], data->x2[frame],
569 data->voi[voi].y[frame], data->voi[voi].y2[frame],
570 data->voi[voi].y3[frame]);
571 }
572 }
573 printf("Comments:\n");
574 if(strlen(data->comments)>0) printf("%s\n", data->comments);
575 printf("Weights:\n");
576 if(data->isweight)
577 for(frame=0; frame<data->frameNr; frame++)
578 printf(" %03d %11.3e %11.3e %11.3e\n", frame+1,
579 data->x1[frame], data->x2[frame], data->w[frame]);
580 else
581 printf(" contains no weights.\n");
582 return;
583}
double * w
double * x1
char comments[_DFT_COMMENT_LEN+1]
int voiNr
double * x2
int frameNr
int isweight
double * x
double * y2
double * y
double * y3

Referenced by csv2dft(), dftRead(), img_k1_using_ki(), img_logan(), and img_patlak().

◆ dftRead()

int dftRead ( char * filename,
DFT * data )

Read TAC file contents into specified DFT data structure. Reads standard DFT files, plain DFT files, and some other formats.

See also
dftFormat, dftWrite
Returns
Returns 0 when successful, in case of error sets dfterrmsg.
Parameters
filenameName of file to be read.
dataPointer to initiated DFT struct where data will be written; any old content is deleted.

Definition at line 22 of file dftio.c.

27 {
28 const int verbose=0;
29 if(verbose>0) {printf("%s(%s, dft)\n", __func__, filename); fflush(stdout);}
30
31 FILE *fp;
32 char *cptr, *line, *lptr, temp[128];
33 int ret, i, j, c, type=0, voiNr=0, frameNr=0, longest=0;
34 double f;
35 IFT ift;
36
37
38 /* Empty data */
39 if(data==NULL) {strcpy(dfterrmsg, "invalid data"); return 1;}
40 dftEmpty(data);
41
42 /* Check if file can be opened for read; then close it for now */
43 if(verbose>1) {printf("opening file\n"); fflush(stdout);}
44 fp=fopen(filename, "r");
45 if(fp==NULL) {strcpy(dfterrmsg, "cannot open file"); return 1;}
46 fclose(fp);
47
48 /* Try to identify the file format */
49 type=dftFormat(filename); if(verbose>1) printf(" type := %d\n", type);
50 if(type==DFT_FORMAT_UNKNOWN) {
51 strcpy(dfterrmsg, "unknown file format"); return 1;
52 } else if(type==DFT_FORMAT_FIT) {
53 strcpy(dfterrmsg, "cannot read fit file"); return 1;
54 }
55
56 /* Read some special formats */
57 if(type==DFT_FORMAT_NCI) { // TPC format before DFT
58 if(verbose>1) {printf("calling roikbqRead()\n"); fflush(stdout);}
59 ret=roikbqRead(filename, data); if(ret!=0) return ret;
60 dftFrametimes(data);
61 return(0);
62 } else if(type==DFT_FORMAT_IDWC) {
63 if(verbose>1) {printf("calling idwcRead()\n"); fflush(stdout);}
64 ret=idwcRead(filename, data); if(ret!=0) return ret;
65 if(strlen(data->studynr)==0) studynr_from_fname(filename, data->studynr);
66 return(0);
67 } else if(type==DFT_FORMAT_IF) {
68 if(verbose>1) {printf("calling iftRead()\n"); fflush(stdout);}
69 ret=ifRead(filename, data); if(ret!=0) return ret;
70 if(strlen(data->studynr)==0) studynr_from_fname(filename, data->studynr);
71 return(0);
72 } else if(type==DFT_FORMAT_CSV_INT || type==DFT_FORMAT_CSV_UK) {
73 CSV csv;
74 csvInit(&csv); //CSV_TEST=100;
75 if(verbose>1) {printf("calling csvRead()\n"); fflush(stdout);}
76 ret=csvRead(&csv, filename);
77 if(ret==0) ret=csv2dft(&csv, data);
78 csvEmpty(&csv);
79 if(ret==0) {
80 /* Try to read information from an interfile-type header */
81 IFT ift; iftInit(&ift);
82 if(iftRead(&ift, filename, 1, 0)==0 && ift.keyNr>0) dft_fill_hdr_from_IFT(data, &ift);
83 iftEmpty(&ift);
84 /* study number, too */
85 if(strlen(data->studynr)==0) studynr_from_fname(filename, data->studynr);
86 /* Set DFT comments */
87 dftSetComments(data);
88 return(0);
89 }
90 // if not ok, then just drop through with plain format
92 }
93
94 /* Try to read supported TAC formats, not the others */
95 if(type!=DFT_FORMAT_PLAIN && type!=DFT_FORMAT_STANDARD &&
96 type!=DFT_FORMAT_IFT && type!=DFT_FORMAT_PMOD
97 ) {
98 strcpy(dfterrmsg, "unsupported file format"); return 1;
99 }
100
101 /* Try to read information from an interfile-type header */
102 if(verbose>1) {printf("calling iftRead()\n"); fflush(stdout);}
103 iftInit(&ift);
104 if(iftRead(&ift, filename, 1, 0)!=0) iftEmpty(&ift);
105
106 /* Open file */
107 if(verbose>1) {printf("re-opening file\n"); fflush(stdout);}
108 fp=fopen(filename, "r");
109 if(fp==NULL) {
110 strcpy(dfterrmsg, "cannot open file"); iftEmpty(&ift); return 1;
111 }
112
113 /* Get the length of the longest line */
114 i=0; while((c=fgetc(fp))!=EOF) {
115 if(c==10 || c==13) {if(i>longest) longest=i; i=0;} else i++;}
116 if(i>longest) longest=i;
117 rewind(fp); longest+=2;
118 if(verbose>1) {printf(" longest := %d\n", longest); fflush(stdout);}
119
120 /* and allocate memory for string of that length */
121 line=(char*)malloc((longest+1)*sizeof(char));
122 if(line==NULL) {strcpy(dfterrmsg, "out of memory"); iftEmpty(&ift); fclose(fp); return 2;}
123
124 /* Get the frame number */
125 i=0; while(fgets(line, longest, fp)!=NULL && *line) {
126 if(line[0]=='#') continue;
127 cptr=strchr(line, '#'); if(cptr!=NULL) *cptr=(char)0;
128 for(j=0; j<(int)strlen(line); j++)
129 if(isalnum((int)line[j]) || line[j]=='.') {i++; break;}
130 }
131 rewind(fp); frameNr=i;
132 if(type==DFT_FORMAT_STANDARD) frameNr-=4; /* title lines */
133 if(type==DFT_FORMAT_PMOD) frameNr-=1;
134 if(verbose>1) {printf("frameNr := %d\n", frameNr); fflush(stdout);}
135 if(frameNr<1) {
136 strcpy(dfterrmsg, "contains no data");
137 iftEmpty(&ift); free(line); fclose(fp); return 1;
138 }
139
140 /* Get the number of curves */
141 /* find first line that is not an empty or a comment line */
142 while(fgets(line, longest, fp)!=NULL) {
143 if(line[0]=='#') continue;
144 /* If PMOD file, then read it from the title */
145 if(type==DFT_FORMAT_PMOD) {voiNr=dftGetPmodTitle(NULL, line); break;}
146 /* In plain data file that is first frame, which starts with time */
147 /* In normal DFT file that is 1st title line, which starts with 'DFT' */
148 char *nline; nline=strdup(line); lptr=nline;
149 cptr=strtok(lptr, " \t\n\r"); if(cptr==NULL) {free(nline); continue;}
150 voiNr=0; while((cptr=strtok(NULL, " \t\n\r"))!=NULL) voiNr++;
151 free(nline);
152 break;
153 }
154 rewind(fp);
155 if(verbose>1) {printf("voiNr := %d\n", voiNr); fflush(stdout);}
156 if(voiNr<1) {
157 strcpy(dfterrmsg, "contains no curves");
158 iftEmpty(&ift); free(line); fclose(fp); return 1;
159 }
160
161 /* Allocate memory for data */
162 if(verbose>1) {printf("allocating memory\n"); fflush(stdout);}
163 if(dftSetmem(data, frameNr, voiNr)) {
164 strcpy(dfterrmsg, "out of memory");
165 iftEmpty(&ift); free(line); fclose(fp); return 2;
166 }
167
168 /* For plain data files, set defaults for title data */
169 if(type==DFT_FORMAT_PLAIN || type==DFT_FORMAT_IFT) {
170 if(verbose>1) {printf("setting title defaults for plain data\n"); fflush(stdout);}
171 int u, n; u=voiNr; n=1; while((u/=10)>=1) n++;
173 for(i=0; i<voiNr; i++) {
174 snprintf(data->voi[i].voiname, MAX_REGIONSUBNAME_LEN+1, "%0*d", n, i+1);
175 strcpy(data->voi[i].name, data->voi[i].voiname);
176 }
177 /* Default: times in minutes, and frame mid time */
178 data->timeunit=TUNIT_UNKNOWN; data->timetype=DFT_TIME_MIDDLE;
179 }
180
181 /*
182 * Try to read information from an interfile-type header
183 */
184 if(ift.keyNr>0) {
185 if(verbose>1) {printf("calling dft_fill_hdr_from_IFT\n"); fflush(stdout);}
186 dft_fill_hdr_from_IFT(data, &ift);
187 }
188 iftEmpty(&ift);
189
190 /* Try to read information from a single title line in PMOD files */
191 if(type==DFT_FORMAT_PMOD) {
192 if(fgets(line, longest, fp)==NULL) {
193 strcpy(dfterrmsg, "wrong format"); free(line); fclose(fp); return 101;}
194 if(verbose>1) {printf("calling dftGetPmodTitle\n"); fflush(stdout);}
195 dftGetPmodTitle(data, line);
196 // do not rewind!
197 }
198
199 /*
200 * Read DFT title lines, if they exist
201 */
202 i=0;
203 if(type==DFT_FORMAT_STANDARD) {
204 if(verbose>1) {printf("reading DFT title lines\n"); fflush(stdout);}
205 do {
206 if(fgets(line, longest, fp)==NULL) {
207 strcpy(dfterrmsg, "wrong format"); free(line); fclose(fp); return 102;}
208 lptr=line;
209 /* Check for comment line */
210 if(line[0]=='#') { /* Read comment only if there is space left */
211 strlcat(data->comments, line, _DFT_COMMENT_LEN);
212 continue;
213 }
214 cptr=strchr(line, '#'); if(cptr!=NULL) *cptr=(char)0;
215 /* Read first token, and check for empty lines as well */
216 cptr=strtok(lptr, " \t\n\r"); if(cptr==NULL) continue; else i++;
217 if(i==1) { /* VOI names */
218 for(j=0; j<voiNr; j++) {
219 cptr=strtok(NULL, " \t\n\r");
220 if(cptr==NULL) {strcpy(dfterrmsg, "wrong format"); free(line); fclose(fp); return 103;}
221 if(strlen(cptr)>1 || *cptr!='.') {
222 strncpy(data->voi[j].name, cptr, MAX_REGIONNAME_LEN);
223 data->voi[j].name[MAX_REGIONNAME_LEN]=(char)0;
224 strncpy(data->voi[j].voiname, cptr, MAX_REGIONSUBNAME_LEN);
225 data->voi[j].voiname[MAX_REGIONSUBNAME_LEN]=(char)0;
226 /* if name is long, then divide it into name subfields */
227 if(strlen(cptr)>MAX_REGIONSUBNAME_LEN) {
229 data->voi[j].hemisphere[MAX_REGIONSUBNAME_LEN]=(char)0;
230 if(strlen(cptr)>2*MAX_REGIONSUBNAME_LEN) {
231 strncpy(data->voi[j].place, cptr+2*MAX_REGIONSUBNAME_LEN, MAX_REGIONSUBNAME_LEN);
232 data->voi[j].place[MAX_REGIONSUBNAME_LEN]=(char)0;
233 }
234 }
235 } else {
236 int u, n; u=voiNr; n=1; while((u/=10)>=1) n++; if(n>6) n=6;
237 snprintf(data->voi[j].voiname, 7, "%0*d", n, j+1);
238 strcpy(data->voi[j].name, data->voi[j].voiname);
239 }
240 }
241 } else if(i==2) { /* 2nd VOI names (hemispheres) */
242 if(strcmp(cptr, ".")!=0) {
243 strlcpy(data->studynr, cptr, MAX_STUDYNR_LEN);
244 } else strcpy(data->studynr, "");
245 for(j=0; j<voiNr; j++) {
246 if((cptr=strtok(NULL, " \t\n\r"))==NULL) {
247 strcpy(dfterrmsg, "missing field on 2nd line");
248 free(line); fclose(fp); return 104;
249 }
250 if(strlen(cptr)>1 || *cptr!='.') {
251 strncpy(data->voi[j].hemisphere, cptr, MAX_REGIONSUBNAME_LEN);
252 data->voi[j].hemisphere[MAX_REGIONSUBNAME_LEN]=(char)0;
253 strcat(data->voi[j].name, " ");
254 strlcat(data->voi[j].name, data->voi[j].hemisphere, MAX_REGIONNAME_LEN);
255 } else {
256 strlcat(data->voi[j].name, " .", MAX_REGIONNAME_LEN+1);
257 }
258 }
259 /* check that there are no more contents */
260 if((cptr=strtok(NULL, " \t\n\r"))!=NULL) {
261 strcpy(dfterrmsg, "wrong format"); free(line); fclose(fp); return 105;}
262 } else if(i==3) { /* unit and VOI place (planes) */
263 /* first, copy the unit */
264 strlcpy(data->unit, cptr, 13); //data->unit[12]=(char)0;
265 /* then, copy the names */
266 int len, ii=0;
267 j=0;
268 while(j<voiNr) {
269 if((cptr=strtok(NULL, " \t\n\r"))==NULL) {
270 strcpy(dfterrmsg, "missing field on 3rd line");
271 free(line); fclose(fp); return 106;
272 }
273 len=strlen(cptr);
274 /* check if cunit consists of two parts */
275 if(ii==0 && cptr[0]=='(' && cptr[len-1]==')') {ii++; continue;}
276 /* copy the name */
277 if(len>1 || *cptr!='.') {
278 strlcpy(data->voi[j].place, cptr, MAX_REGIONSUBNAME_LEN+1);
279 //data->voi[j].place[MAX_REGIONSUBNAME_LEN]=(char)0;
280 strcat(data->voi[j].name, " ");
281 strlcat(data->voi[j].name, data->voi[j].place, MAX_REGIONNAME_LEN+1);
282 } else {
283 strlcat(data->voi[j].name, " .", MAX_REGIONNAME_LEN+1);
284 }
285 j++; ii++;
286 }
287 } else if(i==4) { /* time type, time unit, and VOI sizes */
288 /* time type */
289 if(strcasecmp(cptr, "Time")==0) data->timetype=DFT_TIME_MIDDLE;
290 else if(strcasecmp(cptr, "Times")==0) data->timetype=DFT_TIME_STARTEND;
291 else if(strcasecmp(cptr, "Start")==0) data->timetype=DFT_TIME_START;
292 else if(strcasecmp(cptr, "End")==0) data->timetype=DFT_TIME_END;
293 else if(strcasecmp(cptr, "Distance")==0) data->timetype=DFT_TIME_MIDDLE;
294 else if(strcasecmp(cptr, "Distances")==3) data->timetype=DFT_TIME_STARTEND;
295 else {strcpy(dfterrmsg, "wrong format"); free(line); fclose(fp); return 108;}
296 /* time unit */
297 if((cptr=strtok(NULL, " \t\n\r"))==NULL) {
298 strcpy(dfterrmsg, "wrong format"); free(line); fclose(fp); return 109;}
299 strcpy(temp, ""); j=sscanf(cptr, "(%127s)", temp);
300 j=strlen(temp)-1; if(j>=0 && temp[j]==')') temp[j]=(char)0;
301 data->timeunit=petTunitId(temp);
302 if(data->timeunit<0) {
303 strcpy(dfterrmsg, "wrong format"); free(line); fclose(fp); return 110;}
304 /* volumes */
305 for(j=0; j<voiNr; j++) {
306 if((cptr=strtok(NULL, " \t\n\r"))==NULL) {
307 strcpy(dfterrmsg, "wrong format"); free(line); fclose(fp); return 111;}
308 if(strlen(cptr)==1 && *cptr=='.') data->voi[j].size=0.0;
309 else data->voi[j].size=atof_dpi(cptr);
310 }
311 }
312 } while(i<4); // Standard DFT title lines are now read
313 }
314
315 /* Read data lines */
316 if(verbose>1) {printf("reading data lines\n"); fflush(stdout);}
317 i=0; while(fgets(line, longest, fp)!=NULL) {
318
319 /* Check for comment line */
320 if(line[0]=='#') { /* Read comment only if there is space left */
321 strlcat(data->comments, line, _DFT_COMMENT_LEN);
322 continue;
323 }
324 // remove end-of-line comment
325 cptr=strchr(line, '#'); if(cptr!=NULL) *cptr=(char)0;
326
327 /* Read first token, and check for empty lines as well */
328 char *nline; nline=strdup(line); lptr=nline;
329 cptr=strtok(lptr, " \t\n\r"); if(cptr==NULL) {free(nline); continue;}
330 if(i<frameNr) {
331 /* Read time(s) */
332 if(atof_with_check(cptr, &f)!=0) {
333 strcpy(dfterrmsg, "wrong format");
334 free(line); free(nline); fclose(fp); return 130;
335 }
336 if(data->timetype==DFT_TIME_STARTEND) {
337 data->x1[i]=f; cptr=strtok(NULL, " \t\n\r");
338 if(atof_with_check(cptr, &data->x2[i])!=0) {
339 strcpy(dfterrmsg, "wrong format");
340 free(line); free(nline); fclose(fp); return 131;
341 }
342 data->x[i]=0.5*(data->x1[i]+data->x2[i]);
343 } else data->x[i]=f;
344 /* curve data */
345 for(j=0; j<voiNr; j++) {
346 if((cptr=strtok(NULL, " \t\n\r"))==NULL) {
347 strcpy(dfterrmsg, "wrong format");
348 free(line); free(nline); fclose(fp); return 132;
349 }
350 if(strlen(cptr)==1 && *cptr=='.')
351 data->voi[j].y[i]=nan("");
352 else {
353 if(atof_with_check(cptr, &data->voi[j].y[i])!=0) {
354 strcpy(dfterrmsg, "wrong format");
355 free(line); free(nline); fclose(fp); return 133;
356 }
357 c=dec_nr(cptr);
359 }
360 }
361 }
362 free(nline);
363 i++;
364 }
365 if(i!=frameNr) {strcpy(dfterrmsg, "wrong format"); fclose(fp); free((char*)line); return 134;}
366
367 /* Close file */
368 fclose(fp); free((char*)line);
369
370 /* Set voiNr and frameNr, and type */
371 data->voiNr=voiNr; data->frameNr=frameNr;
372 if(type==DFT_FORMAT_IFT) {
374 } else if(type==DFT_FORMAT_PMOD) {
375 data->_type=type; // keeping PMOD format
376 // unless TAC names could not be read
377 for(i=0; i<data->voiNr; i++) if(strlen(data->voi[i].name)<1) {
378 data->_type=DFT_FORMAT_PLAIN; break;}
379 } else {
380 data->_type=type;
381 }
382
383 /* Set study number from file name, if necessary */
384 if(strlen(data->studynr)==0) studynr_from_fname(filename, data->studynr);
385
386 /* If weight 'voi' was read, move it to its own place */
387 for(i=0; i<data->voiNr; i++) if(!strcasecmp(data->voi[i].voiname, "weight")) {
388 data->isweight=1;
389 for(j=0; j<data->frameNr; j++) data->w[j]=data->voi[i].y[j];
390 /* Move the following VOIs one step backwards */
391 for(c=i+1; c<data->voiNr; c++) if(dftCopyvoi(data, c, c-1)) {
392 strcpy(dfterrmsg, "cannot read weight"); return 4;}
393 data->voiNr--;
394 break;
395 }
396 /* If no weights were found, set uniform weight */
397 if(!data->isweight) for(i=0; i<data->frameNr; i++) data->w[i]=1.0;
398
399 /* Calculate frame mid times, or frame start and end times;
400 this works only if time units are known */
401 dftFrametimes(data);
402
403 /* Make again the full ROI names from the separate sub parts */
404 for(i=0; i<data->voiNr; i++)
405 rnameCatenate(data->voi[i].name, MAX_REGIONNAME_LEN, data->voi[i].voiname,
406 data->voi[i].hemisphere, data->voi[i].place, ' ');
407
408
409 if(CSV_TEST>100) dftPrint(data);
410 return(0);
411}
int csv2dft(CSV *csv, DFT *dft)
Definition csv.c:200
int atof_with_check(char *double_as_string, double *result_value)
Definition decpoint.c:107
int dec_nr(char *str)
Definition decpoint.c:81
char dfterrmsg[64]
Definition dft.c:6
void dftSetComments(DFT *dft)
Definition dft.c:1326
int dftCopyvoi(DFT *data, int from, int to)
Definition dft.c:472
int dftSetmem(DFT *data, int frameNr, int voiNr)
Definition dft.c:57
void dftEmpty(DFT *data)
Definition dft.c:20
void dftFrametimes(DFT *data)
Definition dft.c:340
int DFT_NR_OF_DECIMALS
Definition dftio.c:13
int dftFormat(char *fname)
Definition dftio.c:422
int dft_fill_hdr_from_IFT(DFT *dft, IFT *ift)
Definition dftio.c:971
void dftPrint(DFT *data)
Definition dftio.c:538
int dftGetPmodTitle(DFT *dft, char *title_line)
Definition dftio.c:1109
int idwcRead(char *filename, DFT *dft)
Definition idwc.c:77
int ifRead(char *filename, DFT *dft)
Definition if.c:78
void iftEmpty(IFT *ift)
Definition ift.c:60
void iftInit(IFT *ift)
Definition ift.c:45
int iftRead(IFT *ift, char *filename, int is_key_required, int verbose)
Definition iftfile.c:24
int roikbqRead(char *fname, DFT *dft)
Definition ncifile.c:95
#define DFT_TIME_END
#define DFT_TIME_START
#define DFT_FORMAT_IFT
int rnameCatenate(char *rname, int max_rname_len, char *name1, char *name2, char *name3, char space)
Definition rname.c:189
int studynr_from_fname(char *fname, char *studynr)
Definition studynr.c:119
size_t strlcat(char *dst, const char *src, size_t dstsize)
Definition strext.c:206
int _type
int keyNr
Definition libtpcmisc.h:270

Referenced by dftReadinput(), dftReadModelingData(), dftReadReference(), and imgReadModelingData().

◆ dftType()

int dftType ( FILE * fp)

Determine the type of DFT file.

Deprecated
Replace calls to dftType() by dftFormat(), but note that return values have changed.
See also
dftFormat
Returns
0=unknown; 1=normal DFT; 2=plain data; 3=fit file; 4=nci file; 5=KI file

Definition at line 503 of file dftio.c.

504{
505 char tmp[256];
506 int c;
507
508 /* Find first line that is not empty or comment line */
509 rewind(fp);
510 while(fgets(tmp, 4, fp) != NULL) {if(strlen(tmp) && tmp[0]!='#') break;}
511 rewind(fp);
512
513 /* Check for identification strings */
514 if(strncasecmp(tmp, "DFT", 3)==0) return 1;
515 else if(strncasecmp(tmp, "FIT1", 3)==0) return 3;
516 else if(strncasecmp(tmp, "cpt", 3)==0) return 4;
517
518 /* Binary data? */
519 while((c=fgetc(fp))!=EOF)
520 if(!isalnum(c) && !isspace(c) && !isgraph(c) && c!=169) {
521 rewind(fp); return 0;
522 }
523
524 /* File with one title line without comment mark? */
525 rewind(fp);
526 while(fgets(tmp, 10, fp) != NULL) {if(strlen(tmp)) break;}
527 if(strncasecmp(tmp, "Time", 4)==0) {rewind(fp); return 5;}
528
529 rewind(fp); return 2;
530}

◆ dftWrite()

int dftWrite ( DFT * data,
char * filename )

Write DFT data, usually containing regional time-activity curves (TACs) into specified file.

The file format specified in data is applied. Number of decimals can be determined by changing global variable DFT_NR_OF_DECIMALS.

See also
dftRead, resWrite
Returns
Returns 0 when successful, in case of error sets dfterrmsg.
Parameters
dataPointer to DFT structure which contents are to be written.
filenameFile name where DFT contents are written. If file exists, original file is renamed to a backup file.

Definition at line 594 of file dftio.c.

600 {
601 int i, j, n, sw, mfw, prec;
602 char tmp[1024], tmp2[128], is_stdout=0;
603 FILE *fp;
604
605
606 /* Check that there is some data to write */
607 if(data->voiNr<1 || data->frameNr<1) {strcpy(dfterrmsg, "no data"); return 1;}
608
609 /* If format if DFT_FORMAT_HTML or extension is *.HTM(L),
610 write in HTML format */
611 if(data->_type==DFT_FORMAT_HTML || fncasematch(filename, "*.htm")==1 || fncasematch(filename, "*.html")==1) {
612 return(dftWriteHTML(data, filename, 1));
613 }
614
615 /* Check if writing to stdout */
616 if(!strcasecmp(filename, "stdout")) is_stdout=1;
617
618 /* Set minimum field width and precision for concentrations */
619 mfw=11; if(DFT_NR_OF_DECIMALS>3) mfw+=DFT_NR_OF_DECIMALS-3;
620 prec=0; if(DFT_NR_OF_DECIMALS>prec) prec=DFT_NR_OF_DECIMALS;
621
622 /* Check if file exists; backup, if necessary */
623 if(!is_stdout) (void)backupExistingFile(filename, NULL, NULL);
624
625 /* Open output file */
626 if(is_stdout) fp=(FILE*)stdout;
627 else if((fp = fopen(filename, "w")) == NULL) {strcpy(dfterrmsg, "cannot open file"); return 2;}
628
629 /* Write title lines */
630 if(data->_type==DFT_FORMAT_STANDARD) {
631 /* 1st line with filetype identification string and region names */
632 n=fprintf(fp, "%s", DFT_VER);
633 if(n==0) {strcpy(dfterrmsg, "disk full"); if(!is_stdout) fclose(fp); return 3;}
634 for(i=0; i<data->voiNr; i++) fprintf(fp,"\t%s", data->voi[i].voiname);
635 if(data->isweight) fprintf(fp,"\t%s", "weight");
636 fprintf(fp, "\n");
637 /* 2nd line with study identification and 2nd name (hemisphere) */
638 if(strlen(data->studynr)) strlcpy(tmp, data->studynr, 11); else strcpy(tmp, ".");
639 fprintf(fp, "%s", tmp);
640 for(i=0; i<data->voiNr; i++) {
641 if(strlen(data->voi[i].hemisphere)) strcpy(tmp, data->voi[i].hemisphere);
642 else strcpy(tmp, ".");
643 fprintf(fp, "\t%s", tmp);
644 }
645 if(data->isweight) fprintf(fp,"\t%s", ".");
646 fprintf(fp, "\n");
647 /* 3rd line with unit and plane names */
648 if(strlen(data->unit)) strcpy(tmp, data->unit); else strcpy(tmp, ".");
649 fprintf(fp, "%s", tmp);
650 for(i=0; i<data->voiNr; i++) {
651 if(strlen(data->voi[i].place)) strcpy(tmp, data->voi[i].place);
652 else strcpy(tmp, ".");
653 fprintf(fp, "\t%s", tmp);
654 }
655 if(data->isweight) fprintf(fp,"\t%s", ".");
656 fprintf(fp, "\n");
657 /* 4th line with time type & unit and region volumes */
658 switch(data->timetype) {
659 case DFT_TIME_MIDDLE:
660 if(data->timeunit==TUNIT_MM || data->timeunit==TUNIT_UM || data->timeunit==TUNIT_CM)
661 strcpy(tmp, "Distance ");
662 else
663 strcpy(tmp, "Time ");
664 break;
665 case DFT_TIME_START: strcpy(tmp, "Start "); break;
666 case DFT_TIME_END: strcpy(tmp, "End "); break;
668 if(data->timeunit==TUNIT_MM || data->timeunit==TUNIT_UM || data->timeunit==TUNIT_CM)
669 strcpy(tmp, "Distances ");
670 else
671 strcpy(tmp, "Times ");
672 break;
673 }
674 snprintf(tmp2, 128, "(%s)", petTunit(data->timeunit)); strcat(tmp, tmp2);
675 fprintf(fp, "%s", tmp);
676 for(i=0; i<data->voiNr; i++) {
677 if(data->voi[i].size>=0.0) sprintf(tmp, "%.*e", prec, data->voi[i].size);
678 else strcpy(tmp, ".");
679 fprintf(fp, "\t%s", tmp);
680 }
681 if(data->isweight) fprintf(fp,"\t%s", ".");
682 fprintf(fp, "\n");
683 } else if(data->_type==DFT_FORMAT_PMOD) { // write PMOD title line
684 char *cptr, tunit[128], cunit[128]; // Set units to format accepted by PMOD
685 if(data->timeunit==TUNIT_SEC) strcpy(tunit, "seconds");
686 else if(data->timeunit==TUNIT_MIN) strcpy(tunit, "minutes");
687 else strcpy(tunit, petTunit(data->timeunit));
688 if(petCunitId(data->unit)==CUNIT_UNITLESS) strcpy(cunit, "1/1"); else strcpy(cunit, data->unit);
689 cptr=strstr(cunit, "mL"); if(cptr!=NULL) {*cptr='c'; cptr++; *cptr='c';}
690 if(data->timetype==DFT_TIME_STARTEND) fprintf(fp, "start[%s]\tend[%s]", tunit, cunit);
691 else fprintf(fp, "time[%s]", tunit);
692 for(i=0; i<data->voiNr; i++) {
693 /* write roi names, must not include spaces */
694 char *s=strdup(data->voi[i].name);
695 strReplaceChar(s, ' ', '-'); fprintf(fp, "\t%s", s); free(s);
696 /* write calibration unit when necessary */
697 if(i==0 && data->timetype!=DFT_TIME_STARTEND) fprintf(fp, "[%s]", cunit);
698 }
699 if(data->isweight) fprintf(fp,"\t%s", "weight");
700 fprintf(fp, "\n");
701 }
702
703 /* Make sure that only frame mid times are saved without titles */
704 if(data->_type==DFT_FORMAT_PLAIN && data->timetype!=DFT_TIME_MIDDLE) sw=0;
705 else sw=data->timetype;
706
707 /* Write data */
708 for(j=0; j<data->frameNr; j++) {
709 /* Time(s) */
710 switch(sw) {
711 case 0: fprintf(fp, "%.5f", data->x[j]); break;
712 case 1: fprintf(fp, "%.5f", data->x1[j]); break;
713 case 2: fprintf(fp, "%.5f", data->x2[j]); break;
714 case 3: fprintf(fp, "%.5f\t%.5f", data->x1[j], data->x2[j]); break;
715 }
716 /* y values */
717 for(i=0; i<data->voiNr; i++) {
718 if(!isnan(data->voi[i].y[j])) sprintf(tmp, "%.*e", prec, data->voi[i].y[j]);
719 else strcpy(tmp, ".");
720 fprintf(fp, "\t%s", tmp);
721 }
722 if(data->isweight) {
723 if(data->_type==DFT_FORMAT_STANDARD || data->_type==DFT_FORMAT_PMOD) {
724 if(!isnan(data->w[j])) sprintf(tmp, "%.*e", prec, data->w[j]);
725 else strcpy(tmp, ".");
726 fprintf(fp,"\t%s", tmp);
727 }
728 }
729 n=fprintf(fp, "\n");
730 if(n==0) {strcpy(dfterrmsg, "disk full"); if(!is_stdout) fclose(fp); return 3;}
731 }
732
733 /* Write comments */
734 if(1) { //data->_type!=DFT_FORMAT_PMOD) {
735 n=strnlen(data->comments, _DFT_COMMENT_LEN);
736 if(n) for(i=0; i<n; i++) {
737 if(i>0 && data->comments[i]=='#' && (data->comments[i-1]!='\n' && data->comments[i-1]!='\r'))
738 fputc('\n', fp);
739 fputc(data->comments[i], fp);
740 }
741 }
742
743 /* Close file */
744 if(!is_stdout) {fflush(fp); fclose(fp);}
745
746 return 0;
747}
int backupExistingFile(char *filename, char *backup_ext, char *status)
Definition backup.c:14
int dftWriteHTML(DFT *dft, char *fname, int orientation)
Definition dftio.c:757
#define DFT_FORMAT_HTML
void strReplaceChar(char *str, char c1, char c2)
Definition strext.c:159
size_t strnlen(const char *s, size_t n)
Definition strext.c:181
char * petTunit(int tunit)
Definition petunits.c:226

Referenced by plotdata_as_dft().

◆ dftWriteHTML()

int dftWriteHTML ( DFT * dft,
char * fname,
int orientation )

Write DFT contents in HTML table format If file exists, a backup file (+BACKUP_EXTENSION) is written also. If "stdout" is given as filename, output is directed to stdout In case of an error, description is written in dfterrmsg.

Returns
Returns 0 if ok.
Parameters
dftInput DFT
fnameHTML filename
orientationTable orientation: 1=original, 2=transposed

Definition at line 757 of file dftio.c.

764 {
765 int ri, fi, is_stdout=0, ret;
766 char tmp[FILENAME_MAX];
767 FILE *fp;
768
769
770 /* Check input */
771 strcpy(dfterrmsg, "invalid input to dftWriteHTML()");
772 if(dft==NULL || dft->frameNr<1 || dft->voiNr<1) return(1);
773 if(fname==NULL || strlen(fname)<1) return(1);
774 strcpy(dfterrmsg, "");
775 /* Check if writing to stdout */
776 if(!strcasecmp(fname, "stdout")) is_stdout=1;
777
778 /* Check if file exists; backup, if necessary */
779 if(!is_stdout && access(fname, 0) != -1) {
780 strcpy(tmp, fname); strcat(tmp, BACKUP_EXTENSION); rename(fname, tmp);}
781 strcpy(dfterrmsg, "cannot write file");
782
783 /* Open output file */
784 if(is_stdout) fp=(FILE*)stdout;
785 else if((fp=fopen(fname, "w"))==NULL) {strcpy(dfterrmsg, "cannot open file"); return(2);}
786
787 /* Write XHTML 1.1 doctype and head */
789 strcpy(dfterrmsg, "disk full"); if(!is_stdout) fclose(fp); return(3);
790 }
791
792 /* Start writing the body of the HTML file */
793 ret=fprintf(fp, "<body>\n");
794 if(ret==0) {strcpy(dfterrmsg, "disk full"); if(!is_stdout) fclose(fp); return(3);}
795
796 /* Start the div for table, and the table */
797 fprintf(fp, "\n<div id=\"table\">\n");
798 fprintf(fp, "<table>\n");
799
800 /* Write the title lines, if there are titles, into the head of the table */
801 if(dft->_type!=DFT_FORMAT_PLAIN) {
802 fprintf(fp, "<thead>\n");
803 if(orientation!=2) {
804 /* Empty cell and Region names */
805 fprintf(fp, "<tr><td> </td>\n");
806 for(ri=0; ri<dft->voiNr; ri++) {
807 char *senc=strEncodeForXML(dft->voi[ri].voiname);
808 if(senc==NULL) fprintf(fp, "<th>%s</th>\n", dft->voi[ri].voiname);
809 else {fprintf(fp, "<th>%s</th>\n", senc); free(senc);}
810 }
811 fprintf(fp, "</tr>\n");
812 /* Study number and Hemispheres */
813 fprintf(fp, "<tr><th>%s</th>\n", dft->studynr);
814 for(ri=0; ri<dft->voiNr; ri++) {
815 char *senc=strEncodeForXML(dft->voi[ri].hemisphere);
816 if(senc==NULL) fprintf(fp, "<th>%s</th>\n", dft->voi[ri].hemisphere);
817 else {fprintf(fp, "<th>%s</th>\n", senc); free(senc);}
818 }
819 fprintf(fp, "</tr>\n");
820 /* Unit and Places */
821 fprintf(fp, "<tr><th>%s</th>\n", dft->unit);
822 for(ri=0; ri<dft->voiNr; ri++) {
823 char *senc=strEncodeForXML(dft->voi[ri].place);
824 if(senc==NULL) fprintf(fp, "<th>%s</th>\n", dft->voi[ri].place);
825 else {fprintf(fp, "<th>%s</th>\n", senc); free(senc);}
826 }
827 fprintf(fp, "</tr>\n");
828 /* Time unit and Volumes */
829 fprintf(fp, "<tr><th>%s</th>\n", petTunit(dft->timeunit));
830 for(ri=0; ri<dft->voiNr; ri++)
831 fprintf(fp, "<th>%g</th>\n", dft->voi[ri].size);
832 fprintf(fp, "</tr>\n");
833 } else if(orientation==2) {
834 /* Study number and Unit */
835 fprintf(fp, "<tr><th>%s</th>\n", dft->studynr);
836 fprintf(fp, "<th>%s</th></tr>\n", dft->unit);
837 }
838 /* End the head of table */
839 fprintf(fp, "</thead>\n");
840 }
841
842 /* Write the DFT data into the body of the table */
843 fprintf(fp, "<tbody>\n");
844
845 /* If transposed, write titles */
846 if(orientation==2) {
847 fprintf(fp, "<tr><th>Region</th><th>Hemisphere</th><th>Plane</th>\n");
848 fprintf(fp, "<th>Volume</th></tr>\n");
849 }
850 if(orientation!=2) { /* Not transposed */
851 for(fi=0; fi<dft->frameNr; fi++) {
852 if(fi%2) strcpy(tmp, "evenframe"); else strcpy(tmp, "oddframe");
853 /* Time */
854 fprintf(fp, "<tr class=\"%s\"><th>%g</th>\n", tmp, dft->x[fi]);
855 /* Values */
856 for(ri=0; ri<dft->voiNr; ri++)
857 fprintf(fp, "<th>%g</th>", dft->voi[ri].y[fi]);
858 fprintf(fp, "</tr>\n");
859 }
860 } else { /* transposed */
861 for(ri=0; ri<dft->voiNr; ri++) {
862 if(ri%2) strcpy(tmp, "evenframe"); else strcpy(tmp, "oddframe");
863 fprintf(fp, "<tr class=\"%s\">", tmp);
864 /* Region names */
865 char *senc;
866 senc=strEncodeForXML(dft->voi[ri].voiname);
867 if(senc==NULL) fprintf(fp, "<th>%s</th>", dft->voi[ri].voiname);
868 else {fprintf(fp, "<th>%s</th>", senc); free(senc);}
869 senc=strEncodeForXML(dft->voi[ri].hemisphere);
870 if(senc==NULL) fprintf(fp, "<th>%s</th>", dft->voi[ri].hemisphere);
871 else {fprintf(fp, "<th>%s</th>", senc); free(senc);}
872 senc=strEncodeForXML(dft->voi[ri].place);
873 if(senc==NULL) fprintf(fp, "<th>%s</th>\n", dft->voi[ri].place);
874 else {fprintf(fp, "<th>%s</th>\n", senc); free(senc);}
875 /* Region volume */
876 fprintf(fp, "<td>%g</td>\n", dft->voi[ri].size);
877 /* Values */
878 for(fi=0; fi<dft->frameNr; fi++) {
879 fprintf(fp, "<td>%g</td>", dft->voi[ri].y[fi]);
880 }
881 fprintf(fp, "</tr>\n");
882 }
883 }
884 /* End the table body and table */
885 fprintf(fp, "</tbody></table>\n");
886
887 /* Stop writing the body of the HTML file, and end the file */
888 fprintf(fp, "</div>\n");
889 ret=fprintf(fp, "</body></html>\n\n");
890 if(ret==0) {
891 strcpy(dfterrmsg, "disk full");
892 if(!is_stdout) fclose(fp);
893 return(3);
894 }
895
896 /* Close file */
897 if(!is_stdout) {fflush(fp); fclose(fp);}
898 strcpy(dfterrmsg, "");
899
900 return(0);
901}
int dftWriteXHTML11_doctype(FILE *fp)
Definition dftio.c:908
int dftWriteXHTML11_head(FILE *fp, char *author_name)
Definition dftio.c:926
#define BACKUP_EXTENSION
char * strEncodeForXML(const char *s)
Definition strext.c:364

Referenced by dftWrite().

◆ dftWriteXHTML11_doctype()

int dftWriteXHTML11_doctype ( FILE * fp)

Write XHTML 1.1 doctype into an opened file pointer.

Returns
Returns 0 if successful, non-zero in case of a failure.

Definition at line 908 of file dftio.c.

910 {
911 int n;
912 if(fp==NULL) return(1);
913 n=fprintf(fp, "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" ");
914 n+=fprintf(fp, "\"https://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">\n");
915 if(n<20) return(2);
916 n=fprintf(fp, "<html xmlns=\"https://www.w3.org/1999/xhtml\" xml:lang=\"en\">\n\n");
917 if(n<20) return(2);
918 return(0);
919}

Referenced by dftWriteHTML().

◆ dftWriteXHTML11_head()

int dftWriteXHTML11_head ( FILE * fp,
char * author_name )

Write XHTML 1.1 head for DFT file into an opened file pointer.

Returns
Returns 0 if successful, non-zero in case of a failure.
Parameters
fpFile pointer where to write
author_nameAuthor name, for example software name

Definition at line 926 of file dftio.c.

931 {
932 int n;
933 if(fp==NULL) return(1);
934
935 n=fprintf(fp, "<head>\n"); if(n<6) return(2);
936 fprintf(fp, " <title>PET data</title>\n");
937 fprintf(fp, " <meta http-equiv=\"content-type\" content=\"text/html; charset=iso-8859-1\" />\n");
938 fprintf(fp, " <meta http-equiv=\"content-language\" content=\"en-gb\" />\n");
939 fprintf(fp, " <meta name=\"author\" content=\"%s\" />\n", author_name);
940 fprintf(fp, " <meta name=\"ProgId\" content=\"Excel.Sheet\" />\n");
941 fprintf(fp, " <link rel=\"icon\" href=\"https://www.turkupetcentre.net/favicon.ico\" type=\"image/x-icon\" />\n");
942 fprintf(fp, " <link rel=\"shortcut icon\" href=\"https://www.turkupetcentre.net/favicon.ico\" type=\"image/x-icon\" />\n");
943 /* write local CSS with basic settings in case that external CSS is not available */
944 fprintf(fp, " <style type=\"text/css\">\n");
945 fprintf(fp, " thead {background-color:#999999; color:black;}\n");
946 fprintf(fp, " table {text-align:left; width:100%%; border-collapse:collapse; empty-cells:show;}\n");
947 fprintf(fp, " td {border:1px solid black;}\n");
948 fprintf(fp, " .oddframe {background-color:#FFFFFF; color:black;}\n");
949 fprintf(fp, " .evenframe {background-color:#CCCCCC; color:black;}\n");
950 fprintf(fp, " #regcontainer ul {margin-left:0; padding-left:0;}\n");
951 fprintf(fp, " #regcontainer ul li {display:inline; list-style-type:none;}\n");
952 fprintf(fp, " #regcontainer a {padding:2px 4px;}\n");
953 fprintf(fp, " <!--table\n");
954 fprintf(fp, " {mso-displayed-decimal-separator:\"\\.\";\n");
955 fprintf(fp, " mso-displayed-thousand-separator:\" \";}\n");
956 fprintf(fp, " -->\n");
957 fprintf(fp, " </style>\n");
958 /* load external CSS with more fancy settings */
959 fprintf(fp, " <link rel=\"stylesheet\" type=\"text/css\" ");
960 fprintf(fp, "href=\"https://www.turkupetcentre.net/dft.css\" />\n");
961 fprintf(fp, "</head>\n");
962 if(n<7) return(2);
963 return(0);
964}

Referenced by dftWriteHTML().

Variable Documentation

◆ DFT_NR_OF_DECIMALS

int DFT_NR_OF_DECIMALS = 3

Nr of decimals for concentration values

Definition at line 13 of file dftio.c.

Referenced by dftRead(), and dftWrite().