Rework comparison components.

More focused on error ellipses.
This commit is contained in:
D. Berge
2025-08-19 19:28:19 +02:00
parent 5527576679
commit 674d818fee
2 changed files with 69 additions and 29 deletions

View File

@@ -10,8 +10,8 @@
<thead> <thead>
<tr> <tr>
<th>Metric</th> <th>Metric</th>
<th>X (m)</th> <th>I (m)</th>
<th>Y (m)</th> <th>J (m)</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@@ -34,21 +34,24 @@
</template> </template>
</v-simple-table> </v-simple-table>
<h3 class="mt-4">Counts</h3> <h3 class="mt-4">Error distribution</h3>
<ul> <ul>
<li>Common Points: {{ comparison.common }}</li> <li title="Relative to I-axis positive direction">Primary Direction: {{ (comparison.primaryDirection * 180 / Math.PI).toFixed(2) }}°</li>
<li>Comparison Length: {{ comparison.length }}</li> <li>Anisotropy: {{ comparison.anisotropy.toFixed(2) }}</li>
<li>Baseline Length: {{ comparison.baselineLength }} (Unique: {{ comparison.baselineUniqueLength }})</li> <li title="Length of the semi-major axis of the error ellipse">Semi-Major Axis: {{ semiMajorAxis.toFixed(2) }} m</li>
<li>Monitor Length: {{ comparison.monitorLength }} (Unique: {{ comparison.monitorUniqueLength }})</li> <li title="Length of the semi-minor axis of the error ellipse">Semi-Minor Axis: {{ semiMinorAxis.toFixed(2) }} m</li>
<li>Compared Points: {{ comparison.compared }}</li> <li title="Area of the error ellipse">Error Ellipse Area: {{ ellipseArea.toFixed(2) }} </li>
</ul> </ul>
<h3 class="mt-4">Other Metrics</h3> <h3 class="mt-4">Counts</h3>
<ul> <ul>
<li>Anisotropy: {{ comparison.anisotropy.toFixed(2) }}</li> <li title="Unique line / point pairs found in both projects">Common Points: {{ comparison.common }}</li>
<li title="Relative to I-axis positive direction">Primary Direction: {{ (comparison.primaryDirection * 180 / Math.PI).toFixed(2) }}°</li> <li title="Total number of points compared, including reshoots, infills, etc.">Comparison Length: {{ comparison.length }}</li>
<li>Timestamp: {{ new Date(comparison.tstamp).toLocaleString() }}</li> <li title="Number of points in the baseline project">Baseline Points: {{ comparison.baselineLength }} (Unique: {{ comparison.baselineUniqueLength }})</li>
<li title="Number of points in the monitor project">Monitor Points: {{ comparison.monitorLength }} (Unique: {{ comparison.monitorUniqueLength }})</li>
</ul> </ul>
<p class="mt-3" title="Date and time when the comparison was last performed">Computation timestamp: {{ new Date(comparison.tstamp).toLocaleString() }}</p>
</v-col> </v-col>
<v-col cols="12" md="6"> <v-col cols="12" md="6">
@@ -139,10 +142,34 @@ export default {
Math.abs(this.comparison['μ'][0]), Math.abs(this.comparison['μ'][0]),
Math.abs(this.comparison['μ'][1]) Math.abs(this.comparison['μ'][1])
); );
const maxExtent = maxMu + 3 * maxSigma; //const maxExtent = maxMu + 3 * maxSigma;
const maxExtent = 20;
return 100 / maxExtent; // Adjust scale to fit within ~200 pixels diameter return 100 / maxExtent; // Adjust scale to fit within ~200 pixels diameter
}, },
ellipseArea () {
if (!this.comparison) return 0;
const a = Math.sqrt(this.comparison.eigenvalues[0]);
const b = Math.sqrt(this.comparison.eigenvalues[1]);
return Math.PI * a * b;
},
semiMajorAxis () {
if (!this.comparison) return 0;
return Math.max(
Math.sqrt(this.comparison.eigenvalues[0]),
Math.sqrt(this.comparison.eigenvalues[1])
);
},
semiMinorAxis () {
if (!this.comparison) return 0;
return Math.min(
Math.sqrt(this.comparison.eigenvalues[0]),
Math.sqrt(this.comparison.eigenvalues[1])
);
},
meanX () { meanX () {
return this.comparison ? this.comparison['μ'][0] : 0; return this.comparison ? this.comparison['μ'][0] : 0;
}, },

View File

