TPCCLIB
Loading...
Searching...
No Matches
parcomp.c File Reference

Comparison of PAR struct data. More...

#include "tpcclibConfig.h"
#include "tpcift.h"
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include <ctype.h>
#include <string.h>
#include <strings.h>
#include "tpcpar.h"

Go to the source code of this file.

Functions

int parCompareParameterNames (PAR *d1, PAR *d2, const int i, const int casens, TPCSTATUS *status)
int parCompareParameterUnits (PAR *d1, PAR *d2, const int i, TPCSTATUS *status)
int parCompareTacNames (PAR *d1, PAR *d2, const int i, const int casens, TPCSTATUS *status)
int parCompareParameters (PAR *d1, PAR *d2, const int pi, const int ti, int checkpar, int checksd, int checkcl, const double test_abs, const double test_rel, TPCSTATUS *status)
int parCompareWSS (PAR *d1, PAR *d2, const int ti, const double test_abs, const double test_rel, TPCSTATUS *status)

Detailed Description

Comparison of PAR struct data.

Definition in file parcomp.c.

Function Documentation

◆ parCompareParameterNames()

int parCompareParameterNames ( PAR * d1,
PAR * d2,
const int i,
const int casens,
TPCSTATUS * status )

Check whether parameter names are the same in two PAR data.

Comparison is very strict, thus the names may need to be preprocessed if this is used for other purpose than SW testing.

Returns
0 in case of match, 1 if no match or error.
Author
Vesa Oikonen
Parameters
d1Pointer to PAR struct.
d2Pointer to PAR struct.
iParameter index [0..parNr-1] to compare; enter <0 to verify all.
casensCase-sensitivity: 0=case does not have to match; <>0=case must match.
statusPointer to status data; enter NULL if not needed.

Definition at line 28 of file parcomp.c.

39 {
40 int verbose=0; if(status!=NULL) verbose=status->verbose;
41 if(verbose>1) printf("%s()\n", __func__);
42
43 /* Check that required data exists */
44 if(d1==NULL || d2==NULL || d1->parNr<1 || d2->parNr<1) {
45 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_DATA);
46 return 1;
47 }
48 /* If index is specified, then verify that that parameter is available */
49 if(i>=0 && (i>=d1->parNr || i>=d2->parNr)) {
50 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_FAIL);
51 return 1;
52 }
53
54 /* If index is not specified, then parNr must match */
55 if(i<0 && (d1->parNr!=d2->parNr)) {
56 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OK);
57 if(verbose>0) printf("different parameter nr.\n");
58 return(1);
59 }
60
61 /* Compare */
62 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OK);
63 int vr;
64 for(int pi=0; pi<d1->parNr; pi++) if(i<0 || i==pi) {
65 if(casens==0) vr=strcasecmp(d1->n[pi].name, d2->n[pi].name);
66 else vr=strcmp(d1->n[pi].name, d2->n[pi].name);
67 if(vr==0) continue;
68 /* No problem, if difference is '_' versus '-' */
69 if(strchr(d1->n[pi].name, '-') || strchr(d1->n[pi].name, '_')) {
70 char *buf1, *buf2;
71 buf1=strdup(d1->n[pi].name); strReplaceChar(buf1, '-', '_');
72 buf2=strdup(d2->n[pi].name); strReplaceChar(buf2, '-', '_');
73 if(verbose>100) printf("'%s' vs '%s'\n", buf1, buf2);
74 if(casens==0) vr=strcasecmp(buf1, buf2); else vr=strcmp(buf1, buf2);
75 free(buf1); free(buf2);
76 }
77 if(vr==0) continue;
78 /* No problem, if difference is '_' versus ' ' */
79 if(strchr(d1->n[pi].name, '_') || strchr(d2->n[pi].name, '_')) {
80 char *buf1, *buf2;
81 buf1=strdup(d1->n[pi].name); strReplaceChar(buf1, '_', ' ');
82 buf2=strdup(d2->n[pi].name); strReplaceChar(buf2, '_', ' ');
83 if(verbose>100) printf("'%s' vs '%s'\n", buf1, buf2);
84 if(casens==0) vr=strcasecmp(buf1, buf2); else vr=strcmp(buf1, buf2);
85 free(buf1); free(buf2);
86 }
87 if(vr==0) continue;
88 if(verbose>0) {
89 printf("par1.n[%d].name := '%s'\n", pi, d1->n[pi].name);
90 printf("par2.n[%d].name := '%s'\n", pi, d2->n[pi].name);
91 }
92 return(1);
93 }
94 return(0);
95}
void statusSet(TPCSTATUS *s, const char *func, const char *srcfile, int srcline, tpcerror error)
Definition statusmsg.c:142
void strReplaceChar(char *s, char c1, char c2)
Definition stringext.c:134
char * strdup(const char *s)
Definition stringext.c:185
int parNr
Definition tpcpar.h:108
PARN * n
Definition tpcpar.h:112
char name[MAX_PARNAME_LEN+1]
Definition tpcpar.h:82
int verbose
Verbose level, used by statusPrint() etc.
@ TPCERROR_FAIL
General error.
@ TPCERROR_OK
No error.
@ TPCERROR_NO_DATA
File contains no data.

