TPCCLIB
Loading...
Searching...
No Matches
tacxmlio.c
Go to the documentation of this file.
1
4/*****************************************************************************/
5#include "tpcclibConfig.h"
6/*****************************************************************************/
7#include "tpcift.h"
8#include "tpcisotope.h"
9#include "tpccsv.h"
10/*****************************************************************************/
11#include <stdio.h>
12#include <stdlib.h>
13#include <math.h>
14#include <time.h>
15#include <string.h>
16/*****************************************************************************/
17#include "tpctac.h"
18/*****************************************************************************/
19
20/*****************************************************************************/
28 TAC *tac,
30 FILE *fp,
32 TPCSTATUS *status
33) {
34 int verbose=0; if(status!=NULL) verbose=status->verbose;
35 if(verbose>0) printf("%s()\n", __func__);
36 if(fp==NULL) {
37 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_CANNOT_WRITE);
39 }
40 if(tac==NULL || tac->tacNr<1 || tac->sampleNr<1) {
41 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_DATA);
42 return TPCERROR_NO_DATA;
43 }
44
45 char *cptr, tunit[128], cunit[128];
46 int n;
47
48 /* Set units to format accepted by PMOD */
49 if(tac->tunit==UNIT_SEC) strcpy(tunit, "seconds");
50 else if(tac->tunit==UNIT_MIN) strcpy(tunit, "minutes");
51 else strcpy(tunit, unitName(tac->tunit));
52 strcpy(cunit, unitName(tac->cunit));
53 if(strcasestr(cunit, "dL")==NULL) {
54 /* Replace mL by cc, but only if unit does not contain 'dL' */
55 cptr=strcasestr(cunit, "mL");
56 if(cptr!=NULL) {*cptr='c'; cptr++; *cptr='c';}
57 }
58
59 /* Make sure that TAC names are available */
60 if(verbose>2) printf("constructing TAC names\n");
61 tacEnsureNames(tac);
62
63 /* Write XML header */
64 n=fprintf(fp, "<?xml version=\"1.0\"?>\n");
65 if(n<1) {
66 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_CANNOT_WRITE);
68 }
69 fprintf(fp, "<ss:Workbook xmlns:ss=\"urn:schemas-microsoft-com:office:spreadsheet\">\n");
70 fprintf(fp, " <ss:Styles>\n");
71 fprintf(fp, " <ss:Style ss:ID=\"1\">\n");
72 fprintf(fp, " <ss:Font ss:Bold=\"1\"/>\n");
73 fprintf(fp, " </ss:Style>\n");
74 fprintf(fp, " </ss:Styles>\n");
75 fprintf(fp, " <ss:Worksheet ss:Name=\"Sheet1\">\n");
76 fprintf(fp, " <ss:Table>\n");
77
78 /* Set column widths */
79 n=tac->tacNr+1;
80 if(tac->isframe) n++;
81 if(tacIsWeighted(tac)) n++;
82 for(int i=0; i<n; i++) fprintf(fp, " <ss:Column ss:Width=\"80\"/>\n");
83
84 /* Write the title line */
85 fprintf(fp, " <ss:Row ss:StyleID=\"1\">\n");
86 if(tac->isframe==0) {
87 fprintf(fp, " <ss:Cell>\n");
88 fprintf(fp, " <ss:Data ss:Type=\"String\">time[%s]</ss:Data>\n", tunit);
89 fprintf(fp, " </ss:Cell>\n");
90 } else {
91 fprintf(fp, " <ss:Cell>\n");
92 fprintf(fp, " <ss:Data ss:Type=\"String\">start[%s]</ss:Data>\n", tunit);
93 fprintf(fp, " </ss:Cell>\n");
94 fprintf(fp, " <ss:Cell>\n");
95 fprintf(fp, " <ss:Data ss:Type=\"String\">end[%s]</ss:Data>\n", cunit);
96 fprintf(fp, " </ss:Cell>\n");
97 }
98 for(int ri=0; ri<tac->tacNr; ri++) {
99 /* write TAC names */
100 char *nptr=tac->c[ri].name;
101 char *senc=strEncodeForXML(nptr);
102 if(senc!=NULL) nptr=senc;
103 fprintf(fp, " <ss:Cell>\n");
104 if(ri==0 && tac->isframe==0)
105 fprintf(fp, " <ss:Data ss:Type=\"String\">%s[%s]</ss:Data>\n", nptr, cunit);
106 else
107 fprintf(fp, " <ss:Data ss:Type=\"String\">%s</ss:Data>\n", nptr);
108 fprintf(fp, " </ss:Cell>\n");
109 if(senc!=NULL) free(senc);
110 }
111 if(tacIsWeighted(tac)) {
112 fprintf(fp, " <ss:Cell>\n");
113 fprintf(fp, " <ss:Data ss:Type=\"String\">weight</ss:Data>\n");
114 fprintf(fp, " </ss:Cell>\n");
115 }
116 n=fprintf(fp, " </ss:Row>\n");
117 if(n<1) {
118 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_CANNOT_WRITE);
120 }
121
122 /* Write data */
123 if(verbose>2) printf("writing data table\n");
124 for(int fi=0; fi<tac->sampleNr; fi++) {
125
126 fprintf(fp, " <ss:Row>\n");
127
128 /* Note: missing values are written as empty cells, with string type, because with
129 number type Excel seems to read those as zeroes. */
130
131 /* Time(s) (x, or x1 and x2) */
132 double v; if(tac->isframe==0) v=tac->x[fi]; else v=tac->x1[fi];
133 fprintf(fp, " <ss:Cell>\n");
134 if(isnan(v)) fprintf(fp, " <ss:Data ss:Type=\"String\"></ss:Data>\n");
135 else fprintf(fp, " <ss:Data ss:Type=\"Number\">%g</ss:Data>\n", v);
136 fprintf(fp, " </ss:Cell>\n");
137
138 if(tac->isframe) {
139 v=tac->x2[fi];
140 fprintf(fp, " <ss:Cell>\n");
141 if(isnan(v)) fprintf(fp, " <ss:Data ss:Type=\"String\"></ss:Data>\n");
142 else fprintf(fp, " <ss:Data ss:Type=\"Number\">%g</ss:Data>\n", v);
143 fprintf(fp, " </ss:Cell>\n");
144 }
145
146 /* Concentrations (y values) */
147 for(int ri=0; ri<tac->tacNr; ri++) {
148 fprintf(fp, " <ss:Cell>\n");
149 if(isnan(tac->c[ri].y[fi])) fprintf(fp, " <ss:Data ss:Type=\"String\"></ss:Data>\n");
150 else fprintf(fp, " <ss:Data ss:Type=\"Number\">%g</ss:Data>\n", tac->c[ri].y[fi]);
151 fprintf(fp, " </ss:Cell>\n");
152 }
153
154 /* Weight */
155 if(tacIsWeighted(tac)) {
156 fprintf(fp, " <ss:Cell>\n");
157 if(isnan(tac->w[fi])) fprintf(fp, " <ss:Data ss:Type=\"String\"></ss:Data>\n");
158 else fprintf(fp, " <ss:Data ss:Type=\"Number\">%g</ss:Data>\n", tac->w[fi]);
159 fprintf(fp, " </ss:Cell>\n");
160 }
161
162 fprintf(fp, " </ss:Row>\n");
163 }
164
165 /* Write XML end part */
166 fprintf(fp, " </ss:Table>\n");
167 fprintf(fp, " </ss:Worksheet>\n");
168 n=fprintf(fp, "</ss:Workbook>\n");
169 if(n<1) {
170 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_CANNOT_WRITE);
172 }
173
174 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OK);
175 return(TPCERROR_OK);
176}
177/*****************************************************************************/
178
179/*****************************************************************************/
void statusSet(TPCSTATUS *s, const char *func, const char *srcfile, int srcline, tpcerror error)
Definition statusmsg.c:142
char * strEncodeForXML(const char *s)
Definition stringext.c:731
char * strcasestr(const char *haystack, const char *needle)
Definition stringext.c:155
char name[MAX_TACNAME_LEN+1]
Definition tpctac.h:81
double * y
Definition tpctac.h:75
Definition tpctac.h:87
double * x
Definition tpctac.h:97
int sampleNr
Definition tpctac.h:89
double * w
Definition tpctac.h:111
int cunit
Definition tpctac.h:105
int isframe
Definition tpctac.h:95
TACC * c
Definition tpctac.h:117
int tunit
Definition tpctac.h:109
double * x2
Definition tpctac.h:101
double * x1
Definition tpctac.h:99
int tacNr
Definition tpctac.h:91
int verbose
Verbose level, used by statusPrint() etc.
void tacEnsureNames(TAC *tac)
Definition tacname.c:50
int tacIsWeighted(TAC *tac)
Definition tacw.c:24
int tacWriteXML(TAC *tac, FILE *fp, TPCSTATUS *status)
Definition tacxmlio.c:26
Header file for library libtpccsv.
@ UNIT_MIN
minutes
@ UNIT_SEC
seconds
@ TPCERROR_OK
No error.
@ TPCERROR_NO_DATA
File contains no data.
@ TPCERROR_CANNOT_WRITE
Cannot write file.
char * unitName(int unit_code)
Definition units.c:143
Header file for library libtpcift.
Header file for library libtpcisotope.
Header file for library libtpctac.