Skip to content

Commit ea2ec42

Browse files
andyedclaude
andcommitted
fix(peripheral): attach trial metadata before mouseup fires
The hold-duration table was all dashes because ClickSense's onCapture callback fires on mouseup — which is BEFORE the DOM click event where I was populating currentTrialMeta. Events were being pushed to clicksenseData without target_color / target_ecc attached, and the result-page aggregator filter (require both fields) skipped them. Fix: populate currentTrialMeta in showTarget() (before target is clickable), then enrich with click-dependent fields (rt, click error, was_hit) in onCanvasClick(). Same pattern for the timeout branch. Also adds a `phase: 'target'` marker so downstream PostHog analysis can filter target clicks from fixation clicks (fixation clicks still produce ClickSense events but with currentTrialMeta null). TODO.md: add PostHog data-pull analysis entry — cross-participant aggregation of peripheral_click events to test the cyan × far advantage hypothesis once N is large enough to wash out single- subject noise. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent db76de8 commit ea2ec42

1 file changed

Lines changed: 26 additions & 27 deletions

File tree

experiments/peripheral/index.html

Lines changed: 26 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -417,18 +417,12 @@ <h2>Data</h2>
417417
var hit = d2 <= TARGET_RADIUS + CLICK_HIT_TOLERANCE;
418418
clearTimeout(timerId);
419419

420-
currentTrialMeta = {
421-
target_color: trial.color,
422-
target_ecc: trial.ecc,
423-
target_ecc_px: Math.round(halfMin * trial.ecc_frac),
424-
target_angle_deg: Math.round(trial.angle_deg),
425-
target_x: Math.round(targetPos.x),
426-
target_y: Math.round(targetPos.y),
427-
trial_rt_ms: Math.round(rt),
428-
click_error_px: Math.round(d2),
429-
was_hit: hit,
430-
trial_index: currentTrialIdx,
431-
};
420+
// currentTrialMeta was set in showTarget() so ClickSense's onCapture
421+
// (which fires on mouseup, BEFORE the DOM click event) already saw the
422+
// trial context. Enrich with click-dependent fields for trialResults.
423+
currentTrialMeta.trial_rt_ms = Math.round(rt);
424+
currentTrialMeta.click_error_px = Math.round(d2);
425+
currentTrialMeta.was_hit = hit;
432426

433427
trialResults.push(Object.assign({}, currentTrialMeta));
434428

@@ -459,26 +453,31 @@ <h2>Data</h2>
459453
targetPos = targetPosForTrial(trial);
460454
}
461455
targetShownAt = performance.now();
456+
457+
// Set currentTrialMeta BEFORE target is clickable so the ClickSense
458+
// onCapture callback (fires on mouseup, before the DOM click event) has
459+
// the trial context attached to its event.
460+
currentTrialMeta = {
461+
phase: 'target',
462+
target_color: trial.color,
463+
target_ecc: trial.ecc,
464+
target_ecc_px: Math.round(halfMin * trial.ecc_frac),
465+
target_angle_deg: Math.round(trial.angle_deg),
466+
target_x: Math.round(targetPos.x),
467+
target_y: Math.round(targetPos.y),
468+
trial_index: currentTrialIdx,
469+
};
470+
462471
state = 'target_visible';
463472
render();
464473
// Timeout if user doesn't click within MAX_VISIBLE_MS
465474
timerId = setTimeout(function() {
466475
if (state === 'target_visible') {
467-
// Record miss (timeout)
468-
var trial = trials[currentTrialIdx];
469-
currentTrialMeta = {
470-
target_color: trial.color,
471-
target_ecc: trial.ecc,
472-
target_ecc_px: Math.round(halfMin * trial.ecc_frac),
473-
target_angle_deg: Math.round(trial.angle_deg),
474-
target_x: Math.round(targetPos.x),
475-
target_y: Math.round(targetPos.y),
476-
trial_rt_ms: null,
477-
click_error_px: null,
478-
was_hit: false,
479-
trial_index: currentTrialIdx,
480-
timed_out: true,
481-
};
476+
// Record miss (timeout) — enrich the meta that was set in showTarget.
477+
currentTrialMeta.trial_rt_ms = null;
478+
currentTrialMeta.click_error_px = null;
479+
currentTrialMeta.was_hit = false;
480+
currentTrialMeta.timed_out = true;
482481
trialResults.push(Object.assign({}, currentTrialMeta));
483482
state = 'iti';
484483
setTimeout(function() {

0 commit comments

Comments
 (0)