@@ -2,7 +2,7 @@
<v-card class="ma-1"> <v-card class="ma-1">
<v-card-title>Group Repeatability Summary</v-card-title> <v-card-title>Group Repeatability Summary</v-card-title>
<v-card-text> <v-card-text>
<p>Inline standard deviation (σ_x) for each baseline-monitor pair. Lower values indicate better repeatability. Colors range from green (best) to red (worst).</p> <p>Error ellipse area for each baseline-monitor pair. Lower values indicate better repeatability. Colors range from green (best) to red (worst).</p>
<v-simple-table dense> <v-simple-table dense>
<thead> <thead>
<tr> <tr>
@@ -17,18 +17,19 @@
<v-tooltip v-if="colIndex > rowIndex" top> <v-tooltip v-if="colIndex > rowIndex" top>
<template v-slot:activator="{ on, attrs }"> <template v-slot:activator="{ on, attrs }">
<div <div
:style="{ backgroundColor: getSigmaXColor(baselineProject.pid, monitorProject.pid), color: 'white', textAlign: 'center', padding: '4px' }" :style="{ backgroundColor: getEllipseAreaColor(baselineProject.pid, monitorProject.pid), color: 'white', textAlign: 'center', padding: '4px' }"
v-bind="attrs" v-bind="attrs"
v-on="on" v-on="on"
@click="emitInput(baselineProject, monitorProject)" @click="emitInput(baselineProject, monitorProject)"
> >
{{ formatSigmaX(baselineProject.pid, monitorProject.pid) }} {{ formatEllipseArea(baselineProject.pid, monitorProject.pid) }}
</div> </div>
</template> </template>
<span v-if="getComp(baselineProject.pid, monitorProject.pid)"> <span v-if="getComp(baselineProject.pid, monitorProject.pid)">
<div>σ_x: {{ getComp(baselineProject.pid, monitorProject.pid).meta['σ'][0].toFixed(2) }} m</div> <div>σ_i: {{ getComp(baselineProject.pid, monitorProject.pid).meta['σ'][0].toFixed(2) }} m</div>
<div>σ_y: {{ getComp(baselineProject.pid, monitorProject.pid).meta['σ'][1].toFixed(2) }} m</div> <div>σ_j: {{ getComp(baselineProject.pid, monitorProject.pid).meta['σ'][1].toFixed(2) }} m</div>
<div>Anisotropy: {{ getComp(baselineProject.pid, monitorProject.pid).meta.anisotropy.toFixed(0) }}</div> <div>Anisotropy: {{ getComp(baselineProject.pid, monitorProject.pid).meta.anisotropy.toFixed(0) }}</div>
<div>Ellipse Area: {{ getEllipseArea(baselineProject.pid, monitorProject.pid).toFixed(2) }} </div>
<div>Primary Direction: {{ formatPrimaryDirection(getComp(baselineProject.pid, monitorProject.pid)) }}°</div> <div>Primary Direction: {{ formatPrimaryDirection(getComp(baselineProject.pid, monitorProject.pid)) }}°</div>
</span> </span>
</v-tooltip> </v-tooltip>
@@ -64,30 +65,42 @@ export default {
compMap () { compMap () {
return new Map(this.comparisons.map(c => [`${c.baseline_pid}-${c.monitor_pid}`, c])); return new Map(this.comparisons.map(c => [`${c.baseline_pid}-${c.monitor_pid}`, c]));
}, },
minSigmaX () { minEllipseArea () {
if (!this.comparisons.length) return 0; if (!this.comparisons.length) return 0;
return Math.min(...this.comparisons.map(c => c.meta['σ'][0])); return Math.min(...this.comparisons.map(c => {
const a = Math.sqrt(c.meta.eigenvalues[0]);
const b = Math.sqrt(c.meta.eigenvalues[1]);
return Math.PI * a * b;
}));
}, },
maxSigmaX () { maxEllipseArea () {
if (!this.comparisons.length) return 0; if (!this.comparisons.length) return 0;
return Math.max(...this.comparisons.map(c => c.meta['σ'][0])); return Math.max(...this.comparisons.map(c => {
const a = Math.sqrt(c.meta.eigenvalues[0]);
const b = Math.sqrt(c.meta.eigenvalues[1]);
return Math.PI * a * b;
}));
} }
}, },
methods: { methods: {
getComp (basePid, monPid) { getComp (basePid, monPid) {
return this.compMap.get(`${basePid}-${monPid}`); return this.compMap.get(`${basePid}-${monPid}`);
}, },
getSigmaX (basePid, monPid) { getEllipseArea (basePid, monPid) {
return this.getComp(basePid, monPid)?.meta?.['σ']?.[0] ?? null; const comp = this.getComp(basePid, monPid);
if (!comp) return null;
const a = Math.sqrt(comp.meta.eigenvalues[0]);
const b = Math.sqrt(comp.meta.eigenvalues[1]);
return Math.PI * a * b;
}, },
formatSigmaX (basePid, monPid) { formatEllipseArea (basePid, monPid) {
const val = this.getSigmaX(basePid, monPid); const val = this.getEllipseArea(basePid, monPid);
return val !== null ? val.toFixed(1) : ''; return val !== null ? val.toFixed(1) : '';
}, },
getSigmaXColor (basePid, monPid) { getEllipseAreaColor (basePid, monPid) {
const val = this.getSigmaX(basePid, monPid); const val = this.getEllipseArea(basePid, monPid);
if (val === null) return ''; if (val === null) return '';
const ratio = (val - this.minSigmaX) / (this.maxSigmaX - this.minSigmaX); const ratio = (val - this.minEllipseArea) / (this.maxEllipseArea - this.minEllipseArea);
const hue = (1 - ratio) * 120; const hue = (1 - ratio) * 120;
return `hsl(${hue}, 70%, 70%)`; return `hsl(${hue}, 70%, 70%)`;
}, },