TPCCLIB
Loading...
Searching...
No Matches
llsqe3.c
Go to the documentation of this file.
1
10/*****************************************************************************/
11#include "tpcclibConfig.h"
12/*****************************************************************************/
13#include <stdio.h>
14#include <stdlib.h>
15#include <string.h>
16#include <math.h>
17/*****************************************************************************/
18#include "tpcextensions.h"
19#include "tpcift.h"
20#include "tpctac.h"
21#include "tpcpar.h"
22#include "tpcli.h"
23#include "tpctacmod.h"
24#include "tpclinopt.h"
25/*****************************************************************************/
26
27/*****************************************************************************/
28static char *info[] = {
29 "Linear fitting of sum of three exponentials function",
30 " f(x) = p1*exp(p2*x) + p3*exp(p4*x) + p5*exp(p6*x) + p7*exp(p8*x)",
31 ", where p8=0, to time-activity curves.",
32 " ",
33 "Usage: @P [options] TAC results",
34 " ",
35 "Options:",
36 " -svg=<Filename>",
37 " Fitted and measured TACs are plotted in specified SVG file.",
38 " -fit=<Filename>",
39 " Fitted regional TTACs are written in specified file.",
40 " -lp=<Filename>",
41 " Parameters of initial linear model are saved in specified file.",
42 " -stdoptions", // List standard options like --help, -v, etc
43 " ",
44 "See also: fit_exp, fit_dexp",
45 " ",
46 "Keywords: TAC, modelling, compartmental model, LLSQ",
47 0};
48/*****************************************************************************/
49
50/*****************************************************************************/
51/* Turn on the globbing of the command line, since it is disabled by default in
52 mingw-w64 (_dowildcard=0); in MinGW32 define _CRT_glob instead, if necessary;
53 In Unix&Linux wildcard command line processing is enabled by default. */
54/*
55#undef _CRT_glob
56#define _CRT_glob -1
57*/
58int _dowildcard = -1;
59/*****************************************************************************/
60
61/*****************************************************************************/
62#define MAX_LLSQ_N 7
63/*****************************************************************************/
64
65/*****************************************************************************/
69int main(int argc, char **argv)
70{
71 int ai, help=0, version=0, verbose=1;
72 char tacfile[FILENAME_MAX], resfile[FILENAME_MAX],
73 fitfile[FILENAME_MAX], svgfile[FILENAME_MAX], lpfile[FILENAME_MAX];
74 int weights=WEIGHTING_UNKNOWN; // 0=default, 1=no weighting, 2=frequency
75 int ret;
76
77 /*
78 * Get arguments
79 */
80 if(argc==1) {tpcPrintUsage(argv[0], info, stderr); return(1);}
81 tacfile[0]=resfile[0]=fitfile[0]=svgfile[0]=lpfile[0]=(char)0;
82 /* Options */
83 for(ai=1; ai<argc; ai++) if(*argv[ai]=='-') {
84 if(tpcProcessStdOptions(argv[ai], &help, &version, &verbose)==0) continue;
85 char *cptr=argv[ai]+1; if(*cptr=='-') cptr++; if(!*cptr) continue;
86 if(strncasecmp(cptr, "SVG=", 4)==0) {
87 strlcpy(svgfile, cptr+4, FILENAME_MAX); if(strlen(svgfile)>0) continue;
88 } else if(strncasecmp(cptr, "FIT=", 4)==0) {
89 strlcpy(fitfile, cptr+4, FILENAME_MAX); if(strlen(fitfile)>0) continue;
90 } else if(strncasecmp(cptr, "LP=", 3)==0) {
91 strlcpy(lpfile, cptr+3, FILENAME_MAX); if(strlen(lpfile)>0) continue;
92 } else if(strcasecmp(cptr, "W1")==0) {
93 weights=WEIGHTING_OFF; continue;
94 } else if(strcasecmp(cptr, "WF")==0) {
95 weights=WEIGHTING_ON_FD; continue;
96 }
97 fprintf(stderr, "Error: invalid option '%s'.\n", argv[ai]);
98 return(1);
99 } else break;
100
101 TPCSTATUS status; statusInit(&status);
102 statusSet(&status, __func__, __FILE__, __LINE__, TPCERROR_OK);
103 status.verbose=verbose-3;
104
105 /* Print help or version? */
106 if(help==2) {tpcHtmlUsage(argv[0], info, ""); return(0);}
107 if(help) {tpcPrintUsage(argv[0], info, stdout); return(0);}
108 if(version) {tpcPrintBuild(argv[0], stdout); return(0);}
109
110 /* Process other arguments, starting from the first non-option */
111 if(ai<argc) strlcpy(tacfile, argv[ai++], FILENAME_MAX);
112 if(ai<argc) strlcpy(resfile, argv[ai++], FILENAME_MAX);
113 if(ai<argc) {
114 fprintf(stderr, "Error: invalid argument '%s'.\n", argv[ai]);
115 return(1);
116 }
117 /* Did we get all the information that we need? */
118 if(!resfile[0]) {
119 fprintf(stderr, "Error: missing command-line argument; use option --help\n");
120 return(1);
121 }
122
123
124 /* In verbose mode print arguments and options */
125 if(verbose>1) {
126 printf("tacfile := %s\n", tacfile);
127 printf("resfile := %s\n", resfile);
128 printf("fitfile := %s\n", fitfile);
129 printf("svgfile := %s\n", svgfile);
130 printf("lpfile := %s\n", lpfile);
131 printf("weights := %d\n", weights);
132 }
133
134
135
136 /*
137 * Read TAC data
138 */
139 if(verbose>1) printf("reading TAC data\n");
140 statusSet(&status, __func__, __FILE__, __LINE__, TPCERROR_OK);
141 TAC tac0; tacInit(&tac0);
142 ret=tacRead(&tac0, tacfile, &status);
143 if(ret!=TPCERROR_OK) {
144 fprintf(stderr, "Error: %s\n", errorMsg(status.error));
145 tacFree(&tac0); return(2);
146 }
147 if(verbose>2) {
148 printf("fileformat := %s\n", tacFormattxt(tac0.format));
149 printf("tacNr := %d\n", tac0.tacNr);
150 printf("sampleNr := %d\n", tac0.sampleNr);
151 printf("xunit := %s\n", unitName(tac0.tunit));
152 printf("yunit := %s\n", unitName(tac0.cunit));
153 }
154 if(tac0.sampleNr<=MAX_LLSQ_N) {
155 fprintf(stderr, "Error: too few samples for fitting.\n");
156 tacFree(&tac0); return(2);
157 }
158
159 /* Add data weights, if requested */
160 if(weights!=WEIGHTING_UNKNOWN) tacSetWeights(&tac0, weights, tac0.sampleNr, NULL);
161
162 /* Integrate TACs */
163 if(verbose>1) printf("integrating TACs\n");
164 TAC tac1; tacInit(&tac1); // 1st integral
165 TAC tac2; tacInit(&tac2); // 2nd integral
166 TAC tac3; tacInit(&tac3); // 3rd integral
167 ret=tacInterpolate(&tac0, &tac0, NULL, &tac1, &tac2, &status);
168 if(ret!=TPCERROR_OK) {
169 fprintf(stderr, "Error: %s\n", errorMsg(status.error));
170 tacFree(&tac0); tacFree(&tac1); tacFree(&tac2); tacFree(&tac3);
171 }
172 ret=tacDuplicate(&tac2, &tac3);
173 if(ret==TPCERROR_OK) {
174 for(int i=0; i<tac2.tacNr; i++) {
175 ret=liIntegrate(tac2.x, tac2.c[i].y, tac2.sampleNr, tac3.c[i].y, 3, 0);
176 if(ret!=TPCERROR_OK) break;
177 }
178 }
179 if(ret!=TPCERROR_OK) {
180 fprintf(stderr, "Error: cannot make 3rd integral of TAC.\n");
181 tacFree(&tac0); tacFree(&tac1); tacFree(&tac2); tacFree(&tac3);
182 return(3);
183 }
184
185
186 /*
187 * Prepare the room for LLSQ parameters
188 */
189 if(verbose>1) printf("initializing LLSQ parameter data\n");
190 PAR lp; parInit(&lp);
191 ret=parAllocateWithTAC(&lp, &tac0, MAX_LLSQ_N, &status);
192 if(ret!=TPCERROR_OK) {
193 fprintf(stderr, "Error: %s\n", errorMsg(status.error));
194 tacFree(&tac0); tacFree(&tac1); tacFree(&tac2); tacFree(&tac3);
195 return(4);
196 }
197 iftFree(&lp.h);
198 /* Copy titles & file names */
199 lp.parNr=MAX_LLSQ_N;
200 {
201 int i;
202 char buf[256];
203 time_t t=time(NULL);
204 /* set program name */
205 tpcProgramName(argv[0], 1, 1, buf, 256);
206 iftPut(&lp.h, "program", buf, 0, NULL);
207 /* set file names */
208 iftPut(&lp.h, "tacfile", tacfile, 0, NULL);
209 /* Set current time to results */
210 iftPut(&lp.h, "analysis_time", ctime_r_int(&t, buf), 0, NULL);
211 /* Set fit times for each TAC */
212 for(i=0; i<lp.tacNr; i++) {
213 lp.r[i].dataNr=tac0.sampleNr;
214 /* and nr of fitted parameters */
215 lp.r[i].fitNr=MAX_LLSQ_N;
216 }
217 /* Set the parameter names and units */
218 for(i=0; i<MAX_LLSQ_N; i++) {
219 sprintf(lp.n[i].name, "P%d", 1+i);
220 }
221 }
222
223
224 /*
225 * Allocate memory required by linear LSQ
226 */
227 if(verbose>1) printf("allocating memory for LLSQ\n");
228 int llsq_n=MAX_LLSQ_N;
229 int llsq_m=tac0.sampleNr;
230 double *llsq_mat=(double*)malloc((2*llsq_n*llsq_m)*sizeof(double));
231 if(llsq_mat==NULL) {
232 fprintf(stderr, "Error: cannot allocate memory.\n");
233 tacFree(&tac0); tacFree(&tac1); tacFree(&tac2); tacFree(&tac3);
234 parFree(&lp);
235 return(5);
236 }
237 double **llsq_a=(double**)malloc(llsq_m*sizeof(double*));
238 if(llsq_a==NULL) {
239 fprintf(stderr, "Error: cannot allocate memory.\n");
240 tacFree(&tac0); tacFree(&tac1); tacFree(&tac2); tacFree(&tac3);
241 parFree(&lp);
242 return(5);
243 }
244 for(int mi=0; mi<llsq_m; mi++) llsq_a[mi]=llsq_mat+mi*llsq_n;
245 double r2, llsq_b[llsq_m], llsq_r[llsq_n];
246 double *matbackup=llsq_mat+llsq_n*llsq_m;
247
248 /*
249 * Fit each regional TAC
250 */
251 int okNr=0;
252 for(int ti=0; ti<tac0.tacNr; ti++) {
253
254 if(verbose>1 && tac0.tacNr>1) {
255 printf("TAC %d %s\n", 1+ti, tac0.c[ti].name); fflush(stdout);}
256
257 /* Setup data matrix A and vector B */
258 for(int mi=0; mi<llsq_m; mi++)
259 llsq_b[mi]=tac0.c[ti].y[mi];
260 for(int mi=0; mi<llsq_m; mi++) {
261 llsq_a[mi][0]=tac3.c[ti].y[mi]; // TAC 3rd integral
262 llsq_a[mi][1]=tac2.c[ti].y[mi]; // TAC 2nd integral
263 llsq_a[mi][2]=tac1.c[ti].y[mi]; // TAC 1st integral
264 llsq_a[mi][3]=tac0.x[mi]*tac0.x[mi]*tac0.x[mi]; // x^3
265 llsq_a[mi][4]=tac0.x[mi]*tac0.x[mi]; // x^2
266 llsq_a[mi][5]=tac0.x[mi]; // x
267 llsq_a[mi][6]=1.0; // Scale
268 }
269 if(verbose>5) {
270 printf("Matrix A and vector B:\n");
271 for(int mi=0; mi<llsq_m; mi++) {
272 printf("%.2e", llsq_a[0][mi]);
273 for(int ni=1; ni<llsq_n; ni++) printf(", %.2e", llsq_a[ni][mi]);
274 printf("; %.3e\n", llsq_b[mi]);
275 }
276 }
277 /* Make a copy of A matrix for later use */
278 for(int i=0; i<llsq_n*llsq_m; i++) matbackup[i]=llsq_mat[i];
279
280 /* Apply data weights */
281 if(tacIsWeighted(&tac0)) qrWeight(llsq_n, llsq_m, llsq_a, llsq_b, tac0.w, NULL);
282
283 if(verbose>5) {
284 printf("\nA matrix and B vector\n");
285 for(int mi=0; mi<llsq_m; mi++) {
286 for(int ni=0; ni<llsq_n; ni++) printf("\t%g", llsq_a[mi][ni]);
287 printf("\t\t%g\n", llsq_b[mi]);
288 }
289 printf("\n");
290 }
291
292 /* Compute QR */
293 if(verbose>5) printf("starting QR...\n");
294 ret=qrLSQ(llsq_a, llsq_b, llsq_r, llsq_m, llsq_n, &r2);
295 if(verbose>5) printf(" ... done.\n");
296 if(ret==0) {
297 for(int ni=0; ni<llsq_n; ni++) lp.r[ti].p[ni]=llsq_r[ni];
298 lp.r[ti].wss=r2;
299 okNr++;
300 } else {
301 fprintf(stderr, "Warning: no solution for TAC %d %s\n", 1+ti, tac0.c[ti].name);
302 for(int ni=0; ni<llsq_n; ni++) lp.r[ti].p[ni]=0.0;
303 lp.r[ti].wss=0.0;
304 }
305 lp.r[ti].dataNr=tacWSampleNr(&tac0);
306 lp.r[ti].fitNr=llsq_n;
307
308 /* Compute fitted TAC (into ttac1 since it is otherwise not needed) */
309 for(int mi=0; mi<llsq_m; mi++) {
310 tac1.c[ti].y[mi]=0.0;
311 for(int ni=0; ni<llsq_n; ni++) tac1.c[ti].y[mi]+=llsq_r[ni]*llsq_a[mi][ni];
312 }
313
314 } // next TAC
315
316 /* Free allocated memory */
317 free(llsq_a); free(llsq_mat);
318
319 if(okNr==0) {
320 fprintf(stderr, "Error: no solution found for any of the TACs.\n");
321 return(10);
322 }
323
324 /*
325 * Print original LLSQ parameters on screen
326 */
327 if(verbose>1 && lp.tacNr<50)
328 parWrite(&lp, stdout, PAR_FORMAT_TSV_UK /*PAR_FORMAT_RES*/, 0, &status);
329
330
331 /*
332 * Save original LLSQ results, if requested
333 */
334 if(lpfile[0]) {
335 if(verbose>1) printf("writing %s\n", lpfile);
337 if(verbose>2) printf("result file format := %s\n", parFormattxt(lp.format));
339 FILE *fp; fp=fopen(lpfile, "w");
340 if(fp==NULL) {
341 fprintf(stderr, "Error: cannot open file for writing parameter file.\n");
342 ret=TPCERROR_FAIL;
343 } else {
344 ret=parWrite(&lp, fp, PAR_FORMAT_UNKNOWN, 1, &status);
345 fclose(fp);
346 if(ret!=TPCERROR_OK) fprintf(stderr, "Error: %s\n", errorMsg(status.error));
347 }
348 if(ret!=TPCERROR_OK) {
349 tacFree(&tac0); tacFree(&tac1); tacFree(&tac2); tacFree(&tac3);
350 parFree(&lp);
351 return(11);
352 }
353 if(verbose>0) printf("Results saved in %s.\n", lpfile);
354 }
355
356
357 /*
358 * Prepare the room for exponential function parameters
359 */
360 if(verbose>1) printf("initializing exponential parameter data\n");
361 PAR par; parInit(&par);
362 ret=parAllocateWithTAC(&par, &tac0, 8, &status);
363 if(ret!=TPCERROR_OK) {
364 fprintf(stderr, "Error: %s\n", errorMsg(status.error));
365 tacFree(&tac0); tacFree(&tac1); tacFree(&tac2); tacFree(&tac3);
366 parFree(&lp);
367 return(4);
368 }
369 iftFree(&par.h);
370 /* Copy titles & file names */
371 par.parNr=8;
372 {
373 int i;
374 char buf[256];
375 time_t t=time(NULL);
376 /* set program name */
377 tpcProgramName(argv[0], 1, 1, buf, 256);
378 iftPut(&par.h, "program", buf, 0, NULL);
379 /* set file names */
380 iftPut(&par.h, "tacfile", tacfile, 0, NULL);
381 /* Set current time to results */
382 iftPut(&par.h, "analysis_time", ctime_r_int(&t, buf), 0, NULL);
383 /* Descriptions for each TAC */
384 for(i=0; i<par.tacNr; i++) {
385 par.r[i].dataNr=tacWSampleNr(&tac0);
386 par.r[i].fitNr=7;
387 par.r[i].start=tac0.x[0];
388 par.r[i].end=tac0.x[tac0.sampleNr-1];
389 par.r[i].model=MF_EXP4;
390 }
391 /* Set the parameter names and units */
392 for(i=0; i<par.parNr; i++) {
393 sprintf(par.n[i].name, "P%d", 1+i);
394 }
395 for(int i=0; i<par.parNr; i+=2) {
396 par.n[i].unit=tac0.cunit;
397 par.n[i+1].unit=unitInverse(tac0.tunit);
398 }
399 }
400
401
402 /*
403 * Solve exponential function parameters from parameters of linear regression
404 */
405 okNr=0;
406 for(int ti=0; ti<tac0.tacNr; ti++) {
407
408 if(verbose>1 && tac0.tacNr>1) {
409 printf("TAC %d %s\n", 1+ti, tac0.c[ti].name); fflush(stdout);}
410
411 for(int i=0; i<par.parNr; i++) par.r[ti].p[i]=0.0;
412 par.r[ti].wss=0.0;
413
414 /* Calculate the exponential rate constants as the real solutions of cubic equation */
415 double A=-lp.r[ti].p[2];
416 double B=-lp.r[ti].p[1];
417 double C=-lp.r[ti].p[0];
418 double x1, x2, x3;
419 int roots=rootsCubic(A, B, C, &x1, &x2, &x3);
420 if(roots==0) {
421 fprintf(stderr, "Warning: no solution for TAC %d %s\n", 1+ti, tac0.c[ti].name);
422 continue;
423 }
424 if(verbose>2) {
425 printf(" %d roots: %g", roots, x1);
426 if(roots>1) printf(" %g", x2);
427 if(roots>2) printf(" %g", x3);
428 printf("\n");
429 }
430 /* Write into results */
431 par.r[ti].p[3]=x1;
432 if(roots>1) par.r[ti].p[5]=x2;
433 if(roots>2) par.r[ti].p[7]=x3;
434
435 /* Solve the amplitudes with linear regression */
436 llsq_m=tac0.sampleNr;
437 llsq_n=1+roots;
438 llsq_mat=(double*)malloc((llsq_n*llsq_m)*sizeof(double));
439 llsq_a=(double**)malloc(llsq_m*sizeof(double*));
440 for(int mi=0; mi<llsq_m; mi++) llsq_a[mi]=llsq_mat+mi*llsq_n;
441
442 /* Setup data matrix A and vector B */
443 /* Must be done separately for each TAC because parameter number may vary */
444 for(int mi=0; mi<llsq_m; mi++)
445 llsq_b[mi]=tac0.c[ti].y[mi];
446 for(int mi=0; mi<llsq_m; mi++)
447 llsq_a[mi][0]=1.0; // Scale
448 for(int mi=0; mi<llsq_m; mi++)
449 llsq_a[mi][1]=exp(x1*tac0.x[mi]); // 1st exponential
450 if(llsq_n>2) for(int mi=0; mi<llsq_m; mi++)
451 llsq_a[mi][2]=exp(x2*tac0.x[mi]); // 2nd exponential
452 if(llsq_n>3) for(int mi=0; mi<llsq_m; mi++)
453 llsq_a[mi][3]=exp(x3*tac0.x[mi]); // 3rd exponential
454
455 /* Apply data weights */
456 if(tacIsWeighted(&tac0)) qrWeight(llsq_n, llsq_m, llsq_a, llsq_b, tac0.w, NULL);
457
458 if(verbose>5) {
459 printf("\nA matrix and B vector\n");
460 for(int mi=0; mi<llsq_m; mi++) {
461 for(int ni=0; ni<llsq_n; ni++) printf("\t%g", llsq_a[mi][ni]);
462 printf("\t\t%g\n", llsq_b[mi]);
463 }
464 printf("\n");
465 }
466
467 /* Compute QR */
468 if(verbose>5) printf("starting QR...\n");
469 ret=qrLSQ(llsq_a, llsq_b, llsq_r, llsq_m, llsq_n, &r2);
470 if(verbose>5) printf(" ... done.\n");
471 if(ret!=0) {
472 fprintf(stderr, "Warning: no solution for TAC %d %s\n", 1+ti, tac0.c[ti].name);
473 continue;
474 }
475 if(verbose>2) {
476 printf(" amplitudes: %g %g", llsq_r[0], llsq_r[1]);
477 if(llsq_n>2) printf(" %g", llsq_r[2]);
478 if(llsq_n>3) printf(" %g", llsq_r[3]);
479 printf("\n");
480 }
481 /* Write into results */
482 par.r[ti].p[0]=llsq_r[0];
483 par.r[ti].p[2]=llsq_r[1];
484 if(llsq_n>2) par.r[ti].p[4]=llsq_r[2];
485 if(llsq_n>3) par.r[ti].p[6]=llsq_r[3];
486
487 okNr++;
488 /* Free allocated memory */
489 free(llsq_a); free(llsq_mat);
490 }
491 if(okNr==0) {
492 fprintf(stderr, "Error: no solution found for any of the TACs.\n");
493 tacFree(&tac0); tacFree(&tac2); tacFree(&tac2); tacFree(&tac3);
494 parFree(&lp); parFree(&par);
495 return(10);
496 }
497
498
499 /*
500 * Print exponential function parameters
501 */
502 if(verbose>0 && par.tacNr<80)
503 parWrite(&par, stdout, PAR_FORMAT_TSV_UK, 0, &status);
504
505 /*
506 * Save exponential function parameters
507 */
508 {
509 if(verbose>1) printf("writing %s\n", resfile);
510 par.format=parFormatFromExtension(resfile);
511 if(verbose>2) printf("result file format := %s\n", parFormattxt(par.format));
513 FILE *fp; fp=fopen(resfile, "w");
514 if(fp==NULL) {
515 fprintf(stderr, "Error: cannot open file for writing parameter file.\n");
516 ret=TPCERROR_FAIL;
517 } else {
518 ret=parWrite(&par, fp, PAR_FORMAT_UNKNOWN, 1, &status);
519 fclose(fp);
520 if(ret!=TPCERROR_OK) fprintf(stderr, "Error: %s\n", errorMsg(status.error));
521 }
522 if(ret!=TPCERROR_OK) {
523 tacFree(&tac0); tacFree(&tac2); tacFree(&tac2); tacFree(&tac3);
524 parFree(&lp); parFree(&par);
525 return(21);
526 }
527 if(verbose>0) printf("Results saved in %s.\n", resfile);
528 }
529
530
531
532 /*
533 * Compute fitted TAC, if necessary
534 */
535 if(svgfile[0] || fitfile[0]) {
536 if(verbose>1) printf("computing fitted TACs\n");
537 // into ttac2 since it is otherwise not needed
538 for(int ti=0; ti<tac0.tacNr; ti++) {
539 for(int mi=0; mi<tac0.sampleNr; mi++)
540 tac2.c[ti].y[mi]=par.r[ti].p[0] + par.r[ti].p[2]*exp(par.r[ti].p[3]*tac0.x[mi]) +
541 par.r[ti].p[4]*exp(par.r[ti].p[5]*tac0.x[mi]) +
542 par.r[ti].p[6]*exp(par.r[ti].p[7]*tac0.x[mi]);
543 }
544 }
545
546
547 /*
548 * SVG plot of fitted and original data
549 */
550 if(svgfile[0]) {
551
552 if(verbose>1) printf("saving SVG plot\n");
553 int i;
554 char buf[128];
555 sprintf(buf, "3exp");
556 i=iftFindKey(&tac0.h, "studynr", 0);
557 if(i<0) i=iftFindKey(&tac0.h, "study_number", 0);
558 if(i>=0) {strcat(buf, ": "); strcat(buf, tac0.h.item[i].value);}
559 ret=tacPlotFitSVG(&tac0, &tac2, buf, 0.0, nan(""), 0.0, nan(""), svgfile, &status);
560 if(ret!=TPCERROR_OK) {
561 fprintf(stderr, "Error: %s\n", errorMsg(status.error));
562 tacFree(&tac0); tacFree(&tac2); tacFree(&tac2); tacFree(&tac3);
563 parFree(&lp); parFree(&par);
564 return(31);
565 }
566 if(verbose>0) printf("Plots written in %s.\n", svgfile);
567 }
568
569
570 /*
571 * Save fitted TTACs
572 */
573 if(fitfile[0]) {
574 if(verbose>1) printf("writing %s\n", fitfile);
575 FILE *fp; fp=fopen(fitfile, "w");
576 if(fp==NULL) {
577 fprintf(stderr, "Error: cannot open file for writing fitted TTACs.\n");
578 ret=TPCERROR_FAIL;
579 } else {
580 ret=tacWrite(&tac2, fp, TAC_FORMAT_UNKNOWN, 1, &status);
581 fclose(fp);
582 if(ret!=TPCERROR_OK) fprintf(stderr, "Error: %s\n", errorMsg(status.error));
583 }
584 if(ret!=TPCERROR_OK) {
585 tacFree(&tac0); tacFree(&tac1); tacFree(&tac2); tacFree(&tac3);
586 parFree(&lp);
587 return(32);
588 }
589 if(verbose>0) printf("fitted TACs saved in %s.\n", fitfile);
590 }
591
592
593 tacFree(&tac0); tacFree(&tac1); tacFree(&tac2); tacFree(&tac3);
594 parFree(&lp); parFree(&par);
595
596 return(0);
597}
598/*****************************************************************************/
599
600/*****************************************************************************/
char * ctime_r_int(const time_t *t, char *buf)
Convert calendar time t into a null-terminated string of the form YYYY-MM-DD hh:mm:ss,...
Definition datetime.c:119
void iftFree(IFT *ift)
Definition ift.c:37
int iftPut(IFT *ift, const char *key, const char *value, char comment, TPCSTATUS *status)
Definition ift.c:63
int iftFindKey(IFT *ift, const char *key, int start_index)
Definition iftfind.c:30
int liIntegrate(double *x, double *y, const int nr, double *yi, const int se, const int verbose)
Linear integration of TAC with trapezoidal method.
Definition integrate.c:33
int tacInterpolate(TAC *inp, TAC *xinp, TAC *tac, TAC *itac, TAC *iitac, TPCSTATUS *status)
Interpolate and/or integrate TACs from one TAC structure into a new TAC structure,...
Definition litac.c:141
void parFree(PAR *par)
Definition par.c:75
void parInit(PAR *par)
Definition par.c:25
char * parFormattxt(parformat c)
Definition pario.c:59
int parWrite(PAR *par, FILE *fp, parformat format, int extra, TPCSTATUS *status)
Definition pario.c:148
int parFormatFromExtension(const char *s)
Definition pario.c:102
int parAllocateWithTAC(PAR *par, TAC *tac, int parNr, TPCSTATUS *status)
Allocate PAR based on data in TAC.
Definition partac.c:90
int tpcProcessStdOptions(const char *s, int *print_usage, int *print_version, int *verbose_level)
Definition proginfo.c:47
void tpcProgramName(const char *program, int version, int copyright, char *prname, int n)
Definition proginfo.c:406
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
int qrLSQ(double **mat, double *rhs, double *sol, const unsigned int rows, const unsigned int cols, double *r2)
QR least-squares solving routine.
Definition qrlsq.c:72
int qrWeight(int N, int M, double **A, double *b, double *weight, double *ws)
Definition qrlsq.c:745
int rootsCubic(const double a, const double b, const double c, double *x1, double *x2, double *x3)
Definition roots.c:30
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
char * value
Definition tpcift.h:37
IFT_ITEM * item
Definition tpcift.h:57
Definition tpcpar.h:100
int format
Definition tpcpar.h:102
IFT h
Optional (but often useful) header information.
Definition tpcpar.h:147
int parNr
Definition tpcpar.h:108
int tacNr
Definition tpcpar.h:104
PARR * r
Definition tpcpar.h:114
PARN * n
Definition tpcpar.h:112
int unit
Definition tpcpar.h:86
char name[MAX_PARNAME_LEN+1]
Definition tpcpar.h:82
double wss
Definition tpcpar.h:72
int fitNr
Definition tpcpar.h:58
int dataNr
Definition tpcpar.h:62
unsigned int model
Definition tpcpar.h:48
double * p
Definition tpcpar.h:64
double start
Definition tpcpar.h:52
double end
Definition tpcpar.h:54
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
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
double * w
Definition tpctac.h:111
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
int tacDuplicate(TAC *tac1, TAC *tac2)
Make a duplicate of TAC structure.
Definition tac.c:356
void tacInit(TAC *tac)
Definition tac.c:24
int tacPlotFitSVG(TAC *tac1, TAC *tac2, const char *main_title, const double x1, const double x2, const double y1, const double y2, const char *fname, TPCSTATUS *status)
Definition tacfitplot.c:27
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 tacSetWeights(TAC *tac, weights weightMethod, int weightNr, TPCSTATUS *status)
Definition tacw.c:462
int tacIsWeighted(TAC *tac)
Definition tacw.c:24
unsigned int tacWSampleNr(TAC *tac)
Definition tacw.c:219
Header file for library libtpcextensions.
weights
Is data weighted, or are weight factors available with data?
@ WEIGHTING_OFF
Not weighted or weights not available (weights for all included samples are 1.0).
@ WEIGHTING_ON_FD
Weights based on decay and sample frequency or frame length (Thiele et al, 2008).
@ WEIGHTING_UNKNOWN
Not known; usually assumed that not weighted.
int unitInverse(int u)
Definition units.c:654
@ TPCERROR_FAIL
General error.
@ 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 libtpclinopt.
Header file for libtpcpar.
@ PAR_FORMAT_UNKNOWN
Unknown format.
Definition tpcpar.h:28
@ PAR_FORMAT_TSV_UK
UK TSV (point as decimal separator).
Definition tpcpar.h:35
Header file for library libtpctac.
@ TAC_FORMAT_UNKNOWN
Unknown format.
Definition tpctac.h:28
Header file for libtpctacmod.