Commit 0fe8f5c1 authored by Andrey Filippov's avatar Andrey Filippov

CLAUDE: RT-seed step 1b wiring - LoG A/B products in the RT render (curt.log_test)

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>
parent cfc93456
......@@ -288,10 +288,106 @@ public class CuasRender {
System.out.println("testRenderSequence(): WARNING - no per-sequence DC level (RT-STATE missing, curt.dc_center==0):"+
" falling back to the PER-SCENE sky median (rotation-synced DC flicker!)");
}
final ArrayList<float [][]> rendered = new ArrayList<float [][]>();
final ArrayList<String> ts_names = new ArrayList<String>();
final float [] nan_slice = new float [img_width * img_height];
java.util.Arrays.fill(nan_slice, Float.NaN);
final ArrayList<float [][]> rendered = renderPass( // By Claude on 07/06/2026 (loop extracted for the LoG A/B second pass)
clt_parameters, center_CLT, quadCLTs, image_dtt, ers_center,
center_disparity, pXpYD_center, cond_cfg, margin,
mb_en, mb_tau, mb_max_gain, ts_names, debugLevel);
saveRenderHyper(center_CLT, "-CUAS-RT-RENDER", rendered, ts_names,
img_width, img_height, num_comps);
// ---- LoG A/B (curt.log_test): the aberration+LoG kernel-fold validation
// (roadmap RT-seed step 1b). Two more comparable hyperstacks:
// -LOG-ORACLE: the EXISTING pre-DNN pixel-domain LoG (convolve2DLReLU,
// LINEAR alpha=1) applied to the product above;
// -LOG-FOLDED: same render chain, but the LoG folded into the aberration
// kernels (CuasLogFold) and re-uploaded to the GPU - NO
// pixel-domain convolution. Original kernels restored after.
// Offline compare (attic/CLAUDE/compare_cuda_versions.py --only LOG-) is
// the match verdict. By Claude on 07/06/2026, Andrey's step-1b spec.
if (clt_parameters.curt.log_test) {
// EXACT pre-DNN LoG: same class, same construction as CuasDetectRT.detectTargets
final CuasRTUtils cuasRTUtils = new CuasRTUtils (
clt_parameters.curt.psf_radius, // double psf_radius,
clt_parameters.curt.n_sigma, // double n_sigma,
clt_parameters.curt.temp_weights.clone(), // double[] temporal_weights,
clt_parameters.curt.pix_decimate, // int pixel_decimate,
clt_parameters.curt.vel_decimate, // int velocity_decimate,
clt_parameters.curt.vel_radius, // int velocity_radius,
clt_parameters.curt.vel_suppr_rad, // int vel_suppr_rad,
img_width, // int width,
img_height); // int height
final double [] kernel2d = cuasRTUtils.getKernel2d();
System.out.println("testRenderSequence(): LoG A/B - applying pixel-domain LoG (LINEAR) for -LOG-ORACLE");
for (int ns = 0; ns < rendered.size(); ns++) { // in place: slices replaced, originals already saved
final float [][] r = rendered.get(ns);
if (r == null) continue;
for (int nc = 0; nc < r.length; nc++) {
if (r[nc] == null) continue;
final double [] dslice = new double [r[nc].length];
for (int i = 0; i < dslice.length; i++) dslice[i] = r[nc][i];
final double [] dlog = cuasRTUtils.convolve2DLReLU(
dslice, // final double [] data,
kernel2d, // final double [] kernel, // square
null, // double [] result_in,
1.0); // final double alpha) - LINEAR (the standing ruling)
final float [] fslice = new float [dlog.length];
for (int i = 0; i < fslice.length; i++) fslice[i] = (float) dlog[i];
r[nc] = fslice;
}
}
saveRenderHyper(center_CLT, "-CUAS-RT-RENDER-LOG-ORACLE", rendered, ts_names,
img_width, img_height, num_comps);
rendered.clear(); // release ~11GB before the second render pass
// ---- second pass: folded aberration+LoG kernels on the GPU ----
final GpuQuad gpuQuad = center_CLT.getGPUQuad();
final double [][][][][][] orig_kernels = gpuQuad.getQuadCLT().getCLTKernels();
if (orig_kernels == null) {
System.out.println("testRenderSequence(): LoG A/B ERROR - getCLTKernels()==null (kernels never loaded?), skipping -LOG-FOLDED");
} else {
final double [] log_td = CuasLogFold.getLogTd(
clt_parameters.curt.psf_radius,
clt_parameters.curt.n_sigma);
System.out.println("testRenderSequence(): LoG A/B - uploading FOLDED aberration+LoG kernels (CuasLogFold, tap-precompensated)");
gpuQuad.setConvolutionKernels(CuasLogFold.foldKernels(orig_kernels, log_td), true);
try {
final ArrayList<String> ts_names2 = new ArrayList<String>();
final ArrayList<float [][]> rendered2 = renderPass(
clt_parameters, center_CLT, quadCLTs, image_dtt, ers_center,
center_disparity, pXpYD_center, cond_cfg, margin,
mb_en, mb_tau, mb_max_gain, ts_names2, debugLevel);
saveRenderHyper(center_CLT, "-CUAS-RT-RENDER-LOG-FOLDED", rendered2, ts_names2,
img_width, img_height, num_comps);
} finally { // ALWAYS restore the original kernels for anything running after
gpuQuad.setConvolutionKernels(orig_kernels, true);
System.out.println("testRenderSequence(): LoG A/B - original kernels restored");
}
}
System.out.println("testRenderSequence(): LoG A/B done - compare -LOG-ORACLE vs -LOG-FOLDED offline"+
" (attic/CLAUDE/compare_cuda_versions.py --only LOG-)");
}
}
/**
* One full render pass over the sequence (the loop extracted verbatim from
* testRenderSequence so the LoG A/B can run it twice - with the original and
* with the folded kernels). By Claude on 07/06/2026.
*/
private static ArrayList<float [][]> renderPass(
final CLTParameters clt_parameters,
final QuadCLT center_CLT,
final QuadCLT [] quadCLTs,
final ImageDtt image_dtt,
final ErsCorrection ers_center,
final double [] center_disparity,
final double [][] pXpYD_center,
final CuasConditioning.Config cond_cfg,
final int margin,
final boolean mb_en,
final double mb_tau,
final double mb_max_gain,
final ArrayList<String> ts_names, // OUT: aligned scene names
final int debugLevel) {
final ArrayList<float [][]> rendered = new ArrayList<float [][]>();
int num_ok = 0, num_fail = 0;
for (int nscene = 0; nscene < quadCLTs.length; nscene++) {
if (quadCLTs[nscene] == null) continue;
......@@ -347,21 +443,35 @@ public class CuasRender {
System.out.println("testRenderSequence(): rendered "+(num_ok+num_fail)+" scenes ("+num_fail+" failed)");
}
}
// ---- Save: [t: s00..s15, merged][z: scenes] hyperstack ----
System.out.println("testRenderSequence(): render pass done, scenes OK="+num_ok+", failed="+num_fail);
return rendered;
}
/** Save a render-product hyperstack [t: s00..s15, merged][z: scenes].
* By Claude on 07/06/2026 (extracted from testRenderSequence for the LoG A/B products). */
private static void saveRenderHyper(
final QuadCLT center_CLT,
final String suffix,
final ArrayList<float [][]> rendered,
final ArrayList<String> ts_names,
final int img_width,
final int img_height,
final int num_comps) {
final float [] nan_slice = new float [img_width * img_height];
java.util.Arrays.fill(nan_slice, Float.NaN);
final ImageStack stack = new ImageStack(img_width, img_height);
for (int nc = 0; nc < num_comps; nc++) {
final String comp = (nc < num_sens) ? String.format("s%02d", nc) : "merged";
final String comp = (nc < (num_comps - 1)) ? String.format("s%02d", nc) : "merged";
for (int ns = 0; ns < rendered.size(); ns++) {
final float [][] r = rendered.get(ns);
stack.addSlice(comp+":"+ts_names.get(ns), ((r != null) && (r[nc] != null)) ? r[nc] : nan_slice);
}
}
final ImagePlus imp = new ImagePlus(center_CLT.getImageName()+"-CUAS-RT-RENDER", stack);
final ImagePlus imp = new ImagePlus(center_CLT.getImageName()+suffix, stack);
imp.setDimensions(1, rendered.size(), num_comps);
imp.setOpenAsHyperStack(true);
imp.getProcessor().resetMinAndMax();
center_CLT.saveImagePlusInModelDirectory(null, imp); // title as filename
System.out.println("testRenderSequence(): scenes OK="+num_ok+", failed="+num_fail+
", saved -CUAS-RT-RENDER ("+num_comps+" components x "+rendered.size()+" scenes)");
System.out.println("testRenderSequence(): saved "+suffix+" ("+num_comps+" components x "+rendered.size()+" scenes)");
}
}
......@@ -28,6 +28,7 @@ public class CuasRtParameters {
public boolean pose_img_save = false; // DEBUG: save the composite scenes actually correlated - imclt render of the consolidated 16-sensor TD average at the converged pose (-POSE-RT-COMPOSITE: z=scenes; NaN outside task tiles) + the virtual-center reference render (-POSE-RT-CENTER-REF). Lean engine only. // By Claude on 07/04/2026
public boolean pose_stored = false; // DEBUG: decouple rendering/measurement from the LMA - use the STORED (oracle vintage) pose for every scene, no adjustment; one leanMeasure per scene feeds -POSE-RT-HYPER/-CORR2D/-COMPOSITE. The composite must then match the oracle CUAS-MERGED-CUAS-DBG renders tile-for-tile. Lean engine only. // By Claude on 07/04/2026
public boolean rend_test = false; // RT full-render product (CuasRender.testRenderSequence): per scene raw /jp4/ -> conditionSceneToGpu -> virtual-grid render at BORROWED stored pose+ERS rates -> -CUAS-RT-RENDER hyperstack [s00..s15, merged][scenes], comparable to -CUAS-INDIVIDUAL/MERGED-CUAS-DBG. NON-exclusive: runs AFTER the pose stage when both are ON (the pose stage is part of the RT cycle - Andrey 07/06/2026). // By Claude on 07/05/2026
public boolean log_test = false; // LoG A/B with the RT render (CuasRender): also save -CUAS-RT-RENDER-LOG-ORACLE (product convolved with the EXISTING pre-DNN pixel LoG, LINEAR alpha=1) and -CUAS-RT-RENDER-LOG-FOLDED (same render, LoG folded into the GPU aberration kernels via CuasLogFold - no pixel convolution; originals restored). The aberration+LoG kernel-fold validation (RT-seed step 1b). // By Claude on 07/06/2026
public boolean dbg_fpixels = true; // save the ORACLE debug renders during ingest (prepareFpixels): -CUAS-INDIVIDUAL-CUAS-DBG (an EXTRA per-sensor render pass, ~11GB) + -CUAS-MERGED-CUAS-DBG (save only - the merged render is the production input regardless). Was hardcoded. Turn OFF to save the render time and disk once the RT chain (-CUAS-RT-RENDER) is the trusted full render. // By Claude on 07/05/2026
public double fz_inter = 10000.0; // RT fat zero, INTER (pose/motion: scene x virtual-center correlation). DECOUPLED from the legacy gpu_fatz*/AUX switches (which stay untouched for non-RT/FOPEN). Value is for a single physical-pair amplitude; FZ ~ amplitude^2 in the GPU normalize - scale down x4..x16 for consolidated-average applications as needed. 10000 = the proven oracle INTER operating point (the lean code erroneously used the INTRA value before). // By Claude on 07/05/2026
public double fz_intra = 2000.0; // RT fat zero, INTRA (ranging/disparity: sensor-pair correlations within one scene). Reserved for the RT ranging path; same decoupling/scaling notes as fz_inter. // By Claude on 07/05/2026
......@@ -113,6 +114,8 @@ public class CuasRtParameters {
"DEBUG: measure/render every scene at its STORED pose, skip the LMA entirely - decouples the task/render/correlation chain from the solver. Lean engine only.");
gd.addCheckbox ("CUAS RT render (full product)", this.rend_test, // By Claude on 07/05/2026
"Full RT-chain render: raw jp4 -> conditioning -> virtual-grid render at borrowed stored poses/ERS; saves -CUAS-RT-RENDER [s00..s15+merged][scenes], comparable to the -CUAS-*-DBG oracle products. NON-exclusive: runs AFTER the pose stage when both are ON.");
gd.addCheckbox ("RT render LoG A/B (folded kernels)", this.log_test, // By Claude on 07/06/2026
"With the RT render ON: also save -CUAS-RT-RENDER-LOG-ORACLE (the product convolved with the EXISTING pre-DNN pixel-domain LoG, LINEAR) and -CUAS-RT-RENDER-LOG-FOLDED (same render with the LoG FOLDED into the GPU aberration kernels - no pixel convolution; original kernels restored after). Compare offline: the aberration+LoG kernel-fold validation (roadmap RT-seed step 1b).");
gd.addCheckbox ("Save oracle DBG renders (11GB)", this.dbg_fpixels, // By Claude on 07/05/2026
"Save -CUAS-INDIVIDUAL-CUAS-DBG (an EXTRA per-sensor render pass, ~11GB) and -CUAS-MERGED-CUAS-DBG during ingest. Turn OFF to save render time and disk once -CUAS-RT-RENDER (RT render test) is the trusted full render.");
gd.addNumericField("RT fat zero INTER (pose/motion)", this.fz_inter, 1,9,"", // By Claude on 07/05/2026
......@@ -256,6 +259,7 @@ public class CuasRtParameters {
this.pose_img_save = gd.getNextBoolean(); // By Claude on 07/04/2026
this.pose_stored = gd.getNextBoolean(); // By Claude on 07/04/2026
this.rend_test = gd.getNextBoolean(); // By Claude on 07/05/2026
this.log_test = gd.getNextBoolean(); // By Claude on 07/06/2026
this.dbg_fpixels = gd.getNextBoolean(); // By Claude on 07/05/2026
this.fz_inter = gd.getNextNumber(); // By Claude on 07/05/2026
this.fz_intra = gd.getNextNumber(); // By Claude on 07/05/2026
......@@ -339,6 +343,7 @@ public class CuasRtParameters {
properties.setProperty(prefix+"pose_img_save", this.pose_img_save+""); // boolean // By Claude on 07/04/2026
properties.setProperty(prefix+"pose_stored", this.pose_stored+""); // boolean // By Claude on 07/04/2026
properties.setProperty(prefix+"rend_test", this.rend_test+""); // boolean // By Claude on 07/05/2026
properties.setProperty(prefix+"log_test", this.log_test+""); // boolean // By Claude on 07/06/2026
properties.setProperty(prefix+"dbg_fpixels", this.dbg_fpixels+""); // boolean // By Claude on 07/05/2026
properties.setProperty(prefix+"fz_inter", this.fz_inter+""); // double // By Claude on 07/05/2026
properties.setProperty(prefix+"fz_intra", this.fz_intra+""); // double // By Claude on 07/05/2026
......@@ -422,6 +427,7 @@ public class CuasRtParameters {
if (properties.getProperty(prefix+"pose_img_save")!=null) this.pose_img_save=Boolean.parseBoolean(properties.getProperty(prefix+"pose_img_save")); // By Claude on 07/04/2026
if (properties.getProperty(prefix+"pose_stored")!=null) this.pose_stored=Boolean.parseBoolean(properties.getProperty(prefix+"pose_stored")); // By Claude on 07/04/2026
if (properties.getProperty(prefix+"rend_test")!=null) this.rend_test=Boolean.parseBoolean(properties.getProperty(prefix+"rend_test")); // By Claude on 07/05/2026
if (properties.getProperty(prefix+"log_test")!=null) this.log_test=Boolean.parseBoolean(properties.getProperty(prefix+"log_test")); // By Claude on 07/06/2026
if (properties.getProperty(prefix+"dbg_fpixels")!=null) this.dbg_fpixels=Boolean.parseBoolean(properties.getProperty(prefix+"dbg_fpixels")); // By Claude on 07/05/2026
if (properties.getProperty(prefix+"fz_inter")!=null) this.fz_inter=Double.parseDouble(properties.getProperty(prefix+"fz_inter")); // By Claude on 07/05/2026
if (properties.getProperty(prefix+"fz_intra")!=null) this.fz_intra=Double.parseDouble(properties.getProperty(prefix+"fz_intra")); // By Claude on 07/05/2026
......@@ -508,6 +514,7 @@ public class CuasRtParameters {
cp.pose_img_save = this.pose_img_save; // By Claude on 07/04/2026
cp.pose_stored = this.pose_stored; // By Claude on 07/04/2026
cp.rend_test = this.rend_test; // By Claude on 07/05/2026
cp.log_test = this.log_test; // By Claude on 07/06/2026
cp.dbg_fpixels = this.dbg_fpixels; // By Claude on 07/05/2026
cp.fz_inter = this.fz_inter; // By Claude on 07/05/2026
cp.fz_intra = this.fz_intra; // By Claude on 07/05/2026
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment