TPCCLIB
Loading...
Searching...
No Matches
b2rbc.c
Go to the documentation of this file.
1
7/*****************************************************************************/
8#include "tpcclibConfig.h"
9/*****************************************************************************/
10#include <stdio.h>
11#include <stdlib.h>
12#include <string.h>
13#include <math.h>
14/*****************************************************************************/
15#include "tpcextensions.h"
16#include "tpcift.h"
17#include "tpctac.h"
18#include "tpcli.h"
19/*****************************************************************************/
20
21/*****************************************************************************/
22static char *info[] = {
23 "Calculates the TAC of blood cells (erythrocytes, RBC) using",
24 "haematocrit (HCT), blood TAC, and plasma TAC, based on equation",
25 " ",
26 " Blood = HCT*RBC + (1-HCT)*Plasma ",
27 " ",
28 "HCT is normally between 0.40-0.51 in men and 0.36-0.47 in women.",
29 " ",
30 "Usage: @P [Options] bloodfile plasmafile HCT rbcfile",
31 " ",
32 "Options:",
33 " -stdoptions", // List standard options like --help, -v, etc
34 " ",
35 "See also: bpr2cpr, p2blood, b2plasma, taccalc, fit_bpr",
36 " ",
37 "Keywords: input, modelling, simulation, RBC, plasma, blood",
38 0};
39/*****************************************************************************/
40
41/*****************************************************************************/
42/* Turn on the globbing of the command line, since it is disabled by default in
43 mingw-w64 (_dowildcard=0); in MinGW32 define _CRT_glob instead, if necessary;
44 In Unix&Linux wildcard command line processing is enabled by default. */
45/*
46#undef _CRT_glob
47#define _CRT_glob -1
48*/
49int _dowildcard = -1;
50/*****************************************************************************/
51
52/*****************************************************************************/
56int main(int argc, char **argv)
57{
58 int ai, help=0, version=0, verbose=1;
59 int ret;
60 char pfile[FILENAME_MAX], bfile[FILENAME_MAX], rfile[FILENAME_MAX];
61 TAC plasma, blood;
62 double HCT=-1.0;
63
64
65 /*
66 * Get arguments
67 */
68 if(argc==1) {tpcPrintUsage(argv[0], info, stderr); return(1);}
69 pfile[0]=bfile[0]=rfile[0]=(char)0;
70 tacInit(&blood); tacInit(&plasma);
71 /* Options */
72 for(ai=1; ai<argc; ai++) if(*argv[ai]=='-') {
73 if(tpcProcessStdOptions(argv[ai], &help, &version, &verbose)==0) continue;
74 //cptr=argv[ai]+1;
75 fprintf(stderr, "Error: invalid option '%s'.\n", argv[ai]);
76 return(1);
77 } else break; // tac name argument may start with '-'
78
79 TPCSTATUS status; statusInit(&status);
80 statusSet(&status, __func__, __FILE__, __LINE__, TPCERROR_OK);
81 status.verbose=verbose-1;
82
83 /* Print help or version? */
84 if(help==2) {tpcHtmlUsage(argv[0], info, ""); return(0);}
85 if(help) {tpcPrintUsage(argv[0], info, stdout); return(0);}
86 if(version) {tpcPrintBuild(argv[0], stdout); return(0);}
87
88 /* Arguments */
89 for(; ai<argc; ai++) {
90 if(!bfile[0]) {
91 strlcpy(bfile, argv[ai], FILENAME_MAX); continue;
92 } else if(!pfile[0]) {
93 strlcpy(pfile, argv[ai], FILENAME_MAX); continue;
94 } else if(HCT<0.0) {
95 if(!atofCheck(argv[ai], &HCT)) {
96 if(HCT>1.0) HCT/=100.0;
97 if(HCT>0.0 && HCT<=1.0) continue;
98 }
99 fprintf(stderr, "Error: invalid HCT.\n");
100 return(1);
101 } else if(!rfile[0]) {
102 strlcpy(rfile, argv[ai], FILENAME_MAX); continue;
103 }
104 fprintf(stderr, "Error: too many arguments: '%s'.\n", argv[ai]);
105 return(1);
106 }
107
108 /* Is something missing? */
109 if(!rfile[0]) {
110 fprintf(stderr, "Error: missing command-line argument; use option --help\n");
111 return(1);
112 }
113
114 /* In verbose mode print arguments and options */
115 if(verbose>1) {
116 for(ai=0; ai<argc; ai++)
117 printf("%s ", argv[ai]);
118 printf("\n");
119 printf("pfile := %s\n", pfile);
120 printf("bfile := %s\n", bfile);
121 printf("rfile := %s\n", rfile);
122 printf("HCT := %g\n", HCT);
123 }
124
125
126 /*
127 * Read blood TAC
128 */
129 if(verbose>1) printf("reading %s\n", bfile);
130 ret=tacRead(&blood, bfile, &status);
131 if(ret!=TPCERROR_OK) {
132 fprintf(stderr, "Error (%d): %s\n", ret, errorMsg(status.error));
133 tacFree(&blood); return(2);
134 }
135 if(verbose>2) {
136 printf("fileformat := %s\n", tacFormattxt(blood.format));
137 printf("tacNr := %d\n", blood.tacNr);
138 printf("sampleNr := %d\n", blood.sampleNr);
139 printf("xunit := %s\n", unitName(blood.tunit));
140 printf("yunit := %s\n", unitName(blood.cunit));
141 }
142 if(blood.tacNr>1) {
143 fprintf(stderr, "Warning: only first TAC in blood file is used.\n");
144 blood.tacNr=1;
145 }
146
147 /*
148 * Read plasma TAC
149 */
150 if(verbose>1) printf("reading %s\n", pfile);
151 ret=tacRead(&plasma, pfile, &status);
152 if(ret!=TPCERROR_OK) {
153 fprintf(stderr, "Error (%d): %s\n", ret, errorMsg(status.error));
154 tacFree(&blood); tacFree(&plasma); return(2);
155 }
156 if(verbose>2) {
157 printf("fileformat := %s\n", tacFormattxt(plasma.format));
158 printf("tacNr := %d\n", plasma.tacNr);
159 printf("sampleNr := %d\n", plasma.sampleNr);
160 printf("xunit := %s\n", unitName(plasma.tunit));
161 printf("yunit := %s\n", unitName(plasma.cunit));
162 }
163 if(plasma.tacNr>1) {
164 fprintf(stderr, "Warning: only first TAC in plasma file is used.\n");
165 plasma.tacNr=1;
166 }
167
168 /* Sort by sample times */
169 tacSortByTime(&blood, NULL); tacSortByTime(&plasma, NULL);
170
171 /* Check for missing values */
172 ret=tacNaNs(&blood);
173 if(ret>0) {
174 if(verbose>1) printf("missing blood concentrations.\n");
175 /* Try to fix missing concentrations */
176 ret=tacFixNaNs(&blood);
177 if(ret!=0) {
178 fprintf(stderr, "Error: missing concentrations in %s.\n", bfile);
179 tacFree(&blood); tacFree(&plasma); return(2);
180 }
181 }
182 ret=tacNaNs(&plasma);
183 if(ret>0) {
184 if(verbose>1) printf("missing plasma concentrations.\n");
185 /* Try to fix missing concentrations */
186 ret=tacFixNaNs(&plasma);
187 if(ret!=0) {
188 fprintf(stderr, "Error: missing concentrations in %s.\n", pfile);
189 tacFree(&blood); tacFree(&plasma); return(2);
190 }
191 }
192
193 /* Convert units */
194 ret=tacXUnitConvert(&plasma, blood.tunit, &status);
195 if(ret!=TPCERROR_OK && verbose>0) {
196 fprintf(stderr, "Warning: different or unknown time units.\n");
197 }
198 ret=tacYUnitConvert(&plasma, blood.cunit, &status);
199 if(ret!=TPCERROR_OK && verbose>0) {
200 fprintf(stderr, "Warning: different or unknown concentration units.\n");
201 }
202
203 /* Check the sample nr */
204 if(plasma.sampleNr!=blood.sampleNr ||
205 plasma.x[plasma.sampleNr-1] != blood.x[blood.sampleNr-1])
206 {
207 fprintf(stderr, "Warning: different sample times.\n");
208 }
209
210 /* Interpolate plasma data to the same sample times as blood data */
211 ret=tacAllocateMore(&blood, 1);
212 if(!ret)
213 ret=liInterpolate(plasma.x, plasma.c[0].y, plasma.sampleNr,
214 blood.x, blood.c[1].y, NULL, NULL, blood.sampleNr,
215 4, 1, verbose-2);
216 if(ret) {
217 fprintf(stderr, "Error: cannot interpolate plasma TAC.\n");
218 tacFree(&blood); tacFree(&plasma); return(4);
219 }
220
221 /* Calculate RBC curve */
222 for(int i=0; i<blood.sampleNr; i++)
223 blood.c[0].y[i] = (blood.c[0].y[i] - (1.0-HCT)*blood.c[1].y[i]) / HCT;
224 tacFree(&plasma);
225
226 /*
227 * Save RBC TAC
228 */
229 if(verbose>1) printf("writing %s\n", rfile);
230 blood.tacNr=1; // just to be sure
231 FILE *fp; fp=fopen(rfile, "w");
232 if(fp==NULL) {
233 fprintf(stderr, "Error: cannot open file for writing (%s)\n", rfile);
234 tacFree(&blood); return(11);
235 }
236 ret=tacWrite(&blood, fp, TAC_FORMAT_UNKNOWN, 1, &status);
237 fclose(fp); tacFree(&blood);
238 if(ret!=TPCERROR_OK) {
239 fprintf(stderr, "Error (%d): %s\n", ret, errorMsg(status.error));
240 return(12);
241 }
242 if(verbose>=0) printf("RBC curve written in %s\n", rfile);
243
244 return(0);
245}
246/*****************************************************************************/
247
248/*****************************************************************************/
int atofCheck(const char *s, double *v)
Definition decpoint.c:94
int liInterpolate(double *x, double *y, const int nr, double *newx, double *newy, double *newyi, double *newyii, const int newnr, const int se, const int ee, const int verbose)
Linear interpolation and/or integration with trapezoidal method.
int tpcProcessStdOptions(const char *s, int *print_usage, int *print_version, int *verbose_level)
Definition proginfo.c:47
int tpcHtmlUsage(const char *program, char *text[], const char *path)
Definition proginfo.c:169
void tpcPrintBuild(const char *program, FILE *fp)
Definition proginfo.c:339
void tpcPrintUsage(const char *program, char *text[], FILE *fp)
Definition proginfo.c:114
void statusInit(TPCSTATUS *s)
Definition statusmsg.c:104
char * errorMsg(tpcerror e)
Definition statusmsg.c:68
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
double * y
Definition tpctac.h:75
Definition tpctac.h:87
double * x
Definition tpctac.h:97
unit cunit
Definition tpctac.h:105
tacformat format
Definition tpctac.h:93
int sampleNr
Definition tpctac.h:89
TACC * c
Definition tpctac.h:117
unit tunit
Definition tpctac.h:109
int tacNr
Definition tpctac.h:91
int verbose
Verbose level, used by statusPrint() etc.
tpcerror error
Error code.
void tacFree(TAC *tac)
Definition tac.c:106
void tacInit(TAC *tac)
Definition tac.c:24
int tacAllocateMore(TAC *tac, int tacNr)
Definition tac.c:178
int tacRead(TAC *d, const char *fname, TPCSTATUS *status)
Definition tacio.c:413
char * tacFormattxt(tacformat c)
Definition tacio.c:98
int tacWrite(TAC *tac, FILE *fp, tacformat format, int extra, TPCSTATUS *status)
Definition tacio.c:332
int tacNaNs(TAC *tac)
Definition tacnan.c:71
int tacFixNaNs(TAC *tac)
Definition tacnan.c:121
int tacSortByTime(TAC *d, TPCSTATUS *status)
Definition tacorder.c:74
int tacYUnitConvert(TAC *tac, const int u, TPCSTATUS *status)
Definition tacunits.c:72
int tacXUnitConvert(TAC *tac, const int u, TPCSTATUS *status)
Definition tacunits.c:23
Header file for library libtpcextensions.
@ TPCERROR_OK
No error.
char * unitName(int unit_code)
Definition units.c:143
Header file for library libtpcift.
Header file for libtpcli.
Header file for library libtpctac.
@ TAC_FORMAT_UNKNOWN
Unknown format.
Definition tpctac.h:28