30 for(i=0; i<csv->
nr; i++)
32 free(csv->
c); csv->
c=NULL;
48 if(
CSV_TEST>2) {printf(
"csvRead('%s')\n", fname); fflush(stdout);}
51 int i, nr, ret, nonprintable=0, inside_quotes=0, previous, col_nr=0;
52 const int MAX_CSV_FIELD_LENGTH=1024;
53 char buf[MAX_CSV_FIELD_LENGTH+1];
54 int tabnr, spacenr, commanr;
57 if(csv==NULL || fname==NULL)
return CSV_ERROR;
59 fp=fopen(fname,
"r");
if(fp==NULL)
return CSV_CANNOTOPEN;
62 nr=nonprintable=0;
while((ret=fgetc(fp))!=EOF) {
63 if(iscntrl(ret) && ret!=13 && ret!=10 && ret!=9) {nonprintable=1;
break;}
66 if(
CSV_TEST>0) printf(
"filesize := %d\n", nr);
67 if(nr<2) {fclose(fp);
return CSV_INVALIDFORMAT;}
68 if(nr>5000000) {fclose(fp);
return CSV_TOOBIG;}
74 inside_quotes=0; nr=0; tabnr=0; spacenr=0; commanr=0;
75 while((ret=fgetc(fp))!=EOF) {
77 if(inside_quotes==0) inside_quotes=1;
else inside_quotes=0;
80 if(inside_quotes==1)
continue;
82 else if(ret==
'\t') tabnr++;
83 else if(ret==
',') commanr++;
84 else if(ret==
' ') spacenr++;
87 printf(
"semicolon_nr := %d\n", nr);
88 printf(
"tab_nr := %d\n", tabnr);
89 printf(
"comma_nr := %d\n", commanr);
90 printf(
"space_nr := %d\n", spacenr);
95 else if(commanr>spacenr) csv->
separator=
',';
101 if(csv->
separator==
' ') {fclose(fp);
return CSV_INVALIDFORMAT;}
105 inside_quotes=0; nr=0; previous=0;
106 while((ret=fgetc(fp))!=EOF) {
107 if((previous==13 || previous==10) && (ret==13 || ret==10)) {previous=ret;
continue;}
109 if(inside_quotes==0) inside_quotes=1;
else inside_quotes=0;
110 previous=ret;
continue;
112 if(inside_quotes==0) {
117 if( (ret==13 || ret==10) && previous!=13 && previous!=10) {
133 rewind(fp);
if(
CSV_TEST>0) printf(
"field_nr := %d\n", nr);
137 if(csv->
c==NULL) {fclose(fp);
return CSV_OUTOFMEMORY;}
141 if(
CSV_TEST>0) printf(
" copying contents...\n");
142 inside_quotes=0; nr=0; previous=0; i=0; col_nr=0;
143 while((ret=fgetc(fp))!=EOF) {
144 if((previous==13 || previous==10) && (ret==13 || ret==10)) {previous=ret;
continue;}
146 if(inside_quotes==0) inside_quotes=1;
else inside_quotes=0;
147 previous=ret;
continue;
149 if(inside_quotes==0) {
152 if(nr>=csv->
nr) {printf(
" index overflow\n");
break;}
155 i=0; nr++; col_nr++; previous=ret;
158 if( (ret==13 || ret==10) && previous!=13 && previous!=10) {
160 if(nr>=csv->
nr) {printf(
" index overflow\n");
break;}
165 i=0; nr++; col_nr=0; previous=ret; csv->
row_nr++;
174 if(nr>=csv->
nr) {printf(
" index overflow\n");
break;}
179 i=0; nr++; col_nr=0; previous=ret; csv->
row_nr++;
184 if(i<MAX_CSV_FIELD_LENGTH) buf[i]=(char)ret;
188 if(
CSV_TEST>0) printf(
" ... copied: nr=%d\n", nr);
208 if(
CSV_TEST>2) {printf(
"csv2dft()\n"); fflush(stdout);}
209 if(csv==NULL || dft==NULL)
return CSV_ERROR;
210 if(csv->
row_nr<1 || csv->
col_nr<1)
return CSV_INVALIDFORMAT;
213 if(strcasecmp(csv->
c[0].
content,
"LinkSet")==0) {
216 if(
CSV_TEST>2) printf(
"reading LinkSet CSV format failed.\n");
224 if(
CSV_TEST>2) printf(
"reading Mat CSV format successful.\n");
230 if(
CSV_TEST>2) printf(
"trying to read 1st CSV format\n");
233 if(
CSV_TEST>2) printf(
"reading 1st CSV format failed; trying 2nd format\n");
237 if(
CSV_TEST>2) printf(
"2nd CSV format failed\n");
241 u=dft->
voiNr; n=1;
while((u/=10)>=1) n++;
243 for(i=0, m=0; i<dft->
voiNr; i++) {
245 snprintf(dft->
voi[i].
voiname, 7,
"%0*d", n, i+1);
268 int ri, ci, sci, ii, ret;
271 if(
CSV_TEST>2) {printf(
"csv2dft_a()\n"); fflush(stdout);}
272 if(csv==NULL || dft==NULL)
return CSV_ERROR;
273 if(csv->
row_nr<1 || csv->
col_nr<1)
return CSV_INVALIDFORMAT;
277 for(
int i=0; i<csv->
nr; i++)
278 printf(
"row=%d col=%d content='%s'\n", csv->
c[i].
row, csv->
c[i].
col, csv->
c[i].
content);
284 printf(
"frame_nr=%d voi_nr=%d\n", csv->
row_nr, csv->
col_nr-1);
288 if(ret!=0)
return CSV_OUTOFMEMORY;
295 for(ri=0; ri<csv->
row_nr; ri++) dft->
w[ri]=1.0;
296 for(ci=0; ci<csv->
col_nr-1; ci++) dft->
voi[ci].
sw=0;
300 for(ii=0; ii<csv->
nr;) {
302 for(; ii<csv->
nr && csv->
c[ii].
col!=1; ii++) {}
303 if(ii==csv->
nr)
break;
305 printf(
"\nline start at %d\n", ii);
306 printf(
" ri=%d\n", ri);
311 if(
CSV_TEST>11) {printf(
" empty first column\n"); fflush(stdout);}
316 if(
CSV_TEST>11) {printf(
" comment line\n"); fflush(stdout);}
322 if(strstr(csv->
c[ii].
content,
"Time")==NULL &&
323 strstr(csv->
c[ii].
content,
"TIME")==NULL &&
324 strstr(csv->
c[ii].
content,
"time")==NULL)
326 if(
CSV_TEST>11) {printf(
" not a numerical value or title\n"); fflush(stdout);}
330 if(strncasecmp(csv->
c[ii].
content,
"Start time", 10)==0 &&
331 strncasecmp(csv->
c[ii+1].
content,
"End time", 8)==0)
337 printf(
"first title field := '%s'\n", csv->
c[ii].
content);
346 for(ci=sci; ci<=csv->
col_nr && ii<csv->
nr; ci++, ii++) {
348 printf(
"col=%d row=%d\n", csv->
c[ii].
col, csv->
c[ii].
row);
349 if(
CSV_TEST>3) printf(
"ci=%d ii=%d\n", ci, ii);
352 if(csv->
c[ii].
col!=ci) {
dftEmpty(dft);
return CSV_NOTABLE;}
355 if(strstr(csv->
c[ii].
content,
" - Time")!=NULL) {
356 if(
CSV_TEST>2) printf(
" ignored time column.\n");
357 dft->
voi[ci-sci].
sw=1;
continue;
359 if(strstr(csv->
c[ii].
content,
"(upper bound)")!=NULL) {
360 if(
CSV_TEST>2) printf(
" ignored upper bound column.\n");
361 dft->
voi[ci-sci].
sw=2;
continue;
363 if(strstr(csv->
c[ii].
content,
"(lower bound)")!=NULL) {
364 if(
CSV_TEST>2) printf(
" ignored lower bound column.\n");
365 dft->
voi[ci-sci].
sw=3;
continue;
367 if(strstr(csv->
c[ii].
content,
"(standard deviation)")!=NULL) {
368 if(
CSV_TEST>2) printf(
" ignored s.d. column.\n");
369 dft->
voi[ci-sci].
sw=4;
continue;
373 if(strstr(csv->
c[ii].
content,
"(Bq/ml)")!=NULL)
375 else if(strstr(csv->
c[ii].
content,
"(kBq/ml)")!=NULL)
377 else if(strstr(csv->
c[ii].
content,
"(MBq/ml)")!=NULL)
379 else if(strstr(csv->
c[ii].
content,
"(% ID/g)")!=NULL)
381 else if(strstr(csv->
c[ii].
content,
"Bq/ml")!=NULL)
383 else if(strstr(csv->
c[ii].
content,
"kBq/ml")!=NULL)
385 else if(strstr(csv->
c[ii].
content,
"MBq/ml")!=NULL)
387 else if(strstr(csv->
c[ii].
content,
"% ID/g")!=NULL)
392 sprintf(dft->
voi[ci-sci].
name,
"%d", ci-sci+1);
395 cptr=strstr(csv->
c[ii].
content,
" - ");
if(cptr!=NULL) *cptr=(char)0;
410 if(
CSV_TEST>3) printf(
"x[%d]=%g\n", ri, dft->
x[ri]);
414 dft->
x[ri]=0.5*(dft->
x1[ri]+dft->
x2[ri]);
415 if(
CSV_TEST>3) printf(
"x1[%d]=%g x2[%d]=%g\n", ri, dft->
x1[ri], ri, dft->
x2[ri]);
419 for(ci=sci; ci<=csv->
col_nr && ii<csv->
nr; ci++, ii++) {
421 printf(
" col=%d row=%d\n", csv->
c[ii].
col, csv->
c[ii].
row);
422 if(
CSV_TEST>3) printf(
" ci=%d ii=%d\n", ci, ii);
425 if(csv->
c[ii].
col!=ci) {
dftEmpty(dft);
return CSV_NOTABLE;}
427 dft->
voi[ci-sci].
y[ri]=nan(
"");
431 printf(
" y[%d][%d]=%g\n", ri, ci-sci, dft->
voi[ci-sci].
y[ri]);
435 if(
CSV_TEST>1) printf(
" %d frame(s) read from CSV\n", ri);
436 if(ri<1) {
dftEmpty(dft);
return CSV_INVALIDFORMAT;}
441 for(ci=dft->
voiNr-1, ret=0; ci>=0; ci--)
if(dft->
voi[ci].
sw!=0) {
442 ret=
dftDelete(dft, ci);
if(ret!=0)
break;}
443 if(ret!=0) {
dftEmpty(dft);
return CSV_INVALIDFORMAT;}
464 int ri, fi, fip, ii, ret;
465 char *cptr, *cptr2, tmp[256];
468 if(
CSV_TEST>2) {printf(
"csv2dft_b()\n"); fflush(stdout);}
469 if(csv==NULL || dft==NULL)
return CSV_ERROR;
471 if(csv->
row_nr<4 || csv->
col_nr!=9)
return CSV_INVALIDFORMAT;
475 if(strcasecmp(csv->
c[0].
content,
"#Subject ID")!=0)
return CSV_INVALIDFORMAT;
476 if(strcasecmp(csv->
c[1].
content,
"Subject Weight")!=0)
return CSV_INVALIDFORMAT;
477 if(strcasecmp(csv->
c[2].
content,
"Subject Sex")!=0)
return CSV_INVALIDFORMAT;
478 if(strcasecmp(csv->
c[3].
content,
"Unique Series ID")!=0)
return CSV_INVALIDFORMAT;
479 if(strcasecmp(csv->
c[4].
content,
"Series Date")!=0)
return CSV_INVALIDFORMAT;
480 if(strcasecmp(csv->
c[5].
content,
"Series Description")!=0)
return CSV_INVALIDFORMAT;
483 if(strcasecmp(csv->
c[12].
content,
"#Name")!=0)
return CSV_INVALIDFORMAT;
484 if(strcasecmp(csv->
c[13].
content,
"Volume (mm^3)")!=0)
return CSV_INVALIDFORMAT;
485 if(strcasecmp(csv->
c[14].
content,
"Mean")!=0)
return CSV_INVALIDFORMAT;
486 if(strcasecmp(csv->
c[15].
content,
"SD")!=0)
return CSV_INVALIDFORMAT;
487 if(strcasecmp(csv->
c[16].
content,
"Min")!=0)
return CSV_INVALIDFORMAT;
488 if(strcasecmp(csv->
c[17].
content,
"Max")!=0)
return CSV_INVALIDFORMAT;
489 if(strcasecmp(csv->
c[18].
content,
"Frame Index")!=0)
return CSV_INVALIDFORMAT;
490 if(strncasecmp(csv->
c[19].
content,
"Mid time (sec)", 10)!=0)
return CSV_INVALIDFORMAT;
491 if(strncasecmp(csv->
c[20].
content,
"Duration (sec)", 10)!=0)
return CSV_INVALIDFORMAT;
494 ri=1; fi=0; fip=-1; ii=21; cptr=csv->
c[ii].
content;
496 for(; ii<csv->
nr; ii+=9) {
499 if(strcmp(cptr, cptr2)==0) fi++;
502 if(fip<0) fip=fi;
else if(fi!=fip)
return CSV_INVALIDFORMAT;
510 if(
CSV_TEST>2) {printf(
"frame_nr=%d voi_nr=%d\n", fi, ri); fflush(stdout);}
512 if(ret!=0)
return CSV_OUTOFMEMORY;
518 for(fi=0; fi<dft->
frameNr; fi++) dft->
w[fi]=1.0;
529 cptr=strchr(dft->
studynr,
'.');
if(cptr!=NULL) *cptr=(char)0;
530 cptr=strchr(dft->
studynr,
',');
if(cptr!=NULL) *cptr=(char)0;
531 cptr=strchr(dft->
studynr,
' ');
if(cptr!=NULL) *cptr=(char)0;
533 ii=7;
if(ii>=csv->
nr) {
dftEmpty(dft);
return CSV_INVALIDFORMAT;}
535 if(v1>0.0) sprintf(dft->
comments,
"# weight := %g\n", v1);
537 ii=10;
if(ii>=csv->
nr) {
dftEmpty(dft);
return CSV_INVALIDFORMAT;}
539 sprintf(tmp,
"# scan_start_time := %s\n", csv->
c[ii].
content);
543 for(fi=0; fi<dft->
frameNr; fi++) {
544 ii= 21 + fi*9 + 7;
if(ii>csv->
nr-2) {
dftEmpty(dft);
return CSV_INVALIDFORMAT;}
547 dft->
x[fi]=v1; dft->
x1[fi]=v1-0.5*v2; dft->
x2[fi]=v1+0.5*v2;
550 for(ri=0; ri<dft->
voiNr; ri++) {
553 if(ii>=csv->
nr) {
dftEmpty(dft);
return CSV_INVALIDFORMAT;}
560 ii++;
if(ii>=csv->
nr) {
dftEmpty(dft);
return CSV_INVALIDFORMAT;}
563 ii++;
for(fi=0; fi<dft->
frameNr; fi++) {
564 if((ii+6)>=csv->
nr) {
dftEmpty(dft);
return CSV_INVALIDFORMAT;}
571 if(dft->
x[fi]!=v1) {
dftEmpty(dft);
return CSV_INVALIDFORMAT;}
590 int ri, ci, fi, sci, ii, ret;
595 if(
CSV_TEST>2) {printf(
"csv2dft_linkset()\n"); fflush(stdout);}
596 if(csv==NULL || dft==NULL)
return CSV_ERROR;
597 if(csv->
nr<2 || csv->
row_nr<1 || csv->
col_nr<1)
return CSV_INVALIDFORMAT;
598 if(strcasecmp(csv->
c[0].
content,
"LinkSet")!=0)
return CSV_INVALIDFORMAT;
600 for(ii=1, ri=0; ii<csv->
nr; ii++)
if(csv->
c[ii].
col==1) {
601 if(csv->
c[ii].
content==NULL)
continue;
602 if(strncmp(csv->
c[ii].
content,
"VOI:", 4)==0) ri++;
605 printf(
"frame_nr=%d voi_nr=%d\n", csv->
col_nr-2, ri);
608 if(ri<1 || csv->col_nr<3)
return CSV_INVALIDFORMAT;
612 ret=
dftSetmem(dft, csv->
col_nr-2, ri);
if(ret!=0)
return CSV_OUTOFMEMORY;
622 for(fi=0; fi<dft->
frameNr; fi++) dft->
w[fi]=1.0;
623 for(ri=0; ri<dft->
voiNr; ri++) dft->
voi[ri].
sw=0;
626 for(ri=0; ri<dft->
voiNr; ri++) {
627 if(
CSV_TEST>3) printf(
"reading VOI %d\n", 1+ri);
630 for(ii=1; ii<csv->
nr; ii++)
if(csv->
c[ii].
col==1) {
631 if(csv->
c[ii].
content==NULL)
continue;
632 if(strncmp(csv->
c[ii].
content,
"VOI:", 4)==0) sci++;
637 if(
CSV_TEST>5) printf(
" ri=%d ii=%d row=%d col=%d\n", ri, ii, csv->
c[ii].
row, csv->
c[ii].
col);
642 if(
CSV_TEST>4 && ri==0) printf(
"reading time unit\n");
643 cptr=strchr(csv->
c[ii+1].
content,
'(');
649 if(
CSV_TEST>0) printf(
"different time units.\n");
650 return CSV_INVALIDFORMAT;
655 for(fi=0; fi<dft->
frameNr; fi++) {
656 ci=ii+fi+2;
if(ci>=csv->
nr)
return CSV_INVALIDFORMAT;
662 if(fabs(v-dft->
x[fi])>1.0E-003)
return CSV_INVALIDFORMAT;
666 if(
CSV_TEST>4) printf(
"reading VOI name\n");
667 ii+=csv->
col_nr;
if(ii>=csv->
nr)
return CSV_INVALIDFORMAT;
676 if(
CSV_TEST>4) printf(
"reading VOI values\n");
677 ii+=2*csv->
col_nr;
if(ii>=csv->
nr)
return CSV_INVALIDFORMAT;
679 ii++;
if(ii>=csv->
nr)
return CSV_INVALIDFORMAT;
680 cptr=csv->
c[ii].
content;
if(cptr==NULL)
return CSV_INVALIDFORMAT;
681 if(strncasecmp(cptr,
"Average", 7)!=0)
return CSV_INVALIDFORMAT;
682 cptr=strchr(csv->
c[ii].
content,
'(');
685 printf(
"reading activity unit from string: '%s'\n", cptr+1);
690 if(
CSV_TEST>0) printf(
"different concentration units.\n");
691 return CSV_INVALIDFORMAT;
696 for(fi=0; fi<dft->
frameNr; fi++) {
697 ci=ii+fi+1;
if(ci>=csv->
nr)
return CSV_INVALIDFORMAT;
700 dft->
voi[ri].
y[fi]=v;
703 if(ri<dft->voiNr)
return CSV_INVALIDFORMAT;
723 if(
CSV_TEST>2) {printf(
"csv2dft_mat()\n"); fflush(stdout);}
724 if(csv==NULL || dft==NULL)
return CSV_ERROR;
725 if(csv->
nr<4 || csv->
row_nr<2 || csv->
col_nr<2)
return CSV_INVALIDFORMAT;
742 for(fi=0; fi<dft->
frameNr; fi++) dft->
w[fi]=1.0;
743 for(ri=0; ri<dft->
voiNr; ri++) dft->
voi[ri].
sw=0;
746 for(
int i=0; i<csv->
nr; i++)
747 printf(
"row=%d col=%d content='%s'\n", csv->
c[i].
row, csv->
c[i].
col, csv->
c[i].
content);
751 if(cptr!=NULL && cptr[0] &&
strnlen(cptr, 20)<20) {
758 for(ri=0; ri<dft->
voiNr; ri++) {
759 if(
CSV_TEST>3) printf(
"reading VOI %d\n", 1+ri);
762 if(cptr==NULL) {ret++;
break;}
763 int n=strlen(cptr);
if(n<3) {ret++;
break;}
764 if(cptr[n-1]==
'\'') {cptr[n-1]=(char)0; n--;}
else {ret++;
break;}
765 if(cptr[0]==
'\'') {cptr++; n--;}
else {ret++;
break;}
770 for(fi=0; fi<dft->
frameNr; fi++) {
777 if(ret!=0) {
dftEmpty(dft);
return CSV_INVALIDFORMAT;}
780 if(
CSV_TEST>3) printf(
"reading frames\n");
782 for(fi=0; fi<dft->
frameNr; fi++) {
783 cptr=
csvCell(csv, 1, fi+2);
if(cptr==NULL) {ret++;
break;}
784 int n=strlen(cptr);
if(n<3) {ret++;
break;}
785 char *cptr2=strchr(cptr+1,
'-');
if(cptr2!=NULL) {*cptr2=(char)0; cptr2++;}
789 dft->
x[fi]=0.5*(dft->
x1[fi]+dft->
x2[fi]);
791 if(ret!=0) {
dftEmpty(dft);
return CSV_INVALIDFORMAT;}
807 if(csv==NULL)
return(0);
808 if(csv->
nr<2)
return(1);
810 i=0; r=csv->
c[i].
row; m++;
811 for(i=1; i<csv->
nr; i++) {
812 if(r==csv->
c[i].
row) {m++;
continue;}
813 if(n>0 && m!=n)
return(0);
814 r=csv->
c[i].
row; n=m; m=1;
816 if(n>0 && m!=n)
return(0);
835 if(csv==NULL)
return((
char*)NULL);
836 for(
int i=0; i<csv->
nr; i++)
837 if(csv->
c[i].
row==row && csv->
c[i].
col==col)
int csv2dft_a(CSV *csv, DFT *dft)
int csvIsRegular(CSV *csv)
int csv2dft_mat(CSV *csv, DFT *dft)
char * csvCell(CSV *csv, int row, int col)
int csv2dft(CSV *csv, DFT *dft)
int csvRead(CSV *csv, char *fname)
int csv2dft_linkset(CSV *csv, DFT *dft)
int csv2dft_b(CSV *csv, DFT *dft)
int atof_with_check(char *double_as_string, double *result_value)
double atof_dpi(char *str)
int dftDelete(DFT *dft, int voi)
int dftSetmem(DFT *data, int frameNr, int voiNr)
void dftFrametimes(DFT *data)
void dftUnitToDFT(DFT *dft, int dunit)
Header file for libtpccurveio.
#define DFT_FORMAT_STANDARD
#define DFT_TIME_STARTEND
int petCunitId(const char *unit)
char * petCunit(int cunit)
int strCleanSpaces(char *s)
int rnameSplit(char *rname, char *name1, char *name2, char *name3, int max_name_len)
#define MAX_REGIONNAME_LEN
size_t strnlen(const char *s, size_t n)
size_t strlcpy(char *dst, const char *src, size_t dstsize)
char * petTunit(int tunit)
int petTunitId(const char *timeunit)
#define MAX_REGIONSUBNAME_LEN
char studynr[MAX_STUDYNR_LEN+1]
char comments[_DFT_COMMENT_LEN+1]
char unit[MAX_UNITS_LEN+1]
char voiname[MAX_REGIONSUBNAME_LEN+1]
char name[MAX_REGIONNAME_LEN+1]
char hemisphere[MAX_REGIONSUBNAME_LEN+1]
char place[MAX_REGIONSUBNAME_LEN+1]