"""Compare rr_ngx_probe outputs of the synthetic noisy scene against its noise-free answer, frame by frame.
The fixture's frames.txt first line is `size RW RH OW OH`; dynamic-extents.txt (when present) gives each frame's render
size. Per frame the reference is clean-.bin (clean.bin for fixtures from the first generator version) at output
size. When a frame's render size differs from the output size the baselines are the noisy input nearest-resampled to
output size and, if clean-render-.bin exists, the noise-free render-size image resampled the same way (the best a
render-resolution result could be).
"""
import argparse
import json
import sys
from pathlib import Path
repo = Path(__file__).resolve().parents[2]
sys.path.insert(0, str(repo / '.tools/python/vendor'))
import numpy as np
def resampler(render_shape, shape):
if render_shape == shape:
return lambda a: a
ys = np.minimum((np.arange(shape[0]) * render_shape[0] / shape[0]).astype(int), render_shape[0] - 1)
xs = np.minimum((np.arange(shape[1]) * render_shape[1] / shape[1]).astype(int), render_shape[1] - 1)
return lambda a: a[ys][:, xs]
def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('--fixture', required=True, type=Path)
parser.add_argument('--output', required=True, type=Path)
parser.add_argument('--report', required=True, type=Path)
parser.add_argument('--ratio', type=float, default=0.5, help='tail RMSE must be below ratio * the input baseline')
parser.add_argument('--output-float32', action='store_true')
parser.add_argument('--switch-output', action='store_true')
args = parser.parse_args()
sizes = list(map(int, (args.fixture / 'frames.txt').read_text().split('\n')[0].split()[1:5]))
shape = (sizes[3], sizes[2], 4) # output size
n = len(list(args.fixture.glob('*-color.bin')))
extents_file = args.fixture / 'dynamic-extents.txt'
extents = [tuple(map(int, line.split())) for line in extents_file.read_text().split('\n') if line.strip()] if extents_file.exists() else None
sky = np.load(args.fixture / 'sky.npy')
body = ~sky
rows = []
for i in range(n):
fw, fh = extents[i] if extents else (sizes[0], sizes[1])
render_shape = (fh, fw, 4)
resample = resampler(render_shape, shape)
reference = args.fixture / f'clean-{i}.bin'
clean = np.fromfile(reference if reference.exists() else args.fixture / 'clean.bin', '