Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 | 1x 1x 1x 1x 4x 4x 8x 8x 1x 2x 2x 2x 4x 4x 2x 1x 8x 8x 8x 3x 5x 5x 8x 5x 3x 3x 2x 2x 2x 1x 5x 5x 2x 3x 3x 3x | import {PluginParams} from '@grnsft/if-core/types';
import {aggregateInputsIntoOne} from '../util/aggregation-helper';
import {STRINGS} from '../config/strings';
import {AggregationParams, AggregationParamsSure} from '../types/manifest';
const {AGGREGATING_NODE, AGGREGATING_OUTPUTS} = STRINGS;
/**
* Gets `i`th element from all children outputs and collects them in single array.
*/
const getIthElementsFromChildren = (children: any, i: number) => {
const values = Object.values(children);
return values.map((value: any) => {
const output = value.outputs;
return output[i];
});
};
/**
* 1. Gets the i'th element from each childrens outputs (treating children as rows and we are after a column of data).
* 2. Now we just aggregate over the `ithSliceOfOutputs` the same as we did for the normal outputs.
*/
const temporalAggregation = (node: any, metrics: string[]) => {
const outputs: PluginParams[] = [];
const values: any = Object.values(node.children);
for (let i = 0; i < values[0].outputs.length; i++) {
const ithSliceOfOutputs = getIthElementsFromChildren(node.children, i);
outputs.push(aggregateInputsIntoOne(ithSliceOfOutputs, metrics, true));
}
return outputs;
};
/**
* Navigates the tree depth first, bottom up,
* left to right aggregating the component nodes and then the grouping nodes will be aggregated
* only when all their child nodes have been aggregated.
* 1. Aggregates all the children.
* 2. At this point you can be positive all your children have been aggregated and so you can now work on aggregating yourself.
* 3. It's component node, аggregates just the outputs of THIS component node (horizontal/component aggregation).
* 4. Else it's grouping node, first does temporal aggregation. This assumes everything is on the same time-grid.
* The outputs of the grouping node are the aggregated time bucketed outputs of it's children.
* 5. Now a grouping node has it's own outputs, it can horizotnally aggregate them.
*/
const aggregateNode = (node: any, aggregationParams: AggregationParamsSure) => {
const metrics = aggregationParams!.metrics;
const type = aggregationParams!.type;
if (node.children) {
for (const child in node.children) {
console.debug(AGGREGATING_NODE(child));
aggregateNode(node.children[child], aggregationParams);
}
}
if (!node.children) {
if (type === 'horizontal' || type === 'both') {
node.aggregated = aggregateInputsIntoOne(node.outputs, metrics);
}
} else {
if (type === 'vertical' || type === 'both') {
const outputs = temporalAggregation(node, metrics);
node.outputs = outputs;
node.aggregated = aggregateInputsIntoOne(outputs, metrics);
}
}
};
/**
* If aggregation is disabled, then returns given `tree`.
* Otherwise creates copy of the tree, then applies aggregation to it.
*/
export const aggregate = (tree: any, aggregationParams: AggregationParams) => {
console.debug(AGGREGATING_OUTPUTS);
if (!aggregationParams || !aggregationParams.type) {
return tree;
}
const copyOfTree = structuredClone(tree);
aggregateNode(copyOfTree, aggregationParams);
return copyOfTree;
};
|