impute requested data properly

This commit is contained in:
Scott Bell 2024-10-09 22:15:26 +02:00
parent e17702dabf
commit a83f8a3f56
3 changed files with 63 additions and 14 deletions

View File

@ -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 telemetryForComps = {};
const newTelemetryKey = Object.keys(newTelemetry)[0]; const newTelemetryKey = Object.keys(newTelemetry)[0];
const newTelemetryParameter = this.#getParameterForKeyString(newTelemetryKey); const newTelemetryParameter = this.#getParameterForKeyString(newTelemetryKey);
@ -247,16 +302,9 @@ export default class CompsManager extends EventEmitter {
newTelemetryData.forEach((newDatum) => { newTelemetryData.forEach((newDatum) => {
otherTelemetryKeysNotAccumulating.forEach((otherKeyString) => { otherTelemetryKeysNotAccumulating.forEach((otherKeyString) => {
const otherCollection = this.#telemetryCollections[otherKeyString]; const otherCollection = this.#telemetryCollections[otherKeyString];
// otherwise we need to find the closest datum to the new datum const imputedDatum = this.#getImputedDataUsingLOCF(newDatum, otherCollection);
let insertionPointForNewData = otherCollection._sortedIndex(newDatum); if (imputedDatum) {
const otherCollectionData = otherCollection.getAll(); telemetryForComps[otherKeyString].push(imputedDatum);
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);
} }
}); });
}); });
@ -272,7 +320,7 @@ export default class CompsManager extends EventEmitter {
this.deleteParameter(keyString); this.deleteParameter(keyString);
}; };
requestUnderlyingTelemetry() { #requestUnderlyingTelemetry() {
const underlyingTelemetry = {}; const underlyingTelemetry = {};
Object.keys(this.#telemetryCollections).forEach((collectionKey) => { Object.keys(this.#telemetryCollections).forEach((collectionKey) => {
const collection = this.#telemetryCollections[collectionKey]; const collection = this.#telemetryCollections[collectionKey];

View File

@ -119,6 +119,7 @@ function calculate(dataFrame, parameters, expression) {
scope[parameter.name] = otherValue; scope[parameter.name] = otherValue;
}); });
if (missingData) { if (missingData) {
console.debug('🤦‍♂️ Missing data for some parameters, skipping calculation');
return; return;
} }
const value = evaluate(expression, scope); const value = evaluate(expression, scope);

View File

@ -64,7 +64,7 @@ export default class CompsTelemetryProvider {
specificCompsManager.load(options).then(() => { specificCompsManager.load(options).then(() => {
const callbackID = this.#getCallbackID(); const callbackID = this.#getCallbackID();
const telemetryForComps = JSON.parse( const telemetryForComps = JSON.parse(
JSON.stringify(specificCompsManager.requestUnderlyingTelemetry()) JSON.stringify(specificCompsManager.getDataFrameForRequest())
); );
const expression = specificCompsManager.getExpression(); const expression = specificCompsManager.getExpression();
const parameters = JSON.parse(JSON.stringify(specificCompsManager.getParameters())); const parameters = JSON.parse(JSON.stringify(specificCompsManager.getParameters()));
@ -95,7 +95,7 @@ export default class CompsTelemetryProvider {
return; return;
} }
const expression = specificCompsManager.getExpression(); const expression = specificCompsManager.getExpression();
const telemetryForComps = specificCompsManager.getTelemetryForComps(newTelemetry); const telemetryForComps = specificCompsManager.getDataFrameForSubscription(newTelemetry);
const parameters = JSON.parse(JSON.stringify(specificCompsManager.getParameters())); const parameters = JSON.parse(JSON.stringify(specificCompsManager.getParameters()));
if (!expression || !parameters) { if (!expression || !parameters) {
return; return;