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

I/O functions for DFT TAC file format. 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

int tacNameSplit (const char *rname, char *name1, char *name2, char *name3, unsigned int max_name_len)
int tacWriteDFT (TAC *tac, FILE *fp, int extra, TPCSTATUS *status)
int tacReadDFT (TAC *tac, CSV *csv, IFT *hdr, TPCSTATUS *status)

Detailed Description

I/O functions for DFT TAC file format.

Definition in file dftio.c.

Function Documentation

◆ tacNameSplit()

int tacNameSplit ( const char * rname,
char * name1,
char * name2,
char * name3,
unsigned int max_name_len )

Split TAC name into 1-3 subparts of given max length.

Returns
Returns the number of subparts; note that number is 3 if third subpart is found even if 1st and/or 2nd subparts were not found.
See also
roinameSubpart
Parameters
rnameTAC name to split
name1Pointer to 1st subname (usually anatomical region); NULL if not needed
name2Pointer to 2nd subname (usually hemisphere); NULL if not needed
name3Pointer to 3rd subname (usually image plane); NULL if not needed
max_name_lenMax length of subnames, excluding terminal null

Definition at line 26 of file dftio.c.

37 {
38 /* Initiate subnames */
39 if(name1!=NULL) strcpy(name1, "");
40 if(name2!=NULL) strcpy(name2, "");
41 if(name3!=NULL) strcpy(name3, "");
42
43 /* Check input */
44 if(max_name_len<1) return 0;
45 if(rname==NULL || *rname=='\0') return 0;
46
47 /* Work with a copy of TAC name */
48 char *temp=strdup(rname);
49
50 /* Remove any quotes and trailing and initial spaces */
51 if(strClean(temp)) {free(temp); return 0;}
52 //printf("temp='%s'\n", temp);
53
54 /* Allocate memory for local subnames */
55 int fullLen=(int)strlen(rname);
56 char sname[3][fullLen+1];
57
58 /* Determine the subpart delimiters so that subpart number would be optimal */
59 char space[32];
60 strcpy(space, " \t");
61 int n=strTokenNr(temp, space);
62 if(n<3) {strcat(space, "_"); n=strTokenNr(temp, space);}
63 if(n<3) {strcat(space, "-"); n=strTokenNr(temp, space);}
64 //printf("n=%d space='%s'\n", n, space);
65
66 /* get subparts */
67 char *cptr=temp; int i;
68 n=0; i=0;
69 while(n<3 && *cptr!='\0') {
70 //printf(" cptr='%s' n=%d i=%d\n", cptr, n, i);
71 /* If delimiter */
72 if(strspn(cptr, space)>0) {
73 /* then end this subpart */
74 sname[n][i]='\0';
75 /* and prepare for the next */
76 n++; i=0;
77 cptr++; continue;
78 }
79 sname[n][i]=*cptr;
80 cptr++; i++;
81 }
82 if(n<3) {sname[n][i]='\0'; n++;}
83 for( ; n<3 ;n++) strcpy(sname[n], "");
84
85 for(i=0; i<3; i++) {
86 /* If name was '.' then replace it with empty string */
87 if(strcmp(sname[i], ".")==0) strcpy(sname[i], "");
88 //printf(" -> '%s'\n", sname[i]);
89 }
90
91 /* If subname2 is empty and subname1 is too long, then divide it */
92 if(sname[1][0]=='\0' && strlen(sname[0])>max_name_len)
93 strlcpy(sname[1], &sname[0][max_name_len], fullLen+1);
94 /* If subname3 is empty and subname2 is too long, then divide it */
95 if(sname[2][0]=='\0' && strlen(sname[1])>max_name_len)
96 strlcpy(sname[2], &sname[1][max_name_len], fullLen+1);
97
98 /* Fill the output strings */
99 char *nptr;
100 for(i=n=0; i<3; i++) {
101 //printf(" -> '%s'\n", sname[i]);
102 if(i==0) nptr=name1; else if(i==1) nptr=name2; else nptr=name3;
103 if(strlen(sname[i])>0) n=i+1;
104 if(nptr==NULL) continue;
105 strlcpy(nptr, sname[i], max_name_len+1);
106 }
107
108 free(temp);
109 return n;
110}
int strTokenNr(const char *s1, const char *s2)
Definition stringext.c:25
char * strdup(const char *s)
Definition stringext.c:185
size_t strlcpy(char *dst, const char *src, size_t dstsize)
Definition stringext.c:632
int strClean(char *s)
Definition stringext.c:389

