TPCCLIB
Loading...
Searching...
No Matches
tacx.c
Go to the documentation of this file.
1
4/*****************************************************************************/
5#include "tpcclibConfig.h"
6/*****************************************************************************/
7#include "tpcift.h"
8/*****************************************************************************/
9#include <stdio.h>
10#include <stdlib.h>
11#include <math.h>
12#include <time.h>
13#include <string.h>
14/*****************************************************************************/
15#include "tpctac.h"
16/*****************************************************************************/
17
18/*****************************************************************************/
26 TAC *tac1,
28 TAC *tac2,
30 int i1,
32 int i2
33) {
34 if(tac1==NULL || tac2==NULL) return(TPCERROR_FAIL);
35 if(i1<0 || i1>i2) return(TPCERROR_FAIL);
36 if(i2>=tac1->_sampleNr || i2>=tac2->_sampleNr) return(TPCERROR_FAIL);
37
38 for(int i=i1; i<=i2; i++) {
39 tac2->x[i]=tac1->x[i];
40 tac2->x1[i]=tac1->x1[i];
41 tac2->x2[i]=tac1->x2[i];
42 }
43 return(TPCERROR_OK);
44}
45/*****************************************************************************/
46
47/*****************************************************************************/
67 TAC *d,
69 TPCSTATUS *status
70) {
71 int verbose=0; if(status!=NULL) verbose=status->verbose;
72 if(verbose>0) printf("%s()\n", __func__);
73 if(d==NULL) {
74 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_FAIL);
75 return TPCERROR_FAIL;
76 }
77 /* If no frame start and end times, then just check the order */
78 if(d->isframe==0) {
79 if(tacVerifyTimeOrder(d, status)) {
80 if(verbose>0) fprintf(stderr, "Error: sample times are not in order.\n");
81 return(status->error);
82 }
83 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OK);
84 return TPCERROR_OK;
85 }
86 /* Check each frame */
87 double overlap, flen1, flen2, overlap_limit=0.0;
88 for(int fi=0; fi<d->sampleNr-1; fi++) {
89 overlap=d->x2[fi]-d->x1[fi+1];
90 if(overlap==0.0) continue; // no gap or overlap
91 /* Calculate the frame length of current frame and the next frame */
92 flen1=d->x2[fi]-d->x1[fi]; flen2=d->x2[fi+1]-d->x1[fi+1];
93 if(flen1<0.0 || flen2<0.0) return(1);
94 /* Set the limit */
95 if(flen1<flen2) overlap_limit=0.2*flen1; else overlap_limit=0.2*flen2;
96 /* Check if gap or overlap is too large to be fixed automatically */
97 if(overlap<-overlap_limit) continue; // gap is too large, then do nothing
98 if(overlap>overlap_limit) { // overlap is too large: error
99 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OVERLAPPING_DATA);
101 }
102 /* Correct the small gap/overlap by making frame durations more similar */
103 if(overlap>0.0) { // overlap
104 if(flen1>flen2) d->x2[fi]=d->x1[fi+1]; else d->x1[fi+1]=d->x2[fi];
105 } else { // gap
106 if(flen1>flen2) d->x1[fi+1]=d->x2[fi]; else d->x2[fi]=d->x1[fi+1];
107 }
108 }
109
110 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OK);
111 return TPCERROR_OK;
112}
113/*****************************************************************************/
114
115/*****************************************************************************/
126 TAC *d,
128 double *xmin,
130 double *xmax
131) {
132 if(xmin!=NULL) *xmin=nan("");
133 if(xmax!=NULL) *xmax=nan("");
134 /* Check the data */
135 if(d==NULL || d->sampleNr<1) return(1);
136 /* Find the min and max time */
137 double mi, ma, *xi, *xa;
138 mi=ma=nan("");
139 if(d->isframe) {xi=d->x1; xa=d->x2;} else xi=xa=d->x;
140 for(int i=0; i<d->sampleNr; i++) {
141 if(!isfinite(xi[i]) || !isfinite(xa[i])) continue;
142 if(isnan(mi) || isnan(ma)) {mi=xi[i]; ma=xa[i]; continue;}
143 if(xi[i]<mi) mi=xi[i]; else if(xa[i]>ma) ma=xa[i];
144 }
145 if(xmin!=NULL) *xmin=mi;
146 if(xmax!=NULL) *xmax=ma;
147 if(!isfinite(mi) || !isfinite(ma)) return(2);
148 return(0);
149}
150/*****************************************************************************/
151
152/*****************************************************************************/
164 TAC *d,
166 double *xmin,
168 double *xmax
169) {
170 if(xmin!=NULL) *xmin=nan("");
171 if(xmax!=NULL) *xmax=nan("");
172 /* Check the data */
173 if(d==NULL || d->sampleNr<1) return(1);
174 /* Find the min and max time */
175 double mi, ma, *xi, *xa;
176 mi=ma=nan("");
177 if(d->isframe) {xi=d->x1; xa=d->x2;} else xi=xa=d->x;
178 int weighted=tacIsWeighted(d);
179 int i, j;
180 for(i=0; i<d->sampleNr; i++) {
181 if(!isfinite(xi[i]) || !isfinite(xa[i])) continue;
182 if(weighted && !(d->w[i]>0.0)) continue;
183 for(j=0; j<d->tacNr; j++) if(isfinite(d->c[j].y[i])) break;
184 if(j==d->tacNr) continue;
185 if(isnan(mi) || isnan(ma)) {mi=xi[i]; ma=xa[i]; continue;}
186 if(xi[i]<mi) mi=xi[i]; else if(xa[i]>ma) ma=xa[i];
187 }
188 if(xmin!=NULL) *xmin=mi;
189 if(xmax!=NULL) *xmax=ma;
190 if(!isfinite(mi) || !isfinite(ma)) return(2);
191 return(0);
192}
193/*****************************************************************************/
194
195/*****************************************************************************/
203 TAC *d
204) {
205 if(d==NULL || !(d->sampleNr>0)) return(-1);
206 int imin=-1; double xmin=nan("");
207 for(int i=0; i<d->sampleNr; i++) {
208 double t1; if(d->isframe) t1=0.5*(d->x1[i]+d->x2[i]); else t1=d->x[i];
209 if(!isfinite(t1)) continue;
210 if(!isfinite(xmin) || imin<0 || t1<xmin) {xmin=t1; imin=i; continue;}
211 }
212 return(imin);
213}
214/*****************************************************************************/
215
216/*****************************************************************************/
228 TAC *d
229) {
230 if(d==NULL || d->sampleNr<1) return(0);
231 double a, b;
232 if(tacXRange(d, &a, &b)) return(0);
233 if(fabs(a)<1.0E-30 && fabs(b)<1.0E-30) return(0);
234 if(fabs(a)<1.0E-30 && fabs(a-b)<1.0E-30) return(0);
235 return(1);
236}
237/*****************************************************************************/
238
239/*****************************************************************************/
251 TAC *d1,
254 TAC *d2,
256 const int verbose
257) {
258 if(verbose>0) printf("\n%s()\n", __func__);
259
260 /* Check data */
261 if(d1==NULL || d2==NULL) return 0;
262 double xmin[2], xmax[2];
263 if(tacXRange(d1, xmin, xmax) || tacXRange(d2, xmin+1, xmax+1)) return(0);
264
265 /* Which has less samples? */
266 int smaller_sampleNr;
267 if(d1->sampleNr<d2->sampleNr) smaller_sampleNr=d1->sampleNr;
268 else smaller_sampleNr=d2->sampleNr;
269 if(verbose>1) printf("smaller_sampleNr := %d\n", smaller_sampleNr);
270 if(smaller_sampleNr<=0) return 0;
271
272 /* Get conversion factors for sample times to get those in sec */
273 double ts1, ts2;
275 if(isnan(ts1)) {
276 if(verbose>1) printf("cannot convert tac1 sample times to sec.\n");
277 ts1=1.0; if(d1->tunit==UNIT_UNKNOWN) ts1=60.0; // assuming min
278 }
280 if(isnan(ts2)) {
281 if(verbose>1) printf("cannot convert tac2 sample times to sec.\n");
282 ts2=1.0; if(d2->tunit==UNIT_UNKNOWN) ts2=60.0; // assuming min
283 }
284 /* Convert time ranges to sec */
285 xmin[0]*=ts1; xmax[0]*=ts1;
286 xmin[1]*=ts2; xmax[1]*=ts2;
287 if(verbose>1) {
288 printf("tac1->isframe := %d\n", d1->isframe);
289 if(verbose>2) printf("time_range1 := %g - %g\n", xmin[0], xmax[0]);
290 printf("tac2->isframe := %d\n", d2->isframe);
291 if(verbose>2) printf("time_range2 := %g - %g\n", xmin[1], xmax[1]);
292 }
293
294 /* Set the accepted time difference */
295 double f, accepted_timedif=2.2; // sec
296 /* With short study the accepted time difference must be shorter */
297 f=xmax[0]-xmin[0]; if((xmax[1]-xmin[1])>f) f=xmax[1]-xmin[1];
298 f*=0.01; if(accepted_timedif>f) accepted_timedif=f;
299 if(verbose>1) {
300 printf("accepted_timedif := %g [s]\n", accepted_timedif);
301 fflush(stdout);
302 }
303
304 /* Compare sample times frame-by-frame */
305 int fi, n=0;
306 if(d1->isframe==0 && d2->isframe==0) {
307 if(verbose>2) {printf("frame mid times\n"); fflush(stdout);}
308 for(fi=0; fi<smaller_sampleNr; fi++) {
309 if(d1->x[fi]*ts1==d2->x[fi]*ts2) continue;
310 if(isnan(d1->x[fi]) && isnan(d2->x[fi])) continue; // match if both NaN
311 if(isnan(d1->x[fi]) || isnan(d2->x[fi])) {n++; continue;} // no match
312 f=fabs(d1->x[fi]*ts1-d2->x[fi]*ts2);
313 if(verbose>3) printf("timedif[%d] := %g\n", fi, f);
314 if(verbose>4) printf(" %g vs %g\n", ts1*d1->x[fi], ts2*d2->x[fi]);
315 if(f>accepted_timedif) n++;
316 }
317 } else if(d1->isframe!=0 && d2->isframe!=0) {
318 if(verbose>2) {printf("frame start and end times\n"); fflush(stdout);}
319 for(fi=0; fi<smaller_sampleNr; fi++) {
320 if(d1->x1[fi]*ts1==d2->x1[fi]*ts2) continue;
321 if(isnan(d1->x1[fi]) && isnan(d2->x1[fi])) continue; // match if both NaN
322 if(isnan(d1->x1[fi]) || isnan(d2->x1[fi])) {n++; continue;} // no match
323 f=fabs(d1->x1[fi]*ts1-d2->x1[fi]*ts2);
324 if(verbose>3) printf("timedif[%d] := %g\n", fi, f);
325 if(verbose>4) printf(" %g vs %g\n", ts1*d1->x1[fi], ts2*d2->x1[fi]);
326 if(f>accepted_timedif) n++;
327 }
328 for(fi=0; fi<smaller_sampleNr; fi++) {
329 if(d1->x2[fi]*ts1==d2->x2[fi]*ts2) continue;
330 if(isnan(d1->x2[fi]) && isnan(d2->x2[fi])) continue; // match if both NaN
331 if(isnan(d1->x2[fi]) || isnan(d2->x2[fi])) {n++; continue;} // no match
332 f=fabs(d1->x2[fi]*ts1-d2->x2[fi]*ts2);
333 if(verbose>3) printf("timedif[%d] := %g\n", fi, f);
334 if(verbose>4) printf(" %g vs %g\n", ts1*d1->x2[fi], ts2*d2->x2[fi]);
335 if(f>accepted_timedif) n++;
336 }
337 } else {
338 if(verbose>2) {printf("mixed frame times\n"); fflush(stdout);}
339 double x1, x2;
340 for(fi=0; fi<smaller_sampleNr; fi++) {
341 if(d1->isframe) x1=0.5*(d1->x1[fi]+d1->x2[fi]); else x1=d1->x[fi];
342 if(d2->isframe) x2=0.5*(d2->x1[fi]+d2->x2[fi]); else x2=d2->x[fi];
343 if(x1*ts1==x2*ts2) continue;
344 if(isnan(x1) && isnan(x2)) continue; // match if both NaN
345 if(isnan(x1) || isnan(x2)) {n++; continue;} // no match
346 f=fabs(x1*ts1-x2*ts2);
347 if(verbose>3) printf("timedif[%d] := %g\n", fi, f);
348 if(verbose>4) printf(" %g vs %g\n", x1, x2);
349 if(f>accepted_timedif) n++;
350 }
351 }
352 if(verbose>2) {printf("nr of different frame times := %d\n", n); fflush(stdout);}
353 if(n==0) return 1; else return 0;
354}
355/*****************************************************************************/
356
357/*****************************************************************************/
368 TAC *d,
370 TPCSTATUS *status
371) {
372 int verbose=0; if(status!=NULL) verbose=status->verbose;
373 if(verbose>0) printf("%s()\n", __func__);
374 if(d==NULL || d->_sampleNr<1 || d->_tacNr<1) {
375 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_FAIL);
376 return TPCERROR_FAIL;
377 }
378
379 /* Check if we already have the zero sample */
380 if(d->sampleNr>0) {
381 if((d->isframe && d->x1[0]<=0.0) || (!d->isframe && d->x[0]<=0.0)) {
382 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OK);
383 return TPCERROR_OK;
384 }
385 }
386
387 /* If we have no samples at all, but space for samples, then just make one */
388 if(d->sampleNr==0 && d->_sampleNr>0) {
389 d->x[0]=d->x1[0]=d->x2[0]=0.0; d->sampleNr=1;
390 for(int j=0; j<d->tacNr; j++) d->c[j].y[0]=0.0;
391 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OK);
392 return TPCERROR_OK;
393 }
394
395 /* Add space for one more sample */
396 int ret;
397 ret=tacAllocateMoreSamples(d, 1);
398 if(ret!=TPCERROR_OK) {statusSet(status, __func__, __FILE__, __LINE__, ret); return ret;}
399
400 /* Move all data to make room for the zero sample */
401 for(int fi=d->sampleNr; fi>0; fi--) {
402 d->x[fi]=d->x[fi-1]; d->x1[fi]=d->x1[fi-1]; d->x2[fi]=d->x2[fi-1];
403 for(int ri=0; ri<d->tacNr; ri++) d->c[ri].y[fi]=d->c[ri].y[fi-1];
404 d->w[fi]=d->w[fi-1];
405 } // previous sample
406 d->sampleNr++;
407 /* ... and then add the zero sample */
408 for(int ri=0; ri<d->tacNr; ri++) d->c[ri].y[0]=0.0;
409 if(!d->isframe) {
410 d->x[0]=d->x1[0]=d->x2[0]=0.0;
411 } else {
412 d->x1[0]=0.0; d->x2[0]=d->x1[1]; d->x[0]=0.5*(d->x1[0]+d->x2[0]);
413 }
414
415 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OK);
416 return TPCERROR_OK;
417}
418/*****************************************************************************/
419
420/*****************************************************************************/
428 TAC *d,
430 int i
431) {
432 if(d==NULL || i<0 || i>=d->sampleNr) return TPCERROR_FAIL;
433 int fi, ri;
434 for(fi=i+1; fi<d->sampleNr; fi++) {
435 d->x[fi-1]=d->x[fi]; d->x1[fi-1]=d->x1[fi]; d->x2[fi-1]=d->x2[fi];
436 for(ri=0; ri<d->tacNr; ri++) d->c[ri].y[fi-1]=d->c[ri].y[fi];
437 d->w[fi-1]=d->w[fi];
438 }
439 d->sampleNr--;
440 return TPCERROR_OK;
441}
442/*****************************************************************************/
443
444/*****************************************************************************/
452 TAC *d
453) {
454 if(d==NULL) return TPCERROR_FAIL;
455 int fi, ri, n, delthat=0;
456 fi=d->sampleNr-1;
457 while(fi>=0) {
458 delthat=0;
459 /* check the x value(s) for this sample */
460 if(d->isframe) {
461 if(!isfinite(d->x1[fi]) || !isfinite(d->x2[fi])) delthat=1;
462 } else {
463 if(!isfinite(d->x[fi])) delthat=1;
464 }
465 /* check the y value(s) for this sample */
466 for(ri=n=0; ri<d->tacNr; ri++) if(isfinite(d->c[ri].y[fi])) n++;
467 if(n==0) delthat=1;
468 if(delthat!=0) {
469 /* delete sample */
470 tacDeleteSample(d, fi);
471 }
472 /* go to previous sample */
473 fi--;
474 }
475 return TPCERROR_OK;
476}
477/*****************************************************************************/
478
479/*****************************************************************************/
488 TAC *d1,
492 TAC *d2,
494 double startT,
496 double endT
497) {
498 if(d1==NULL || d2==NULL) return TPCERROR_FAIL;
499 if(d1->sampleNr<1) return TPCERROR_NO_DATA;
500 if(endT<startT) return TPCERROR_INVALID_VALUE;
501
502 /* Duplicate source TAC, in case target points to the same data */
503 TAC tac; tacInit(&tac); if(tacDuplicate(d1, &tac)!=TPCERROR_OK) return TPCERROR_FAIL;
504
505 /* Remove any old contents in target structure */
506 tacFree(d2);
507
508 /* Get the range of TAC frame middle times */
509 double beg, end;
510 if(tac.isframe) {
511 beg=0.5*(tac.x1[0]+tac.x2[0]);
512 end=0.5*(tac.x1[tac.sampleNr-1]+tac.x2[tac.sampleNr-1]);
513 } else {
514 beg=tac.x[0]; end=tac.x[tac.sampleNr-1];
515 }
516
517 /* Check whether required range is outside the TAC range */
518 if(startT>=end || endT<beg) {tacFree(&tac); return TPCERROR_NO_DATA;}
519
520 /* If the whole TAC is inside required range, then just copy it */
521 if(startT<=beg && endT>=end) {
522 int ret=tacDuplicate(&tac, d2);
523 tacFree(&tac); return(ret);
524 }
525
526 /* Count how many samples are inside the required range */
527 /* And get the first and last sample indices */
528 int i, n=0, i1=-1, i2=-1;
529 double x;
530 for(i=0; i<tac.sampleNr; i++) {
531 if(tac.isframe) x=0.5*(tac.x1[i]+tac.x2[i]); else x=tac.x[i];
532 if(x<startT) continue;
533 if(x>endT) break;
534 i2=i; if(i1<0) i1=i;
535 n++;
536 }
537 if(n==0 || i1<0 || i2<i1) {tacFree(&tac); return TPCERROR_NO_DATA;}
538
539 /* Allocate memory for the data to be extracted */
540 int ret;
541 ret=tacAllocate(d2, n, tac.tacNr); if(ret!=TPCERROR_OK) {tacFree(&tac); return(ret);}
542 d2->sampleNr=n;
543 d2->tacNr=tac.tacNr;
544
545 /* Copy the contents */
546 ret=tacCopyHdr(&tac, d2); if(ret!=TPCERROR_OK) {tacFree(&tac); return(ret);}
547 for(int j=0, ret=0; j<tac.tacNr && ret==0; j++)
548 ret=tacCopyTacchdr(&tac.c[j], &d2->c[j]);
549 if(ret!=TPCERROR_OK) {tacFree(&tac); return(ret);}
550 d2->isframe=tac.isframe;
551 d2->weighting=tac.weighting;
552 for(i=i1, n=0; i<=i2 && n<d2->sampleNr; i++, n++) {
553 d2->x[n]=tac.x[i]; d2->x1[n]=tac.x1[i]; d2->x2[n]=tac.x2[i];
554 d2->w[n]=tac.w[i];
555 for(int j=0; j<tac.tacNr; j++) d2->c[j].y[n]=tac.c[j].y[i];
556 }
557 tacFree(&tac);
558 return TPCERROR_OK;
559}
560/*****************************************************************************/
561
562/*****************************************************************************/
570 TAC *d1,
572 TAC *d2,
574 int si,
576 int ei
577) {
578 if(d1==NULL || d2==NULL) return TPCERROR_FAIL;
579 if(d1->sampleNr<1) return TPCERROR_NO_DATA;
580 if(si<0 || ei<si || si>d1->sampleNr-1) return TPCERROR_INVALID_VALUE;
581 if(ei>d1->sampleNr-1) ei=d1->sampleNr-1;
582
583 /* Remove any old contents in target struct */
584 tacFree(d2);
585
586 /* If the whole TAC is inside required range, then just copy it */
587 if(si==0 && ei==d1->sampleNr-1) return(tacDuplicate(d1, d2));
588
589 /* Count how many samples are inside the required range */
590 int n=1+ei-si; if(n==0) return TPCERROR_NO_DATA;
591
592 /* Allocate memory for the data to be extracted */
593 int ret=tacAllocate(d2, n, d1->tacNr); if(ret!=TPCERROR_OK) return(ret);
594 d2->sampleNr=n;
595 d2->tacNr=d1->tacNr;
596
597 /* Copy the contents */
598 ret=tacCopyHdr(d1, d2); if(ret!=TPCERROR_OK) return(ret);
599 for(int j=0, ret=0; j<d1->tacNr && ret==0; j++) ret=tacCopyTacchdr(&d1->c[j], &d2->c[j]);
600 if(ret!=TPCERROR_OK) return(ret);
601 d2->isframe=d1->isframe;
602 d2->weighting=d1->weighting;
603 for(int i=si, n=0; i<=ei && n<d2->sampleNr; i++, n++) {
604 d2->x[n]=d1->x[i]; d2->x1[n]=d1->x1[i]; d2->x2[n]=d1->x2[i];
605 d2->w[n]=d1->w[i];
606 for(int j=0; j<d1->tacNr; j++) d2->c[j].y[n]=d1->c[j].y[i];
607 }
608
609 return TPCERROR_OK;
610}
611/*****************************************************************************/
612
613/*****************************************************************************/
624 TAC *d
625) {
626 if(d==NULL || d->sampleNr<1) return(0);
627 int i, n;
628 double x1, x2, x, dx;
629
630 for(i=n=0; i<d->sampleNr; i++) {
631 x1=d->x1[i]; x2=d->x2[i]; dx=x2-x1; x=0.5*(x1+x2);
632 /* if not similar, or both missing (NaN), that is considered as non-match */
633 if(!doubleMatch(x, d->x[i], 0.15*dx)) {n++; break;}
634 /* check that there is not much overlap with previous sample */
635 if(i>0 && (x1+0.15*dx)<d->x2[i-1]) {n++; break;}
636 /* check that there is not much gap on both sides */
637 if(i>0 && i<d->sampleNr-1) {
638 if(x1-0.15*dx>d->x2[i-1] && x2+0.15*dx<d->x1[i+1]) {n++; break;}
639 }
640 }
641 if(n>0) return(0); else return(1);
642}
643/*****************************************************************************/
644
645/*****************************************************************************/
658 TAC *d,
660 TPCSTATUS *status
661) {
662 int verbose=0; if(status!=NULL) verbose=status->verbose;
663 if(verbose>0) printf("%s()\n", __func__);
664
665 if(d==NULL) {
666 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_FAIL);
667 return TPCERROR_FAIL;
668 }
669 if(d->sampleNr==0) {
670 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OK);
671 return TPCERROR_OK;
672 }
673 /* Check that some x values are there to begin with */
674 if(!tacIsX(d)) {
675 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_X);
676 return TPCERROR_NO_X;
677 }
678
679 /* If x1 and x2 are set, then calculate x for each sample */
680 if(d->isframe) {
681 if(verbose>1) printf("calculating x[] based on x1[] and x2[].\n");
682 int i, n, ret;
683 for(i=n=0; i<d->sampleNr; i++) {
684 d->x[i]=0.5*(d->x1[i]+d->x2[i]);
685 if(isfinite(d->x[i])) n++;
686 }
687 if(n>0) ret=TPCERROR_OK; else ret=TPCERROR_NO_X;
688 statusSet(status, __func__, __FILE__, __LINE__, ret);
689 return(ret);
690 }
691
692 /* We should start guessing x1 and x2 values based on their averages in x */
693 if(verbose>1) printf("estimating x1[] and x2[] based on x[].\n");
694
695 /* If reasonable x1 and x2 values already are set, then quit */
696 if(tacCheckX1X2X(d)) {
697 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OK);
698 return TPCERROR_OK;
699 }
700
701 /* If only one sample, then set x1=0 and x2=2*x, and quit */
702 if(d->sampleNr==1) {
703 if(verbose>2) printf("just one sample.\n");
704 if(d->x[0]<=0.0) {d->x1[0]=2.0*d->x[0]; d->x2[0]=0.0;}
705 else {d->x1[0]=0.0; d->x2[0]=2.0*d->x[0];}
706 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OK);
707 return TPCERROR_OK;
708 }
709
710 /* If only two samples */
711 if(d->sampleNr==2) {
712 if(verbose>2) printf("just two samples.\n");
713 if(d->x[0]>0.0 && 2.0*d->x[0]<0.95*d->x[1]) {
714 d->x1[0]=0.0; d->x2[0]=2.0*d->x[0];
715 d->x1[1]=d->x2[0]; d->x2[1]=d->x2[0]+2.0*(d->x[1]-d->x2[0]);
716 } else {
717 double f; f=d->x[1]-d->x[0];
718 d->x1[0]=d->x[0]-0.5*f; d->x2[0]=d->x[0]+0.5*f;
719 d->x1[1]=d->x2[0]; d->x2[1]=d->x2[0]+2.0*f;
720 }
721 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OK);
722 return TPCERROR_OK;
723 }
724
725 int i, n, ret;
726
727 /* Allocate playground as TAC struct t */
728 TAC t; tacInit(&t);
729 n=d->tacNr; d->tacNr=1; ret=tacDuplicate(d, &t); d->tacNr=n;
730 if(ret==0) ret=tacAllocateMore(&t, 1);
731 if(ret) {
732 statusSet(status, __func__, __FILE__, __LINE__, ret);
733 return(ret);
734 }
735 double *x, *x1, *x2, *fa, *fb;
736 x=t.x; x1=t.x1; x2=t.x2; fa=t.c[0].y; fb=t.c[1].y;
737 n=t.sampleNr;
738
739 /* Convert playground times to sec if possible */
740 tacXUnitConvert(&t, UNIT_SEC, NULL);
741
742 /* Set each x1 and x1 to x */
743 for(i=0; i<n; i++) x1[i]=x2[i]=x[i];
744
745 /* Calculate the min gap, excluding zeroes */
746 double gap, v;
747 gap=nan("");
748 for(i=0; i<n-1; i++) {
749 v=x[i+1]-x[i]; if(!isfinite(v) || v<0.001) continue;
750 if(isnan(gap)) {gap=v; continue;}
751 if(v<gap) gap=v;
752 }
753
754 if(!isfinite(gap)) {
755 tacFree(&t);
756 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_X);
757 return(TPCERROR_NO_X);
758 }
759 if(verbose>2) printf("smallest gap := %g\n", gap);
760 /* Set gap to smallest step value for frame lengths */
761 if(t.tunit!=UNIT_SEC) {
762 gap*=0.01;
763 } else {
764 /* Set to 0.5 sec, unless calculated gap is smaller */
765 if(gap>0.5) gap=0.5;
766 }
767 if(verbose>2) printf("stepsize := %g\n", gap);
768
769 /* Initiate frame lengths to 0 */
770 for(i=0; i<n; i++) fa[i]=fb[i]=0.0;
771 int fixed[n]; for(i=0; i<n; i++) fixed[i]=0;
772
773 /* Iterate until gaps are as small as possible */
774 int anr=0;
775 do {
776 anr=0;
777 /* Set tentative frames to the last accepted frame lengths */
778 for(i=0; i<n; i++) fa[i]=fb[i];
779 /* Add fraction of gap to frames that have not yet been fixed */
780 for(i=0; i<n; i++) if(!fixed[i]) fa[i]+=gap;
781 /* Calculate x1 and x2 based on the tentative frames */
782 for(i=0; i<n; i++) {x1[i]=x[i]-0.5*fa[i]; x2[i]=x[i]+0.5*fa[i];}
783 /* If no overlap, then copy frame */
784 i=0;
785 if(x2[i]<=x1[i+1]+0.001*gap && (x[i]<=0.0 || x1[i]>-0.001*gap)) {
786 fb[i]=fa[i]; if(!fixed[i]) anr++;
787 } else
788 fixed[i]=1;
789 for(i=1; i<n-1; i++) {
790 if(x2[i]<=x1[i+1]+0.001*gap && x1[i]>=x2[i-1]-0.001*gap) {
791 fb[i]=fa[i]; if(!fixed[i]) anr++;} else fixed[i]=1;
792 }
793 if(x1[i]>=x2[i-1]-0.001*gap) {
794 fb[i]=fa[i]; if(!fixed[i]) anr++;} else fixed[i]=1;
795 if(verbose>5) {
796 printf("frames:");
797 for(i=0; i<n; i++) printf(" %g", fb[i]);
798 printf("\n");
799 }
800 } while(anr>0);
801
802 if(verbose>6) {
803 printf("temp frames:");
804 for(i=0; i<n; i++) printf(" %g", fa[i]);
805 printf("\n");
806 }
807
808 /* Calculate final frames */
809 for(i=0; i<n; i++) {x1[i]=x[i]-0.5*fb[i]; x2[i]=x[i]+0.5*fb[i];}
810
811 /* Convert playground to original time units */
812 tacXUnitConvert(&t, d->tunit, NULL);
813
814 /* Copy the guessed x1 and x2 values from playground */
815 t.isframe=1; tacXCopy(&t, d, 0, d->sampleNr-1);
816
817 /* Delete playground TAC */
818 tacFree(&t);
819
820 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OK);
821 return TPCERROR_OK;
822}
823/*****************************************************************************/
824
825/*****************************************************************************/
834 TAC *d,
838 double ilimit,
840 double *minfdur,
842 double *maxfdur
843) {
844 if(minfdur!=NULL) *minfdur=nan("");
845 if(maxfdur!=NULL) *maxfdur=nan("");
846 /* Check the data */
847 if(d==NULL || d->sampleNr<1) return(1);
848 double mi=nan(""), ma=nan("");
849 if(d->isframe) {
850 for(int i=0; i<d->sampleNr; i++) {
851 double f=d->x2[i]-d->x1[i];
852 if(!isnan(ilimit) && !(f>=ilimit)) continue;
853 if(isnan(mi) || f<mi) mi=f;
854 if(isnan(ma) || f>ma) ma=f;
855 }
856 } else {
857 for(int i=1; i<d->sampleNr; i++) {
858 double f=d->x[i]-d->x[i-1];
859 if(!isnan(ilimit) && !(f>=ilimit)) continue;
860 if(isnan(mi) || f<mi) mi=f;
861 if(isnan(ma) || f>ma) ma=f;
862 }
863 if(isnan(mi) || isnan(ma)) { // as the last resort use the time of first sample
864 double f=d->x[0];
865 if(f>0.0 && !isnan(ilimit) && f>=ilimit) {
866 if(isnan(mi)) mi=f;
867 if(isnan(ma)) ma=f;
868 }
869 }
870 }
871 if(minfdur!=NULL) *minfdur=mi;
872 if(maxfdur!=NULL) *maxfdur=ma;
873
874 if(minfdur!=NULL && isnan(mi)) return(2);
875 if(maxfdur!=NULL && isnan(ma)) return(2);
876
877 return(0);
878}
879/*****************************************************************************/
880
881/*****************************************************************************/
890 TAC *tac1,
893 TAC *tac2
894) {
895 if(tac1==NULL || tac2==NULL || tac1->sampleNr<1 || tac1->tacNr<1) return(1);
896 /* Make sure that frame start and end times are present */
897 if(tac1->isframe==0) return(2);
898 /* Remove any old contents in target struct */
899 tacFree(tac2);
900
901 /* Make a copy of the TAC data */
902 if(tacDuplicate(tac1, tac2)!=0) return(3);
903 /* Add room for more frames; we plot each frame as its own bar
904 and therefore we may need 4x the original space */
905 if(tacAllocateMoreSamples(tac2, 3*tac1->sampleNr)!=0) return(4);
906
907 /* Make separate 'samples' for each frame start and end time */
908 tac2->isframe=0;
909 int fj=0;
910 for(int fi=0; fi<tac1->sampleNr; fi++) {
911 /* Do nothing if missing values */
912 if(isnan(tac1->x1[fi]) || isnan(tac1->x2[fi])) continue;
913 if(tac1->tacNr==1 && isnan(tac1->c[0].y[fi])) continue;
914 /* Otherwise make bar of each frame */
915 tac2->x[fj]=tac1->x1[fi];
916 for(int ri=0; ri<tac2->tacNr; ri++) tac2->c[ri].y[fj]=0.0;
917 fj++;
918 tac2->x[fj]=tac1->x1[fi];
919 for(int ri=0; ri<tac2->tacNr; ri++) tac2->c[ri].y[fj]=tac1->c[ri].y[fi];
920 fj++;
921 tac2->x[fj]=tac1->x2[fi];
922 for(int ri=0; ri<tac2->tacNr; ri++) tac2->c[ri].y[fj]=tac1->c[ri].y[fi];
923 fj++;
924 tac2->x[fj]=tac1->x2[fi];
925 for(int ri=0; ri<tac2->tacNr; ri++) tac2->c[ri].y[fj]=0.0;
926 fj++;
927 }
928 tac2->sampleNr=fj;
929 if(fj<1) {tacFree(tac2); return(5);}
930 return(0);
931}
932/*****************************************************************************/
933
934/*****************************************************************************/
935#if(1)
947 TAC *inp,
949 TAC *out,
951 TPCSTATUS *status
952) {
953 int verbose=0; if(status!=NULL) verbose=status->verbose;
954 if(verbose>0) printf("%s()\n", __func__);
955 if(inp==NULL || out==NULL) {
956 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_FAIL);
957 return TPCERROR_FAIL;
958 }
959 /* Check the function input */
960 if(inp->sampleNr<1 || inp->tacNr<1) {
961 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_DATA);
962 return TPCERROR_NO_DATA;
963 }
964
965 /* Check that input does not have any missing values */
966 if(tacNaNs(inp)>0) {
967 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_MISSING_DATA);
969 }
970
971 /* Check that there are no gaps or overlap between frames */
972 {
973 //printf(" checking that there are no gaps or overlap\n"); fflush(stdout);
974 int ret=tacIsXContiguous(inp);
975 statusSet(status, __func__, __FILE__, __LINE__, ret);
976 if(ret!=TPCERROR_OK) return(ret);
977 }
978
979 /* First, duplicate the TAC data */
980 //printf(" copying data\n"); fflush(stdout);
981 if(tacDuplicate(inp, out)!=TPCERROR_OK) {
982 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_FAIL);
983 return TPCERROR_FAIL;
984 }
985
986 /* If frame start and end times are NOT present, then consider that work is done */
987 if(inp->isframe==0) return(TPCERROR_OK);
988
989 /* Add room for more frames */
990 //printf(" allocating memory for output\n"); fflush(stdout);
991 if(tacAllocateMoreSamples(out, 2+2*out->sampleNr)!=0) {
992 tacFree(out);
993 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OUT_OF_MEMORY);
995 }
996
997 /* Make separate 'samples' for each frame start and end time */
998 out->isframe=0;
999 out->sampleNr=0;
1000 /* Add zero sample at zero time if data starts later */
1001 if(inp->x1[0]>0.01*(inp->x2[0]-inp->x1[0])) {
1002 if(verbose>10) printf(" add zero sample\n");
1003 out->x[0]=0.0;
1004 for(int ri=0; ri<out->tacNr; ri++) out->c[ri].y[0]=0.0;
1005 out->sampleNr++;
1006 }
1007 /* Add zero sample at the start of the first frame */
1008 if(verbose>10) printf(" add first frame zero sample\n");
1009 out->x[out->sampleNr]=inp->x1[0];
1010 for(int ri=0; ri<out->tacNr; ri++) out->c[ri].y[out->sampleNr]=0.0;
1011 out->sampleNr++;
1012
1013 /* Add frame start and end times */
1014 for(int fi=0; fi<inp->sampleNr; fi++) {
1015 if(verbose>10) printf(" frame %d: %g - %g\n", 1+fi, inp->x1[fi], inp->x2[fi]);
1016 /* add start sample, if any of y values differs from previous one */
1017 out->x[out->sampleNr]=out->x[out->sampleNr-1];
1018// if(fi==0) out->x[out->sampleNr]=inp->x1[fi];
1019// else out->x[out->sampleNr]=out->x[out->sampleNr-1];
1020 int dn=0;
1021 for(int ri=0; ri<out->tacNr; ri++) {
1022 out->c[ri].y[out->sampleNr]=inp->c[ri].y[fi];
1023 if(out->c[ri].y[out->sampleNr]!=out->c[ri].y[out->sampleNr-1]) dn++;
1024 }
1025 if(dn>0) out->sampleNr++;
1026 /* add end sample */
1027 out->x[out->sampleNr]=inp->x2[fi];
1028 for(int ri=0; ri<out->tacNr; ri++)
1029 out->c[ri].y[out->sampleNr]=inp->c[ri].y[fi];
1030 out->sampleNr++;
1031 }
1032
1033 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OK);
1034 return(TPCERROR_OK);
1035}
1036#else
1048 TAC *inp,
1050 TAC *out,
1052 TPCSTATUS *status
1053) {
1054 int verbose=0; if(status!=NULL) verbose=status->verbose;
1055 if(verbose>0) printf("%s()\n", __func__);
1056 if(inp==NULL || out==NULL) {
1057 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_FAIL);
1058 return TPCERROR_FAIL;
1059 }
1060 /* Check the function input */
1061 if(inp->sampleNr<1 || inp->tacNr<1) {
1062 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_DATA);
1063 return TPCERROR_NO_DATA;
1064 }
1065
1066 /* Check that input does not have any missing values */
1067 if(tacNaNs(inp)>0) {
1068 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_MISSING_DATA);
1069 return TPCERROR_MISSING_DATA;
1070 }
1071
1072 /* First, duplicate the TAC data */
1073 if(tacDuplicate(inp, out)!=TPCERROR_OK) {
1074 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_FAIL);
1075 return TPCERROR_FAIL;
1076 }
1077
1078 /* Make sure that frame start and end times are present */
1079 if(inp->isframe==0) return(TPCERROR_OK); // if not, consider that work is done
1080
1081 /* Add room for more frames */
1082 if(tacAllocateMoreSamples(out, 1+2*out->sampleNr)!=0) {
1083 tacFree(out);
1084 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OUT_OF_MEMORY);
1086 }
1087
1088 /* Make separate 'samples' for each frame start and end time */
1089 out->isframe=0;
1090 int fi=0, fj=0;
1091 if(fabs(inp->x1[fi])>1.0E-20) { // add zero sample, if data does not already have it
1092 out->x[fj]=inp->x1[fi];
1093 for(int ri=0; ri<out->tacNr; ri++) out->c[ri].y[fj]=0.0;
1094 fj++;
1095 }
1096 for(fi=0; fi<inp->sampleNr; fi++) {
1097 if(fi>0 && inp->x1[fi]<inp->x2[fi-1]) { // overlap
1098 double x=0.5*(inp->x1[fi]+inp->x2[fi-1]);
1099 if(x<out->x[fj-2]) { // too large overlap
1100 tacFree(out);
1101 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OVERLAPPING_DATA);
1103 }
1104 out->x[fj-1]=out->x[fj]=x;
1105 } else { // no overlap
1106 out->x[fj]=inp->x1[fi];
1107 }
1108 for(int ri=0; ri<out->tacNr; ri++) out->c[ri].y[fj]=inp->c[ri].y[fi];
1109 fj++;
1110 out->x[fj]=inp->x2[fi];
1111 for(int ri=0; ri<out->tacNr; ri++) out->c[ri].y[fj]=inp->c[ri].y[fi];
1112 fj++;
1113 }
1114 out->sampleNr=fj;
1115
1116 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OK);
1117 return(TPCERROR_OK);
1118}
1119#endif
1120/*****************************************************************************/
1121
1122/*****************************************************************************/
1132 TAC *d
1133) {
1134 if(d==NULL) return TPCERROR_FAIL;
1135 if(tacXNaNs(d)>0) return(TPCERROR_INVALID_X);
1136
1137 /* If no frame start and end times, then just check the order */
1138 if(d->isframe==0) {
1139 if(tacVerifyTimeOrder(d, NULL)) return(TPCERROR_INVALID_XRANGE);
1140 return TPCERROR_OK;
1141 }
1142
1143 /* Check each frame */
1144 for(int fi=0; fi<d->sampleNr-1; fi++) {
1145 double e=d->x2[fi]-d->x1[fi+1];
1146 if(e<0.0) return(TPCERROR_LARGE_GAP);
1147 if(e>0.0) return(TPCERROR_OVERLAPPING_DATA);
1148 }
1149
1150 return(TPCERROR_OK);
1151}
1152/*****************************************************************************/
1153
1154/*****************************************************************************/
1168 TAC *d
1169) {
1170 if(d==NULL) return TPCERROR_FAIL;
1171 if(tacXNaNs(d)>0) return(TPCERROR_INVALID_X);
1172
1173 /* If no frame start and end times, then just make the times increasing */
1174 if(d->isframe==0) return(tacSortByTime(d, NULL));
1175
1176 /* If there are no gaps or overlap, then we're done */
1178
1179 /* Make a duplicate for editing */
1180 TAC tac; tacInit(&tac);
1181 int ret=tacDuplicate(d, &tac); if(ret!=TPCERROR_OK) return(ret);
1182
1183 /* Check for small frame overlaps or gaps; fix small, and return error if large overlap */
1184 int fixed=0, large=0;
1185 for(int fi=0; fi<d->sampleNr-1; fi++) {
1186 double dif=d->x1[fi+1]-d->x2[fi]; if(dif==0.0) continue; // not gap or overlap
1187 double fdur1=d->x2[fi]-d->x1[fi];
1188 double fdur2=d->x2[fi+1]-d->x1[fi+1];
1189 if(dif>0) { // gap
1190 if(dif<0.2*fdur1 && dif<0.2*fdur2) { // small gap; increase the shorter frame duration
1191 if(fdur1<fdur2) tac.x2[fi]=d->x1[fi+1]; else tac.x1[fi+1]=d->x2[fi];
1192 fixed++;
1193 } else {
1194 large++; // large gap not fixed yet
1195 }
1196 continue;
1197 }
1198 /* Overlap */
1199 dif=-dif;
1200 if(dif>0.2*fdur1 || dif>0.2*fdur2) { // too large overlap
1201 tacFree(&tac); return(TPCERROR_OVERLAPPING_DATA);
1202 }
1203 /* Reduce the longer frame length */
1204 if(fdur1>fdur2) tac.x2[fi]=d->x1[fi+1]; else tac.x1[fi+1]=d->x2[fi];
1205 fixed++;
1206 }
1207
1208 /* If we fixed something, then copy the fixed frame times */
1209 if(fixed>0) {
1210 for(int i=0; i<d->sampleNr; i++) {
1211 d->x1[i]=tac.x1[i]; d->x2[i]=tac.x2[i]; d->x[i]=0.5*(d->x1[i]+d->x2[i]);
1212 }
1213 }
1214
1215 /* If there were no large gaps, we're done */
1216 if(large==0) {tacFree(&tac); return(TPCERROR_OK);}
1217
1218 /* Fill large gaps with new frames */
1220 if(tacAllocateMoreSamples(d, large)!=0) {
1221 tacFree(&tac); return(TPCERROR_OUT_OF_MEMORY);
1222 }
1223 d->sampleNr=1;
1224 for(int fi=1; fi<tac.sampleNr; fi++) {
1225 double dif=tac.x1[fi]-tac.x2[fi-1];
1226 if(dif>0.0) {
1227 /* Add new frame times */
1228 d->x1[d->sampleNr]=tac.x2[fi-1]; d->x2[d->sampleNr]=tac.x1[fi];
1229 d->x[fi]=0.5*(d->x1[d->sampleNr]+d->x2[d->sampleNr]);
1230 /* Calculate y values for the new frame */
1231 double x1=0.5*(tac.x1[fi-1]+tac.x2[fi-1]);
1232 double x2=0.5*(tac.x1[fi]+tac.x2[fi]);
1233 for(int ri=0; ri<tac.tacNr; ri++) {
1234 double s=(tac.c[ri].y[fi]-tac.c[ri].y[fi-1])/(x2-x1);
1235 d->c[ri].y[d->sampleNr]=tac.c[ri].y[fi-1] + s*(d->x[fi]-x1);
1236 }
1237 d->sampleNr++;
1238 }
1239 /* copy the existing frame */
1240 d->x1[d->sampleNr]=tac.x1[fi]; d->x2[d->sampleNr]=tac.x2[fi];
1241 for(int ri=0; ri<tac.tacNr; ri++) d->c[ri].y[d->sampleNr]=tac.c[ri].y[fi];
1242 d->sampleNr++;
1243 }
1244
1245 tacFree(&tac);
1246 return(TPCERROR_OK);
1247}
1248/*****************************************************************************/
1249
1250/*****************************************************************************/
int doubleMatch(const double v1, const double v2, const double lim)
Definition doubleutil.c:27
void statusSet(TPCSTATUS *s, const char *func, const char *srcfile, int srcline, tpcerror error)
Definition statusmsg.c:142
double * y
Definition tpctac.h:75
Definition tpctac.h:87
double * x
Definition tpctac.h:97
int _sampleNr
Definition tpctac.h:121
int sampleNr
Definition tpctac.h:89
double * w
Definition tpctac.h:111
int isframe
Definition tpctac.h:95
TACC * c
Definition tpctac.h:117
weights weighting
Definition tpctac.h:115
int tunit
Definition tpctac.h:109
double * x2
Definition tpctac.h:101
int _tacNr
Definition tpctac.h:119
double * x1
Definition tpctac.h:99
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
int tacAllocate(TAC *tac, int sampleNr, int tacNr)
Definition tac.c:130
void tacInit(TAC *tac)
Definition tac.c:24
int tacAllocateMoreSamples(TAC *tac, int addNr)
Allocate memory for more samples in TAC data.
Definition tac.c:435
int tacAllocateMore(TAC *tac, int tacNr)
Definition tac.c:178
int tacCopyTacchdr(TACC *d1, TACC *d2)
Definition tac.c:282
int tacCopyHdr(TAC *tac1, TAC *tac2)
Copy TAC header data from tac1 to tac2.
Definition tac.c:310
int tacNaNs(TAC *tac)
Definition tacnan.c:71
int tacXNaNs(TAC *tac)
Definition tacnan.c:23
int tacSortByTime(TAC *d, TPCSTATUS *status)
Definition tacorder.c:74
int tacVerifyTimeOrder(TAC *d, TPCSTATUS *status)
Definition tacorder.c:25
int tacXUnitConvert(TAC *tac, const int u, TPCSTATUS *status)
Definition tacunits.c:23
int tacIsWeighted(TAC *tac)
Definition tacw.c:24
int tacSampleXRange(TAC *d, double *xmin, double *xmax)
Get the range of x values (times) in TAC structure.
Definition tacx.c:162
int tacXMatch(TAC *d1, TAC *d2, const int verbose)
Check whether sample (frame) times are the same (or very close to) in two TAC structures.
Definition tacx.c:249
int tacDeleteMissingSamples(TAC *d)
Delete those samples (time frames) from TAC structure, which contain only missing y values,...
Definition tacx.c:450
int tacIsXContiguous(TAC *d)
Check that PET TAC frame times are contiguous, without even tiny overlap or gaps in between.
Definition tacx.c:1130
int tacMinX(TAC *d)
Get the minimum x value in TAC structure.
Definition tacx.c:201
int tacCorrectFrameOverlap(TAC *d, TPCSTATUS *status)
Correct PET frame start and end times if frames are slightly overlapping or have small gaps in betwee...
Definition tacx.c:65
int tacFramesToSteps(TAC *inp, TAC *out, TPCSTATUS *status)
Transform TAC with frames into TAC with frames represented with stepwise changing dot-to-dot data.
Definition tacx.c:942
int tacAddZeroSample(TAC *d, TPCSTATUS *status)
Add an initial sample to TAC(s) with zero time and concentration.
Definition tacx.c:366
int tacExtractSamples(TAC *d1, TAC *d2, int si, int ei)
Extract the specified sample range from TAC structure.
Definition tacx.c:568
int tacToBars(TAC *tac1, TAC *tac2)
Transform TAC data with frame start and end times into suitable form for plotting with frames as bars...
Definition tacx.c:888
int tacDeleteSample(TAC *d, int i)
Delete a certain sample (time frame) from TAC structure.
Definition tacx.c:426
int tacGetSampleInterval(TAC *d, double ilimit, double *minfdur, double *maxfdur)
Get the shortest and longest sampling intervals or frame lengths in TAC structure.
Definition tacx.c:832
int tacXCopy(TAC *tac1, TAC *tac2, int i1, int i2)
Definition tacx.c:24
int tacExtractRange(TAC *d1, TAC *d2, double startT, double endT)
Extract the specified time (x) range from TAC structure.
Definition tacx.c:486
int tacSetX(TAC *d, TPCSTATUS *status)
Set TAC x values based on x1 and x2 values, or guess x1 and x2 values based on x values.
Definition tacx.c:653
int tacIsX(TAC *d)
Verify if TAC structure contains reasonable x values (times).
Definition tacx.c:226
int tacSetXContiguous(TAC *d)
Set PET TAC frame times contiguous, without even tiny overlap or gaps in between.
Definition tacx.c:1166
int tacXRange(TAC *d, double *xmin, double *xmax)
Get the range of x values (times) in TAC structure.
Definition tacx.c:124
int tacCheckX1X2X(TAC *d)
Check that sample (time frame) x, x1, and x2 values are reasonably set when compared to each other in...
Definition tacx.c:621
@ WEIGHTING_OFF
Not weighted or weights not available (weights for all included samples are 1.0).
@ UNIT_UNKNOWN
Unknown unit.
@ UNIT_SEC
seconds
@ TPCERROR_INVALID_XRANGE
Invalid sample time range.
@ TPCERROR_INVALID_VALUE
Invalid value.
@ TPCERROR_OVERLAPPING_DATA
Overlapping data.
@ TPCERROR_FAIL
General error.
@ TPCERROR_OUT_OF_MEMORY
Cannot allocate memory.
@ TPCERROR_INVALID_X
Invalid sample time.
@ TPCERROR_NO_X
No sample times.
@ TPCERROR_OK
No error.
@ TPCERROR_LARGE_GAP
Large gap in data.
@ TPCERROR_NO_DATA
File contains no data.
@ TPCERROR_MISSING_DATA
File contains missing values.
double unitConversionFactor(const int u1, const int u2)
Definition units.c:487
Header file for library libtpcift.
Header file for library libtpctac.