Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions apps/cadecon/src/components/controls/AlgorithmSettings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import {
setLpFilterEnabled,
noiseConstrained,
setNoiseConstrained,
massCount,
setMassCount,
maxIterations,
setMaxIterations,
convergenceTol,
Expand Down Expand Up @@ -97,6 +99,14 @@ export function AlgorithmSettings(): JSX.Element {
onChange={setNoiseConstrained}
disabled={isRunLocked()}
/>

<ToggleSwitch
label="Mass-Based Count"
description="Counts each event by its deconvolved mass and refits amplitude, correcting the spike overcount and halved alpha that upsampling causes (bursts closer than one kernel width may still merge)"
checked={massCount()}
onChange={setMassCount}
disabled={isRunLocked()}
/>
</div>
</div>
);
Expand Down
8 changes: 8 additions & 0 deletions apps/cadecon/src/lib/algorithm-store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@ const [lpFilterEnabled, setLpFilterEnabled] = createSignal(true);
// still reaches the data-derived noise floor (no tuning knob). Suppresses noise
// fit as spurious spikes; benefit concentrates at low SNR. Off = current max-PVE.
const [noiseConstrained, setNoiseConstrained] = createSignal(true);
// Mass-based count readout: count events by relaxed mass (calibrated to the
// single-spike mass) and refit alpha, instead of binarize->bin-sum. Undoes the
// coherent-grid overcount that inflates spike counts and halves alpha at high
// upsampling. Off by default (preserves historical output); see
// docs/cadecon-mass-count.md.
const [massCount, setMassCount] = createSignal(false);
// Opt-in: during each iteration, also solve every trace with the OPPOSITE
// noise-constrained setting and store it, so the Trace Inspector can overlay the
// two instantly (no live solve). Doubles inference cost — off by default.
Expand Down Expand Up @@ -63,6 +69,8 @@ export {
setLpFilterEnabled,
noiseConstrained,
setNoiseConstrained,
massCount,
setMassCount,
sparsityCompareEnabled,
setSparsityCompareEnabled,
maxIterations,
Expand Down
2 changes: 2 additions & 0 deletions apps/cadecon/src/lib/bridge-effects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
setUpsampleTarget,
setHpFilterEnabled,
setLpFilterEnabled,
setMassCount,
setMaxIterations,
setConvergenceTol,
} from './algorithm-store.ts';
Expand Down Expand Up @@ -47,6 +48,7 @@ function applyConfig(config: BridgeConfig): void {
if (config.upsample_target != null) setUpsampleTarget(config.upsample_target);
if (config.hp_filter_enabled != null) setHpFilterEnabled(config.hp_filter_enabled);
if (config.lp_filter_enabled != null) setLpFilterEnabled(config.lp_filter_enabled);
if (config.mass_count != null) setMassCount(config.mass_count);
if (config.max_iterations != null) setMaxIterations(config.max_iterations);
if (config.convergence_tol != null) setConvergenceTol(config.convergence_tol);
if (config.num_subsets != null) setNumSubsets(config.num_subsets);
Expand Down
2 changes: 2 additions & 0 deletions apps/cadecon/src/lib/cadecon-pool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ interface TraceJobFields {
lpEnabled: boolean;
lambda: number;
noiseConstrained: boolean;
massCount: boolean;
computeComparison: boolean;
warmCounts?: Float32Array;
onComplete(result: TraceResult): void;
Expand Down Expand Up @@ -123,6 +124,7 @@ const caDeconRouter: MessageRouter<CaDeconPoolJob, CaDeconWorkerOutbound> = {
lpEnabled: job.lpEnabled,
lambda: job.lambda,
noiseConstrained: job.noiseConstrained,
massCount: job.massCount,
computeComparison: job.computeComparison,
warmCounts: warmCopy,
},
Expand Down
6 changes: 6 additions & 0 deletions apps/cadecon/src/lib/iteration-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ import {
hpFilterEnabled,
lpFilterEnabled,
noiseConstrained,
massCount,
sparsityCompareEnabled,
traceFistaMaxIters,
traceFistaTol,
Expand Down Expand Up @@ -167,6 +168,7 @@ function dispatchTraceJobs(
lpEnabled: boolean,
lambda: number,
noiseConstrained: boolean,
massCount: boolean,
computeComparison: boolean,
prevResults?: Map<number, Float32Array>,
): Promise<Array<Map<number, TraceResult>>> {
Expand Down Expand Up @@ -216,6 +218,7 @@ function dispatchTraceJobs(
lpEnabled,
lambda,
noiseConstrained,
massCount,
computeComparison,
warmCounts,
onComplete(result: TraceResult) {
Expand Down Expand Up @@ -454,6 +457,7 @@ export async function startRun(): Promise<void> {
const lpOn = lpFilterEnabled();
const sparsityLambda = 0.0;
const noiseConstrainedOn = noiseConstrained();
const massCountOn = massCount();
const computeComparison = sparsityCompareEnabled();

// Create pool
Expand Down Expand Up @@ -592,6 +596,7 @@ export async function startRun(): Promise<void> {
lpOn,
sparsityLambda,
noiseConstrainedOn,
massCountOn,
computeComparison,
prevTraceCounts,
);
Expand Down Expand Up @@ -931,6 +936,7 @@ export async function startRun(): Promise<void> {
lpEnabled: lpOn,
lambda: sparsityLambda,
noiseConstrained: noiseConstrainedOn,
massCount: massCountOn,
computeComparison,
warmCounts,
onComplete(result: TraceResult) {
Expand Down
3 changes: 3 additions & 0 deletions apps/cadecon/src/workers/cadecon-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ export type CaDeconWorkerInbound =
/** Noise-constrained threshold selection: choose the sparsest spike support
* whose residual meets the data-derived noise floor (no tuning knob). */
noiseConstrained: boolean;
/** Mass-based count readout: count events by relaxed mass and refit alpha,
* undoing the coherent-grid overcount that halves alpha (no tuning knob). */
massCount: boolean;
/** Also solve with the OPPOSITE noise-constrained setting and return it as
* comparisonSCounts (for the teaching/impact overlay). */
computeComparison: boolean;
Expand Down
2 changes: 2 additions & 0 deletions apps/cadecon/src/workers/cadecon-worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ function handleTraceJob(req: Extract<CaDeconWorkerInbound, { type: 'trace-job' }
req.warmCounts ?? EMPTY_F32,
req.lambda,
req.noiseConstrained,
req.massCount,
) as {
s_counts: number[];
filtered_trace: number[] | null;
Expand Down Expand Up @@ -78,6 +79,7 @@ function handleTraceJob(req: Extract<CaDeconWorkerInbound, { type: 'trace-job' }
req.warmCounts ?? EMPTY_F32,
req.lambda,
!req.noiseConstrained,
req.massCount,
) as { s_counts: number[] };
comparisonSCounts = new Float32Array(cmp.s_counts);
transfers.push(comparisonSCounts.buffer as ArrayBuffer);
Expand Down
Loading
Loading