TPCCLIB
Loading...
Searching...
No Matches
tacorder.c
Go to the documentation of this file.
1
4/*****************************************************************************/
5#include "tpcclibConfig.h"
6/*****************************************************************************/
7#include <stdio.h>
8#include <stdlib.h>
9#include <math.h>
10#include <time.h>
11#include <string.h>
12/*****************************************************************************/
13#include "tpctac.h"
14/*****************************************************************************/
15
16/*****************************************************************************/
27 TAC *d,
29 TPCSTATUS *status
30) {
31 int verbose=0; if(status!=NULL) verbose=status->verbose;
32 if(verbose>0) printf("%s()\n", __func__);
33 /* Check that required data exists */
34 if(d==NULL || d->sampleNr<1) {
35 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_DATA);
36 return TPCERROR_NO_DATA;
37 }
38 /* All sample times must be available */
39 if(tacXNaNs(d)>0) {
40 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_MISSING_DATA);
42 }
43 /* Less than two samples are always in order */
44 if(d->sampleNr<2) {
45 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OK);
46 return TPCERROR_OK;
47 }
48
49 int fi;
50 double p, s;
51
52 fi=0; if(d->isframe==0) p=d->x[fi]; else p=0.5*(d->x1[fi]+d->x2[fi]);
53 for(fi=1; fi<d->sampleNr; fi++) {
54 if(d->isframe==0) s=d->x[fi]; else s=0.5*(d->x1[fi]+d->x2[fi]);
55 if(s<p) {
56 if(verbose>2) printf("x[%d]=%g\nx[%d]=%g\n", fi-1, p, fi, s);
57 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OVERLAPPING_DATA);
59 }
60 p=s;
61 }
62 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OK);
63 return TPCERROR_OK;
64}
65/*****************************************************************************/
66
67/*****************************************************************************/
76 TAC *d,
78 TPCSTATUS *status
79) {
80 int verbose=0; if(status!=NULL) verbose=status->verbose;
81 if(verbose>0) printf("%s()\n", __func__);
82 /* Check that required data exists */
83 if(d==NULL || d->tacNr<1) {
84 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_DATA);
85 return TPCERROR_NO_DATA;
86 }
87 /* All sample times must be available */
88 if(tacXNaNs(d)>0) {
89 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_MISSING_DATA);
91 }
92 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OK);
93 if(d->sampleNr<1) return TPCERROR_OK;
94
95 TACC *c;
96 int ri, fi, fj;
97 double s, a1, a2;
98 for(fi=0; fi<d->sampleNr-1; fi++) for(fj=fi+1; fj<d->sampleNr; fj++) {
99 if(d->isframe==0) {a1=d->x[fi]; a2=d->x[fj];}
100 else {a1=0.5*(d->x1[fi]+d->x2[fi]); a2=0.5*(d->x1[fj]+d->x2[fj]);}
101 if(a2>=a1) continue;
102 s=d->x[fi]; d->x[fi]=d->x[fj]; d->x[fj]=s;
103 s=d->x1[fi]; d->x1[fi]=d->x1[fj]; d->x1[fj]=s;
104 s=d->x2[fi]; d->x2[fi]=d->x2[fj]; d->x2[fj]=s;
105 s=d->w[fi]; d->w[fi]=d->w[fj]; d->w[fj]=s;
106 for(ri=0; ri<d->tacNr; ri++) {
107 c=d->c+ri;
108 s=c->y[fi]; c->y[fi]=c->y[fj]; c->y[fj]=s;
109 }
110 }
111 return TPCERROR_OK;
112}
113/*****************************************************************************/
114
115/*****************************************************************************/
124 TAC *d,
126 const int i,
128 TPCSTATUS *status
129) {
130 int verbose=0; if(status!=NULL) verbose=status->verbose;
131 if(verbose>0) printf("%s()\n", __func__);
132 /* Check that required data exists */
133 if(d==NULL || d->tacNr<1) {
134 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_DATA);
135 return TPCERROR_NO_DATA;
136 }
137 if(i<0 || i>=d->_tacNr) {
138 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_FAIL);
139 return TPCERROR_FAIL;
140 }
141 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OK);
142 if(d->sampleNr<1) return TPCERROR_OK;
143
144 TACC *c;
145 int ri, fi, fj;
146 double s, a1, a2;
147 for(fi=0; fi<d->sampleNr-1; fi++) for(fj=fi+1; fj<d->sampleNr; fj++) {
148 a1=d->c[i].y[fi]; a2=d->c[i].y[fj];
149 if(a2<=a1) continue;
150 s=d->x[fi]; d->x[fi]=d->x[fj]; d->x[fj]=s;
151 s=d->x1[fi]; d->x1[fi]=d->x1[fj]; d->x1[fj]=s;
152 s=d->x2[fi]; d->x2[fi]=d->x2[fj]; d->x2[fj]=s;
153 s=d->w[fi]; d->w[fi]=d->w[fj]; d->w[fj]=s;
154 for(ri=0; ri<d->_tacNr; ri++) {
155 c=d->c+ri;
156 s=c->y[fi]; c->y[fi]=c->y[fj]; c->y[fj]=s;
157 }
158 }
159 return TPCERROR_OK;
160}
161/*****************************************************************************/
162
163/*****************************************************************************/
165
166static int tacQSortName(const void *c1, const void *c2)
167{
168 int res;
169 res=strcasecmp( ((TACC*)c1)->name, ((TACC*)c2)->name );
170 return(res);
171}
173
180 TAC *d,
182 TPCSTATUS *status
183) {
184 int verbose=0; if(status!=NULL) verbose=status->verbose;
185 if(verbose>0) printf("%s()\n", __func__);
186 /* Check that required data exists */
187 if(d==NULL) {
188 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_DATA);
189 return TPCERROR_NO_DATA;
190 }
191 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OK);
192 if(d->tacNr<2) return TPCERROR_OK;
193 qsort(d->c, d->tacNr, sizeof(TACC), tacQSortName);
194 return TPCERROR_OK;
195}
196/*****************************************************************************/
197
198/*****************************************************************************/
207 TAC *d,
209 TPCSTATUS *status
210) {
211 int verbose=0; if(status!=NULL) verbose=status->verbose;
212 if(verbose>0) printf("%s()\n", __func__);
213 /* Check that required data exists */
214 if(d==NULL) {
215 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_DATA);
216 return TPCERROR_NO_DATA;
217 }
218 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OK);
219 if(d->tacNr<2) return TPCERROR_OK;
220 /* Calculate AUCs for each TAC */
221 double auc[d->tacNr], fdur, v;
222 int i, j;
223 for(i=0; i<d->tacNr; i++) {
224 auc[i]=0.0;
225 for(j=0; j<d->sampleNr; j++) {
226 fdur=d->x2[0]-d->x1[0]; v=d->c[i].y[j];
227 if(isnan(fdur) || isnan(v)) continue;
228 auc[i]+=fdur*v;
229 }
230 }
231 /* Sort */
232 double a;
233 for(i=0; i<d->tacNr-1; i++)
234 for(j=i+1; j<d->tacNr; j++)
235 if(auc[j]>auc[i]) {
236 tacSwapTACCs(d, j, i);
237 a=auc[i]; auc[i]=auc[j]; auc[j]=a;
238 }
239 return TPCERROR_OK;
240}
241/*****************************************************************************/
242
243/*****************************************************************************/
252 TAC *d,
254 int from,
256 int to
257) {
258 int i;
259 TACC tacc;
260 size_t taccSize;
261
262 if(d==NULL || from<0 || to<0) return(TPCERROR_FAIL);
263 if(from>=d->_tacNr || to>=d->_tacNr) return(TPCERROR_FAIL);
264 if(from==to) return(TPCERROR_OK); // nothing to do
265 taccSize=sizeof(TACC);
266 memcpy(&tacc, d->c+from, taccSize);
267 if(from>to) for(i=from; i>to; i--)
268 memcpy(d->c+i, d->c+(i-1), taccSize);
269 else for(i=from; i<to; i++)
270 memcpy(d->c+i, d->c+(i+1), taccSize);
271 memcpy(d->c+i, &tacc, taccSize);
272 return(TPCERROR_OK);
273}
274/*****************************************************************************/
275
276/*****************************************************************************/
284 TAC *d,
286 int i1,
288 int i2
289) {
290 TACC tacc;
291 size_t taccSize;
292
293 if(d==NULL || i1<0 || i2<0) return(TPCERROR_FAIL);
294 if(i1>=d->_tacNr || i2>=d->_tacNr) return(TPCERROR_FAIL);
295 if(i1==i2) return(TPCERROR_OK); // nothing to do
296 taccSize=sizeof(TACC);
297 memcpy(&tacc, d->c+i1, taccSize);
298 memcpy(d->c+i1, d->c+i2, taccSize);
299 memcpy(d->c+i2, &tacc, taccSize);
300 return(TPCERROR_OK);
301}
302/*****************************************************************************/
303
304/*****************************************************************************/
312 TAC *d,
314 int i
315) {
316 /* Check that region exists */
317 if(d==NULL || i<0 || i>=d->tacNr) return(TPCERROR_FAIL);
318 /* If the last TACC is to be deleted, then just decrease the tacNr */
319 if(i==d->tacNr-1) {d->tacNr--; return(TPCERROR_OK);}
320 /* Otherwise move it to the last position, and then decrease tacNr */
321 if(tacMoveTACC(d, i, d->tacNr-1)!=TPCERROR_OK) return(TPCERROR_FAIL);
322 d->tacNr--;
323 return(TPCERROR_OK);
324}
325/*****************************************************************************/
326
327/*****************************************************************************/
338 TAC *d1,
340 const int fixMode,
343 TAC *d2,
345 const int verbose
346) {
347 if(verbose>0) {printf("\n%s(%d)\n", __func__, fixMode); fflush(stdout);}
348
349 /* Check data */
350 if(fixMode!=0 && (d1==NULL || d2==NULL || d1->sampleNr<1)) return(2);
351 if(d1==NULL || d1->sampleNr<2 || !tacIsX(d1)) return(0);
352
353 /* Set limit for similarity of sample times; the same sample times can have been saved in
354 files with variable precision. */
355 const double simlim=1.0E-03; if(verbose>1) printf(" limit := %g\n", simlim);
356
357 /* Check if there are any multiple samples */
358 int isMultiple=0;
359 for(int i=0; i<d1->sampleNr-1 && !isMultiple; i++) {
360 double t1; if(d1->isframe) t1=0.5*(d1->x1[i]+d1->x2[i]); else t1=d1->x[i];
361 for(int j=i+1; j<d1->sampleNr; j++) {
362 double t2; if(d1->isframe) t2=0.5*(d1->x1[j]+d1->x2[j]); else t2=d1->x[j];
363 double dt=fabs(t2-t1);
364 if(verbose>4) printf(" |%g - %g| = %g\n", t1, t2, dt);
365 if(dt<simlim) {isMultiple=1; break;}
366 }
367 }
368 if(verbose>1) {printf(" isMultiple := %d\n", isMultiple); fflush(stdout);}
369 if(fixMode==0) return(isMultiple); // done, if fixing not asked for
370
371 /* If there were no multiples, copy the input to output and quit */
372 if(!isMultiple) {
373 TAC itac; tacInit(&itac);
374 if(tacDuplicate(d1, &itac)!=TPCERROR_OK) return(3);
375 if(tacDuplicate(&itac, d2)!=TPCERROR_OK) {tacFree(&itac); return(3);}
376 tacFree(&itac); return(0);
377 }
378
379 /* Ok there are multiples that need to be fixed. */
380 /* We'll start by making a copy of the input data, and removing any existing data in
381 the output; copy is needed, because output structure can be the same as input */
382 TAC itac; tacInit(&itac); if(tacDuplicate(d1, &itac)!=TPCERROR_OK) return(4);
383 tacFree(d2);
384 /* Delete missing samples from the input */
385 tacDeleteMissingSamples(&itac); if(verbose>2) printf(" itac.sampleNr := %d\n", itac.sampleNr);
386 /* Allocate memory for the output data */
387 if(tacAllocate(d2, itac.sampleNr, itac.tacNr)!=TPCERROR_OK) {tacFree(&itac); return(5);}
388 if(tacCopyHdr(&itac, d2)!=TPCERROR_OK) {tacFree(&itac); return(6);}
389 for(int r=0; r<itac.tacNr; r++)
390 if(tacCopyTacchdr(&itac.c[r], &d2->c[r])!=TPCERROR_OK) {tacFree(&itac); return(7);}
392 d2->tacNr=itac.tacNr;
393
394 /* Go through the input data */
395 while(itac.sampleNr>0) {
396 /* Find the smallest sample time */
397 int i=tacMinX(&itac); if(i<0) break;
398 if(verbose>3) printf(" smallest x[%d]=%g\n", i, itac.x[i]);
399 /* Copy values to the first free output sample */
400 for(int r=0; r<itac.tacNr; r++) d2->c[r].y[d2->sampleNr]=0.0;
401 int rn[itac.tacNr]; for(int r=0; r<itac.tacNr; r++) rn[r]=0;
402 for(int r=0; r<itac.tacNr; r++)
403 if(isfinite(itac.c[r].y[i])) {
404 d2->c[r].y[d2->sampleNr]=itac.c[r].y[i];
405 rn[r]++;
406 }
407 d2->x[d2->sampleNr]=itac.x[i]; d2->x1[d2->sampleNr]=itac.x1[i]; d2->x2[d2->sampleNr]=itac.x2[i];
408 double t1; if(itac.isframe) t1=0.5*(itac.x1[i]+itac.x2[i]); else t1=itac.x[i];
409 /* Delete the sample from input */
410 tacDeleteSample(&itac, i);
411 /* Search the input for matching sample times */
412 while(itac.sampleNr>0) {
413 /* Find the smallest sample time left */
414 int i=tacMinX(&itac); if(i<0) break;
415 if(verbose>3) printf(" smallest x[%d]=%g\n", i, itac.x[i]);
416 double t2; if(itac.isframe) t2=0.5*(itac.x1[i]+itac.x2[i]); else t2=itac.x[i];
417 double dt=fabs(t2-t1); if(verbose>4) printf(" |%g - %g| = %g\n", t1, t2, dt);
418 if(!(dt<simlim)) break; // if this is not close enough, then none will be
419 /* Add values to the first free output sample */
420 for(int r=0; r<itac.tacNr; r++)
421 if(isfinite(itac.c[r].y[i])) {
422 d2->c[r].y[d2->sampleNr]+=itac.c[r].y[i];
423 rn[r]++;
424 }
425 /* Delete also this sample from input */
426 tacDeleteSample(&itac, i);
427 }
428 /* Divide values by the summed number of samples */
429 for(int r=0; r<itac.tacNr; r++) d2->c[r].y[d2->sampleNr]/=(double)rn[r];
430 /* Move to next output sample */
431 d2->sampleNr++;
432 }
433 tacFree(&itac);
434
435 /* Check that we got something left */
436 if(d2->sampleNr<1) return(10);
437
438 return(0);
439}
440/*****************************************************************************/
441
442/*****************************************************************************/
void statusSet(TPCSTATUS *s, const char *func, const char *srcfile, int srcline, tpcerror error)
Definition statusmsg.c:142
Definition tpctac.h:66
double * y
Definition tpctac.h:75
Definition tpctac.h:87
double * x
Definition tpctac.h:97
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
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.
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 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 tacXNaNs(TAC *tac)
Definition tacnan.c:23
int tacSortByTime(TAC *d, TPCSTATUS *status)
Definition tacorder.c:74
int tacSortByConc(TAC *d, const int i, TPCSTATUS *status)
Definition tacorder.c:122
int tacSortByAUC(TAC *d, TPCSTATUS *status)
Definition tacorder.c:205
int tacSortByName(TAC *d, TPCSTATUS *status)
Definition tacorder.c:178
int tacDeleteTACC(TAC *d, int i)
Definition tacorder.c:310
int tacVerifyTimeOrder(TAC *d, TPCSTATUS *status)
Definition tacorder.c:25
int tacSwapTACCs(TAC *d, int i1, int i2)
Definition tacorder.c:282
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...
Definition tacorder.c:336
int tacMoveTACC(TAC *d, int from, int to)
Definition tacorder.c:250
int tacDeleteMissingSamples(TAC *d)
Delete those samples (time frames) from TAC structure, which contain only missing y values,...
Definition tacx.c:450
int tacMinX(TAC *d)
Get the minimum x value in TAC structure.
Definition tacx.c:201
int tacDeleteSample(TAC *d, int i)
Delete a certain sample (time frame) from TAC structure.
Definition tacx.c:426
int tacIsX(TAC *d)
Verify if TAC structure contains reasonable x values (times).
Definition tacx.c:226
@ WEIGHTING_OFF
Not weighted or weights not available (weights for all included samples are 1.0).
@ TPCERROR_OVERLAPPING_DATA
Overlapping data.
@ TPCERROR_FAIL
General error.
@ TPCERROR_OK
No error.
@ TPCERROR_NO_DATA
File contains no data.
@ TPCERROR_MISSING_DATA
File contains missing values.
Header file for library libtpctac.