9#include "tpcclibConfig.h"
28double *petmeas, *petsim, *weight;
29double pc=0.9464, Beta=0.91;
32double wss_wo_penalty=0.0;
36 CM_FLOW, CM_PTF, CM_VA, CM_RMBF, CM_WSS
40double mbfFunc(
int parNr,
double *p,
void*);
41double mbfFunc2(
int parNr,
double *p,
void*);
45static char *info[] = {
46 "Non-linear fitting of Iida's MBF model (1, 2) as represented in (3) to",
47 "regional dynamic PET [O-15]H2O study data.",
48 "The model parameters are myocardial blood flow in perfusable tissue (ptMBF),",
49 "perfusable tissue fraction (PTF), and arterial blood volume and spillover",
50 "(Va); in addition, mean blood flow in the myocardial region (rMBF), and",
51 "weighted sum-of-squares (WSS) are reported.",
53 "The same method is applied in Carimas, and for clinical work use of Carimas",
54 "is recommended; however, it is possible to save regional TACs in Carimas or",
55 "other software and use those with this program.",
57 "User must provide the regional TAC file (tacfile, in DFT or PMOD format),",
58 "and the names or numbers of LV cavity (lvcav) and whole myocardial (myoc)",
59 "TAC inside the TAC file, and filename for the results.",
60 "LV cavity and whole myocardial ROI TACs are used to estimate a spill-in",
61 "corrected arterial blood TAC, which is then used as model input for",
62 "the smaller myocardial regions; to omit this step and use the LV cavity TAC",
63 "directly as input, enter 'none' in place of the myocardial ROI name.",
65 "Usage: @P [Options] tacfile lvcav myoc resultfile",
69 " Specify the constraints for model parameters;",
70 " This file with default values can be created by giving this",
71 " option as the only command-line argument to this program.",
72 " Without filename the default values are printed on screen.",
73 " Parameter can be fixed to a certain value by setting its",
74 " lower and upper limit to that value.",
75 " -beta=<Beta value>",
76 " Enter the Beta value (from [O-15]CO study); by default 0.91.",
77 " -pH2O=<Partition coefficient for water>",
78 " Enter the partition coefficient of water; 0.9464 by default.",
79 " -end=<Fit end time (sec)>",
80 " By default line is fitted to the end of data. Use this option to enter",
83 " Standard deviations are calculated and saved in results (Y, default),",
84 " or not calculated (n).",
85 " Program runs a lot faster if SD and CL are not calculated.",
87 " 95% Confidence limits are calculated and saved in results (y), or",
88 " not calculated (N, default).",
90 " Save arterial concentration curves, estimated from LV cavity and whole",
91 " myocardial TACs, into specified TAC file.",
93 " Fitted regional TACs are written in DFT format.",
94 " Input TAC sample times are corrected by the median of fitted time",
95 " delay values and saved; resulting input file can be used with imgflow,",
96 " or as input to this program to have common time delay for all regions.",
98 " Fitted and measured TACs are plotted in specified SVG file.",
102 " @P -beta=0.91 s2345.tac 'lv Pl06' 'whole' s2345mbf.res",
105 "1. Iida H, Rhodes CG, de Silva R, Yamamoto Y, Araujo LI, Maseri A, Jones T.",
106 " Myocardial tissue fraction - correction for partial volume effects and",
107 " measure of tissue viability. J Nucl Med 1991; 32:2169-2175.",
108 "2. Iida H, Rhodes CG, de Silva R, Araujo LI, Bloomfield P, Lammertsma AA,",
109 " Jones T. Use of the left ventricular time-activity curve as a noninvasive",
110 " input function in dynamic oxygen-15-water positron emission tomography.",
111 " J Nucl Med 1992; 33:1669-1677.",
112 "3. Oikonen V. Model equations for myocardial perfusion studies with [15O]H2O",
113 " PET. https://www.turkupetcentre.net/reports/tpcmod0005.pdf",
115 "See also: sim_mbf, b2t_h2o, simimyoc, fit_h2o, tacweigh, rescoll",
117 "Keywords: TAC, modelling, myocardium, perfusion, radiowater, 1TCM",
136int main(
int argc,
char **argv)
138 int ai, help=0, version=0, verbose=1;
140 char tacfile[FILENAME_MAX], resfile[FILENAME_MAX],
141 fitfile[FILENAME_MAX], svgfile[FILENAME_MAX],
142 lvcavname[FILENAME_MAX], myocname[FILENAME_MAX],
143 limfile[FILENAME_MAX], inputfile[FILENAME_MAX];
144 int doBootstrap=0, doSD=0, doCL=0;
147 int ret, originallyMinutes=0;
152 def_pmin[0]=0.00; def_pmax[0]=10.0;
153 def_pmin[1]=0.05; def_pmax[1]=1.0;
154 def_pmin[2]=0.05; def_pmax[2]=0.99;
159 if(argc==1) {
tpcPrintUsage(argv[0], info, stderr);
return(1);}
160 tacfile[0]=resfile[0]=limfile[0]=inputfile[0]=(char)0;
161 svgfile[0]=fitfile[0]=lvcavname[0]=myocname[0]=(char)0;
163 for(ai=1; ai<argc; ai++)
if(*argv[ai]==
'-') {
164 char *cptr=argv[ai]+1;
if(*cptr==
'-') cptr++;
if(cptr==NULL)
continue;
166 if(strncasecmp(cptr,
"CL", 2)==0) {
167 if(strlen(cptr)==2) {doCL=1;
continue;}
168 cptr+=2;
if(*cptr==
'=') {
170 if(*cptr==
'Y' || *cptr==
'y') {doCL=1;
continue;}
171 if(*cptr==
'N' || *cptr==
'n') {doCL=0;
continue;}
173 }
else if(strncasecmp(cptr,
"SD", 2)==0) {
174 if(strlen(cptr)==2) {doSD=1;
continue;}
175 cptr+=2;
if(*cptr==
'=') {
177 if(*cptr==
'Y' || *cptr==
'y') {doSD=1;
continue;}
178 if(*cptr==
'N' || *cptr==
'n') {doSD=0;
continue;}
180 }
else if(strncasecmp(cptr,
"LIM=", 4)==0 && strlen(cptr)>4) {
181 strlcpy(limfile, cptr+4, FILENAME_MAX);
continue;
182 }
else if(strcasecmp(cptr,
"LIM")==0) {
183 strcpy(limfile,
"stdout");
continue;
184 }
else if(strncasecmp(cptr,
"BETA=", 5)==0 && strlen(cptr)>5) {
186 }
else if(strncasecmp(cptr,
"PH2O=", 5)==0) {
188 }
if(strncasecmp(cptr,
"INPUT=", 6)==0) {
189 strlcpy(inputfile, cptr+6, FILENAME_MAX);
190 if(strlen(inputfile)>0)
continue;
191 }
else if(strncasecmp(cptr,
"SVG=", 4)==0) {
192 strlcpy(svgfile, cptr+4, FILENAME_MAX);
193 if(strlen(svgfile)>0)
continue;
194 }
else if(strncasecmp(cptr,
"FIT=", 4)==0) {
195 strlcpy(fitfile, cptr+4, FILENAME_MAX);
196 if(strlen(fitfile)>0)
continue;
197 }
else if(strncasecmp(cptr,
"END=", 4)==0) {
200 fprintf(stderr,
"Error: invalid option '%s'.\n", argv[ai]);
205 if(help==2) {
tpcHtmlUsage(argv[0], info,
"");
return(0);}
210 if(ai<argc) {
strlcpy(tacfile, argv[ai++], FILENAME_MAX);}
211 if(ai<argc) {
strlcpy(lvcavname, argv[ai++], FILENAME_MAX);}
213 strlcpy(myocname, argv[ai++], FILENAME_MAX);
214 if(!strcasecmp(myocname,
"NONE") || !strcasecmp(myocname,
"'NONE'") ||
215 !strcasecmp(myocname,
"NO") || !strcasecmp(myocname,
"0"))
218 if(ai<argc) {
strlcpy(resfile, argv[ai++], FILENAME_MAX);}
221 fprintf(stderr,
"Error: too many arguments: '%s'.\n", argv[ai]);
224 if(doSD || doCL) doBootstrap=1;
else doBootstrap=0;
228 if(limfile[0] && !tacfile[0]) {
231 if(strcasecmp(limfile,
"stdout")!=0 && access(limfile, 0) != -1) {
232 fprintf(stderr,
"Error: parameter constraint file %s exists.\n", limfile);
235 if(verbose>1) printf(
"writing parameter constraints file\n");
237 iftPutDouble(&ift,
"ptMBF_lower", def_pmin[0], NULL, 0);
238 iftPutDouble(&ift,
"ptMBF_upper", def_pmax[0], NULL, 0);
244 fprintf(stderr,
"Error in writing '%s': %s\n", limfile, ift.
status);
247 if(strcasecmp(limfile,
"stdout")!=0)
248 fprintf(stdout,
"Parameter file %s with initial values written.\n", limfile);
254 printf(
"limfile := %s\n", limfile);
255 printf(
"tacfile := %s\n", tacfile);
256 printf(
"lvcavname := %s\n", lvcavname);
257 printf(
"myocname := %s\n", myocname);
258 printf(
"resfile := %s\n", resfile);
259 printf(
"fitfile := %s\n", fitfile);
260 printf(
"svgfile := %s\n", svgfile);
261 printf(
"inputfile := %s\n", inputfile);
262 printf(
"beta := %g\n", Beta);
263 printf(
"pH2O := %g\n", pc);
264 printf(
"doBootstrap := %d\n", doBootstrap);
265 printf(
"doSD := %d\n", doSD);
266 printf(
"doCL := %d\n", doCL);
267 if(fittime>0.0) printf(
"requested_fittime := %g\n", fittime);
273 fprintf(stderr,
"Error: missing command-line argument; use option --help\n");
285 if(verbose>1) printf(
"reading %s\n", limfile);
286 if(
iftRead(&ift, limfile, 1, 0)) {
287 fprintf(stderr,
"Error in reading '%s': %s\n", limfile, ift.
status);
290 if(verbose>10)
iftWrite(&ift,
"stdout", 0);
304 if(n==0) {fprintf(stderr,
"Error: invalid parameter file.\n");
return(9);}
310 for(pi=0; pi<parNr; pi++) {
311 if(def_pmin[pi]<0.0) ret++;
312 if(def_pmax[pi]<def_pmin[pi]) ret++;
313 if(def_pmax[pi]>def_pmin[pi]) fittedparNr++;
316 fprintf(stderr,
"Error: invalid parameter constraints.\n");
320 fprintf(stderr,
"Error: no model parameters left free for fitting.\n");
325 fflush(stdout); printf(
"Parameter constraints:\n");
326 for(
int pi=0; pi<parNr; pi++) {
327 printf(
"def_pmin[%d] := %g\n", pi+1, def_pmin[pi]);
328 printf(
"def_pmax[%d] := %g\n", pi+1, def_pmax[pi]);
330 printf(
"fittedParNr := %d\n", fittedparNr);
334 def_pmin[0]/=60.0; def_pmax[0]/=60.0;
340 if(verbose>1) printf(
"reading '%s'.\n", tacfile);
344 fprintf(stderr,
"Error in reading '%s': %s\n", tacfile,
dfterrmsg);
345 if(verbose>1) printf(
" ret :=%d\n", ret);
350 fprintf(stderr,
"Error: missing sample(s) in %s.\n", tacfile);
358 if(verbose>1) printf(
"Note: assuming that times are in seconds.\n");
361 if(verbose>1) printf(
"Note: assuming that times are in minutes.\n");
368 fprintf(stdout,
"common_data_weights := %g", dft.
w[0]);
369 for(
int i=1; i<dft.
frameNr; i++) fprintf(stdout,
", %g", dft.
w[i]);
370 fprintf(stdout,
"\n");
378 fprintf(stderr,
"Error: check the contents of datafile.\n");
384 fprintf(stderr,
"Error: file has overlapping frame times.\n");
390 double endtime=1.0E+90;
if(fittime>0.0) endtime=fittime/60.0;
393 &first, &last, verbose-1);
395 printf(
"frameNr := %d\n", dft.
frameNr);
396 printf(
"starttime := %g\n", starttime);
397 printf(
"endtime := %g\n", endtime);
398 printf(
"first := %d\n", first);
399 printf(
"last := %d\n", last);
400 printf(
"fitframeNr := %d\n", fitframeNr);
403 fittime=60.0*endtime;
406 fprintf(stderr,
"Error: check the contents of datafile.\n");
417 if(verbose>1) printf(
"searching for (whole) myocardium ROI.\n");
420 if(verbose>1) printf(
"nr of myoc regions := %d/%d\n", n, dft.
voiNr);
422 fprintf(stderr,
"Error: cannot find myoc region.\n");
426 fprintf(stderr,
"Error: all regions match myoc name.\n");
431 fprintf(stderr,
"Error: cannot select the best myoc region.\n");
439 if(verbose>1) printf(
"searching for LV cavity ROI.\n");
442 if(verbose>1) printf(
"nr of lvcav regions := %d/%d\n", n, dft.
voiNr);
444 fprintf(stderr,
"Error: cannot find lvcav region.\n");
448 fprintf(stderr,
"Error: all regions match lvcav name.\n");
453 fprintf(stderr,
"Error: cannot select the best lvcav region.\n");
460 fprintf(stderr,
"Error: cannot determine lvcav or myoc TAC.\n");
464 printf(
"selected lvcav region := %s\n", dft.
voi[lvroi].
name);
465 if(wmroi>=0) printf(
"selected myoc region := %s\n", dft.
voi[wmroi].
name);
472 fprintf(stderr,
"Error: cannot allocate more memory.\n");
477 strcpy(dft.
voi[bs_index].
name,
"BS");
485 if(verbose>1) printf(
"initializing result data\n");
488 fprintf(stderr,
"Error: cannot setup memory for results.\n");
497 res.
beta=Beta; res.
Vb=-1.0;
500 sprintf(res.
datarange,
"%g - %g min", starttime, endtime);
511 pi=0; strcpy(res.
parname[pi],
"ptMBF");
512 strcpy(res.
parunit[pi],
"mL/(min*mL)");
513 pi++; strcpy(res.
parname[pi],
"PTF"); strcpy(res.
parunit[pi],
"mL/mL");
514 pi++; strcpy(res.
parname[pi],
"Va");
515 strcpy(res.
parunit[pi],
"mL/mL");
516 pi++; strcpy(res.
parname[pi],
"rMBF");
517 strcpy(res.
parunit[pi],
"mL/(min*mL)");
518 pi++; strcpy(res.
parname[pi],
"WSS"); strcpy(res.
parunit[pi],
"");
527 fprintf(stderr,
"Error: cannot allocate memory for input TAC.\n");
533 for(
int i=0; i<input.
frameNr; i++) {
534 input.
x[i]=dft.
x[i]; input.
x1[i]=dft.
x1[i]; input.
x2[i]=dft.
x2[i];
543 fprintf(stderr,
"Error: cannot allocate memory for fitted curves.\n");
544 if(verbose>1) printf(
" ret :=%d\n", ret);
554 for(
int i=0; i<input.
frameNr; i++) {
555 input.
voi[0].
y[i]=dft.
voi[lvroi].
y[i];
558 if(verbose>1) printf(
"Note: using LV cavity directly as the input.\n");
560 if(verbose>1) printf(
"starting myoc fitting\n");
561 int tgoNr, neighNr, iterNr;
562 double *sd, *cl1, *cl2;
566 for(
int pi=0; pi<parNr; pi++) {
567 pmin[pi]=def_pmin[pi]; pmax[pi]=def_pmax[pi];
571 petmeas=dft.
voi[wmroi].
y; petsim=fit.
voi[wmroi].
y;
575 if(verbose>2) printf(
" fitting\n");
582 pmin, pmax, mbfFunc, NULL, parNr, neighNr,
586 fprintf(stderr,
"\nError in optimization (%d).\n", ret);
598 printf(
" Measured Fitted Weight:\n");
599 for(
int fi=0; fi<fitframeNr; fi++)
600 printf(
" %2d %8.2e %8.2e %8.2e\n", fi+1, petmeas[fi], petsim[fi],
606 if(verbose>1) printf(
" bootstrapping\n");
610 petmeas=dft.
voi[bs_index].
y;
611 petsim=dft.
voi[bs_index].
y2;
613 if(doSD) sd=res.
voi[wmroi].
sd;
else sd=NULL;
614 if(doCL) {cl1=res.
voi[wmroi].
cl1; cl2=res.
voi[wmroi].
cl2;}
else cl1=cl2=NULL;
616 fitframeNr, dft.
voi[wmroi].
y, fit.
voi[wmroi].
y, petmeas,
617 parNr, dft.
w, mbfFunc, buf, verbose-6);
619 fprintf(stderr,
"\nError in bootstrap: %s\n", buf);
620 for(
int pi=0; pi<parNr; pi++) {
621 if(doSD) sd[pi]=nan(
"");
622 if(doCL) cl1[pi]=cl2[pi]=nan(
"");
626 petmeas=dft.
voi[wmroi].
y; petsim=fit.
voi[wmroi].
y;
636 for(
int fi=0; fi<dft.
frameNr; fi++) {
643 ((1.0-Beta)*petsim[fi]-alpha*dft.
voi[lvroi].
y[fi])
644 / (Va*(1.0-Beta)-alpha*Beta);
656 for(
int ri=0; ri<dft.
voiNr; ri++) {
659 if(ri==lvroi)
continue;
661 if(ri==wmroi)
continue;
663 if(verbose>1) printf(
"starting %s fitting\n", dft.
voi[ri].
name);
664 int tgoNr, neighNr, iterNr;
665 double *sd, *cl1, *cl2;
669 for(
int pi=0; pi<parNr; pi++) {
670 pmin[pi]=def_pmin[pi]; pmax[pi]=def_pmax[pi];
674 petmeas=dft.
voi[ri].
y; petsim=fit.
voi[ri].
y;
678 if(verbose>2) printf(
" fitting\n");
685 pmin, pmax, mbfFunc2, NULL, parNr, neighNr,
689 fprintf(stderr,
"\nError in optimization (%d).\n", ret);
701 printf(
" Measured Fitted Weight:\n");
702 for(
int fi=0; fi<fitframeNr; fi++)
703 printf(
" %2d %8.2e %8.2e %8.2e\n", fi+1, petmeas[fi], petsim[fi],
709 if(verbose>1) printf(
" bootstrapping\n");
713 petmeas=dft.
voi[bs_index].
y;
714 petsim=dft.
voi[bs_index].
y2;
716 if(doSD) sd=res.
voi[ri].
sd;
else sd=NULL;
717 if(doCL) {cl1=res.
voi[ri].
cl1; cl2=res.
voi[ri].
cl2;}
else cl1=cl2=NULL;
719 fitframeNr, dft.
voi[ri].
y, fit.
voi[ri].
y, petmeas,
720 parNr, dft.
w, mbfFunc2, buf, verbose-6);
722 fprintf(stderr,
"\nError in bootstrap: %s\n", buf);
723 for(
int pi=0; pi<parNr; pi++) {
724 if(doSD) sd[pi]=nan(
"");
725 if(doCL) cl1[pi]=cl2[pi]=nan(
"");
729 petmeas=dft.
voi[ri].
y; petsim=fit.
voi[ri].
y;
741 for(
int ri=0; ri<res.
voiNr; ri++) {
743 res.
voi[ri].
sd[0]*=60.;
748 for(
int ri=0; ri<res.
voiNr; ri++) {
757 if(verbose>0) {
resPrint(&res); fprintf(stdout,
"\n");}
763 if(verbose>1) printf(
"saving results\n");
764 if(
resWrite(&res, resfile, verbose-3)!=0) {
765 fprintf(stderr,
"Error in writing '%s': %s\n", resfile,
reserrmsg);
769 if(verbose>1) fprintf(stdout,
"Model parameters written in %s\n", resfile);
776 if(originallyMinutes) {
784 if(svgfile[0] || fitfile[0]) {
788 if(verbose>1) printf(
"saving fitted curves\n");
790 fprintf(stderr,
"Error in writing '%s': %s\n", fitfile,
dfterrmsg);
791 }
else if(verbose>0) printf(
"fitted TACs written in %s\n", fitfile);
796 if(verbose>1) printf(
"saving SVG plot\n");
798 sprintf(tmp,
"MBF fit ");
801 0.0, nan(
""), svgfile, verbose-8);
803 fprintf(stderr,
"Error (%d) in writing '%s'.\n", ret, svgfile);
804 }
else if(verbose>0) printf(
"plots written in %s\n", svgfile);
814 if(verbose>1) printf(
"saving arterial blood data in %s\n", inputfile);
816 fprintf(stderr,
"Error in writing %s: %s\n", inputfile,
dfterrmsg);
820 if(verbose>0) printf(
"Estimated arterial blood TAC saved in %s\n", inputfile);
836double mbfFunc(
int parNr,
double *p,
void *fdata)
839 double wss=0.0, d, K1, k2, Vfit, flow, Va, alpha;
847 flow=pa[0]; alpha=pa[1]; Va=pa[2];
848 K1=(flow/Beta)*(alpha+Va/pc);
849 k2=flow*(1.0/pc+(1.0-Beta)/Beta);
855 fprintf(stderr,
"error %d in simulation\n", ret);
859 for(fi=0; fi<fitframeNr; fi++)
if(weight[fi]>0.0) {
860 d=petmeas[fi]-petsim[fi]; wss+=weight[fi]*d*d;
868double mbfFunc2(
int parNr,
double *p,
void *fdata)
871 double wss=0.0, d, K1, k2, Vfit, flow, Va, alpha;
879 flow=pa[0]; alpha=pa[1]; Va=pa[2];
880 K1=flow*(alpha+Va/pc);
887 fprintf(stderr,
"error %d in simulation\n", ret);
891 for(fi=0; fi<fitframeNr; fi++)
if(weight[fi]>0.0) {
892 d=petmeas[fi]-petsim[fi]; wss+=weight[fi]*d*d;
int bootstrap(int iterNr, double *cLim1, double *cLim2, double *SD, double *parameter, double *lowlim, double *uplim, int frameNr, double *origTac, double *fitTac, double *bsTac, int parNr, double *weight, double(*objf)(int, double *, void *), char *status, int verbose)
int modelCheckParameters(int par_nr, double *lower_p, double *upper_p, double *test_p, double *accept_p, double *penalty)
int atof_with_check(char *double_as_string, double *result_value)
int dftCopyvoihdr(DFT *dft1, int from, DFT *dft2, int to)
int dftdup(DFT *dft1, DFT *dft2)
int dftDeleteFrameOverlap(DFT *dft)
int dftAddmem(DFT *dft, int voiNr)
int dftSortByFrame(DFT *dft)
int dftSelectBestReference(DFT *dft)
int dftValidNr(DFT *dft, double tstart, double tstop, int index)
int dftSetmem(DFT *data, int frameNr, int voiNr)
int dft_nr_of_NA(DFT *dft)
int dftSelectRegions(DFT *dft, char *region_name, int reset)
int dftCopymainhdr(DFT *dft1, DFT *dft2)
int dftRead(char *filename, DFT *data)
int dftWrite(DFT *data, char *filename)
int res_allocate_with_dft(RES *res, DFT *dft)
void dftSec2min(DFT *dft)
void dftMin2sec(DFT *dft)
int fittime_from_dft(DFT *dft, double *startTime, double *endTime, int *first, int *last, int verbose)
int iftPutDouble(IFT *ift, char *key, double value, char *cmt_type, int verbose)
int iftRead(IFT *ift, char *filename, int is_key_required, int verbose)
int iftWrite(IFT *ift, char *filename, int verbose)
int iftGetDoubleValue(IFT *ift, int si, const char *key, double *value, int verbose)
Header file for libtpccurveio.
int resWrite(RES *res, char *filename, int verbose)
int resDelete(RES *res, int voi)
#define DFT_TIME_STARTEND
Header file for libtpcmisc.
int tpcProcessStdOptions(const char *s, int *print_usage, int *print_version, int *verbose_level)
size_t strlcpy(char *dst, const char *src, size_t dstsize)
void tpcProgramName(const char *program, int version, int copyright, char *prname, int n)
int tpcHtmlUsage(const char *program, char *text[], const char *path)
size_t strlcat(char *dst, const char *src, size_t dstsize)
void tpcPrintBuild(const char *program, FILE *fp)
void tpcPrintUsage(const char *program, char *text[], FILE *fp)
Header file for libtpcmodel.
int tgo(double *lowlim, double *uplim, double(*objf)(int, double *, void *), void *objfData, int dim, int neighNr, double *fmin, double *gmin, int samNr, int tgoNr, int verbose)
int simMBF(double *t, double *ci, int nr, double k1, double k2, double Vfit, double *ct)
Header file for libtpcmodext.
int plot_fitrange_svg(DFT *dft1, DFT *dft2, char *main_title, double x1, double x2, double y1, double y2, char *fname, int verbose)
Header file for libtpcsvg.
char studynr[MAX_STUDYNR_LEN+1]
char parname[MAX_RESPARAMS][MAX_RESPARNAME_LEN+1]
char datafile[FILENAME_MAX]
char parunit[MAX_RESPARAMS][MAX_RESPARNAME_LEN+1]
double parameter[MAX_RESPARAMS]
double cl2[MAX_RESPARAMS]
double cl1[MAX_RESPARAMS]
char voiname[MAX_REGIONSUBNAME_LEN+1]
char name[MAX_REGIONNAME_LEN+1]