◆ parCompareParameters()

int parCompareParameters ( PAR * d1,
PAR * d2,
const int pi,
const int ti,
int checkpar,
int checksd,
int checkcl,
const double test_abs,
const double test_rel,
TPCSTATUS * status )

Check whether parameter values are the same in two PAR data.

Note that units are ignored here. If either absolute or relative difference is below the limit, the test is reported as passed.

See also
parCompareParameterUnits.
Returns
0 in case of match, and >0 if no match or error.
Author
Vesa Oikonen
Parameters
d1Pointer to PAR structure.
d2Pointer to PAR structure.
piPAR index [0..parNr-1] to compare; enter <0 to verify all parameters.
tiTAC index [0..tacNr-1] to compare; enter <0 to verify all TACs.
checkparCheck parameter values (1) or do not check (0).
checksdCheck parameter SD values (1) or do not check (0).
checkclCheck parameter CL values (1) or do not check (0).
test_absLimit for accepted absolute difference; obligatory.
test_relOptional limit for accepted relative difference |2*(x1-x2)/(x1+x2)| ; set to negative value to not test this; in case of zero mean, this test is assumed to fail, but test for absolute difference may still pass.
statusPointer to status data; enter NULL if not needed.

Definition at line 237 of file parcomp.c.

260 {
261 int verbose=0; if(status!=NULL) verbose=status->verbose;
262 if(verbose>1) printf("%s()\n", __func__);
263
264 /* Check that required data exists */
265 if(d1==NULL || d2==NULL || d1->tacNr<1 || d2->tacNr<1 || d1->parNr<1 || d2->parNr<1) {
266 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_DATA);
267 return 1;
268 }
269 /* Check that at least something is tested */
270 if(!checkpar && !checksd && !checkcl) {
271 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_FAIL);
272 return 1;
273 }
274 /* If index is specified, then verify that TAC or PAR is available */
275 if(pi>=0 && (pi>=d1->parNr || pi>=d2->parNr)) {
276 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_FAIL);
277 return 2;
278 }
279 if(ti>=0 && (ti>=d1->tacNr || ti>=d2->tacNr)) {
280 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_FAIL);
281 return 2;
282 }
283
284 /* If index is not specified, then parNr or tacNr must match */
285 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OK);
286 if(pi<0 && (d1->parNr!=d2->parNr)) {
287 if(verbose>0) printf("different parameter nr.\n");
288 return(3);
289 }
290 if(ti<0 && (d1->tacNr!=d2->tacNr)) {
291 if(verbose>0) printf("different TAC nr.\n");
292 return(3);
293 }
294
295 /* Compare */
296 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OK);
297 int pj, tj;
298 if(checkpar) {
299 for(tj=0; tj<d1->tacNr; tj++) if(ti<0 || tj==ti) {
300 for(pj=0; pj<d1->parNr; pj++) if(pi<0 || pj==pi) {
301 if(doubleMatch(d1->r[tj].p[pj], d2->r[tj].p[pj], test_abs)==1) continue;
302 if(test_rel>0.0 && doubleMatchRel(d1->r[tj].p[pj], d2->r[tj].p[pj], test_rel)==1) continue;
303 if(verbose>0) {
304 double s=fabs(d1->r[tj].p[pj]-d2->r[tj].p[pj]);
305 printf("par1.r[%d].p[%d] := %g\n", tj, pj, d1->r[tj].p[pj]);
306 printf("par2.r[%d].p[%d] := %g\n", tj, pj, d2->r[tj].p[pj]);
307 printf("|diff| := %g\n", s);
308 printf("diff_limit := %g\n", test_abs);
309 if(test_rel>0.0) printf("rel_diff_limit := %g\n", test_rel);
310 }
311 return(10);
312 }
313 }
314 }
315 if(checksd) {
316 for(tj=0; tj<d1->tacNr; tj++) if(ti<0 || tj==ti) {
317 for(pj=0; pj<d1->parNr; pj++) if(pi<0 || pj==pi) {
318 if(doubleMatch(d1->r[tj].sd[pj], d2->r[tj].sd[pj], test_abs)==1) continue;
319 if(test_rel>0.0 && doubleMatchRel(d1->r[tj].sd[pj], d2->r[tj].sd[pj], test_rel)==1) continue;
320 if(verbose>0) {
321 double s=fabs(d1->r[tj].sd[pj]-d2->r[tj].sd[pj]);
322 printf("par1.r[%d].sd[%d] := %g\n", tj, pj, d1->r[tj].sd[pj]);
323 printf("par2.r[%d].sd[%d] := %g\n", tj, pj, d2->r[tj].sd[pj]);
324 printf("|diff| := %g\n", s);
325 printf("diff_limit := %g\n", test_abs);
326 if(test_rel>0.0) printf("rel_diff_limit := %g\n", test_rel);
327 }
328 return(10);
329 }
330 }
331 }
332 if(checkcl) {
333 for(tj=0; tj<d1->tacNr; tj++) if(ti<0 || tj==ti) {
334 for(pj=0; pj<d1->parNr; pj++) if(pi<0 || pj==pi) {
335 if(doubleMatch(d1->r[tj].cl1[pj], d2->r[tj].cl1[pj], test_abs)==1) continue;
336 if(test_rel>0.0 && doubleMatchRel(d1->r[tj].cl1[pj], d2->r[tj].cl1[pj], test_rel)==1) continue;
337 if(verbose>0) {
338 double s=fabs(d1->r[tj].cl1[pj]-d2->r[tj].cl1[pj]);
339 printf("par1.r[%d].cl1[%d] := %g\n", tj, pj, d1->r[tj].cl1[pj]);
340 printf("par2.r[%d].cl1[%d] := %g\n", tj, pj, d2->r[tj].cl1[pj]);
341 printf("|diff| := %g\n", s);
342 printf("diff_limit := %g\n", test_abs);
343 if(test_rel>0.0) printf("rel_diff_limit := %g\n", test_rel);
344 }
345 return(10);
346 }
347 }
348 for(tj=0; tj<d1->tacNr; tj++) if(ti<0 || tj==ti) {
349 for(pj=0; pj<d1->parNr; pj++) if(pi<0 || pj==pi) {
350 if(doubleMatch(d1->r[tj].cl2[pj], d2->r[tj].cl2[pj], test_abs)==1) continue;
351 if(test_rel>0.0 && doubleMatchRel(d1->r[tj].cl2[pj], d2->r[tj].cl2[pj], test_rel)==1) continue;
352 if(verbose>0) {
353 double s=fabs(d1->r[tj].cl2[pj]-d2->r[tj].cl2[pj]);
354 printf("par1.r[%d].cl2[%d] := %g\n", tj, pj, d1->r[tj].cl2[pj]);
355 printf("par2.r[%d].cl2[%d] := %g\n", tj, pj, d2->r[tj].cl2[pj]);
356 printf("|diff| := %g\n", s);
357 printf("diff_limit := %g\n", test_abs);
358 if(test_rel>0.0) printf("rel_diff_limit := %g\n", test_rel);
359 }
360 return(10);
361 }
362 }
363 }
364
365 return(0);
366}
int doubleMatch(const double v1, const double v2, const double lim)
Definition doubleutil.c:27
int doubleMatchRel(const double v1, const double v2, const double lim)
Definition doubleutil.c:77
int tacNr
Definition tpcpar.h:104
PARR * r
Definition tpcpar.h:114
double * cl2
Definition tpcpar.h:70
double * p
Definition tpcpar.h:64
double * sd
Definition tpcpar.h:66
double * cl1
Definition tpcpar.h:68

