--- session: ses_2b4f updated: 2026-04-01T21:57:48.280Z --- # Session Summary ## Goal Analyze how the SVD Components tab in `explorer.py` computes party positions, focusing on: data loading flow, window_size default, X/Y coordinate computation, and whether positions are individual MPs or party centroids. ## Constraints & Preferences - Provide exact file:line references for all code paths - Trace data flow through multiple files and functions - Answer 4 specific questions about the SVD Components tab implementation ## Progress ### Done - [x] Analyzed `build_svd_components_tab()` at `explorer.py:2449-2867` - [x] Traced `load_positions()` at `explorer.py:603-656` — default window_size is "quarterly" - [x] Traced `load_party_axis_scores()` at `explorer.py:836-853` - [x] Traced `_load_mp_vectors_by_party()` at `explorer.py:778-832` - [x] Analyzed `compute_2d_axes()` at `analysis/political_axis.py:131-476` - [x] Analyzed `compute_party_bootstrap_cis()` at `analysis/political_axis.py:624-695` - [x] Analyzed `compute_party_centroids()` at `explorer_helpers.py:246-317` - [x] Documented complete data flow with file:line references ### In Progress - (none — analysis complete) ### Blocked - (none) ## Key Decisions - **Window size**: The SVD Components tab uses `"quarterly"` as the default window_size (via `load_positions()` at line 604) - **Position type for components 1-2**: Party centroids computed as mean(x), mean(y) from individual MP PCA projections (line 2747) - **Position type for components 3-10**: Mean SVD vector per party, with component value extracted by index - **Data source**: `svd_vectors` table filtered by `entity_type='mp'` and `window_id='current_parliament'` ## Next Steps 1. (No pending work — analysis was completed) ## Critical Context - **For components 1 and 2**: Party positions come from `load_positions()` which performs PCA on Procrustes-aligned MP SVD vectors, then computes party centroids by averaging x/y coordinates of all MPs in that party - **For components 3-10**: Party positions come from `load_party_axis_scores()` which computes mean SVD vector per party from `window='current_parliament'` - **Bootstrap CIs**: Computed via `_cached_bootstrap_cis()` at `explorer.py:873-880` using `compute_party_bootstrap_cis()` from `analysis/political_axis.py` - **MP→Party mapping**: Via `mp_metadata` table, normalized using `_PARTY_NORMALIZE` dict at `explorer.py:471-480` ## File Operations ### Read - `/home/sgeboers/Projects/stemwijzer/explorer.py` (full file: lines 1-3094) - `/home/sgeboers/Projects/stemwijzer/analysis/political_axis.py` (full file: lines 1-695) - `/home/sgeboers/Projects/stemwijzer/explorer_helpers.py` (full file: lines 1-317) ### Modified - (none)