Skip to content

Commit 1d28e07

Browse files
authored
Fix typo in CPS's RMSD baseline: was 0.3Å, should have been 0.03Å (#225)
* fix typo reported in #224: RMSD baseline was 0.3Å, should be 0.03Å - update test cases to match new scores and add several new test cases for better coverage * remove .weight-display section from RadarChart and show weight percentages directly in SVG chart - include metric names in Combined Performance Score (CPS) description - improve label positioning and spacing in RadarChart.svelte - update tests to reflect changes in weight display logic
1 parent a48c373 commit 1d28e07

File tree

5 files changed

+305
-255
lines changed

5 files changed

+305
-255
lines changed

site/src/lib/RadarChart.svelte

Lines changed: 15 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -287,10 +287,14 @@
287287
aria-label="Radar chart for adjusting metric weights"
288288
>
289289
<!-- Axes -->
290-
{#each weights as weight, i}
291-
{@const angle = (2 * Math.PI * i) / weights.length}
290+
{#each weights as weight, idx}
291+
{@const angle = (2 * Math.PI * idx) / weights.length}
292292
{@const x = center.x + Math.cos(angle) * radius * 0.8}
293293
{@const y = center.y + Math.sin(angle) * radius * 0.8}
294+
{@const label_radius = idx === 2 ? radius * 1.0 : radius * 0.9}
295+
{@const label_x = center.x + Math.cos(angle) * label_radius}
296+
{@const label_y = center.y + Math.sin(angle) * label_radius}
297+
{@const spacing = idx === 1 ? `1.5em` : `1.2em`}
294298

295299
<line
296300
x1={center.x}
@@ -302,28 +306,29 @@
302306
/>
303307

304308
<!-- Axis labels -->
305-
{@const label_x = center.x + Math.cos(angle) * radius * 0.9}
306-
{@const label_y = center.y + Math.sin(angle) * radius * 0.9}
307309
<text
308310
x={label_x}
309311
y={label_y}
310312
text-anchor="middle"
311313
dominant-baseline="middle"
312-
font-size="12"
313-
fill="white"
314+
font-size="14"
315+
fill={colors[idx]}
314316
>
315317
<!-- Handle subscripts and superscripts manually since <sub> and <sup> are not supported in SVG -->
316318
{#if weight.label.includes(`<sub>`)}
317319
{@const parts = weight.label.split(/<sub>|<\/sub>/)}
318320
{parts[0]}
319-
<tspan baseline-shift="sub" font-size="8">{parts[1]}</tspan>
321+
<tspan baseline-shift="sub" font-size="10">{parts[1]}</tspan>
320322
{:else if weight.label.includes(`<sup>`)}
321323
{@const parts = weight.label.split(/<sup>|<\/sup>/)}
322324
{parts[0]}
323-
<tspan baseline-shift="super" font-size="8">{parts[1]}</tspan>
325+
<tspan baseline-shift="super" font-size="10">{parts[1]}</tspan>
324326
{:else}
325327
{@html weight.label}
326328
{/if}
329+
<tspan dy={spacing} x={label_x} font-size="12" font-weight="bold"
330+
>{(weight.value * 100).toFixed(0)}%</tspan
331+
>
327332
</text>
328333
{/each}
329334

@@ -390,40 +395,18 @@
390395
aria-label="Drag to adjust weight balance"
391396
/>
392397
</svg>
393-
394-
<!-- Weight percentages display -->
395-
<div class="weight-display">
396-
{#each weights as weight, idx}
397-
<div class="weight-item" style="color: {colors[idx]}">
398-
<span class="weight-name">{@html weight.label}</span>
399-
<span class="weight-value">{(weight.value * 100).toFixed(0)}%</span>
400-
</div>
401-
{/each}
402-
</div>
403398
</div>
404399

405400
<style>
406401
.radar-chart-container {
407402
display: flex;
408403
flex-direction: column;
409404
align-items: center;
410-
padding: 0.5em;
405+
padding: 0.2em;
406+
margin: 0;
411407
}
412408
svg {
413409
touch-action: none; /* Prevents default touch behaviors */
414410
cursor: pointer; /* Show pointer cursor to hint clickability */
415411
}
416-
.weight-display {
417-
display: flex;
418-
justify-content: space-around;
419-
width: 100%;
420-
margin-top: 0.3em;
421-
}
422-
.weight-item {
423-
display: flex;
424-
flex-direction: column;
425-
place-items: center;
426-
font-size: 0.8em;
427-
font-weight: bold;
428-
}
429412
</style>

site/src/lib/metrics.ts

Lines changed: 12 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ export const [F1_DEFAULT_WEIGHT, RMSD_DEFAULT_WEIGHT, KAPPA_DEFAULT_WEIGHT] = [
102102

103103
export const DEFAULT_COMBINED_METRIC_CONFIG: CombinedMetricConfig = {
104104
name: `CPS`,
105-
description: `Combined Performance Score weighting discovery, structure optimization, and phonon performance`,
105+
description: `Combined Performance Score weighting discovery (F1), structure optimization (RMSD), and phonon performance (κ<sub>SRME</sub>)`,
106106
weights: [
107107
{
108108
metric: `F1`,
@@ -131,14 +131,14 @@ function normalize_f1(value: number | undefined): number {
131131
return value // Already in [0,1] range
132132
}
133133

134-
// RMSD is lower=better, with current models in the range of ~0.02-0.25 Å
134+
// RMSD is lower=better, with current models in the range of ~0.01-0.25 Å
135135
// We invert this so that better performance = higher score
136136
function normalize_rmsd(value: number | undefined): number {
137137
if (value === undefined || isNaN(value)) return 0
138138

139139
// Fixed reference points for RMSD (in Å)
140140
const excellent = 0 // Perfect performance (atoms in exact correct positions)
141-
const baseline = 0.3 // in Å, a reasonable baseline for poor performance given worst performing model at time of writing is AlphaNet-MPTrj at 0.0227 Å
141+
const baseline = 0.03 // baseline for poor performance given worst performing model at time of writing is AlphaNet-MPTrj at 0.0227 Å
142142

143143
// Linear interpolation between fixed points with clamping
144144
// Inverse mapping since lower RMSD is better
@@ -157,26 +157,19 @@ function normalize_kappa_srme(value: number | undefined): number {
157157
return Math.max(0, 1 - value / 2)
158158
}
159159

160-
/**
161-
* Calculate a combined score using normalized metrics weighted by importance factors.
162-
* This uses fixed normalization reference points to ensure score stability when new models are added.
163-
*
164-
* Normalization reference points:
165-
* - F1: Already in [0,1] range, higher is better
166-
* - RMSD: 0.0Å (perfect) to 0.25Å (baseline), lower is better
167-
* - κ_SRME: Range [0,2] linearly mapped to [1,0], lower is better
168-
*
169-
* @param f1 F1 score for discovery
170-
* @param rmsd Root mean square displacement in Å
171-
* @param kappa Symmetric relative mean error for thermal conductivity
172-
* @param config Configuration with weights for each metric
173-
* @returns Combined score between 0-1, or NaN if any weighted metric is missing
174-
*/
160+
// Calculate a combined score using normalized metrics weighted by importance factors.
161+
// This uses fixed normalization reference points to ensure score stability when new models are added.
162+
163+
// Normalization reference points:
164+
// - F1 score for discovery already in [0,1] range, higher is better
165+
// - RMSD Root mean square displacement in range 0Å (perfect) to 0.03Å (baseline), lower is better
166+
// - κ_SRME symmetric relative mean error for lattice thermal conductivity,
167+
// range [0,2] linearly mapped to [1,0], lower is better
175168
export function calculate_combined_score(
176169
f1: number | undefined,
177170
rmsd: number | undefined,
178171
kappa: number | undefined,
179-
config: CombinedMetricConfig,
172+
config: CombinedMetricConfig, // weights for each metric
180173
): number {
181174
// Find weights from config by metric names
182175
const f1_weight =

site/src/routes/+page.svelte

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -162,8 +162,11 @@
162162
<div class="radar-container">
163163
<div class="radar-header">
164164
<span class="metric-name">{metric_config.name}</span>
165-
<Tooltip text={metric_config.description}>
165+
<Tooltip>
166166
<span class="info-icon">ⓘ</span>
167+
{#snippet tip()}
168+
{@html metric_config.description}
169+
{/snippet}
167170
</Tooltip>
168171

169172
<button
@@ -269,19 +272,15 @@
269272
max-width: 100%;
270273
background: var(--light-bg);
271274
border-radius: 4px;
272-
padding: 0.2em 0.5em;
275+
padding: 0.1em 0.3em;
273276
box-sizing: border-box;
274277
}
275278
276279
.radar-header {
277280
display: flex;
278281
align-items: center;
279-
gap: 0.5rem;
280-
}
281-
282-
.metric-name {
283-
font-weight: 600;
284-
margin-right: 0.3em;
282+
gap: 6pt;
283+
font-weight: bold;
285284
}
286285
287286
.info-icon {

site/tests/landing-page.test.ts

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -147,14 +147,10 @@ describe(`Landing Page`, () => {
147147
const axis_lines = document.body.querySelectorAll(`.radar-container svg line`)
148148
expect(axis_lines).toHaveLength(3)
149149

150-
// Check for weight display section
151-
const weight_displays = document.body.querySelectorAll(`.weight-item`)
152-
expect(weight_displays).toHaveLength(3)
153-
154-
// Check the default weight percentages
155-
const weight_values = Array.from(document.body.querySelectorAll(`.weight-value`)).map(
156-
(el) => el.textContent,
157-
)
150+
// Check the default weight percentages in SVG tspan elements
151+
const weight_values = Array.from(
152+
document.body.querySelectorAll(`.radar-container svg tspan:last-child`),
153+
).map((el) => el.textContent)
158154

159155
// Should show the default weights (50%, 40%, 10%)
160156
expect(weight_values).toEqual([`50%`, `40%`, `10%`])

0 commit comments

Comments
 (0)