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

I/O functions for simple ASCII 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 tacWriteSimple (TAC *tac, FILE *fp, int extra, TPCSTATUS *status)
int tacReadSimple (TAC *tac, CSV *csv, IFT *hdr, TPCSTATUS *status)

Detailed Description

I/O functions for simple ASCII TAC file format.

Definition in file simpleio.c.

Function Documentation

◆ tacReadSimple()

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

Read simple format from CSV struct into TAC struct.

Returns
enum tpcerror (TPCERROR_OK when successful).
Author
Vesa Oikonen
See also
tacWriteSimple, tacReadCSV, tacReadMat, tacRead
Parameters
tacPointer to TAC struct, contents of which are to be written.
csvPointer to CSV from which data is read; if it contains only one column, then it is assumed to represent the first y column and x column is not filled.
hdrPointer to possible header data, which, if available, is processed and copied to TAC too; enter NULL if not available.
statusPointer to status data; enter NULL if not needed.

Definition at line 97 of file simpleio.c.

108 {
109 int verbose=0; if(status!=NULL) verbose=status->verbose;
110 if(tac==NULL) {
111 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_FAIL);
112 return TPCERROR_FAIL;
113 }
114 tacFree(tac);
115 if(csv==NULL || csv->row_nr<1 || csv->col_nr<1) {
116 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_DATA);
117 return TPCERROR_NO_DATA;
118 }
119 if(verbose>0) {printf("%s()\n", __func__); fflush(stdout);}
120
121 /* Check that each row has same number of columns */
122 if(verbose>1) {printf(" verifying CSV regularity\n"); fflush(stdout);}
123 if(!csvIsRegular(csv)) {
124 if(verbose>2) {
125 printf("\n <-- CSV contents (irregular) ---\n");
126 csvWrite(csv, 0, stdout, NULL);
127 printf("\n ------------------------------->\n");
128 printf("col_nr := %d\n", csv->col_nr);
129 printf("row_nr := %d\n", csv->row_nr);
130 if(verbose>3) {
131 for(int i=0; i<csv->row_nr; i++)
132 printf("columns_on_row[%d] := %d\n", 1+i, csvRowLength(csv, i));
133 fflush(stdout);
134 }
135 }
136 /* try to make it regular by removing empty columns from the right */
137 if(verbose>1) {printf(" trying to make it regular\n"); fflush(stdout);}
138 if(csvTrimRight(csv) || !csvIsRegular(csv)) {
139 if(verbose>1) {
140 printf("\n <-- CSV contents (still irregular) ---\n");
141 csvWrite(csv, 0, stdout, NULL);
142 printf("\n ------------------------------->\n");
143 printf("col_nr := %d\n", csv->col_nr);
144 printf("row_nr := %d\n", csv->row_nr);
145 if(verbose>5) {
146 for(int i=0; i<csv->row_nr; i++)
147 printf("columns_on_row[%d] := %d\n", 1+i, csvRowLength(csv, i));
148 fflush(stdout);
149 }
150 }
151 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_FORMAT);
153 }
154 }
155
156 /* Check if first line contains fields starting with letter, suggesting title line */
157 int withTitle=0;
158 for(int i=0; i<csv->col_nr; i++) {
159 char *c=csvCell(csv, 0, i);
160 if(c!=NULL && isalpha(c[0])) withTitle++;
161 }
162 if(verbose>1 && withTitle>0) {printf("CSV seems to have title line.\n"); fflush(stdout);}
163 if(withTitle>0) withTitle=1;
164
165 int ret, n, m;
166
167 /* Allocate memory for TAC data */
168 if(verbose>2) {printf(" allocating memory for TAC data\n"); fflush(stdout);}
169 n=csv->col_nr; if(n>1) n--;
170 m=csv->row_nr-withTitle;
171 ret=tacAllocate(tac, m, n);
172 statusSet(status, __func__, __FILE__, __LINE__, ret); if(ret!=TPCERROR_OK) return ret;
173 tac->tacNr=n; tac->sampleNr=m;
174 tac->isframe=0;
175 if(verbose>2) {
176 printf(" tacNr := %d\n", tac->tacNr);
177 printf(" sampleNr := %d\n", tac->sampleNr);
178 fflush(stdout);
179 }
180
181
182 /* Copy title line contents as TAC names */
183 if(withTitle) {
184 if(verbose>2) {printf(" copying TAC names from the title columns\n"); fflush(stdout);}
185 char *c;
186 for(int ri=0; ri<tac->tacNr; ri++) {
187 c=csvCell(csv, 0, 1+ri);
188 if(c!=NULL) strlcpy(tac->c[ri].name, c, MAX_TACNAME_LEN+1);
189 }
190 }
191
192 /* Copy data from CSV into TAC struct */
193 if(verbose>2) {printf(" copying data from CSV to TAC\n"); fflush(stdout);}
194 int fi, ri, oknr=0;
195 char *c;
196 for(fi=0; fi<tac->sampleNr; fi++) {
197 /* Get the x value from the first column */
198 c=csvCell(csv, fi+withTitle, 0);
199 tac->x[fi]=atofVerified(c); if(!isnan(tac->x[fi])) oknr++;
200 /* Get the y values from the next columns */
201 for(ri=0; ri<tac->tacNr; ri++) {
202 c=csvCell(csv, fi+withTitle, 1+ri);
203 tac->c[ri].y[fi]=atofVerified(c); if(!isnan(tac->c[ri].y[fi])) oknr++;
204 }
205 }
206 if(oknr<1) {
207 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_FORMAT);
209 }
210
211 /* Copy header to TAC struct */
212 iftDuplicate(hdr, &tac->h);
213
214 /* Try to read units from header */
215 tacGetHeaderUnit(tac, NULL);
216 tacGetHeaderTimeunit(tac, NULL);
217
220
221 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OK);
222 return(TPCERROR_OK);
223}
int csvIsRegular(CSV *csv)
Definition csv.c:292
char * csvCell(CSV *csv, int row, int col)
Definition csv.c:358
int csvTrimRight(CSV *csv)
Definition csv.c:321
int csvRowLength(CSV *csv, int row)
Definition csv.c:244
int csvWrite(CSV *csv, int regular, FILE *fp, TPCSTATUS *status)
Definition csvio.c:52
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
size_t strlcpy(char *dst, const char *src, size_t dstsize)
Definition stringext.c:632
int row_nr
Definition tpccsv.h:44
int col_nr
Definition tpccsv.h:46
char name[MAX_TACNAME_LEN+1]
Definition tpctac.h:81
double * y
Definition tpctac.h:75
double * x
Definition tpctac.h:97
tacformat format
Definition tpctac.h:93
int sampleNr
Definition tpctac.h:89
IFT h
Optional (but often useful) header information.
Definition tpctac.h:141
int isframe
Definition tpctac.h:95
TACC * c
Definition tpctac.h:117
weights weighting
Definition tpctac.h:115
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
@ WEIGHTING_OFF
Not weighted or weights not available (weights for all included samples are 1.0).
@ WEIGHTING_UNKNOWN
Not known; usually assumed that not weighted.
#define MAX_TACNAME_LEN
Max length of TAC ID name (not including trailing zero).
@ TPCERROR_FAIL
General error.
@ TPCERROR_INVALID_FORMAT
Invalid file format.
@ TPCERROR_OK
No error.
@ TPCERROR_NO_DATA
File contains no data.
@ TAC_FORMAT_SIMPLE
x and y's with space delimiters
Definition tpctac.h:29

