Commit c9cd3f9c authored by vertighel's avatar vertighel
Browse files

feat: guider box tracking + pick overlay X per target mode, white annotations



- guider.py: update box_center after each fit so the search box tracks
  the star across corrections
- guider-panel.js: draw X on overlay for center/stick/custom after
  right-click (non-destructive) and on Target dropdown change;
  fix left-click phase-2 to set TX/TY before calling onTargetChange;
  overlay annotations (box, X, dashed line) now white
- coordinates.py: reformat multiline log.debug fstring (cosmetic)

Co-Authored-By: default avatarClaude Sonnet 4.6 <noreply@anthropic.com>
parent 1ee45cdc
Loading
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -158,14 +158,16 @@ class Guider:

        try:
            fitted = fit_star(data[y0:y1, x0:x1])

        except Exception as e:
            msg = f"fit_star: {e}"
            log.error(f"Guider: {msg}")
            self.error.append(msg)
            return

        star_x = x0 + float(fitted.right.x_0)
        star_y = y0 + float(fitted.right.y_0)
        star_x = x0 + float(fitted.xc)
        star_y = y0 + float(fitted.yc)
        self.box_center = [star_x, star_y]
        log.debug(f"Guider: star at ({star_x:.1f}, {star_y:.1f})")

        if self.target == "center":
+5 −10
Original line number Diff line number Diff line
@@ -209,15 +209,10 @@ def apply_offset(fits_file=temp_fits, box=100, model="moffat", display=False):

    data = data[centx - width // 2:centx + width //
                2, centy - height // 2:centy + height // 2]
    log.debug(f"Taking subimage [{centx -
                                  width //
                                  2}:{centx +
                                      width //
                                      2}, {centy -
                                           height //
                                           2}:{centy +
                                               height //
                                               2}]")
    log.debug(f"Taking subimage [{centx - width // 2
                               }:{centx + width // 2
                               },{centy - height // 2
                               }:{centy + height // 2}]")
    
    # Fit on what you find there

+50 −9
Original line number Diff line number Diff line
@@ -79,6 +79,24 @@ function onTargetChange(panelId, target) {
        tx.value = '';
        ty.value = '';
    }

    const state = _pickState[panelId];
    if (state?.annotating && state.phase === 'idle') {
        if (target === 'center') {
            const { width, height } = state.viewer?.getImageSize() ?? {};
            state.targetX = (width && height) ? Math.round(width  / 2) : null;
            state.targetY = (width && height) ? Math.round(height / 2) : null;
        } else if (target === 'stick') {
            state.targetX = state.centerX;
            state.targetY = state.centerY;
        } else {
            const txv = parseFloat(tx.value);
            const tyv = parseFloat(ty.value);
            state.targetX = isNaN(txv) ? null : txv;
            state.targetY = isNaN(tyv) ? null : tyv;
        }
        state.viewer?.redrawOverlay();
    }
}

// --- 3. Collect + POST ---
@@ -207,16 +225,16 @@ function makeDrawer(state) {
            const half = (state.boxPx ?? 256) / 2;
            const tl   = toCanvas(state.centerX - half, state.centerY - half);
            const br   = toCanvas(state.centerX + half, state.centerY + half);
            ctx.strokeStyle = '#198754';
            ctx.strokeStyle = '#ffffff';
            ctx.lineWidth   = 2;
            ctx.strokeRect(tl.x, tl.y, br.x - tl.x, br.y - tl.y);
        }

        // Green X at target — only when idle (not while a new target is being picked).
        // White X at target — only when idle (not while a new target is being picked).
        if (state.annotating && state.targetX !== null && state.phase === 'idle') {
            const t = toCanvas(state.targetX, state.targetY);
            const s = 8;
            ctx.strokeStyle = '#198754';
            ctx.strokeStyle = '#ffffff';
            ctx.lineWidth   = 2;
            ctx.beginPath();
            ctx.moveTo(t.x - s, t.y - s); ctx.lineTo(t.x + s, t.y + s);
@@ -228,7 +246,7 @@ function makeDrawer(state) {
        if (state.phase === 'picking-target' && state.centerX !== null && state.mousePos) {
            const c = toCanvas(state.centerX, state.centerY);
            const m = toCanvas(state.mousePos.x, state.mousePos.y);
            ctx.strokeStyle = '#ffc107';
            ctx.strokeStyle = '#ffffff';
            ctx.lineWidth   = 1.5;
            ctx.setLineDash([6, 4]);
            ctx.beginPath();
@@ -310,10 +328,31 @@ function initPickMode(panelId) {
                ]) { document.getElementById(id)?.classList.remove('border-warning', 'border-success'); }
            } else {
                // ── Non-destructive: right-click after a left-click ──────────────
                // Box annotation persists; target (if any from previous pick) gone.
                // Box annotation persists; draw X based on Target mode.
                teardownSession(state);
                state.phase = 'idle';
                wrap?.classList.remove('pick-warning', 'pick-success');

                const target = document.getElementById(`guider-target-${panelId}`)?.value;
                if (target === 'center') {
                    const { width, height } = state.viewer?.getImageSize() ?? {};
                    state.targetX = (width  && height) ? Math.round(width  / 2) : null;
                    state.targetY = (width  && height) ? Math.round(height / 2) : null;
                } else if (target === 'stick') {
                    state.targetX = state.centerX;
                    state.targetY = state.centerY;
                    const txEl = document.getElementById(`guider-tx-${panelId}`);
                    const tyEl = document.getElementById(`guider-ty-${panelId}`);
                    if (txEl) txEl.value = state.centerX !== null ? Math.round(state.centerX) : '';
                    if (tyEl) tyEl.value = state.centerY !== null ? Math.round(state.centerY) : '';
                } else {
                    // custom: read whatever is in the TX/TY fields
                    const tx = parseFloat(document.getElementById(`guider-tx-${panelId}`)?.value);
                    const ty = parseFloat(document.getElementById(`guider-ty-${panelId}`)?.value);
                    state.targetX = isNaN(tx) ? null : tx;
                    state.targetY = isNaN(ty) ? null : ty;
                }

                state.viewer?.redrawOverlay();
                for (const id of [`guider-tx-${panelId}`, `guider-ty-${panelId}`]) {
                    document.getElementById(id)?.classList.remove('border-warning');
@@ -358,12 +397,14 @@ function initPickMode(panelId) {
            state.phase   = 'idle';

            // Enable TX/TY and fill them.
            const targetSel = document.getElementById(`guider-target-${panelId}`);
            if (targetSel) { targetSel.value = 'custom'; onTargetChange(panelId, 'custom'); }
            const txEl = document.getElementById(`guider-tx-${panelId}`);
            const tyEl = document.getElementById(`guider-ty-${panelId}`);
            if (txEl) { txEl.value = Math.round(imageX); txEl.classList.remove('border-warning'); txEl.classList.add('border-success'); }
            if (tyEl) { tyEl.value = Math.round(imageY); tyEl.classList.remove('border-warning'); tyEl.classList.add('border-success'); }
            if (txEl) { txEl.value = Math.round(imageX); }
            if (tyEl) { tyEl.value = Math.round(imageY); }
            const targetSel = document.getElementById(`guider-target-${panelId}`);
            if (targetSel) { targetSel.value = 'custom'; onTargetChange(panelId, 'custom'); }
            if (txEl) { txEl.classList.remove('border-warning'); txEl.classList.add('border-success'); }
            if (tyEl) { tyEl.classList.remove('border-warning'); tyEl.classList.add('border-success'); }

            teardownSession(state);
            wrap?.classList.remove('pick-success');