◆ parCompareParameterUnits()

int parCompareParameterUnits ( PAR * d1,
PAR * d2,
const int i,
TPCSTATUS * status )

Check whether parameter units are the same in two PAR data.

Returns
0 in case of match, 1 if no match or error.
Author
Vesa Oikonen
Parameters
d1Pointer to PAR structure.
d2Pointer to PAR structure.
iParameter index [0..parNr-1] to compare; enter <0 to verify all.
statusPointer to status data; enter NULL if not needed.

Definition at line 103 of file parcomp.c.

112 {
113 int verbose=0; if(status!=NULL) verbose=status->verbose;
114 if(verbose>1) printf("%s()\n", __func__);
115
116 /* Check that required data exists */
117 if(d1==NULL || d2==NULL || d1->parNr<1 || d2->parNr<1) {
118 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_DATA);
119 return 1;
120 }
121 /* If index is specified, then verify that parameter is available */
122 if(i>=0 && (i>=d1->parNr || i>=d2->parNr)) {
123 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_FAIL);
124 return 1;
125 }
126
127 /* If index is not specified, then parNr must match */
128 if(i<0 && (d1->parNr!=d2->parNr)) {
129 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OK);
130 if(verbose>0) printf("different parameter nr.\n");
131 return(1);
132 }
133
134 /* Compare */
135 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OK);
136 for(int pi=0; pi<d1->parNr; pi++) if(i<0 || i==pi) {
137 if(d1->n[pi].unit!=d2->n[pi].unit) {
138 if(verbose>0) {
139 printf("par1.n[%d].unit := '%s'\n", pi, unitName(d1->n[pi].unit));
140 printf("par2.n[%d].unit := '%s'\n", pi, unitName(d2->n[pi].unit));
141 }
142 return(1);
143 }
144 }
145 return(0);
146}
int unit
Definition tpcpar.h:86
char * unitName(int unit_code)
Definition units.c:143

