1. 08 Jul, 2026 4 commits
    • Andrey Filippov's avatar
      CLAUDE: -CUAS-RT-RENDER-EVAL: log / log-diff / diff hyperstack (Andrey's spec) · 8726cc75
      Andrey Filippov authored
      New evaluation product with the RT render (replaces the manual
      run-UM-in-ImageJ workflow): merged component only, z = robust all-scenes
      average + each scene, t ordered for ImageJ auto-range: 1) pixel LoG (the
      pre-DNN kernel, LINEAR) of the image, 2) LoG of (scene - average),
      3) plain (scene - average); t2/t3 are 0 for the average frame. The
      average is the new robust one (edge-eroded + outlier-rejected),
      extracted into shared helpers (erodedMasks/robustAverage) used by both
      saveRenderHyper and the EVAL builder.
      Co-Authored-By: 's avatarClaude Fable 5 <noreply@anthropic.com>
      8726cc75
    • Andrey Filippov's avatar
      CLAUDE: RT-RENDER average slices: per-scene edge erosion + outlier rejection · c8cd84bd
      Andrey Filippov authored
      The temporal averages accumulated per-scene edge junk into stable margin
      artifacts (ROWCOL-04: worst columns x=12,20,28 = 8-px tile pitch -
      partially covered virtual tiles at the warped-coverage edge; the wobble
      sweeps which tiles are partial). For the two AVERAGE slices only
      (individual scenes stay liberal/untouched): each scene's contribution is
      box-eroded 24 px (3 tile pitches, AVG_EDGE_ERODE - clears the
      partial-tile ring) and outlier-rejected (3 sigma vs the first-pass mean
      when >= 4 providers, per Andrey's >1-non-NaN-provider rule); zero eroded
      providers -> honest NaN.
      Co-Authored-By: 's avatarClaude Fable 5 <noreply@anthropic.com>
      c8cd84bd
    • Andrey Filippov's avatar
      CLAUDE: RT rowcol: untrusted-line guard (inlier fraction) + physical cap · c0096034
      Andrey Filippov authored
      ROWCOL-04 localization: RT rows regression (18.0 vs 10.6 pre-rework) is
      CONTENT BIAS, zero in the sky and +10..22 counts in terrain rows - with
      dense high-contrast content nearly every |UM residual| exceeds max_abs,
      all pixels get the outlier weight and the weighted mean degenerates to
      the row's content mean (the small weights cancel), stamping bias bands.
      lineAverage now zeroes a line's correction when its inlier fraction is
      below rowcol_min_inlier (default 0.33 - content-dominated lines cannot
      yield a line-noise measurement) or when |estimate| > max_abs (line noise
      cannot physically exceed the gate scale). Both guards are no-ops with
      the gate off (max_abs INF - every pixel is an inlier).
      Co-Authored-By: 's avatarClaude Fable 5 <noreply@anthropic.com>
      c0096034
    • Andrey Filippov's avatar
      CLAUDE: ROWCOL frame-edge margin + physical line cap; RT: single high-pass (QC/ROWCOL-03 findings) · 8db6269b
      Andrey Filippov authored
      ROWCOL-03 QC FAIL (rms 52.9 unchanged by erosion) proved the junk edge
      columns are FULLY covered with DEFINED-BUT-WRONG back-projection values
      (left-edge convert_direct artifact class) - erosion cannot see them:
      - exclude a 16px frame-edge band from the content-excluded estimator by
        geometry (ROWCOL_BP_EDGE_MARGIN); those lines take the legacy fallback;
      - physical cap in the per-line merge: a content-excluded line value over
        max_abs cannot be line noise - use legacy (also blunts any future
        ROWCOL-01-class estimator failure).
      
      RT conditioning: profile HPF now applies ONLY when rowcol_um_sigma==0.
      Stacking it on the UM measurement double-high-passed the row-offset
      estimate ((1-G10)(1-G8)): removed fraction at period ~20 rows dropped
      96% -> 91%, residual mid-band line noise x2 - measured merged RT-RENDER
      rows metric 10.60 (ROWCOL-02, pre-rework) -> 18.73 (ROWCOL-03). Single
      sigma-10 high-pass removes strictly more noise at every period than the
      old sigma-8-only path and protects the LoG band at least as well.
      Co-Authored-By: 's avatarClaude Fable 5 <noreply@anthropic.com>
      8db6269b
  2. 07 Jul, 2026 13 commits
    • Andrey Filippov's avatar
      CLAUDE: disparity conditioning: fill small foreground clusters with background (Laplacian) · 66bd669a
      Andrey Filippov authored
      Where a small foreground object (the 3-tile roadside sign, disp ~22)
      stands in front of a distant background both disparities are legitimate,
      but for CUAS the background matters: a drone flying exactly behind the
      sign must stay detectable. conditionDisparityCuas now detects connected
      clusters of local near-outliers (disparity above the local 7x7 median by
      curt.disp_fg_over, default 2 px) up to curt.disp_fg_tiles (default 8,
      0 = off) tiles and re-fills them with zero-curvature background
      disparity (TileProcessor.fillNaNs Laplacian relaxation). All three RT
      call sites (render, pose, appropriation) share the one conditioned
      source as before.
      Co-Authored-By: 's avatarClaude Fable 5 <noreply@anthropic.com>
      66bd669a
    • Andrey Filippov's avatar
      CLAUDE: ROWCOL edge erosion + RT rowcol rework (order/UM/gate) + QC harness · 275f812b
      Andrey Filippov authored
      1. calculateRowColBackProject: ERODE the coverage mask (blurred mask >=
         ROWCOL_BP_ERODE=0.95 ~ 16px inside at sigma 10) before the masked UM
         and averaging - the back-projection is unreliable near its own
         boundary and boundary garbage dominated the partially-covered EDGE
         columns in v013-ROWCOL-02 (per-x maxima ~1000 for x<14, interior
         clean at 13-39 counts). Excluded edge lines drop below MIN_COVER and
         take the legacy per-line fallback.
      
      2. RT conditioning row/col (problem 2, borrowed from the oracle path,
         /jp4/ input unchanged):
         - REORDER: row/col now AFTER photometric+FPN. Measuring on raw
           captured the FPN's static line structure (rms ~6/12 counts) which
           the later FPN subtraction removed AGAIN - negative FPN line
           structure was injected into the output.
         - UM before averaging (new curt.rowcol_um_sigma, default 10, 0=off):
           profiles measured on an unsharp-masked copy, subtracted from the
           original - content no longer biases the averages and the max_abs
           gate acts on residual counts.
         - rowcol_max_abs default 50 (calibrated counts; configs saved before
           this change carry 0 = no gate - set 50 to enable).
      
      3. CuasQC (Andrey's regression-protection design): per-product health
         statistics with sequence-independent pass bands, appended per run to
         <center>-QC.json; FAIL prints loudly, never aborts. Increment 1:
         ROWCOL vectors (rms<=25, scene-max p95<=500 - both of today's
         defects would have failed) + FPN (rms, row/col line-structure
         energy), hooked after calculation AND reuse in CorrectionFPN.
      Co-Authored-By: 's avatarClaude Fable 5 <noreply@anthropic.com>
      275f812b
    • Andrey Filippov's avatar
      CLAUDE: fix ROWCOL back-project baseline mismatch (v013-ROWCOL-01 junk) · 947c199c
      Andrey Filippov authored
      The first calculateRowColBackProject mixed two baselines in one image:
      content-excluded residual (~0, regression baseline) inside the
      back-projection coverage, full raw-level image-FPN outside it. Whole
      lines fell outside the max_abs gate and the outlier-weighted average
      degenerated to the content mean: vectors reached ~2300 counts (legacy
      ~340) and stamped junk bands at the coverage-window margins into all
      per-sensor images (v013-ROWCOL-01 MERGED-DBG slices 141/408 etc).
      
      Now the two baselines never mix: masked UM (blur(value*mask)/blur(mask))
      high-passes the residual within coverage only; NaN-aware line averages
      use covered pixels only (getLineAvgNaN); lines with under 10% coverage
      (ROWCOL_BP_MIN_COVER) fall back to the pure legacy UM+gating estimate
      per line (mergeLineProfiles). Console reports the line-fallback share.
      Co-Authored-By: 's avatarClaude Fable 5 <noreply@anthropic.com>
      947c199c
    • Andrey Filippov's avatar
      CLAUDE: fix MCP dialog values silently discarded on submit · b70a9f6b
      Andrey Filippov authored
      The registry entry is cleared by submitCurrent() (and again by
      showDialog()) BEFORE applyCltDialog() runs the getNext*() reads, so
      getValueOrDefault() - which looked the session up via the registry -
      always saw null and fell back to every field's default: any value set
      via POST /mcp/dialog/values was silently lost and OK re-applied the
      loaded config. The dialog now keeps its OWN session reference for the
      reads and the await; the registry cleanup clears only its own session
      (covers the timeout path without clobbering a newer dialog).
      Co-Authored-By: 's avatarClaude Fable 5 <noreply@anthropic.com>
      b70a9f6b
    • Andrey Filippov's avatar
      CLAUDE: remove cuas_calc_fpn/cuas_calc_rowcol - file existence is THE recalc trigger · b056e1a5
      Andrey Filippov authored
      Delete-the-file rule (Andrey): FPN and row/col noise recalculate ONLY
      when <center>-FPN.tiff / <center>-ROWCOL.tiff are missing in the model
      directory. The two force-recalc checkboxes are removed from the dialog
      and the config (stale _cuas_calc_* keys in old corr-xml are ignored on
      load). Reuse printlns name the exact file to delete; the dialog shows
      addMessage() notes in place of the removed checkboxes.
      Co-Authored-By: 's avatarClaude Fable 5 <noreply@anthropic.com>
      b056e1a5
    • Andrey Filippov's avatar
      CLAUDE: Row/Col correction (RT step 2): curt rowcol_* dialog params +... · 3cc0997b
      Andrey Filippov authored
      CLAUDE: Row/Col correction (RT step 2): curt rowcol_* dialog params + content-excluded noise calculation
      
      2a: CuasConditioning rowcol_* Config now dialog-driven (curt.rowcol_en/
      rowcol_hpf/rowcol_hpf_sigma/rowcol_max_abs/rowcol_outlier, "CUAS RT" tab)
      via CuasConditioning.configFromCurt(); RT Row/Col is optional/bypassable
      (turn rowcol_en OFF when the FLIR internal correction is verified OK).
      Defaults reproduce the previous hardcoded Config bit-exactly
      (rowcol_max_abs 0 = the old INFINITY no-gate).
      
      2b: new CorrectionFPN.calculateRowColBackProject() (gated by NEW
      imp.cuas_backprop_rowcol, default ON): subtract the back-projected
      (pose-transformed, photometric-matched) virtual center from each scene
      BEFORE the UM + line averaging, so bright content no longer biases the
      row/col averages (the dark horizontal/vertical line artifact). Falls
      back to (image - FPN) where the back-projection is undefined; serial
      scene loop (GPU back-projection per scene) - borrowed/non-RT path only.
      Co-Authored-By: 's avatarClaude Fable 5 <noreply@anthropic.com>
      3cc0997b
    • Andrey Filippov's avatar
    • Andrey Filippov's avatar
      CLAUDE: test 7 - windowed-LoG TD product (correlation machinery): broadband... · 284f6ae1
      Andrey Filippov authored
      CLAUDE: test 7 - windowed-LoG TD product (correlation machinery): broadband exact, crease bands UNCHANGED
      
      Andrey's separate-LoG proposal prototyped on the CPU oracle: LoG as a windowed
      16x16 DATA tile (taps pre-divided by the sine window AND cosAtten so the
      effective filter is the exact flux-normalized LoG), full 16-mult quad product
      per tile (GPU correlateAccumulateTiles table == convolve_tile(conj(data),k) -
      verified term-by-term), dttt_iie back (mode-TRANSPOSED = GPU dttii_2d),
      corr_unfold_tile, windowed OLA with sum(w^2) normalization.
      
      RESULT: impulse fidelity 2.0e-3 (no aberration-kernel cross-term - a separate
      pass), but the ramp crease bands are IDENTICAL to the per-bin fold (+/-0.546):
      the DTT symmetric-extension reflection is only attenuated by the window, not
      removed - the crease is BASIS-INHERENT to any single-tile TD product. The
      per-bin fold is the degenerate (symmetric-kernel) case of this same product.
      Band-free LoG requires pixel-domain convolution on the assembled image.
      
      Calibrated conventions along the way (documented in code): correlation product
      table, dttii mode transpose, corr_unfold patch mapping (+1 offset, no flip),
      global gain 4.000, window and cos tap precompensation.
      Co-Authored-By: 's avatarClaude Fable 5 <noreply@anthropic.com>
      284f6ae1
    • Andrey Filippov's avatar
      CLAUDE: test 6 extension - crease bands per kernel type (Andrey's symmetry argument quantified) · da5c157f
      Andrey Filippov authored
      Same ramp, same chain: identity 0.000; aberration-like kernel 0.624 counts
      (band/output 0.18% - present in every render, invisible under content);
      pure LoG 0.547 (176% of its near-zero output); folded 0.682. The aberration
      kernels DO band identically in absolute counts - the LoG only unmasks them
      by removing the content. Corollary: the CURRENT pixel-LoG conditioning also
      reveals the render's own crease bands (the oracle product bands too, with a
      different pattern).
      Co-Authored-By: 's avatarClaude Fable 5 <noreply@anthropic.com>
      da5c157f
    • Andrey Filippov's avatar
      CLAUDE: test 6 - sky-band root cause reproduced: symmetric-extension crease... · b70a65c5
      Andrey Filippov authored
      CLAUDE: test 6 - sky-band root cause reproduced: symmetric-extension crease response to LINEAR content
      
      Constant -> exactly 0; ramp 5/row -> 8-row-periodic band pattern
      (0,-0.008,-0.297,-0.547,+0.547,+0.297,+0.008,0) = the LOG-01 run's measured sky
      bands scaled by the gradient (2.5/row -> -0.14,-0.30,+0.35,+0.16). Pure double
      CPU chain -> not float32, not GPU, not a kernel coefficient: pixel LoG of a ramp
      is 0 (odd symmetry) but the per-tile symmetric convolution sees the mirrored
      extension's slope crease at tile boundaries. Inherent to any per-bin TD multiply
      (present under aberration kernels too, masked by content - Andrey's LPF-era
      artifact class, confirmed in substance).
      Co-Authored-By: 's avatarClaude Fable 5 <noreply@anthropic.com>
      b70a65c5
    • Andrey Filippov's avatar
      CLAUDE: LoG isolation test (curt.log_ident) - identity vs pure-LoG kernels, aberrations skipped · 7b6d0284
      Andrey Filippov authored
      Andrey's discriminator for the fold-vs-kernel-interaction question: with
      rend_test + new 'RT render LoG isolation (identity krnl)' ON, saves
      -CUAS-RT-RENDER-ID (identity kernels: q0=1, q1..3=0, CltExtra=0 - aberration
      correction AND fractional offsets skipped), -ID-LOG-ORACLE (pixel LoG of -ID),
      and -LOG-ONLY (pure-LoG kernels, CuasLogFold.uniformKernels(log_td)).
      If -LOG-ONLY vs -ID-LOG-ORACLE residual persists, the fold/L0 is wrong; if it
      collapses to the wrap floor, the aberration-kernel interaction is responsible.
      Refactor: pixel-LoG application extracted to applyPixelLog(); log_test and
      log_ident share the kernel fetch/restore (finally).
      
      Evidence so far (offline, this evening's run): per-sensor high-bin tilt varies
      s07 +1.3% .. s01 +2.4% with identical scene content => kernel-dependent;
      per-quadrant deviation maps identical (no single-coefficient signature);
      kx=0 column regionally incoherent (row-structure channel, separate issue).
      Co-Authored-By: 's avatarClaude Fable 5 <noreply@anthropic.com>
      7b6d0284
    • Andrey Filippov's avatar
      CLAUDE: RT-RENDER* hyperstacks organized like -INDIVIDUAL-CUAS-DBG (merged first, 2 average frames) · c9b0452a
      Andrey Filippov authored
      t (channels): merged FIRST then s00..s15; z (frames): 'average' (all scenes) +
      'average-f:l' (middle-half, renderSceneSequence default range) then scenes -
      same dimensions as -CUAS-INDIVIDUAL-CUAS-DBG (17 x 499 x H x W) so ImageJ can
      subtract the stacks directly. NaN-tolerant per-pixel averages. Applies to all
      three products (RT-RENDER, -LOG-ORACLE, -LOG-FOLDED). Per Andrey 07/06/2026.
      Co-Authored-By: 's avatarClaude Fable 5 <noreply@anthropic.com>
      c9b0452a
    • Andrey Filippov's avatar
      CLAUDE: RT-seed step 1b wiring - LoG A/B products in the RT render (curt.log_test) · 0fe8f5c1
      Andrey Filippov authored
      With 'CUAS RT render' + new 'RT render LoG A/B (folded kernels)' checkboxes ON,
      testRenderSequence saves two more hyperstacks comparable to -CUAS-RT-RENDER:
      - -CUAS-RT-RENDER-LOG-ORACLE: the product convolved with the EXISTING pre-DNN
        pixel-domain LoG (same CuasRTUtils.convolve2DLReLU instance construction as
        CuasDetectRT.detectTargets, LINEAR alpha=1);
      - -CUAS-RT-RENDER-LOG-FOLDED: the same render chain re-run with the LoG folded
        into the GPU aberration kernels (CuasLogFold.getLogTd tap-precompensated +
        foldKernels, setConvolutionKernels force re-upload) - NO pixel convolution;
        original kernels restored in a finally block.
      Render loop extracted verbatim into renderPass(), hyperstack save into
      saveRenderHyper() so both passes share the exact chain. Offline verdict:
      attic/CLAUDE/compare_cuda_versions.py --only LOG-
      Co-Authored-By: 's avatarClaude Fable 5 <noreply@anthropic.com>
      0fe8f5c1
  3. 06 Jul, 2026 10 commits
    • Andrey Filippov's avatar
      CLAUDE: CuasLogFold - LoG-into-kernel fold + synthetic impulse/grating... · cfc93456
      Andrey Filippov authored
      CLAUDE: CuasLogFold - LoG-into-kernel fold + synthetic impulse/grating self-test (roadmap RT-seed step 1)
      
      Findings (all validated to stated precision by the self-test, exit 0):
      - Per-bin TD quad-multiply == pixel convolution with cos(pi*dx/16)*cos(pi*dy/16)
        ATTENUATED taps (matches norm_sym_weights in calculateCLTKernel; shift-tap
        error exactly 1-cos(pi/16) before compensation). getLogTd() therefore
        pre-compensates LoG taps by 1/cosAtten so the EFFECTIVE filter is the true
        pixel LoG (machine-exact at non-bin gratings).
      - Residual floors: symmetric-extension wrap ~0.5-2.5% (inherent to the lapped
        structure); folded-vs-pixel-LoG A/B cross-term ~7% on a pessimistic spread
        kernel (test 5 - predicts the full-run A/B floor).
      - clt_symmetrize_kernel quadrant-3 (AA) sign pattern looks like a latent
        copy-paste of the AS expression: pure-AA kernel test - math sign 2.6e-3,
        code sign 1.9e-1. Production kernel files likely carry the wrong AA sign.
      Co-Authored-By: 's avatarClaude Fable 5 <noreply@anthropic.com>
      cfc93456
    • Andrey Filippov's avatar
      CLAUDE: FPN iteration - composite rebuilt center over original (NaN-hole fix) · 953f5efd
      Andrey Filippov authored
      POSE-13 forensics (from files, run 02:18-02:24): the iteration executed but dG
      came out defined on only 5% of the frame (right-edge strip + terrain patches),
      so fpn2 = fpn1 over 95% - the ghost survived. Chain: rebuild accumulation was
      healthy (494/494 scenes, ~75% per scene, ~85% union) but a single-sequence
      new-average center keeps NaN holes in the weak sky (no parent cumulative, no
      fillNewGaps), and convert_direct of a NaN-holed center image NaN-poisons
      nearly all back-projected tiles (task inversion + overlap spread).
      
      Fix: composite before the second back-propagation - keep rebuilt values where
      defined, fall back to the original center in the holes. There dG measures the
      pass-1 residual (~0), so it degrades to "no correction where not rebuilt"
      instead of NaN. Adds a coverage printout and a cuas_debug save of the
      composited center (-FPN-CENTER2-ITERn) so the next run is file-verifiable.
      Co-Authored-By: 's avatarClaude Fable 5 <noreply@anthropic.com>
      953f5efd
    • Andrey Filippov's avatar
      CLAUDE: FPN second back-propagation iteration (imp.cuas_fpn_iters, default 1 = old behavior) · 3b1049d6
      Andrey Filippov authored
      FPN = mean(scene - backProject(center)) is a fixed point that preserves the
      center's own content residual (the rotating ghost): recomputing against the
      same contaminated center reproduces the same ghost regardless of rot_period
      or photometric vintage (POSE-12 confirmed: 43.1/92.0 unchanged).
      
      Iterate per Andrey's design (internal handoff 2026-07-06):
        1. subtract fpn_k from scenes in memory (setApplyFPN, delta-aware)
        2. rebuild the center IMAGE from the corrected scenes over integer
           rotations - new Cuas.rebuildCenterImageInMemory(): new-average only
           (no parent cumulative fold), NOTHING persisted, center_clt and
           image_center untouched (the .cuas cumulative is upstream state)
        3. back-propagate against the rebuilt center image (swapped in/restored
           around the measurement) -> residual dG = the ghost
        4. fpn_{k+1} = fpn_k + dG in NEW arrays (scenes hold fpn_k references as
           applied-FPN for delta re-apply); prints |dG| RMS/max per iteration
        5. cuas_debug saves per-iteration -FPN-DG-ITERn
      
      Gated by new dialog field "FPN back-propagation iterations" next to
      "Rotation period"; default 1 keeps the POSE-12 baseline bit-reproducible.
      Verify by RT-RENDER horizon/sky pk-pk (43.1/92.0 -> temporal-noise floor).
      
      Data path verified: applyFPN sets hasNewImageData, honored by both
      GpuQuad.setBayerImages and GpuQuadJna, so corrected pixels reach the GPU
      for the rebuild and the second back-propagation.
      Co-Authored-By: 's avatarClaude Fable 5 <noreply@anthropic.com>
      3b1049d6
    • Andrey Filippov's avatar
      CLAUDE: retire curt.pose_recalc - delete-the-file is THE force method; reuse printlns say so · 53fe5f5c
      Andrey Filippov authored
      Andrey's clutter rule: calibration force-rerun = erase the file, not a
      config checkbox. pose_recalc removed everywhere (field/dialog/properties/
      copy; old configs' leftover key is ignored harmlessly), poseSequencePass
      lost its allow_recalc parameter. Every file-gated reuse now prints the
      delete-to-recalculate hint:
      - TILE-CALIB: 'reusing ... delete <name>-POSE-RT-TILE-CALIB.tiff to recalculate'
      - RT-STATE dc_center: 'delete <name>-RT-STATE.json (or its dc_center field)'
      - FPN (CorrectionFPN): 'reusing saved <name>-FPN.tiff - delete it to
        recalculate (verify Rotation period first - a mismatch bakes an
        azimuth-sector content ghost into the FPN)'
      Co-Authored-By: 's avatarClaude Fable 5 <noreply@anthropic.com>
      53fe5f5c
    • Andrey Filippov's avatar
      CLAUDE: pose stage non-exclusive with the render product (pose = part of the RT cycle) · 2c6751b8
      Andrey Filippov authored
      Andrey's ruling: the pose stage normally ALWAYS runs (it is part of the RT
      cycle, not a mutually-exclusive test) - the last run had rend_test ON which
      silently skipped the pose stage (old precedence) and left TILE-CALIB unbuilt.
      Now: pose_test runs FIRST, rend_test render follows when also ON, cond_test
      stays standalone (only when nothing else ran). Dialog/tooltips updated
      ('CUAS RT render (full product)').
      
      Verified meanwhile (POSE-11 renders): frozen per-sequence DC cut the
      RT-RENDER horizon wobble 234 -> 42.4 counts pk-pk (5.5x), exactly to the
      oracle DBG floor - the residual at 1-rev period is the shared FPN ghost;
      FPN.tiff still Jun-1 vintage because cuas_calc_fpn was OFF (the '(Re)calculate
      FPN' checkbox) - the rot_period=164.9 recompute has not actually run yet.
      Co-Authored-By: 's avatarClaude Fable 5 <noreply@anthropic.com>
      2c6751b8
    • Andrey Filippov's avatar
      CLAUDE: per-SEQUENCE zero-DC level - fix rotation-synced DC flicker (the rotating ghost) · 689efd90
      Andrey Filippov authored
      POSE-10 forensics: RT-RENDER merged horizon pk-pk 234 counts (sky 187) with
      the dominant period 165.7 scenes = EXACTLY one camera revolution (21.83 rpm
      @ 60 fps -> 164.9); POSE-RT-COMPOSITE real slices the same. Cause: the
      per-SCENE zero-DC sky median (Config.dc_level=NaN auto) oscillates with
      azimuth as warm terrain sweeps through the sky half; downstream temporal
      averages convert the wobble into content-correlated residuals - the faint
      rotating ghost ('real image treated as FPN'). Oracle MERGED-DBG shows a
      separate, 3-6x smaller wobble at the same period (pre-existing, prepared
      path - not addressed here).
      
      Fix (Andrey's rule: one constant per sequence, from the average scene):
      - CuasRT.sequenceDcLevel(): manual curt.dc_center override when nonzero,
        else the RT-STATE value derived by appropriateCenter() from the borrowed
        center (= the sequence average) - scenes and center shift by the
        IDENTICAL constant.
      - CuasPoseRT (A2 ingest) + CuasRender (render test) now pass a Config with
        that dc_level instead of null; NaN fallback (per-scene) kept but warns
        loudly. Config.dc_level doc updated.
      Co-Authored-By: 's avatarClaude Fable 5 <noreply@anthropic.com>
      689efd90
    • Andrey Filippov's avatar
      CLAUDE: curt.dbg_fpixels - parameterize the oracle DBG renders (was hardcoded, ~11GB/run) · 424ac6f9
      Andrey Filippov authored
      New checkbox 'Save oracle DBG renders (11GB)' (default ON - current
      behavior preserved): gates the EXTRA per-sensor -CUAS-INDIVIDUAL-CUAS-DBG
      render pass and the -CUAS-MERGED-CUAS-DBG save in CuasRanging.prepareFpixels
      (the merged render itself stays - it is the production imp_targets input).
      Turn OFF to save render time and disk once -CUAS-RT-RENDER (rend_test, the
      RT-chain full render) is the trusted full product.
      Also refreshed the stale dc_center GUI tooltip (RT-STATE.json semantics).
      Co-Authored-By: 's avatarClaude Fable 5 <noreply@anthropic.com>
      424ac6f9
    • Andrey Filippov's avatar
      CLAUDE: TILE-CALIB bootstrap + per-sequence RT-STATE.json + INTERFRAME poses-only · af6ef9ec
      Andrey Filippov authored
      Missing-file rule (Andrey): calibrations are FILE-gated; missing -> rebuild
      (slow first run), present -> reuse, erase -> force. Config keeps parameters
      only.
      
      - TILE-CALIB bootstrap: testPoseSequence = wrapper over poseSequencePass;
        missing -POSE-RT-TILE-CALIB (or pose_recalc ON) -> FULL pass generates and
        saves it, then AUTOMATICALLY re-runs filtered (~150 cluster tiles) - first
        run on a v013_min copy ends in the warmed-system state, per sequence
        (mixed-state batches self-serve). Bootstrap re-run ignores pose_recalc;
        pose_full still never reads/writes the calibration.
      - NEW CuasRtState (-RT-STATE.json, Gson): per-sequence RT-only persistent
        variables in the CENTER model dir; global params stay with quadCLT_main /
        corr-xml (GUI save + compare/combine). Data-pure (paths, no QuadCLT),
        forward-compatible, failure-safe load. First tenant: dc_center - AUTO now
        reuses/derives-and-stores per sequence; the corr-xml config is never
        mutated (nonzero = manual override).
      - INTERFRAME is QuadCLT-workflow/POSES ONLY (Andrey): rtPhotometricCalibration
        no longer writes the ref INTERFRAME; photometric persists via the explicit
        corr-xml save after a calib-ON run (quadCLT_main carries the values).
      Co-Authored-By: 's avatarClaude Fable 5 <noreply@anthropic.com>
      af6ef9ec
    • Andrey Filippov's avatar
      CLAUDE: CuasRT - single RT entry point + borrow-boundary appropriation + calib fixes · 22d49ee1
      Andrey Filippov authored
      - NEW cuas/rt/CuasRT.java: the ENTIRE CUAS RT mode moved out of
        OpticalFlow.buildSeries (curt_en branch) into one readable top method:
        1. INITIALIZATION (ingest, photometric calibration, center appropriation)
        2. DIAGNOSTICS (rend/pose/cond tests - exclusive, never grow the top)
        3. PRODUCTION (detection; the MVP per-scene jp4 loop will replace the
           bulk oracle ingest without changing this structure).
      - Borrow boundary (Andrey ruling): all transforms of borrowed QuadCLT data
        happen at CuasRT initialization ONLY. appropriateCenter() zeroes the
        center CLT IN MEMORY (setCenterClt; -CLT-UPDATED is saved upstream, so
        the zeroed copy never persists) - the pose test drops its per-run GPU
        appropriation and uploads an already-zeroed reference. The pure math is
        CuasConditioning.zeroDcClt(fclt, pattern, level) - knows no QuadCLT.
      - FIX (POSE-09 silent no-op): the DC-pattern uniform image must be set on
        gpuQuad.getQuadCLT() - what both backends actually read (GpuQuadJna
        setBayerImages(center=true), JCuda base, CorrectionFPN recipe) - not on
        center_CLT; plus an all-zero-pattern guard (warn loudly, never fake-offset).
      - FIX (POSE-09 1470-count per-sensor sky spread vs 17 calibrated):
        rtPhotometricCalibration applies the fit to the ALREADY-SPAWNED per-scene
        instances too (created by ingest before the calib step). The recalibrated
        photometric persists only via ref INTERFRAME + a config save after a
        calib-ON run - all current configs still carry the stale values.
      Co-Authored-By: 's avatarClaude Fable 5 <noreply@anthropic.com>
      22d49ee1
    • Andrey Filippov's avatar
      CLAUDE: appropriateCenterDC AUTO level from the reference buffer render · 194d87a8
      Andrey Filippov authored
      getCenterAverage() is null in the pose flow, so the auto DC level silently
      no-op'd (composite virtual sky stayed at -4511). Derive the level from the
      reference buffer render itself - perSensorImagesFromTD(gpuQuad, true)[0]
      sky-half median - i.e. the exact data being zeroed, right after
      setReferenceGPU uploads it. Failure-safe warnings preserved; explicit
      curt.dc_center and adoption/persistence semantics unchanged.
      
      Verify: pose run -> console 'AUTO center DC level', composite virtual sky ~0.
      Co-Authored-By: 's avatarClaude Fable 5 <noreply@anthropic.com>
      194d87a8
  4. 05 Jul, 2026 13 commits
    • Andrey Filippov's avatar
      CLAUDE: RT zero-DC conditioning + decoupled fat zero + borrowed-center DC appropriation · 024b3bda
      Andrey Filippov authored
      Three coupled improvements from tonight's design discussion with Andrey:
      
      1. ZERO-DC in CuasConditioning (Config default ON): LWIR microbolometers are
         ADDITIVE (fixed tau=8ms exposure, F#~1 for NETD, ~100 counts/K) - day/night
         and seasons SHIFT the level, never scale it; the MCLT has no clean DC/AC
         separation, so a large DC (current ~-3500 counts under ~300 counts AC)
         spreads over many TD points and costs float32 mantissa bits. Subtract ONE
         common constant from all 16 sensors (pure shift, never rescale). AUTO level
         = MEDIAN OF THE TOP (SKY) HALF, robust to the snowy-ground-vs-summer-
         calibration mismatch and to targets.
      
      2. RT-DECOUPLED FAT ZERO (curt.fz_inter=10000, curt.fz_intra=2000 reserved):
         the lean code erroneously used the INTRA getGpuFatZero (2000) instead of
         the INTER value - Andrey's FZ sweep (200/1000/3000/10000: corrRMS
         .54/.39/.37/.31, roll bias +.80/+.62/+.50/+.39) independently rediscovered
         the oracle's INTER operating point (10000). RT now owns its FZ pair, no
         AUX switch; legacy gpu_fatz*/FOPEN configs untouched. Sweep recorded as
         characterization: FZ tolerant over a broad range; revisit only together
         with the argmax method redesign (sharp peaks starve the centroid).
      
      3. BORROWED-CENTER APPROPRIATION (curt.dc_center, 0=auto): the restored
         CenterClt reflects its own footage vintage - offset it ONCE at the borrow
         boundary (firewall: never re-compensate downstream) to match the zero-sky
         scenes. Auto level = sky-half median of the borrowed center average,
         ADOPTED into curt.dc_center (persisted with the config - borrowable later
         like the photometric calibration). Mechanics: DC pattern = CLT of a
         uniform image via the existing back-propagation convert (setImageCenter +
         no_kernels + use_center_image, the CorrectionFPN recipe); failure-safe
         (any missing piece leaves the reference unchanged, with a warning).
      
      Roadmap recorded: per-pixel offset (recalibrated per-sensor + FPN) and
      per-pixel scale maps to the GPU; the average stored in TD AFTER LoG
      (aberration+LoG combined kernels) for fpixels subtraction - possibly for
      poses too; center-average window length trades reference stability vs
      extremely-slow-target detectability.
      
      Verified: mvn -DskipTests clean package OK.
      Co-Authored-By: 's avatarClaude Fable 5 <noreply@anthropic.com>
      024b3bda
    • Andrey Filippov's avatar
      CLAUDE: pose test rebased on the certified CuasRender chain (lean v2: MB + all-defined disparity) · 0a8d2415
      Andrey Filippov authored
      Per Andrey: restore the pose test using the new (certified) data.
      
      - Disparity: ONE source for all of RT - the plain DSI slice through
        CuasRender.conditionDisparityCuas (defined for ALL tiles, sky=infinity,
        negatives clamped). The use_lma_dsi gate removed from the pose test (the
        LMA slice is NaN over the sky and silently shrank the usable set).
      - leanMeasure/leanFitScene: MB compensation (lean v2) - the same certified
        machinery as CuasRender: setInterTasksMotionBlur two task sets + the
        erase-first interCorrTDMotionBlur double convert (undefined tiles NaN for
        the consolidation), gated by imp.mb_en, vectors from the existing per-scene
        getMotionBlur block (previously computed but unused by lean).
      - pose_stored branch gets the same MB treatment.
      
      Expected in the next lean run (LMA, 150-cluster selection, mb_en ON):
      az/tilt wobble (v*tau, 0.5 px rotating) collapses toward the MBEN oracle
      (0.029/0.021 mrad), corr RMS toward ~0.08; roll bias = the remaining open
      question (FPN-mask lead).
      
      Verified: mvn -DskipTests clean package OK.
      Co-Authored-By: 's avatarClaude Fable 5 <noreply@anthropic.com>
      0a8d2415
    • Andrey Filippov's avatar
      CLAUDE: CuasRender - disparity defined for ALL tiles (conditionDisparityCuas) · e4e65e23
      Andrey Filippov authored
      Per Andrey: the sky has nothing to match but is the BACKGROUND FOR DRONES -
      it must render (at infinity), NaN acceptable only outside the image.
      
      Root of the NaN tiles in -CUAS-RT-RENDER: use_lma_dsi=true selected the LMA
      DSI slice, which is NaN wherever the LMA did not fit (the whole sky) ->
      tiles dropped from the task list. The plain slice has no NaN but carries
      garbage (crazy < -1 tiles in the sky, negatives near the sign post).
      
      Fix: NEW static QuadCLT-free conditionDisparityCuas() (the legacy
      conditionInitialDS takes a QuadCLT instance - out per the RT rules):
      plain slice 0, NaN -> 0.0 (infinity), negatives -> 0.0. testRenderSequence
      now uses it unconditionally (not gated by use_lma_dsi - that gate is for
      the pose measurement, not rendering).
      
      Verified: mvn -DskipTests clean package OK.
      Co-Authored-By: 's avatarClaude Fable 5 <noreply@anthropic.com>
      e4e65e23
    • Andrey Filippov's avatar
      CLAUDE: MB convert erase-first overload - undefined tiles reach consolidation as NaN · 48c93f00
      Andrey Filippov authored
      Per Andrey: undefined tiles (= not in the task list; the fixed-length 5120
      arrays represent them as nulls) must be handled by the channel consolidation
      - weighted-by-existing average, all-NaN tile when no sensor has it (now Java
      CuasTD.consolidateSensorsTD, later the CUDA clt_average_sensors kernel).
      The consolidation detects missing by NaN, but the MB double convert ran with
      erase=-1, leaving STALE (valid-looking) data at undefined tiles.
      
      - ImageDtt.interCorrTDMotionBlur: new erase-capable overload (erase_clt_first:
        >0 NaN, 0 zeros, <0 legacy no-erase) - erases before the FIRST (SET) convert
        only; the SECOND (negative-scale SUBTRACT) never erases. Legacy signature
        delegates with -1: oracle/SfM callers byte-identical.
      - CuasRender MB path uses erase_clt_first=1: the GPU TD buffer's NaN pattern
        now mirrors the task-list membership, so consolidation + renders see
        undefined tiles as NaN - never the previous scene.
      
      Verified: mvn -DskipTests clean package OK.
      Co-Authored-By: 's avatarClaude Fable 5 <noreply@anthropic.com>
      48c93f00
    • Andrey Filippov's avatar
      CLAUDE: CuasRender MB compensation + conditionSceneToGpuCuas motion wrapper (ERS omegas/velocities) · 72fd0677
      Andrey Filippov authored
      Per Andrey: of the 3 expected render-vs-oracle mismatch causes, the legitimate
      one is the better photometric calibration; the other two - ERS and motion
      blur - must be implemented in the RT chain:
      
      - ERS: NEW CuasConditioning.conditionSceneToGpuCuas(scene, cfg, omegas,
        velocities, ...) - the ONE place per-scene motion enters the ingest. Sets
        the scene ERS rates (fully-preserved ErsCorrection path); velocities =
        provision ({0,0,0}/null for the rotation-only camera). In production the
        omegas come analytically from wobble radius + RPM; the GPU corr_vector
        imu_rot/imu_move feed is the future upgrade (after the double-application
        check vs CPU pXpYD ERS). Legacy conditionSceneToGpu delegates (unchanged
        behavior for the pose loop).
      - MB: renderSceneVirtual takes mb_vectors/mb_tau/mb_max_gain; when enabled
        uses the ORACLE machinery (setInterTasksMotionBlur two-task-set +
        interCorrTDMotionBlur double convert: positive original + negative shifted
        scale pair summing to 1, ratio from 1-pix-time/tau, offset stretched when
        scales would exceed mb_max_gain). No erased re-convert in MB mode (would
        destroy the accumulation) - comparisons must mask to task tiles.
      - testRenderSequence: MB gated by imp.mb_en (matching the oracle DBG
        products: ON -> compare vs MB DBG, OFF -> vs -NOMB DBG); vectors from the
        same OpticalFlow.getMotionBlur at borrowed pose + stored rates; ingest via
        the new wrapper.
      
      Verified: mvn -DskipTests clean package OK.
      Co-Authored-By: 's avatarClaude Fable 5 <noreply@anthropic.com>
      72fd0677
    • Andrey Filippov's avatar
      CLAUDE: CuasRender - dedicated CUAS RT renderer + MINIMAL ingest+render certification test · 29c7239b
      Andrey Filippov authored
      Per Andrey (2026-07-05): today's problems came from jumping over the standalone
      certification of conditionSceneToGpu (single caller inside the pose test, never
      image-tested by itself). Test and debug the ingest+render chain FIRST, only then
      return to the pose test.
      
      NEW class cuas/rt/CuasRender (the start of the dedicated renderer per the spec
      in imagej-elphel-internal handoffs/2026-07-05_cuas_rt_dataflow_and_grids.md par.6:
      virtual uniform grid always, raw center DSI disparity, jp4+CuasConditioning
      pixels, QuadCLT borrow-only, static methods):
      - renderSceneVirtual(): tasks at pose (ALL valid-disparity tiles) -> convert
        (erase=1, NaN outside tasks) -> 16 per-sensor renders + consolidated (NaN-aware
        weighted average) merged render. No correlation.
      - testRenderSequence(): per scene raw /jp4/ -> conditionSceneToGpu -> render at
        BORROWED stored pose + stored ERS rates (the exact sources the oracle DBG
        renders use) -> saves <center>-CUAS-RT-RENDER.tiff hyperstack
        [t: s00..s15, merged][z: scenes], slice-by-slice comparable to
        -CUAS-INDIVIDUAL-CUAS-DBG / -CUAS-MERGED-CUAS-DBG.
      
      New checkbox "CUAS RT render test (ingest+render)" (curt.rend_test), takes
      precedence over the pose test in the curt_en branch.
      
      Verified: mvn -DskipTests clean package OK.
      Co-Authored-By: 's avatarClaude Fable 5 <noreply@anthropic.com>
      29c7239b
    • Andrey Filippov's avatar
      CLAUDE: REVERT lean sum scaling - falsified by LEAN-07 (peaks blur-dominated, not fz-dominated) · 6eaa8bf4
      Andrey Filippov authored
      LEAN-07 (stored poses, all tiles, sum-scaled input): sqrt_l0 3.22 -> 5.58
      (wider, not the predicted ~2.1), corr RMS 0.82 -> 1.005. At 16x signal-to-
      fat-zero the normalize amplifies the blur-decorrelated high frequencies -
      the fat zero was regularizing usefully. Root of the misdiagnosis: the width
      comparison used the MB-COMPENSATED oracles (FILT150A 2.08, MBEN 2.75); the
      correct no-MB control (NOMB oracle) has sqrt_l0 3.58 ~ lean's 3.22 - lean
      peak shapes were normal all along, and Andrey's "there was no 16x
      difference" was right where it mattered.
      
      Consequences: (1) correlator input back to the true weighted average (the
      same data as the -POSE-RT-COMPOSITE debug render - single upload again);
      (2) the "fz-broadened peak content pull" roll-bias mechanism is falsified -
      the +0.52/+0.33 mrad roll bias needs a new suspect (remaining engine
      differences vs the NOMB oracle: neighbor consolidation min_str_neib,
      min_confidence gates, peak-extraction parameters); (3) MB compensation in
      lean (v2) is the main quality lever - MBEN sharpens peaks 3.6 -> 2.8 and
      removes the 0.5 px wobble.
      
      Verified: mvn -DskipTests clean package OK.
      Co-Authored-By: 's avatarClaude Fable 5 <noreply@anthropic.com>
      6eaa8bf4
    • Andrey Filippov's avatar
      CLAUDE: lean debug render = TRUE weighted average (before the sum scaling) · 41930c37
      Andrey Filippov authored
      Per Andrey's input-verification methodology: the -POSE-RT-COMPOSITE "real"
      component must be the weighted 16-sensor average (comparable to the virtual
      render), while the correlator receives the per-tile SUM (379b3cf6 fix).
      Render moved BEFORE the sum scaling (extra H2D + imclt in debug mode only);
      the post-correlation render (which would now show the count-stepped sum)
      removed.
      
      Verified: mvn -DskipTests clean package OK.
      Co-Authored-By: 's avatarClaude Fable 5 <noreply@anthropic.com>
      41930c37
    • Andrey Filippov's avatar
      CLAUDE: lean pose FIX: consolidated TD scaled to per-tile sensor SUM (oracle... · 379b3cf6
      Andrey Filippov authored
      CLAUDE: lean pose FIX: consolidated TD scaled to per-tile sensor SUM (oracle fat-zero operating point)
      
      The lean conj-multiply fed the plain 16-sensor AVERAGE into the same
      FZ-normalize (same absolute fat zero; JNA drops per-tile weights) that the
      oracle feeds with the unweighted SUM of pair products - 1/16 the amplitude,
      so the effective fat zero was 16x larger. Invisible in output scale (the
      normalize hides it) but measured in peak shape: sqrt_l0 3.22 vs oracle 2.08
      and sqrt_l1 5.83 vs 4.15 on identical tiles, corr RMS 0.46 vs 0.33 - and
      suspected as the roll-bias mechanism (asymmetric-content centroid pull on
      broadened peaks; +0.52 mrad @ 150 edge-weighted tiles, +0.33 @ all tiles).
      
      Fix: multiply each consolidated tile by its per-sensor count (SUM semantics,
      matching the oracle exactly incl. partial tiles). consolidateSensorsTD
      itself unchanged (A2 validation still uses the true average).
      
      Expected in LEAN-05 (normal LMA run): sqrt_l0 ~2.1 in the HYPER eigen
      slices, corr RMS toward ~0.33, roll bias collapse if the mechanism is
      confirmed (survival = clean falsification).
      
      Verified: mvn -DskipTests clean package OK.
      Co-Authored-By: 's avatarClaude Fable 5 <noreply@anthropic.com>
      379b3cf6
    • Andrey Filippov's avatar
      CLAUDE: pose_stored DEBUG: apply STORED per-scene ERS rates (match the render path) · 19355588
      Andrey Filippov authored
      Andrey's diagnosis: the composite-vs-DBG sub-pixel warp field (static, sy-
      dominated: uniform 0.24px, x-shear, +0.3% y-scale ~ tilt_rate*frame_time)
      comes from the ErsCorrection infrastructure - the render path sets each
      scene's ERS from the STORED scenes_<ts>_dt (xyz_dt AND atr_dt,
      renderSceneSequence/OpticalFlow:10555) while the pose loop used finite-
      difference ATR-only rates with xyz_dt=0. Different scene-side ERS by
      construction. (Virtual center's own ERS rates confirmed ZERO in corr-xml;
      GPU corr_vector imu_rot/imu_move ERS support confirmed present but dormant.)
      
      pose_stored mode now sets setErsDt from ers_center.getSceneErsXYZ_dt/
      getSceneErsATR_dt - the exact calls the render uses - so the decoupled
      measurement/render applies IDENTICAL poses AND ERS as CUAS-MERGED-CUAS-DBG.
      If the warp field collapses in the next pose_stored run, the divergence is
      proven. Live (LMA) mode unchanged: finite-difference rates - to be replaced
      by rates computed from pose + rotation model (RT design: ErsCorrection
      preserved fully, thin non-QuadCLT plumbing; per-sensor ERS available on GPU
      via corr_vector imu when fed).
      
      Verified: mvn -DskipTests clean package OK.
      Co-Authored-By: 's avatarClaude Fable 5 <noreply@anthropic.com>
      19355588
    • Andrey Filippov's avatar
      CLAUDE: lean pose DEBUG: pose_stored - stored poses, no LMA (decouple render from solver) · b5e1fcd9
      Andrey Filippov authored
      Per Andrey: static per-tile dx offsets found in -POSE-RT-HYPER (e.g. tile
      x=15,y=41: dx mean +0.92 constant over all 497 scenes, far tile disp 0.02;
      tile x=71,y=51: dx +0.86 dy +1.91, near tile disp 13.2 - neighbors with
      similar disparity are near zero) -> suspect broken per-tile task data.
      
      New checkbox "Pose test stored poses (no LMA)" (curt.pose_stored): every
      scene is measured/rendered at its STORED (oracle-vintage) pose, the LMA is
      skipped entirely. -POSE-RT-HYPER/-CORR2D/-COMPOSITE come from that single
      measurement; CSV rms column = weighted RMS of the measured offsets.
      The -POSE-RT-COMPOSITE "real" component must then match the oracle
      CUAS-MERGED-CUAS-DBG per-scene renders tile-for-tile (and "virtual" its
      [average] slice) - any mismatch localizes the broken tiles in the
      task/render/correlation chain, independent of the solver.
      
      Observability only - the fitting paths are unchanged.
      Verified: mvn -DskipTests clean package OK.
      Co-Authored-By: 's avatarClaude Fable 5 <noreply@anthropic.com>
      b5e1fcd9
    • Andrey Filippov's avatar
      CLAUDE: lean pose DEBUG: -POSE-RT-COMPOSITE hyperstack (real x virtual renders) · a01a6381
      Andrey Filippov authored
      Per Andrey (no blind fixes - see what is going on): save the composite
      (TD-averaged, grid-transformed) scenes actually correlated against the
      virtual center, WITH the virtual render for comparison:
      
      - curt.pose_img_save (checkbox "Pose test save composite scenes"):
        -POSE-RT-COMPOSITE.tiff hyperstack [t: real, virtual][z: scene] - the
        virtual-center render repeated for every scene so the component slider
        blink-compares at any z. z aligned with -POSE-RT-HYPER/-CORR2D.
      - leanMeasure img_out holder: when requested, re-runs execConvertDirect
        with erase_clt=1 (NaN outside task tiles - the standard interCorrTD
        erase=-1 leaves the previous scene's tiles as ghosts in a render;
        correlation itself unaffected), then imclt renders sensor slot 0 = the
        consolidated average (last LMA cycle, converged pose).
      - Virtual component = imclt of the reference buffer (what the conj-multiply
        actually sees), not a re-render from prepared data.
      
      Observability only - processing unchanged, roll-bias symptom preserved.
      Verified: mvn -DskipTests clean package OK.
      Co-Authored-By: 's avatarClaude Fable 5 <noreply@anthropic.com>
      a01a6381
    • Andrey Filippov's avatar
      CLAUDE: lean pose DEBUG observability: -POSE-RT-CORR2D save + all-tiles bypass · a6a8ad3d
      Andrey Filippov authored
      Per Andrey's debug approach (same as used on the oracle): render the actual
      scene-vs-virtual-center correlations in the pixel domain and save them as a
      scene sequence. Observability only - NO processing changes, the roll-bias
      symptom is preserved.
      
      - curt.pose_corr_save (checkbox "Pose test save 2D correlations"): save
        -POSE-RT-CORR2D.tiff - z=scenes (aligned with -POSE-RT-HYPER incl. NaN
        slices for failed/coasted scenes), tile grid of 16x16-pix cells, last LMA
        cycle per scene, ImageDtt.corr_partial_dbg convention as CuasMotion CORR2D.
        Lean engine only (the oracle does not expose its correlation tiles).
      - curt.pose_full (checkbox "Pose test ALL tiles (ignore calibration)"):
        temporarily drop the 150-tile filter and use all strength-selected (~1074)
        tiles; -POSE-RT-TILE-CALIB is neither read NOR written so a debug run
        never pollutes the persistent tile calibration.
      - leanMeasure/leanFitScene: optional corr_pd_out holder (last-cycle PD tiles).
      
      Context: lean run v013-LEAN-01 confirmed the v*tau signature on az/tilt
      (implied tau = 8.4/8.0 ms = mb_tau) but showed a constant +0.52 mrad roll
      bias; peaks ~50% wider than oracle on common tiles (suspect: consolidation
      averages /16 while oracle sums pairs -> effective fat-zero 16x larger).
      These debug outputs are for inspecting exactly that before changing the
      processing.
      
      Verified: mvn -DskipTests clean package OK.
      Co-Authored-By: 's avatarClaude Fable 5 <noreply@anthropic.com>
      a6a8ad3d