Referenced by tacWriteDFT().

◆ tacReadDFT()

int tacReadDFT ( TAC * tac,
CSV * csv,
IFT * hdr,
TPCSTATUS * status )

Read DFT format from CSV structure into TAC structure.

Returns
enum tpcerror (TPCERROR_OK when successful).
Author
Vesa Oikonen
See also
tacWriteDFT, tacWrite
Parameters
tacPointer to TAC structure, into which are to be written; any previous contents are deleted.
csvPointer to CSV from which data is read; it must contain at least one or two x columns and one y column.
hdrPointer to possible header data, which, if available, is copied to TAC as a processed version; enter NULL if not available
statusPointer to status data; enter NULL if not needed

Definition at line 300 of file dftio.c.

311 {
312 int verbose=0; if(status!=NULL) verbose=status->verbose;
313 if(tac==NULL) {
314 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_FAIL);
315 return TPCERROR_FAIL;
316 }
317 tacFree(tac);
318 if(csv==NULL || csv->row_nr<5 || csv->col_nr<2) {
319 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_DATA);
320 return TPCERROR_NO_DATA;
321 }
322 if(verbose>0) printf("%s()\n", __func__);
323
324 /* Verify the magic number first */
325 if(strncasecmp(csv->c[0].content, "DFT", 3)!=0) {
326 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_FORMAT);
328 }
329
330 int ret, i, j, m, n, isframe=0, is2cunit=0, is2tunit=0, tunit;
331 char *cptr;
332
333 /* Get some important information from title lines first */
334 for(i=0; i<csv->nr; i++) if(csv->c[i].col==0 && csv->c[i].row==3) break;
335 if(i==csv->nr) {
336 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_FORMAT);
338 }
339 /* Do we have one or two x columns */
340 // note that time unit may or may not be included in this field, depending
341 // on field separator
342 if(strncasecmp(csv->c[i].content, "Times", 5)==0) isframe=1;
343 else if(strncasecmp(csv->c[i].content, "Time", 4)==0) isframe=0;
344 else if(strncasecmp(csv->c[i].content, "Distances", 9)==0) isframe=1;
345 else if(strncasecmp(csv->c[i].content, "Distance", 8)==0) isframe=0;
346 else {
347 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_FORMAT);
349 }
350 if(verbose>2) printf(" isframe=%d\n", isframe);
351 /* Get time unit from first or second field, inside parens */
352 cptr=strchr(csv->c[i].content, '(');
353 if(cptr==NULL) cptr=strchr(csv->c[i].content, '[');
354 if(cptr==NULL) {cptr=strchr(csv->c[i+1].content, '('); is2tunit=1;}
355 if(cptr==NULL) {cptr=strchr(csv->c[i+1].content, '['); is2tunit=1;}
356 if(cptr==NULL) {
357 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_FORMAT);
359 } else {
360 char *tmp=strdup(cptr); strCleanPars(tmp); tunit=unitIdentify(tmp);
361 free(tmp);
362 }
363
364 /* Allocate memory for TAC data */
365 m=csv->row_nr-4;
366 n=csv->col_nr-1; if(isframe) n--;
367 if(n<1 || m<1) {
368 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_FORMAT);
370 }
371 ret=tacAllocate(tac, m, n);
372 statusSet(status, __func__, __FILE__, __LINE__, ret);
373 if(ret!=TPCERROR_OK) return ret;
374 tac->tacNr=n; tac->sampleNr=m; // these may be refined later
375 tac->isframe=isframe;
376 tac->tunit=tunit;
377
378 /* Copy header to TAC struct */
379 iftDuplicate(hdr, &tac->h);
380
381 /* Read first title line, jumping over magic number */
382 n=0;
383 for(i=1; i<csv->nr; i++) {
384 if(csv->c[i].row!=0 || n>=tac->tacNr) break;
385 /* Copy TAC name */
386 strlcpy(tac->c[n].name, csv->c[i].content, MAX_TACNAME_LEN+1);
387 if(strcmp(tac->c[n].name, ".")==0) strcpy(tac->c[n].name, "");
388 n++;
389 }
390 if(n<1) {
391 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_FORMAT);
393 }
394 tac->tacNr=n;
395 if(verbose>2)
396 printf(" tacNr=%d\n sampleNr=%d\n", tac->tacNr, tac->sampleNr);
397
398 /* Get study number */
399 for(i=0; i<csv->nr; i++) if(csv->c[i].row==1 && csv->c[i].col==0) {
400 if(strlen(csv->c[i].content)>0 && strcmp(csv->c[i].content, ".")!=0)
401 tacSetHeaderStudynr(&tac->h, csv->c[i].content);
402 break;
403 }
404
405 /* Get concentration unit from the first item on line 3 */
406 for(i=0; i<csv->nr; i++) if(csv->c[i].row==2 && csv->c[i].col==0) break;
407 tac->cunit=unitIdentify(csv->c[i].content);
408 /* Carimas may (erroneously) write conc unit in two columns, with actual
409 unit in 2nd column inside parenthesis */
410 if(strInPars(csv->c[i+1].content)
411 && csvRowLength(csv, 2)==csvRowLength(csv, 1)+1)
412 {
413 if(verbose>2) printf(" concentration unit spans two columns\n");
414 is2cunit=1;
415 if(tac->cunit==UNIT_UNKNOWN) {
416 char *tmp=strdup(csv->c[i+1].content);
417 strCleanPars(tmp); tac->cunit=unitIdentify(tmp);
418 free(tmp);
419 }
420 }
421
422
423 /* Catenate additional TAC names if available on lines 2 and 3 */
424 for(int ri=0; ri<tac->tacNr; ri++) {
425 for(i=0; i<csv->nr; i++) if(csv->c[i].row==1 && csv->c[i].col==ri+1) break;
426 for(j=i; j<csv->nr; j++) if(csv->c[j].row==2 && csv->c[j].col==ri+1) break;
427 if(i==csv->nr || j==csv->nr) {
428 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_FORMAT);
430 }
431 if(is2cunit) j++; // add one in case cunit spans two columns
432 m=strlen(csv->c[i].content); if(strcmp(csv->c[i].content, ".")==0) m=0;
433 n=strlen(csv->c[j].content); if(strcmp(csv->c[j].content, ".")==0) n=0;
434 if((m+n)>0 && (strlen(tac->c[ri].name)<MAX_TACNAME_LEN-1))
435 strcat(tac->c[ri].name, "_");
436 if(m>0 && (m+strlen(tac->c[ri].name)<MAX_TACNAME_LEN))
437 strcat(tac->c[ri].name, csv->c[i].content);
438 if(n>0 && (strlen(tac->c[ri].name)<MAX_TACNAME_LEN-1))
439 strcat(tac->c[ri].name, "_");
440 if(n>0 && (n+strlen(tac->c[ri].name)<MAX_TACNAME_LEN))
441 strcat(tac->c[ri].name, csv->c[j].content);
442 }
443
444 /* Read sizes from 4th line */
445 n=csvRowLength(csv, 3);
446 for(i=0; i<csv->nr; i++) if(csv->c[i].row==3) {
447 m=csv->c[i].col-1; if(is2tunit) m--;
448 if(m>=0 && m<tac->tacNr) tac->c[m].size=atofVerified(csv->c[i].content);
449 }
450#if(0)
451 for(i=0, m=-1, n=0; i<csv->nr; i++) if(csv->c[i].row==3) {n++; if(m<0) m=i;}
452 if(n==tac->tacNr+1) m+=1;
453 else if(n==tac->tacNr+2) m+=2;
454 else {
455 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_FORMAT);
457 }
458 for(int ri=0; ri<tac->tacNr; ri++)
459 tac->c[ri].size=atofVerified(csv->c[m++].content);
460#endif
461
462 /* Copy x and y data from CSV into TAC struct */
463 int fi=0, ri=0, oknr=0;
464 ret=0;
465 double v;
466 for(i=0; i<csv->nr; i++) if(csv->c[i].row==4) break;
467 for(; i<csv->nr; i++) {
468 if(verbose>10)
469 printf("i=%d\trow=%d\tcol=%d\n", i, csv->c[i].row, csv->c[i].col);
470 fi=csv->c[i].row-4; if(fi<0 || fi>=tac->sampleNr) {ret++; continue;}
471 if(csv->c[i].col<0) {ret++; continue;}
472 ri=csv->c[i].col-1;
473 if(tac->isframe) ri--;
474 if(ri>=tac->tacNr) {ret++; continue;}
475 v=atofVerified(csv->c[i].content); if(!isnan(v)) oknr++;
476 if(verbose>10) printf(" -> fi=%d\tri=%d\t=\t%g\n", fi, ri, v);
477 if(ri<0) {
478 if(tac->isframe) {
479 if(ri==-2) tac->x1[fi]=v; else if(ri==-1) tac->x2[fi]=v;
480 } else tac->x[fi]=v;
481 } else tac->c[ri].y[fi]=v;
482 }
483 if(verbose>0 && ret>0)
484 printf("%d error(s) in reading DFT file format.\n", ret);
485 if(oknr<1) {
486 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_FORMAT);
488 }
489 /* Set middle sample times when necessary */
490 if(tac->isframe)
491 for(fi=0; fi<tac->sampleNr; fi++)
492 tac->x[fi]=0.5*(tac->x1[fi]+tac->x2[fi]);
493
494 /* If units are not known, try to read units from header */
495 if(tac->cunit==UNIT_UNKNOWN) tacGetHeaderUnit(tac, NULL);
496 else tacSetHeaderUnit(&tac->h, UNIT_UNKNOWN);
497 if(tac->tunit==UNIT_UNKNOWN) tacGetHeaderTimeunit(tac, NULL);
499
500 /* Move column containing weights to its correct place in the struct */
501 ret=tacWMove(tac, 1, status);
502 if(ret!=TPCERROR_OK && ret!=TPCERROR_NO_WEIGHTS) {
503 statusSet(status, __func__, __FILE__, __LINE__, ret);
504 return(ret);
505 }
506 if(tac->tacNr<1) {
507 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_DATA);
508 return TPCERROR_NO_DATA;
509 }
510
512 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OK);
513 return(TPCERROR_OK);
514}
int csvRowLength(CSV *csv, int row)
Definition csv.c:244
double atofVerified(const char *s)
Definition decpoint.c:75
int iftDuplicate(IFT *ift1, IFT *ift2)
Definition ift.c:236
void statusSet(TPCSTATUS *s, const char *func, const char *srcfile, int srcline, tpcerror error)
Definition statusmsg.c:142
int strInPars(char *s)
Definition stringext.c:453
void strCleanPars(char *s)
Definition stringext.c:476
int col
Definition tpccsv.h:28
int row
Definition tpccsv.h:26
char * content
Definition tpccsv.h:30
int row_nr
Definition tpccsv.h:44
int col_nr
Definition tpccsv.h:46
CSV_item * c
Definition tpccsv.h:38
int nr
Definition tpccsv.h:42
char name[MAX_TACNAME_LEN+1]
Definition tpctac.h:81
double * y
Definition tpctac.h:75
double size
Definition tpctac.h:71
double * x
Definition tpctac.h:97
unit cunit
Definition tpctac.h:105
tacformat format
Definition tpctac.h:93
int sampleNr
Definition tpctac.h:89
IFT h
Optional (but often useful) header information.
Definition tpctac.h:141
int isframe
Definition tpctac.h:95
TACC * c
Definition tpctac.h:117
double * x2
Definition tpctac.h:101
unit tunit
Definition tpctac.h:109
double * x1
Definition tpctac.h:99
int tacNr
Definition tpctac.h:91
int verbose
Verbose level, used by statusPrint() etc.
void tacFree(TAC *tac)
Definition tac.c:106
int tacAllocate(TAC *tac, int sampleNr, int tacNr)
Definition tac.c:130
int tacGetHeaderUnit(TAC *tac, TPCSTATUS *status)
Definition tacift.c:145
int tacGetHeaderTimeunit(TAC *tac, TPCSTATUS *status)
Definition tacift.c:234
int tacSetHeaderTimeunit(IFT *h, int u)
Definition tacift.c:201
int tacSetHeaderStudynr(IFT *h, const char *s)
Definition tacift.c:79
int tacSetHeaderUnit(IFT *h, int u)
Definition tacift.c:112
int tacWMove(TAC *tac, int ow, TPCSTATUS *status)
Definition tacw.c:75
#define MAX_TACNAME_LEN
Max length of TAC ID name (not including trailing zero).
@ UNIT_UNKNOWN
Unknown unit.
@ TPCERROR_FAIL
General error.
@ TPCERROR_INVALID_FORMAT
Invalid file format.
@ TPCERROR_OK
No error.
@ TPCERROR_NO_WEIGHTS
File contains no weights.
@ TPCERROR_NO_DATA
File contains no data.
int unitIdentify(const char *s)
Definition units.c:162
@ TAC_FORMAT_DFT
Data format of Turku PET Centre.
Definition tpctac.h:30