Referenced by tacRead().

◆ tacWriteSimple()

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

Write TAC data into specified file pointer in Simple format.

Returns
enum tpcerror (TPCERROR_OK when successful).
Author
Vesa Oikonen
See also
tacReadSimple, tacWriteCSV
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 26 of file simpleio.c.

35 {
36 int verbose=0; if(status!=NULL) verbose=status->verbose;
37 if(fp==NULL) {
38 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_CANNOT_WRITE);
40 }
41 if(tac==NULL || tac->tacNr<1 || tac->sampleNr<1) {
42 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_DATA);
43 return TPCERROR_NO_DATA;
44 }
45 if(verbose>0) {printf("%s(%d)\n", __func__, extra); fflush(stdout);}
46
47
48 int fi, ri, n, prec=6;
49 double v;
50
51 /* Write data */
52 for(fi=0; fi<tac->sampleNr; fi++) {
53 /* Time (x) */
54 if(tac->isframe==0) v=tac->x[fi]; else v=0.5*(tac->x1[fi]+tac->x2[fi]);
55 if(isnan(v)) n=fprintf(fp, "."); else n=fprintf(fp, "%.5f", v);
56 if(n<1) {
57 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_CANNOT_WRITE);
59 }
60 /* Concentrations (y values) */
61 for(ri=0; ri<tac->tacNr; ri++) {
62 if(isnan(tac->c[ri].y[fi])) n=fprintf(fp, " .");
63 else fprintf(fp, " %.*e", prec, tac->c[ri].y[fi]);
64 if(n<1) {
65 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_CANNOT_WRITE);
67 }
68 }
69 n=fprintf(fp, "\n"); if(n<1) {
70 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_CANNOT_WRITE);
72 }
73 }
74
75 /* Write extra header, if requested */
76 if(extra) {
77 if(tac->h.keyNr>0) {
78 int ret=iftWrite(&tac->h, fp, status);
79 if(ret!=TPCERROR_OK) return ret;
80 }
81 /* Write units */
82 if(tac->cunit!=UNIT_UNKNOWN) fprintf(fp, "# unit := %s\n", unitName(tac->cunit));
83 if(tac->tunit!=UNIT_UNKNOWN) fprintf(fp, "# timeunit := %s\n", unitName(tac->tunit));
84 }
85
86 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OK);
87 return(TPCERROR_OK);
88}
int iftWrite(IFT *ift, FILE *fp, TPCSTATUS *status)
Definition iftio.c:98
int keyNr
Definition tpcift.h:47
unit cunit
Definition tpctac.h:105
double * x2
Definition tpctac.h:101
unit tunit
Definition tpctac.h:109
double * x1
Definition tpctac.h:99
@ UNIT_UNKNOWN
Unknown unit.
@ TPCERROR_CANNOT_WRITE
Cannot write file.
char * unitName(int unit_code)
Definition units.c:143

Referenced by tacWrite().