refcmp-metadata.awk 1.8 KB

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