9#include "tpcclibConfig.h"
26static char *info[] = {
27 "Find peak time and value in TAC file.",
29 "Usage: @P [options] tacfile [outputfile]",
32 " -decr=<Percentage>",
33 " Estimate time when TAC decreases to specified percentage of peak value.",
35 " Peak time is reported as weighted average of subsequent samples.",
37 " TAC mean is subtracted from peak value.",
40 "See also: imgpeak, dftmax, inpstart, tacrange, taccut, tacslope",
42 "Keywords: TAC, peak, max, time",
61int main(
int argc,
char **argv)
63 int ai, help=0, version=0, verbose=1;
64 char tacfile[FILENAME_MAX], parfile[FILENAME_MAX];
73 if(argc==1) {
tpcPrintUsage(argv[0], info, stderr);
return(1);}
74 tacfile[0]=parfile[0]=(char)0;
76 for(ai=1; ai<argc; ai++)
if(*argv[ai]==
'-') {
78 char *cptr=argv[ai]+1;
if(*cptr==
'-') cptr++;
if(!*cptr)
continue;
79 if(strncasecmp(cptr,
"DECR=", 5)==0) {
81 if(decr>1.0 && decr<100.0)
continue;
83 }
else if(strcasecmp(cptr,
"WT")==0) {
84 timeAsWAvg=1;
continue;
85 }
else if(strcasecmp(cptr,
"SWA")==0) {
86 subtractWAvg=1;
continue;
88 fprintf(stderr,
"Error: invalid option '%s'\n", argv[ai]);
97 if(help==2) {
tpcHtmlUsage(argv[0], info,
"");
return(0);}
103 if(ai<argc)
strlcpy(tacfile, argv[ai++], FILENAME_MAX);
104 if(ai<argc)
strlcpy(parfile, argv[ai++], FILENAME_MAX);
105 if(ai<argc) {fprintf(stderr,
"Error: too many arguments.\n");
return(1);}
108 if(!tacfile[0]) {
tpcPrintUsage(argv[0], info, stdout);
return(1);}
112 for(ai=0; ai<argc; ai++) printf(
"%s ", argv[ai]);
114 printf(
"tacfile := %s\n", tacfile);
115 if(parfile[0]) printf(
"parfile := %s\n", parfile);
116 if(!isnan(decr)) printf(
"decr_percent := %g\n", decr);
117 printf(
"timeAsWAvg := %d\n", timeAsWAvg);
118 printf(
"subtractWAvg := %d\n", subtractWAvg);
125 if(verbose>1) printf(
"reading %s\n", tacfile);
133 printf(
"tacNr := %d\n", tac.
tacNr);
134 printf(
"sampleNr := %d\n", tac.
sampleNr);
146 fprintf(stderr,
"Error: invalid data sample times.\n");
150 printf(
"xmin := %g\n", xmin);
151 printf(
"xmax := %g\n", xmax);
155 fprintf(stderr,
"Error: cannot process duplicate samples.\n");
162 if(verbose>1) printf(
"preparing space for parameters\n");
171 for(
int i=0; i<tac.
tacNr; i++) {
178 strcpy(par.
n[0].
name,
"Peak");
179 strcpy(par.
n[1].
name,
"PeakT");
180 sprintf(par.
n[2].
name,
"T%g%%", roundf(decr));
185 if(verbose>1) printf(
"searching peaks\n");
186 for(
int ci=0; ci<tac.
tacNr; ci++) {
188 if(verbose>2) printf(
"%s\n", tac.
c[ci].
name);
189 for(
int i=0; i<par.
parNr; i++) par.
r[ci].
p[i]=nan(
"");
192 double ymax;
int imax;
193 if(
tacYRange(&tac, ci, NULL, &ymax, NULL, &imax, NULL, NULL)!=0) {
194 fprintf(stderr,
"Error: no maximum found for TAC '%s'.\n", tac.
c[ci].
name);
198 printf(
" maxv := %g\n", ymax);
199 printf(
" maxx := %g\n", tac.
x[imax]);
202 par.
r[ci].
p[1]=tac.
x[imax];
205 if(timeAsWAvg && imax>0 && imax<tac.
sampleNr-1) {
206 double s=0.0, ws=0.0;
207 int i1, i2; i1=imax-1; i2=imax+1;
if(i1>0 && i2<tac.
sampleNr-1) {i1--; i2++;}
208 for(
int i=i1; i<=i2; i++) {s+=tac.
c[ci].
y[i]*tac.
x[i]; ws+=tac.
c[ci].
y[i];}
209 s/=ws;
if(verbose>2) printf(
" weighted_maxx := %g\n", s);
210 if(!isnan(s)) par.
r[ci].
p[1]=s;
215 double ylim=(decr/100.0)*ymax;
216 double x1=tac.
x[imax];
217 double y1=tac.
c[ci].
y[imax];
218 double x2, y2; x2=y2=nan(
"");
219 for(
int i=imax+1; i<tac.
sampleNr; i++) {
220 if(isnan(tac.
x[i]))
continue;
221 if(isnan(tac.
c[ci].
y[i]))
continue;
222 if(tac.
c[ci].
y[i]>ylim) {x1=tac.
x[i]; y1=tac.
c[ci].
y[i];
continue;}
223 x2=tac.
x[i]; y2=tac.
c[ci].
y[i];
226 if(isnan(x2) || isnan(y2)) {
227 fprintf(stderr,
"Error: TAC '%s' does not drop to specified level.\n", tac.
c[ci].
name);
230 printf(
" prev_sample := (%g, %g)\n", x1, y1);
231 printf(
" next_sample := (%g, %g)\n", x2, y2);
233 if(fabs(y2-y1)>1.0E-20) par.
r[ci].
p[2]=x1+(ylim-y1)*(x2-x1)/(y2-y1);
234 else par.
r[ci].
p[2]=0.5*(x1+x2);
240 double auc=
tacAUC(&tac, ci, xmin, xmax, NULL);
242 fprintf(stderr,
"Error: invalid mean of TAC '%s'.\n", tac.
c[ci].
name);
244 double avg=auc/(xmax-xmin);
259 if(verbose>1) printf(
" saving %s\n", parfile);
260 FILE *fp=fopen(parfile,
"w");
262 fprintf(stderr,
"Error: cannot open file for writing.\n");
271 if(verbose>0) printf(
"parameters saved in %s\n", parfile);
int atofCheck(const char *s, double *v)
double tacAUC(TAC *tac, int ti, double t1, double t2, TPCSTATUS *status)
Calculates TAC AUC from t1 to t2.
int parWrite(PAR *par, FILE *fp, parformat format, int extra, TPCSTATUS *status)
int parAllocateWithTAC(PAR *par, TAC *tac, int parNr, TPCSTATUS *status)
Allocate PAR based on data in TAC.
int tpcProcessStdOptions(const char *s, int *print_usage, int *print_version, int *verbose_level)
int tpcHtmlUsage(const char *program, char *text[], const char *path)
void tpcPrintBuild(const char *program, FILE *fp)
void tpcPrintUsage(const char *program, char *text[], FILE *fp)
void statusInit(TPCSTATUS *s)
char * errorMsg(tpcerror e)
void statusSet(TPCSTATUS *s, const char *func, const char *srcfile, int srcline, tpcerror error)
size_t strlcpy(char *dst, const char *src, size_t dstsize)
char name[MAX_PARNAME_LEN+1]
char name[MAX_TACNAME_LEN+1]
int verbose
Verbose level, used by statusPrint() etc.
tpcerror error
Error code.
int tacRead(TAC *d, const char *fname, TPCSTATUS *status)
char * tacFormattxt(tacformat c)
int tacSortByTime(TAC *d, TPCSTATUS *status)
int tacMultipleSamples(TAC *d1, const int fixMode, TAC *d2, const int verbose)
Check TAC data for multiple samples with the same sample time. Optionally replace the multiple sample...
unsigned int tacWSampleNr(TAC *tac)
int tacXRange(TAC *d, double *xmin, double *xmax)
Get the range of x values (times) in TAC structure.
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.
Header file for library libtpcextensions.
char * unitName(int unit_code)
Header file for libtpcfunc.
Header file for library libtpcift.
Header file for libtpcmodels.
Header file for libtpcpar.
@ PAR_FORMAT_UNKNOWN
Unknown format.
@ PAR_FORMAT_TSV_UK
UK TSV (point as decimal separator).
Header file for library libtpctac.
Header file for libtpctacmod.