From 4de03542f871d0ca2965ab6f6b8c118105779cb5 Mon Sep 17 00:00:00 2001 From: Scott Bell Date: Wed, 9 Oct 2024 22:15:26 +0200 Subject: [PATCH 1/4] impute requested data properly --- src/plugins/comps/CompsManager.js | 72 +++++++++++++++++---- src/plugins/comps/CompsMathWorker.js | 1 + src/plugins/comps/CompsTelemetryProvider.js | 4 +- 3 files changed, 63 insertions(+), 14 deletions(-) diff --git a/src/plugins/comps/CompsManager.js b/src/plugins/comps/CompsManager.js index 68aafca4b0..45695bb17d 100644 --- a/src/plugins/comps/CompsManager.js +++ b/src/plugins/comps/CompsManager.js @@ -215,7 +215,62 @@ export default class CompsManager extends EventEmitter { ); } - getTelemetryForComps(newTelemetry) { + #getImputedDataUsingLOCF(datum, telemetryCollection) { + const telemetryCollectionData = telemetryCollection.getAll(); + let insertionPointForNewData = telemetryCollection._sortedIndex(datum); + if (insertionPointForNewData && insertionPointForNewData >= telemetryCollectionData.length) { + insertionPointForNewData = telemetryCollectionData.length - 1; + } + // get the closest datum to the new datum + const closestDatum = telemetryCollectionData[insertionPointForNewData]; + // clone the closest datum and replace the time key with the new time + const imputedData = { + ...closestDatum, + [telemetryCollection.timeKey]: datum[telemetryCollection.timeKey] + }; + return imputedData; + } + + getDataFrameForRequest() { + // Step 1: Collect all unique timestamps from all telemetry collections + const allTimestampsSet = new Set(); + + Object.values(this.#telemetryCollections).forEach((collection) => { + collection.getAll().forEach((dataPoint) => { + allTimestampsSet.add(dataPoint.timestamp); + }); + }); + + // Convert the set to a sorted array + const allTimestamps = Array.from(allTimestampsSet).sort((a, b) => a - b); + + // Step 2: Initialize the result object + const telemetryForComps = {}; + + // Step 3: Iterate through each telemetry collection to align data + Object.keys(this.#telemetryCollections).forEach((keyString) => { + const telemetryCollection = this.#telemetryCollections[keyString]; + const alignedValues = []; + + // Iterate through each common timestamp + allTimestamps.forEach((timestamp) => { + const timeKey = telemetryCollection.timeKey; + const fakeData = { [timeKey]: timestamp }; + const imputedDatum = this.#getImputedDataUsingLOCF(fakeData, telemetryCollection); + if (imputedDatum) { + alignedValues.push(imputedDatum); + } else { + console.debug(`🚨 Missing data for ${keyString} at ${timestamp}`); + } + }); + + telemetryForComps[keyString] = alignedValues; + }); + + return telemetryForComps; + } + + getDataFrameForSubscription(newTelemetry) { const telemetryForComps = {}; const newTelemetryKey = Object.keys(newTelemetry)[0]; const newTelemetryParameter = this.#getParameterForKeyString(newTelemetryKey); @@ -247,16 +302,9 @@ export default class CompsManager extends EventEmitter { newTelemetryData.forEach((newDatum) => { otherTelemetryKeysNotAccumulating.forEach((otherKeyString) => { const otherCollection = this.#telemetryCollections[otherKeyString]; - // otherwise we need to find the closest datum to the new datum - let insertionPointForNewData = otherCollection._sortedIndex(newDatum); - const otherCollectionData = otherCollection.getAll(); - if (insertionPointForNewData && insertionPointForNewData >= otherCollectionData.length) { - insertionPointForNewData = otherCollectionData.length - 1; - } - // get the closest datum to the new datum - const closestDatum = otherCollectionData[insertionPointForNewData]; - if (closestDatum) { - telemetryForComps[otherKeyString].push(closestDatum); + const imputedDatum = this.#getImputedDataUsingLOCF(newDatum, otherCollection); + if (imputedDatum) { + telemetryForComps[otherKeyString].push(imputedDatum); } }); }); @@ -272,7 +320,7 @@ export default class CompsManager extends EventEmitter { this.deleteParameter(keyString); }; - requestUnderlyingTelemetry() { + #requestUnderlyingTelemetry() { const underlyingTelemetry = {}; Object.keys(this.#telemetryCollections).forEach((collectionKey) => { const collection = this.#telemetryCollections[collectionKey]; diff --git a/src/plugins/comps/CompsMathWorker.js b/src/plugins/comps/CompsMathWorker.js index 2da09178fe..52628fa8d8 100644 --- a/src/plugins/comps/CompsMathWorker.js +++ b/src/plugins/comps/CompsMathWorker.js @@ -119,6 +119,7 @@ function calculate(dataFrame, parameters, expression) { scope[parameter.name] = otherValue; }); if (missingData) { + console.debug('🤦‍♂️ Missing data for some parameters, skipping calculation'); return; } const value = evaluate(expression, scope); diff --git a/src/plugins/comps/CompsTelemetryProvider.js b/src/plugins/comps/CompsTelemetryProvider.js index cb75afe847..4c4f710b85 100644 --- a/src/plugins/comps/CompsTelemetryProvider.js +++ b/src/plugins/comps/CompsTelemetryProvider.js @@ -64,7 +64,7 @@ export default class CompsTelemetryProvider { specificCompsManager.load(options).then(() => { const callbackID = this.#getCallbackID(); const telemetryForComps = JSON.parse( - JSON.stringify(specificCompsManager.requestUnderlyingTelemetry()) + JSON.stringify(specificCompsManager.getDataFrameForRequest()) ); const expression = specificCompsManager.getExpression(); const parameters = JSON.parse(JSON.stringify(specificCompsManager.getParameters())); @@ -95,7 +95,7 @@ export default class CompsTelemetryProvider { return; } const expression = specificCompsManager.getExpression(); - const telemetryForComps = specificCompsManager.getTelemetryForComps(newTelemetry); + const telemetryForComps = specificCompsManager.getDataFrameForSubscription(newTelemetry); const parameters = JSON.parse(JSON.stringify(specificCompsManager.getParameters())); if (!expression || !parameters) { return; From 3b78d4d2bfea6b564ec1911fdd3dba52576cc4a4 Mon Sep 17 00:00:00 2001 From: Scott Bell Date: Thu, 10 Oct 2024 09:38:34 +0200 Subject: [PATCH 2/4] fix output and add accumulation label --- src/plugins/comps/CompsManager.js | 2 +- src/plugins/comps/components/CompsView.vue | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/plugins/comps/CompsManager.js b/src/plugins/comps/CompsManager.js index 45695bb17d..ecac724933 100644 --- a/src/plugins/comps/CompsManager.js +++ b/src/plugins/comps/CompsManager.js @@ -62,7 +62,7 @@ export default class CompsManager extends EventEmitter { testValue: 0, timeMetaData, accumulateValues: false, - sampleSize: null + sampleSize: 10 }); this.emit('parameterAdded', this.#domainObject); } diff --git a/src/plugins/comps/components/CompsView.vue b/src/plugins/comps/components/CompsView.vue index 606bd13613..f34648a5dd 100644 --- a/src/plugins/comps/components/CompsView.vue +++ b/src/plugins/comps/components/CompsView.vue @@ -113,6 +113,9 @@ aria-label="Toggle Parameter Accumulation" > +
+ - accumulating values with sample size {{ parameter.sampleSize }} +
Sample Size { const telemetryOptions = { - size: 1, - strategy: 'latest' + strategy: 'minmax' }; outputTelemetryCollection = openmct.telemetry.requestCollection(domainObject, telemetryOptions); outputTelemetryCollection.on('add', telemetryProcessor); From d5ee430f8b2aa3775d3f54c1c9d643c124f52926 Mon Sep 17 00:00:00 2001 From: Scott Bell Date: Thu, 10 Oct 2024 10:31:16 +0200 Subject: [PATCH 3/4] update output when comp changes --- src/plugins/comps/CompsManager.js | 9 ++++++++- src/plugins/comps/components/CompsView.vue | 7 +++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/plugins/comps/CompsManager.js b/src/plugins/comps/CompsManager.js index ecac724933..f0b649a2c4 100644 --- a/src/plugins/comps/CompsManager.js +++ b/src/plugins/comps/CompsManager.js @@ -345,9 +345,16 @@ export default class CompsManager extends EventEmitter { this.emit('underlyingTelemetryUpdated', { [keyString]: newTelemetry }); }; + reload() { + this.#destroy(); + return this.load(this.#telemetryOptions); + } + clearData(telemetryLoadedPromise) { this.#loaded = false; - this.#telemetryLoadedPromises.push(telemetryLoadedPromise); + if (telemetryLoadedPromise) { + this.#telemetryLoadedPromises.push(telemetryLoadedPromise); + } } setOutputFormat(outputFormat) { diff --git a/src/plugins/comps/components/CompsView.vue b/src/plugins/comps/components/CompsView.vue index f34648a5dd..394cf212be 100644 --- a/src/plugins/comps/components/CompsView.vue +++ b/src/plugins/comps/components/CompsView.vue @@ -266,6 +266,7 @@ function updateParameters() { openmct.objects.mutate(domainObject, `configuration.comps.parameters`, parameters.value); compsManager.setDomainObject(domainObject); applyTestData(); + reload(); } function updateAccumulateValues(parameter) { @@ -297,6 +298,7 @@ function updateExpression() { openmct.objects.mutate(domainObject, `configuration.comps.expression`, expression.value); compsManager.setDomainObject(domainObject); applyTestData(); + reload(); } function getValueFormatter() { @@ -354,6 +356,11 @@ function telemetryProcessor(data) { currentCompOutput.value = formattedOutput; } +function reload() { + clearData(); + outputTelemetryCollection._requestHistoricalTelemetry(); +} + function clearData() { currentCompOutput.value = null; } From 6710ad0d4cd1c4efc9fef4bdb010f008c1cb9098 Mon Sep 17 00:00:00 2001 From: Scott Bell Date: Thu, 10 Oct 2024 10:34:17 +0200 Subject: [PATCH 4/4] remove unused function --- src/plugins/comps/CompsManager.js | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/plugins/comps/CompsManager.js b/src/plugins/comps/CompsManager.js index f0b649a2c4..50b0d0f354 100644 --- a/src/plugins/comps/CompsManager.js +++ b/src/plugins/comps/CompsManager.js @@ -345,11 +345,6 @@ export default class CompsManager extends EventEmitter { this.emit('underlyingTelemetryUpdated', { [keyString]: newTelemetry }); }; - reload() { - this.#destroy(); - return this.load(this.#telemetryOptions); - } - clearData(telemetryLoadedPromise) { this.#loaded = false; if (telemetryLoadedPromise) {