◆ parCompareTacNames()

int parCompareTacNames ( PAR * d1,
PAR * d2,
const int i,
const int casens,
TPCSTATUS * status )

Check whether TAC names are the same in two PAR data.

Comparison is very strict, thus the names may need to be preprocessed if this is used for other purpose than SW testing.

Returns
0 in case of match, 1 if no match or error.
Author
Vesa Oikonen
Parameters
d1Pointer to PAR structure.
d2Pointer to PAR structure.
iParameter index [0..tacNr-1] to compare; enter <0 to verify all.
casensCase-sensitivity: 0=case does not have to match; <>0=case must match.
statusPointer to status data; enter NULL if not needed.

Definition at line 157 of file parcomp.c.

168 {
169 int verbose=0; if(status!=NULL) verbose=status->verbose;
170 if(verbose>1) printf("%s()\n", __func__);
171
172 /* Check that required data exists */
173 if(d1==NULL || d2==NULL || d1->tacNr<1 || d2->tacNr<1) {
174 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_DATA);
175 return 1;
176 }
177 /* If index is specified, then verify that TAC is available */
178 if(i>=0 && (i>=d1->tacNr || i>=d2->tacNr)) {
179 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_FAIL);
180 return 1;
181 }
182
183 /* If index is not specified, then tacNr must match */
184 if(i<0 && (d1->tacNr!=d2->tacNr)) {
185 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OK);
186 if(verbose>0) printf("different TAC nr.\n");
187 return(1);
188 }
189
190 /* Compare */
191 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OK);
192 int vr;
193 for(int ri=0; ri<d1->tacNr; ri++) if(i<0 || i==ri) {
194 if(casens==0) vr=strcasecmp(d1->r[ri].name, d2->r[ri].name);
195 else vr=strcmp(d1->r[ri].name, d2->r[ri].name);
196 if(vr==0) continue;
197 /* No problem, if difference is '_' versus '-' */
198 if(strchr(d1->r[ri].name, '-') || strchr(d1->r[ri].name, '_')) {
199 char *buf1, *buf2;
200 buf1=strdup(d1->r[ri].name); strReplaceChar(buf1, '-', '_');
201 buf2=strdup(d2->r[ri].name); strReplaceChar(buf2, '-', '_');
202 if(verbose>100) printf("'%s' vs '%s'\n", buf1, buf2);
203 if(casens==0) vr=strcasecmp(buf1, buf2); else vr=strcmp(buf1, buf2);
204 free(buf1); free(buf2);
205 }
206 if(vr==0) continue;
207 /* No problem, if difference is '_' versus ' ' */
208 if(strchr(d1->r[ri].name, '_') || strchr(d2->r[ri].name, '_')) {
209 char *buf1, *buf2;
210 buf1=strdup(d1->r[ri].name); strReplaceChar(buf1, '_', ' ');
211 buf2=strdup(d2->r[ri].name); strReplaceChar(buf2, '_', ' ');
212 if(verbose>100) printf("'%s' vs '%s'\n", buf1, buf2);
213 if(casens==0) vr=strcasecmp(buf1, buf2); else vr=strcmp(buf1, buf2);
214 free(buf1); free(buf2);
215 }
216 if(vr==0) continue;
217 if(verbose>0) {
218 printf("par1.r[%d].name := '%s'\n", ri, d1->r[ri].name);
219 printf("par2.r[%d].name := '%s'\n", ri, d2->r[ri].name);
220 }
221 return(1);
222 }
223 return(0);
224}
char name[MAX_TACNAME_LEN+1]
Definition tpcpar.h:50

