Commit 77f8ce01 authored by Andrey Filippov's avatar Andrey Filippov

Continued testing MF approach before connecting CNN inference

parent 0b5e4920
......@@ -80,6 +80,9 @@ public class CuasRecurrentBuffer {
private final double rs_min; // re-sharpen: minimal blob maximum to re-fit; weaker content passes through as residue
private double [][][] buffer; // [roi_width*roi_height][num_sub][vel_dim*vel_dim]
private int num_updates = 0;
private boolean save_stages = false; // keep per-update intermediate stages for debug imaging // By Claude on 06/10/2026
private double [][][] last_cond = null; // conditioned measurement of the last update (zeros for a gap) // By Claude on 06/10/2026
private double [][][] pre_resharpen = null; // last merged state before re-sharpening // By Claude on 06/10/2026
public CuasRecurrentBuffer (
int roi_width,
......@@ -113,13 +116,32 @@ public class CuasRecurrentBuffer {
}
public double [][][] getBufferCopy() {
double [][][] copy = new double [buffer.length][num_sub][vel_dim*vel_dim];
for (int p = 0; p < buffer.length; p++) for (int s = 0; s < num_sub; s++) {
System.arraycopy(buffer[p][s], 0, copy[p][s], 0, buffer[p][s].length);
return deepCopy(buffer);
}
private double [][][] deepCopy(double [][][] src) { // By Claude on 06/10/2026
double [][][] copy = new double [src.length][num_sub][vel_dim*vel_dim];
for (int p = 0; p < src.length; p++) for (int s = 0; s < num_sub; s++) {
System.arraycopy(src[p][s], 0, copy[p][s], 0, src[p][s].length);
}
return copy;
}
/** Enable keeping per-update intermediate stages (conditioned measurement, pre-resharpen state) for debug imaging. */
public void setSaveStages(boolean save_stages) { // By Claude on 06/10/2026
this.save_stages = save_stages;
}
/** Conditioned measurement of the last update (zeros array for a gap); null until the first update with stages enabled. */
public double [][][] getLastConditioned() { // By Claude on 06/10/2026
return last_cond;
}
/** State after the merge, before re-sharpening (== final state when re-sharpening was skipped); null until the first update with stages enabled. */
public double [][][] getPreResharpen() { // By Claude on 06/10/2026
return pre_resharpen;
}
public int getNumUpdates() {
return num_updates;
}
......@@ -141,6 +163,9 @@ public class CuasRecurrentBuffer {
double [][][] shifted = shiftByVelocity(buffer);
if (spread > 0) diffuseVelocity(shifted); // process noise: lets the maximum migrate between velocity cells
double [][][] cond = (measurement != null) ? condition(measurement) : null;
if (save_stages) { // By Claude on 06/10/2026
last_cond = (cond != null) ? cond : new double [buffer.length][num_sub][vel_dim*vel_dim];
}
for (int p = 0; p < buffer.length; p++) {
double w_eff = w;
if (cond == null) {
......@@ -160,6 +185,9 @@ public class CuasRecurrentBuffer {
}
}
}
if (save_stages) { // By Claude on 06/10/2026
pre_resharpen = deepCopy(buffer);
}
if ((cond != null) && (rs_frac > 0)) { // re-fit merged blobs; skipped during gaps - shear accumulates as honest uncertainty // By Claude on 06/10/2026
resharpen();
}
......@@ -398,21 +426,37 @@ public class CuasRecurrentBuffer {
for (int s = 0; s < num_sub; s++) {
java.util.Arrays.fill(claimed, false);
bumps.clear();
while (true) {
// strongest unclaimed cell
double m = 0;
int cell_m = -1;
for (int p = 0; p < buffer.length; p++) {
double [] plane = buffer[p][s];
int base = p * nvel;
for (int v = 0; v < nvel; v++) {
if (!claimed[base + v] && (plane[v] > m)) {
m = plane[v];
cell_m = base + v;
}
// Collect peel candidates (>= rs_min) once and sort - replaces the repeated // By Claude on 06/11/2026
// full-buffer strongest-cell scans (O(cells*blobs), minutes for a large ROI
// with many targets) with one pass + sort. Iterating the sorted list and
// skipping already-claimed cells yields exactly the original peel order:
// unclaimed cell values never change, so the next unclaimed candidate IS the
// strongest remaining. Value packed as float bits (monotonic for positives)
// in the high 32 bits, cell index in the low 32.
int n_cand = 0;
for (int p = 0; p < buffer.length; p++) {
double [] plane = buffer[p][s];
for (int v = 0; v < nvel; v++) {
if (plane[v] >= rs_min) n_cand++;
}
}
long [] cand = new long [n_cand];
n_cand = 0;
for (int p = 0; p < buffer.length; p++) {
double [] plane = buffer[p][s];
int base = p * nvel;
for (int v = 0; v < nvel; v++) {
if (plane[v] >= rs_min) {
cand[n_cand++] = (((long) Float.floatToIntBits((float) plane[v])) << 32) | (base + v);
}
}
if ((cell_m < 0) || (m < rs_min)) break;
}
java.util.Arrays.sort(cand);
for (int nc = cand.length - 1; nc >= 0; nc--) { // strongest first
int cell_m = (int) (cand[nc] & 0xFFFFFFFFL);
if (claimed[cell_m]) continue; // absorbed by a stronger blob's growth
double m = buffer[cell_m / nvel][s][cell_m % nvel];
if (m < rs_min) continue;
double thresh = rs_frac * m;
// grow the blob over 4D-connected cells above thresh, accumulate energy and centroid
int sp = 0;
......
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