1# Compare metadata filter output containing float value strings to reference 2# output data. Returns the whole reference data if delta of each value is below 3# threshold, else returns the whole input data. 4 5function abs(val) { 6 return ((val < 0.0) ? -val : val); 7} 8 9function max(val1, val2) { 10 return ((val1 >= val2) ? val1 : val2); 11} 12 13function is_numeric_str(str) { 14 return (str ~ /^[+-]?[0-9]*\.?[0-9]+$/); 15} 16 17BEGIN { 18 FS = "="; 19 # check for "fuzz" (threshold) program parameter, else use default 20 if (fuzz <= 0.0) { 21 fuzz = 0.1; 22 } 23 # check for "ref" (reference file) program parameter 24 if (ref) { 25 ref_nr = 0; 26 while ((getline line < ref) > 0) { 27 ref_nr++; 28 ref_lines[ref_nr] = line; 29 if (split(line, fields) == 2 && is_numeric_str(fields[2])) { 30 ref_keys[ref_nr] = fields[1]; 31 ref_vals[ref_nr] = fields[2] + 0; # convert to number 32 } 33 } 34 close(ref); 35 } 36 delta_max = 0; 37 result = (ref ? 1 : 0); 38} 39 40{ 41 cmp_lines[NR] = $0; 42 if (NF == 2 && is_numeric_str($2) && ref_vals[NR]) { 43 val = $2 + 0; # convert to number 44 delta = abs((val / ref_vals[NR]) - 1); 45 delta_max = max(delta_max, delta); 46 result = result && ($1 == ref_keys[NR]) && (delta <= fuzz); 47 } else { 48 result = result && ($0 == ref_lines[NR]); 49 } 50} 51 52END { 53 if (result) { 54 for (i = 1; i <= ref_nr; i++) 55 print ref_lines[i]; 56 } else { 57 for (i = 1; i <= NR; i++) 58 print cmp_lines[i]; 59 if (NR != ref_nr) 60 print "[refcmp] lines: " NR " != " ref_nr > "/dev/stderr"; 61 if (delta_max >= fuzz) 62 print "[refcmp] delta_max: " delta_max " >= " fuzz > "/dev/stderr"; 63 } 64} 65