◆ parCompareWSS()

int parCompareWSS ( PAR * d1,
PAR * d2,
const int ti,
const double test_abs,
const double test_rel,
TPCSTATUS * status )

Check whether fit WSS values are the same in two PAR data.

Note that units are ignored here. If either absolute or relative difference is below the limit, the test is reported as passed.

See also
parCompareParameters.
Returns
0 in case of match, and >0 if no match or error.
Author
Vesa Oikonen
Parameters
d1Pointer to PAR structure.
d2Pointer to PAR structure.
tiTAC index [0..tacNr-1] to compare; enter <0 to verify all TACs.
test_absLimit for accepted absolute difference; obligatory.
test_relOptional limit for accepted relative difference |2*(x1-x2)/(x1+x2)| ; set to negative value to not test this; in case of zero mean, this test is assumed to fail, but test for absolute difference may still pass.
statusPointer to status data; enter NULL if not needed.

Definition at line 378 of file parcomp.c.

393 {
394 int verbose=0; if(status!=NULL) verbose=status->verbose;
395 if(verbose>1) printf("%s()\n", __func__);
396
397 /* Check that required data exists */
398 if(d1==NULL || d2==NULL || d1->tacNr<1 || d2->tacNr<1) {
399 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_DATA);
400 return 1;
401 }
402 /* If index is specified, then verify that TAC is available */
403 if(ti>=0 && (ti>=d1->tacNr || ti>=d2->tacNr)) {
404 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_FAIL);
405 return 2;
406 }
407
408 /* If index is not specified, then tacNr must match */
409 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OK);
410 if(ti<0 && (d1->tacNr!=d2->tacNr)) {
411 if(verbose>0) printf("different TAC nr.\n");
412 return(3);
413 }
414
415 /* Compare */
416 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OK);
417 int tj;
418 for(tj=0; tj<d1->tacNr; tj++) if(ti<0 || tj==ti) {
419 if(doubleMatch(d1->r[tj].wss, d2->r[tj].wss, test_abs)==1)
420 continue;
421 if(test_rel>0.0 && doubleMatchRel(d1->r[tj].wss, d2->r[tj].wss, test_rel)==1)
422 continue;
423 if(verbose>0) {
424 double s=fabs(d1->r[tj].wss-d2->r[tj].wss);
425 printf("par1.r[%d].wss := %g\n", tj, d1->r[tj].wss);
426 printf("par2.r[%d].wss := %g\n", tj, d2->r[tj].wss);
427 printf("|diff| := %g\n", s);
428 printf("diff_limit := %g\n", test_abs);
429 if(test_rel>0.0) printf("rel_diff_limit := %g\n", test_rel);
430 }
431 return(10);
432 }
433 return(0);
434}
double wss
Definition tpcpar.h:72