Referenced by tacRead().

◆ tacWriteDFT()

int tacWriteDFT ( TAC * tac,
FILE * fp,
int extra,
TPCSTATUS * status )

Write TAC data into specified file pointer in DFT format.

Returns
enum tpcerror (TPCERROR_OK when successful).
Author
Vesa Oikonen
See also
tacWrite, tacReadDFT
Parameters
tacPointer to TAC struct, contents of which are to be written
fpFile pointer
extraWrite (1) or do not write (0) also extra header fields found in IFT
statusPointer to status data; enter NULL if not needed

Definition at line 119 of file dftio.c.

128 {
129 int verbose=0; if(status!=NULL) verbose=status->verbose;
130 if(fp==NULL) {
131 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_CANNOT_WRITE);
133 }
134 if(tac==NULL || tac->tacNr<1 || tac->sampleNr<1) {
135 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_DATA);
136 return TPCERROR_NO_DATA;
137 }
138 if(verbose>0) printf("%s()\n", __func__);
139
140 int ret, prec=6;
141
142 /* Make sure that TAC names are available */
143 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OK);
144 tacEnsureNames(tac);
145
146 /* Create local copy of headers, which will be edited here and written
147 into DFT file, to preserve the original headers with TAC struct */
148 if(verbose>99) iftWrite(&tac->h, stdout, NULL);
149 IFT localh; iftInit(&localh);
150 ret=iftDuplicate(&tac->h, &localh);
151 if(ret) {
152 statusSet(status, __func__, __FILE__, __LINE__, ret);
153 return ret;
154 }
155
156 /* Writing obligatory header lines */
157 if(verbose>1) printf("writing obligatory title lines\n");
158 int n;
159 char subname[7];
160
161 /* 1st line with filetype identification string and region names */
162 n=fprintf(fp, "DFT1"); if(n<1) {
163 iftFree(&localh);
164 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_CANNOT_WRITE);
166 }
167 for(int ri=0; ri<tac->tacNr; ri++) {
168 n=tacNameSplit(tac->c[ri].name, subname, NULL, NULL, 6);
169 fprintf(fp, "\t%s", subname);
170 }
171 if(tacIsWeighted(tac)) fprintf(fp, "\t%s", "weight");
172 n=fprintf(fp, "\n"); if(n<1) {
173 iftFree(&localh);
174 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_CANNOT_WRITE);
176 }
177
178 /* 2nd line with study identification and 2nd subname */
179 if(verbose>2) printf(" writing 2nd title line\n");
180 char tmp[128];
181 n=tacGetHeaderStudynr(&localh, tmp, status);
182 if(n!=TPCERROR_OK) {
183 strcpy(tmp, "."); if(verbose>5) printf("no studynr\n");
184 } else tacSetHeaderStudynr(&localh, ""); // delete studynr from header
185 n=fprintf(fp, "%s", tmp); if(n<1) {
186 iftFree(&localh);
187 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_CANNOT_WRITE);
189 }
190 for(int ri=0; ri<tac->tacNr; ri++) {
191 n=tacNameSplit(tac->c[ri].name, NULL, subname, NULL, 6);
192 if(n<2 || !subname[0]) strcpy(subname, ".");
193 fprintf(fp, "\t%s", subname);
194 }
195 if(tacIsWeighted(tac)) fprintf(fp, "\t%s", ".");
196 n=fprintf(fp, "\n"); if(n<1) {
197 iftFree(&localh);
198 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_CANNOT_WRITE);
200 }
201
202 /* 3rd line with calibration unit and 3rd subname */
203 if(verbose>2) printf(" writing 3rd title line\n");
204 tacSetHeaderUnit(&localh, UNIT_UNKNOWN); // delete any unit(s) from header
205 if(tac->cunit==UNIT_UNKNOWN) strcpy(tmp, ".");
206 else strcpy(tmp, unitName(tac->cunit));
207 n=fprintf(fp, "%s", tmp); if(n<1) {
208 iftFree(&localh);
209 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_CANNOT_WRITE);
211 }
212 for(int ri=0; ri<tac->tacNr; ri++) {
213 n=tacNameSplit(tac->c[ri].name, NULL, NULL, subname, 6);
214 if(n<3 || !subname[0]) strcpy(subname, ".");
215 fprintf(fp, "\t%s", subname);
216 }
217 if(tacIsWeighted(tac)) fprintf(fp, "\t%s", ".");
218 n=fprintf(fp, "\n"); if(n<1) {
219 iftFree(&localh);
220 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_CANNOT_WRITE);
222 }
223
224 /* 4th line with x (time) type & unit and region volumes */
225 if(verbose>2) printf(" writing 4th title line\n");
226 if(unitIsDistance(tac->tunit)) strcpy(tmp, "Distance");
227 else strcpy(tmp, "Time");
228 if(tac->isframe!=0) strcat(tmp, "s");
229 n=fprintf(fp, "%s (%s)", tmp, unitName(tac->tunit)); if(n<1) {
230 iftFree(&localh);
231 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_CANNOT_WRITE);
233 }
234 for(int ri=0; ri<tac->tacNr; ri++) {
235 if(!isnan(tac->c[ri].size)) sprintf(tmp, "%.*e", prec, tac->c[ri].size);
236 else strcpy(tmp, ".");
237 fprintf(fp, "\t%s", tmp);
238 }
239 if(tacIsWeighted(tac)) fprintf(fp,"\t%s", ".");
240 n=fprintf(fp, "\n"); if(n<1) {
241 iftFree(&localh);
242 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_CANNOT_WRITE);
244 }
245
246 /* Write data */
247 if(verbose>1) printf("writing data table\n");
248 double v;
249 n=10;
250 for(int fi=0; fi<tac->sampleNr; fi++) {
251 /* x or x1 and x2) */
252 if(tac->isframe==0) v=tac->x[fi]; else v=tac->x1[fi];
253 if(isnan(v)) n=fprintf(fp, "."); else n=fprintf(fp, "%.5f", v);
254 if(n<1) break;
255 if(tac->isframe!=0) {
256 v=tac->x2[fi];
257 if(isnan(v)) n=fprintf(fp, "\t."); else n=fprintf(fp, "\t%.5f", v);
258 if(n<1) break;
259 }
260 /* Concentrations (y values) */
261 for(int ri=0; ri<tac->tacNr; ri++) {
262 if(isnan(tac->c[ri].y[fi])) n=fprintf(fp, "\t.");
263 else n=fprintf(fp, "\t%.*e", prec, tac->c[ri].y[fi]);
264 if(n<1) break;
265 }
266 if(n<1) break;
267 /* Weight */
268 if(tacIsWeighted(tac)) {
269 if(isnan(tac->w[fi])) n=fprintf(fp, "\t.");
270 else n=fprintf(fp, "\t%.*e", prec, tac->w[fi]);
271 if(n<1) break;
272 }
273 if(n<1) break;
274 n=fprintf(fp, "\n"); if(n<1) break;
275 } // next sample
276 if(n<1) {
277 iftFree(&localh);
278 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_CANNOT_WRITE);
280 }
281
282 /* Write extra header, if requested */
283 if(extra && localh.keyNr>0) {
284 int ret=iftWrite(&localh, fp, status);
285 if(ret!=TPCERROR_OK) {iftFree(&localh); return ret;}
286 }
287
288 iftFree(&localh);
289 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OK);
290 return(TPCERROR_OK);
291}
int tacNameSplit(const char *rname, char *name1, char *name2, char *name3, unsigned int max_name_len)
Definition dftio.c:26
void iftFree(IFT *ift)
Definition ift.c:37
void iftInit(IFT *ift)
Definition ift.c:21
int iftWrite(IFT *ift, FILE *fp, TPCSTATUS *status)
Definition iftio.c:98
Definition tpcift.h:43
int keyNr
Definition tpcift.h:47
double * w
Definition tpctac.h:111
int tacGetHeaderStudynr(IFT *h, char *s, TPCSTATUS *status)
Definition tacift.c:26
void tacEnsureNames(TAC *tac)
Definition tacname.c:50
int tacIsWeighted(TAC *tac)
Definition tacw.c:24
@ TPCERROR_CANNOT_WRITE
Cannot write file.
char * unitName(int unit_code)
Definition units.c:143
int unitIsDistance(int u)
Definition units.c:339

Referenced by tacWrite().