TPCCLIB
Loading...
Searching...
No Matches
perfrat.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 "tpcpar.h"
19#include "tpcli.h"
20#include "tpctacmod.h"
21/*****************************************************************************/
22
23/*****************************************************************************/
24static char *info[] = {
25 "Calculates perfusion ratio from regional radiowater PET data.",
26 "In animal disease models, such as UUO model, one of kidneys is affected",
27 "by the disease model and the other kidney serves as reference organ.",
28 "Perfusion ratio can be calculated from AUCs of tissue curves without",
29 "input function (1, 2). AUCs are limited to the time of the first peak of",
30 "the control tissue curve.",
31 " ",
32 "Usage: @P [options] tacfile reference [outputfile]",
33 " ",
34 "Options:",
35 " -etime=<time>",
36 " Extend or shorten AUC calculation past the peak by specified time",
37 " (sec). Positive time extends, negative time shortens the time range.",
38 " -fr",
39 " Force given single reference region for every other TAC.",
40 " -stdoptions", // List standard options like --help, -v, etc
41 " ",
42 "As an example, if TAC file rabbit34.tac contains tissue regions with names",
43 "UUO cortex, UUO medulla, CTRL cortex, CTRL medulla,",
44 "then to calculate AUC ratio between UUO and CTRL cortex, and",
45 "between UUO and CTRL medulla, enter command",
46 " @P rabbit34.tac CTRL rabbit34.par",
47 "Program calculates AUCs from 0 to the peak time of the individual",
48 "reference TAC, and saves AUC ratios in parameter file.",
49 " ",
50 "References:",
51 "1. Xia et al. Hypertension 2008;51(2):466-473.",
52 "2. Gulaldi et al. Biomed Res Int. 2013;835859.",
53 " ",
54 "See also: tacpeak, interpol, taccalc, fit_h2o, dftratio",
55 " ",
56 "Keywords: TAC, modelling, perfusion, ratio",
57 0};
58/*****************************************************************************/
59
60/*****************************************************************************/
61/* Turn on the globbing of the command line, since it is disabled by default in
62 mingw-w64 (_dowildcard=0); in MinGW32 define _CRT_glob instead, if necessary;
63 In Unix&Linux wildcard command line processing is enabled by default. */
64/*
65#undef _CRT_glob
66#define _CRT_glob -1
67*/
68int _dowildcard = -1;
69/*****************************************************************************/
70
71/*****************************************************************************/
75int main(int argc, char **argv)
76{
77 int ai, help=0, version=0, verbose=1;
78 int ret;
79 char tacfile[FILENAME_MAX], outfile[FILENAME_MAX], refname[256];
80 double extra_time=nan("");
81 int force_ref=0;
82
83
84 /*
85 * Get arguments
86 */
87 if(argc==1) {tpcPrintUsage(argv[0], info, stderr); return(1);}
88 tacfile[0]=outfile[0]=refname[0]=(char)0;
89 /* Options */
90 for(ai=1; ai<argc; ai++) if(*argv[ai]=='-') {
91 if(tpcProcessStdOptions(argv[ai], &help, &version, &verbose)==0) continue;
92 char *cptr=argv[ai]+1; if(*cptr=='-') cptr++; if(!*cptr) continue;
93 if(strcasecmp(cptr, "DRY")==0) {
94 continue;
95 } else if(strcasecmp(cptr, "FR")==0) {
96 force_ref=1; continue;
97 } else if(strncasecmp(cptr, "ETIME=", 6)==0) {
98 extra_time=atofVerified(cptr+6); if(!isnan(extra_time)) continue;
99 }
100 fprintf(stderr, "Error: invalid option '%s'\n", argv[ai]);
101 return(1);
102 } else break; // tac name argument may start with '-'
103
104 TPCSTATUS status; statusInit(&status);
105 statusSet(&status, __func__, __FILE__, __LINE__, TPCERROR_OK);
106 status.verbose=verbose-5;
107
108 /* Print help or version? */
109 if(help==2) {tpcHtmlUsage(argv[0], info, ""); return(0);}
110 if(help) {tpcPrintUsage(argv[0], info, stdout); return(0);}
111 if(version) {tpcPrintBuild(argv[0], stdout); return(0);}
112
113 /* Process other arguments, starting from the first non-option */
114 if(ai<argc) strlcpy(tacfile, argv[ai++], FILENAME_MAX);
115 if(ai<argc) strlcpy(refname, argv[ai++], 256);
116 if(ai<argc) strlcpy(outfile, argv[ai++], FILENAME_MAX);
117 if(ai<argc) {fprintf(stderr, "Error: too many arguments: '%s'.\n", argv[ai]); return(1);}
118
119 /* Is something missing? */
120 if(!refname[0]) {tpcPrintUsage(argv[0], info, stdout); return(1);}
121 if(strcasecmp(tacfile, outfile)==0) {
122 fprintf(stderr, "Error: input file would be overwritten.\n");
123 return(1);
124 }
125
126 /* In verbose mode print arguments and options */
127 if(verbose>1) {
128 printf("tacfile := %s\n", tacfile);
129 printf("refname := %s\n", refname);
130 if(!isnan(extra_time)) printf("extra_time := %g\n", extra_time);
131 if(outfile[0]) printf("outfile := %s\n", outfile);
132 printf("force_ref := %d\n", force_ref);
133 fflush(stdout);
134 }
135
136
137 /*
138 * Read the file
139 */
140 if(verbose>1) printf("reading %s\n", tacfile);
141 TAC tac; tacInit(&tac);
142 ret=tacRead(&tac, tacfile, &status);
143 if(ret!=TPCERROR_OK) {
144 fprintf(stderr, "Error (%d): %s\n", ret, errorMsg(status.error));
145 tacFree(&tac); return(2);
146 }
147 if(verbose>2) {
148 printf("fileformat := %s\n", tacFormattxt(tac.format));
149 printf("tacNr := %d\n", tac.tacNr);
150 printf("sampleNr := %d\n", tac.sampleNr);
151 printf("xunit := %s\n", unitName(tac.tunit));
152 printf("yunit := %s\n", unitName(tac.cunit));
153 }
154 if(verbose>3) iftWrite(&tac.h, stdout, NULL);
155 if(tac.tacNr<2 || tac.sampleNr<3) {
156 fprintf(stderr, "Error: no data to calculate AUC ratio.\n");
157 tacFree(&tac); return(2);
158 }
159 if(!tacIsX(&tac)) {
160 fprintf(stderr, "Error: sample times not available.\n");
161 tacFree(&tac); return(2);
162 }
163 if(tacNaNs(&tac)) {
164 fprintf(stderr, "Error: missing values in the TAC file.\n");
165 tacFree(&tac); return(2);
166 }
167 if(tacSortByTime(&tac, &status)!=TPCERROR_OK) {
168 fprintf(stderr, "Error: %s\n", errorMsg(status.error));
169 tacFree(&tac); return(2);
170 }
171 double x1, x2;
172 if(tacSampleXRange(&tac, &x1, &x2)) {
173 fprintf(stderr, "Error: invalid sample times.\n");
174 tacFree(&tac); return(2);
175 }
176 if(verbose>1) printf("time range: %g - %g\n", x1, x2);
177
178 /* If sample times are in minutes, then change extra_time to minutes, too */
179 if(!isnan(extra_time)) {
180 if(tac.tunit==UNIT_MIN) {
181 extra_time/=60.0;
182 if(verbose>0) printf("extra_time converted to minutes.\n");
183 } else if(tac.tunit!=UNIT_SEC) {
184 fprintf(stderr, "Warning: sample time assumed to be in seconds.\n");
185 }
186 }
187
188 /* How many matches for reference name we get? */
189 int refNr=tacSelectTACs(&tac, refname, 1, &status);
190 if(refNr<=0) {
191 fprintf(stderr, "Error: specified reference TAC not found.\n");
192 tacFree(&tac); return(3);
193 }
194 if(refNr==tac.tacNr) {
195 fprintf(stderr, "Error: all regions match the reference.\n");
196 tacFree(&tac); return(3);
197 }
198 int refindex=-1;
199 if(force_ref==0) {
200 if(verbose>2 || (verbose>0 && refNr!=1)) {
201 printf("%d tac(s) match name '%s'\n", refNr, refname); fflush(stdout);
202 }
203 } else {
204 if(refNr>1 && verbose>0) {
205 printf("%d tac(s) match name '%s'\n", refNr, refname); fflush(stdout);
206 }
207 refindex=tacSelectBestReference(&tac);
208 if(refindex<0) {
209 fprintf(stderr, "Error: cannot select best match for '%s'.\n", refname);
210 tacFree(&tac); return(3);
211 }
212 }
213
214
215 /*
216 * Pre-calculate AUC from start to each frame mid time for each TAC
217 */
218 if(verbose>1) {printf("integrating TACs\n"); fflush(stdout);}
219 TAC auc; tacInit(&auc);
220 if(tacInterpolate(&tac, &tac, NULL, &auc, NULL, &status)!=TPCERROR_OK) {
221 fprintf(stderr, "Error: %s\n", errorMsg(status.error));
222 tacFree(&tac); return(4);
223 }
224
225
226 /*
227 * Create a new parameter structure for results.
228 */
229 if(verbose>2) {printf("allocating place for results\n"); fflush(stdout);}
230 PAR par; parInit(&par);
231 if(parAllocate(&par, 1, tac.tacNr)) {
232 fprintf(stderr, "Error: cannot allocate memory for results.\n");
233 parFree(&par); tacFree(&tac); tacFree(&auc); return(5);
234 }
235 par.tacNr=0; par.parNr=1;
236 /* Set results information */
237 par.format=parFormatFromExtension(outfile);
239 strcpy(par.n[0].name, "PR"); par.n[0].unit=UNIT_UNITLESS;
240 {
241 char buf[256];
242 tpcProgramName(argv[0], 1, 1, buf, 256);
243 iftPut(&par.h, "program", buf, 0, NULL);
244 time_t t=time(NULL);
245 iftPut(&par.h, "analysis_time", ctime_r_int(&t, buf), 0, NULL);
246 char studynr[MAX_STUDYNR_LEN+1];
247 if(tacGetHeaderStudynr(&tac.h, studynr, NULL)==TPCERROR_OK)
248 studynrFromFilename(tacfile, studynr, 1);
249 parSetStudyNr(&par, studynr);
250 }
251 iftPut(&par.h, "datafile", tacfile, 0, NULL);
252 iftPut(&par.h, "reference_name", refname, 0, NULL);
253
254
255 /*
256 * Calculate perfusion ratios
257 */
258 if(verbose>1) {printf("computing...\n"); fflush(stdout);}
259 if(force_ref!=0) {
260 /* Using the one selected reference for all other TACs */
261 if(verbose>0) {printf("reference '%s'\n", tac.c[refindex].name); fflush(stdout);}
262 /* Get the ref peak time */
263 int maxi;
264 if(tacYRange(&tac, refindex, NULL, NULL, NULL, &maxi, NULL, NULL)!=0) {
265 fprintf(stderr, "Error: no peak found for %s\n", tac.c[refindex].name);
266 tacFree(&tac); tacFree(&auc); parFree(&par); return(8);
267 }
268 if(verbose>3) {
269 printf(" peak at time %g, sample %d, AUC %g\n", tac.x[maxi], 1+maxi, auc.c[refindex].y[maxi]);
270 fflush(stdout);
271 }
272 for(int rj=0; rj<tac.tacNr; rj++) if(rj!=refindex) {
273 /* Set result region name */
274 strcpy(par.r[par.tacNr].name, tac.c[rj].name);
275 /* Set result time range */
276 par.r[par.tacNr].start=tac.x[0]; par.r[par.tacNr].end=tac.x[maxi];
277 if(par.r[par.tacNr].start>0.0) par.r[par.tacNr].start=0.0;
278 /* Calculate AUC ratio */
279 if(isnan(extra_time) || fabs(extra_time)<1.0E-06) {
280 /* Take AUCs directly from pre-calculated AUC-curves */
281 if(verbose>4) {printf(" AUC %g\n", auc.c[rj].y[maxi]); fflush(stdout);}
282 par.r[par.tacNr].p[0]=auc.c[rj].y[maxi]/auc.c[refindex].y[maxi];
283 } else {
284 /* Calculate AUCs from start to peak+extra_time */
285 double et=tac.x[maxi]+extra_time;
286 if(et>x2) et=x2; else if(et<x1) et=x1;
287 par.r[par.tacNr].end=et; // refine result time range
288 double newx[1], newy[1], auc1, auc2;
289 newx[0]=et;
290 ret=liInterpolate(auc.x, auc.c[refindex].y, auc.sampleNr, newx, newy, NULL, NULL, 1, 3, 1, 0);
291 auc1=newy[0];
292 if(!ret)
293 ret=liInterpolate(auc.x, auc.c[rj].y, auc.sampleNr, newx, newy, NULL, NULL, 1, 3, 1, 0);
294 auc2=newy[0];
295 if(ret || isnan(auc1) || isnan(auc2)) {
296 fprintf(stderr, "Error: cannot interpolate.\n");
297 tacFree(&tac); tacFree(&auc); parFree(&par); return(8);
298 }
299 if(verbose>4) {printf(" AUCs %g/%g\n", auc2, auc1); fflush(stdout);}
300 par.r[par.tacNr].p[0]=auc2/auc1;
301 if(!isfinite(par.r[par.tacNr].p[0])) par.r[par.tacNr].p[0]=0.0;
302 }
303 /* Convert result time range into minutes, if necessary */
304 if(tac.tunit==UNIT_SEC) {par.r[par.tacNr].start/=60.0; par.r[par.tacNr].end/=60.0;}
305 /* prepare for next one */
306 par.tacNr++; if(par.tacNr>=par._tacNr) break;
307 }
308
309 } else for(int ri=0; ri<tac.tacNr; ri++) if(tac.c[ri].sw==1) {
310 if(verbose>2) {printf("reference '%s'\n", tac.c[ri].name); fflush(stdout);}
311 /* Get the peak time */
312 int maxi;
313 if(tacYRange(&tac, ri, NULL, NULL, NULL, &maxi, NULL, NULL)!=0) {
314 if(verbose>0) fprintf(stderr, "Error: no peak found for %s\n", tac.c[ri].name);
315 continue;
316 }
317 if(verbose>3) {
318 printf(" peak at time %g, sample %d, AUC %g\n", tac.x[maxi], 1+maxi, auc.c[ri].y[maxi]);
319 fflush(stdout);
320 }
321 /* Extract the parts of region name before and after the given id */
322 char part1[FILENAME_MAX], part2[FILENAME_MAX];
323 strcpy(part1, tac.c[ri].name); char *cptr=strdelstr(part1, refname);
324 strcpy(part2, cptr); *cptr=(char)0;
325 /* Try to find regions with matching name */
326 if(verbose>3) {printf(" searching matches for '%s'...'%s'\n", part1, part2); fflush(stdout);}
327 int matchNr=0;
328 for(int rj=0; rj<tac.tacNr; rj++) if(tac.c[rj].sw==0) { // ... excluding references
329 if(verbose>4) {printf(" checking '%s'\n", tac.c[rj].name); fflush(stdout);}
330 int m=strlen(tac.c[rj].name); if(m<1) continue;
331 int n=strlen(part1); if(m<n) continue;
332 if(n>0 && strncasecmp(tac.c[rj].name, part1, n)) continue;
333 n=strlen(part2); if(m<n) continue;
334 if(n>0 && strcasecmp(tac.c[rj].name+m-n, part2)) continue;
335 if(verbose>4) {printf(" match\n"); fflush(stdout);}
336 /* Set result region name */
337 char *p1=strdup(part1); strCleanSpaces(p1);
338 char *p2=strdup(part2); strCleanSpaces(p2);
339 if(strlen(p1)>0) strcpy(par.r[par.tacNr].name, p1);
340 if(strlen(p1)>0 && strlen(p2)>0) strcat(par.r[par.tacNr].name, " ");
341 if(strlen(p2)>0) strcat(par.r[par.tacNr].name, p2);
342 free(p1); free(p2);
343 if(par.r[par.tacNr].name[0]=='-' || par.r[par.tacNr].name[0]=='_')
344 strTrimLeft(par.r[par.tacNr].name, 1);
345 if(strlen(par.r[par.tacNr].name)<1) sprintf(par.r[par.tacNr].name, "tac%d", 1+par.tacNr);
346 /* Set result time range */
347 par.r[par.tacNr].start=tac.x[0]; par.r[par.tacNr].end=tac.x[maxi];
348 if(par.r[par.tacNr].start>0.0) par.r[par.tacNr].start=0.0;
349 /* Calculate AUC ratio */
350 if(isnan(extra_time) || fabs(extra_time)<1.0E-06) {
351 /* Take AUCs directly from pre-calculated AUC-curves */
352 if(verbose>4) {printf(" AUC %g\n", auc.c[rj].y[maxi]); fflush(stdout);}
353 par.r[par.tacNr].p[0]=auc.c[rj].y[maxi]/auc.c[ri].y[maxi];
354 } else {
355 /* Calculate AUCs from start to peak+extra_time */
356 double et=tac.x[maxi]+extra_time;
357 if(et>x2) et=x2; else if(et<x1) et=x1;
358 par.r[par.tacNr].end=et; // refine result time range
359 double newx[1], newy[1], auc1, auc2;
360 newx[0]=et;
361 ret=liInterpolate(auc.x, auc.c[ri].y, auc.sampleNr, newx, newy, NULL, NULL, 1, 3, 1, 0);
362 auc1=newy[0];
363 if(!ret)
364 ret=liInterpolate(auc.x, auc.c[rj].y, auc.sampleNr, newx, newy, NULL, NULL, 1, 3, 1, 0);
365 auc2=newy[0];
366 if(ret || isnan(auc1) || isnan(auc2)) {
367 fprintf(stderr, "Error: cannot interpolate.\n");
368 tacFree(&tac); tacFree(&auc); parFree(&par); return(8);
369 }
370 if(verbose>4) {printf(" AUCs %g/%g\n", auc2, auc1); fflush(stdout);}
371 par.r[par.tacNr].p[0]=auc2/auc1;
372 if(!isfinite(par.r[par.tacNr].p[0])) par.r[par.tacNr].p[0]=0.0;
373 }
374 matchNr++;
375 /* Convert result time range into minutes, if necessary */
376 if(tac.tunit==UNIT_SEC) {par.r[par.tacNr].start/=60.0; par.r[par.tacNr].end/=60.0;}
377 /* prepare for next one */
378 par.tacNr++; if(par.tacNr>=par._tacNr) break;
379 }
380 if(verbose>0) {
381 if(matchNr==0)
382 fprintf(stderr, "Warning: no matches for '%s'\n", tac.c[ri].name);
383 else if(matchNr>1)
384 fprintf(stderr, "Warning: %d matches for '%s'\n", matchNr, tac.c[ri].name);
385 fflush(stdout);
386 }
387 }
388
389
390 /* Original data and AUCs no more needed */
391 tacFree(&tac); tacFree(&auc);
392 /* Check that something could be calculated */
393 if(par.tacNr<1) {
394 fprintf(stderr, "Error: no data to calculate perfusion ratio.\n");
395 parFree(&par); return(10);
396 }
397
398 /* Print and save the results */
399 if(verbose>0 || !outfile[0]) parWrite(&par, stdout, PAR_FORMAT_TSV_UK, 0, NULL);
400 if(outfile[0]) {
401 /* Save file */
402 if(verbose>1) printf(" saving %s\n", outfile);
403 FILE *fp=fopen(outfile, "w");
404 if(fp==NULL) {
405 fprintf(stderr, "Error: cannot open file for writing.\n");
406 parFree(&par); return(11);
407 }
408 int ret=parWrite(&par, fp, PAR_FORMAT_UNKNOWN, 1, &status);
409 fclose(fp);
410 if(ret!=TPCERROR_OK) {
411 fprintf(stderr, "Error: %s\n", errorMsg(status.error));
412 parFree(&par); return(12);
413 }
414 if(verbose>0) printf("perfusion ratios saved in %s\n", outfile);
415 }
416
417 parFree(&par);
418 return(0);
419}
420/*****************************************************************************/
421
422/*****************************************************************************/
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
double atofVerified(const char *s)
Definition decpoint.c:75
int iftPut(IFT *ift, const char *key, const char *value, char comment, TPCSTATUS *status)
Definition ift.c:63
int iftWrite(IFT *ift, FILE *fp, TPCSTATUS *status)
Definition iftio.c:98
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 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
int parAllocate(PAR *par, int parNr, int tacNr)
Definition par.c:108
void parInit(PAR *par)
Definition par.c:25
int parSetStudyNr(PAR *par, const char *s)
Definition par.c:417
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 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
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
char * strdup(const char *s)
Definition stringext.c:185
int strCleanSpaces(char *s)
Definition stringext.c:300
char * strTrimLeft(char *s, const size_t t)
Definition stringext.c:710
size_t strlcpy(char *dst, const char *src, size_t dstsize)
Definition stringext.c:632
char * strdelstr(char *s1, const char *s2)
Definition stringext.c:688
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
int _tacNr
Definition tpcpar.h:106
PARN * n
Definition tpcpar.h:112
int unit
Definition tpcpar.h:86
char name[MAX_PARNAME_LEN+1]
Definition tpcpar.h:82
char name[MAX_TACNAME_LEN+1]
Definition tpcpar.h:50
double * p
Definition tpcpar.h:64
double start
Definition tpcpar.h:52
double end
Definition tpcpar.h:54
char sw
Definition tpctac.h:77
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
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.
int studynrFromFilename(const char *fname, char *studynr, int force)
Definition studynr.c:79
void tacFree(TAC *tac)
Definition tac.c:106
void tacInit(TAC *tac)
Definition tac.c:24
int tacGetHeaderStudynr(IFT *h, char *s, TPCSTATUS *status)
Definition tacift.c:26
int tacRead(TAC *d, const char *fname, TPCSTATUS *status)
Definition tacio.c:413
char * tacFormattxt(tacformat c)
Definition tacio.c:98
int tacNaNs(TAC *tac)
Definition tacnan.c:71
int tacSortByTime(TAC *d, TPCSTATUS *status)
Definition tacorder.c:74
int tacSelectTACs(TAC *d, const char *region_name, int reset, TPCSTATUS *status)
Definition tacselect.c:24
int tacSelectBestReference(TAC *d)
Definition tacselect.c:139
int tacSampleXRange(TAC *d, double *xmin, double *xmax)
Get the range of x values (times) in TAC structure.
Definition tacx.c:162
int tacIsX(TAC *d)
Verify if TAC structure contains reasonable x values (times).
Definition tacx.c:226
int tacYRange(TAC *d, int i, double *ymin, double *ymax, int *smin, int *smax, int *imin, int *imax)
Get the range of y values (concentrations) in TAC struct.
Definition tacy.c:26
Header file for library libtpcextensions.
@ UNIT_MIN
minutes
@ UNIT_UNITLESS
Unitless.
@ UNIT_SEC
seconds
@ TPCERROR_OK
No error.
char * unitName(int unit_code)
Definition units.c:143
#define MAX_STUDYNR_LEN
Define max study number length.
Header file for library libtpcift.
Header file for libtpcli.
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.
Header file for libtpctacmod.