-
Steve Reis authored58c92148
converters.ts 7.73 KiB
import { MIME_TYPES } from 'src/common/interfaces/utilities.interface';
import { Category } from 'src/engine/models/category.model';
import { Dataset } from 'src/engine/models/dataset.model';
import { Experiment } from 'src/engine/models/experiment/experiment.model';
import { AlgorithmParamInput } from 'src/engine/models/experiment/input/algorithm-parameter.input';
import { ExperimentCreateInput } from 'src/engine/models/experiment/input/experiment-create.input';
import { Group } from 'src/engine/models/group.model';
import { ResultUnion } from 'src/engine/models/result/common/result-union.model';
import {
GroupResult,
GroupsResult,
} from 'src/engine/models/result/groups-result.model';
import { HeatMapResult } from 'src/engine/models/result/heat-map-result.model';
import { LineChartResult } from 'src/engine/models/result/line-chart-result.model';
import { RawResult } from 'src/engine/models/result/raw-result.model';
import { Variable } from 'src/engine/models/variable.model';
import { Entity } from './interfaces/entity.interface';
import { ExperimentData } from './interfaces/experiment/experiment.interface';
import { ResultChartExperiment } from './interfaces/experiment/result-chart-experiment.interface';
import { ResultExperiment } from './interfaces/experiment/result-experiment.interface';
import { Hierarchy } from './interfaces/hierarchy.interface';
import { VariableEntity } from './interfaces/variable-entity.interface';
import {
dataROCToLineResult,
dataToHeatmap,
descriptiveModelToTables,
descriptiveSingleToTables,
transformToExperiment,
} from './transformations';
export const dataToGroup = (data: Hierarchy): Group => {
return {
id: data.code,
label: data.label,
groups: data.groups
? data.groups.map(dataToGroup).map((group) => group.id)
: [],
variables: data.variables
? data.variables.map((data: VariableEntity) => data.code)
: [],
};
};
export const dataToCategory = (data: Entity): Category => {
return {
value: data.code,
label: data.label,
};
};
export const dataToDataset = (data: Entity): Dataset => {
return {
id: data.code,
label: data.label,
isLongitudinal: !!data.code.toLowerCase().includes('longitudinal'),
};
};
export const dataToVariable = (data: VariableEntity): Variable => {
return {
id: data.code,
label: data.label,
type: data.type,
description: data.description,
enumerations: data.enumerations
? data.enumerations.map(dataToCategory)
: [],
groups: [],
};
};
const algoParamInputToData = (param: AlgorithmParamInput) => {
return {
name: param.id,
label: param.id,
value: param.value,
};
};
export const experimentInputToData = (data: ExperimentCreateInput) => {
const formula =
((data.transformations?.length > 0 || data.interactions?.length > 0) && {
single:
data.transformations?.map((t) => ({
var_name: t.id,
unary_operation: t.operation,
})) || [],
interactions:
data.interactions?.map((v) =>
v.reduce((a, e, i) => ({ ...a, [`var${i + 1}`]: e }), {}),
) || [],
}) ||
null;
const params = {
algorithm: {
parameters: [
{
name: 'dataset',
label: 'dataset',
value: data.datasets.join(','),
},
{
name: 'filter',
label: 'filter',
value: data.filter,
},
{
name: 'pathology',
label: 'pathology',
value: data.domain,
},
...(formula
? [
{
name: 'formula',
value: JSON.stringify(formula),
},
]
: []),
].concat(data.algorithm.parameters.map(algoParamInputToData)),
type: data.algorithm.type ?? 'string',
name: data.algorithm.id,
},
name: data.name,
};
if (data.coVariables && data.coVariables.length) {
let separator = ',';
const design = params.algorithm.parameters.find((p) => p.name === 'design');
const excludes = [
'Multiple Histograms',
'CART',
'ID3',
'Naive Bayes Training',
];
if (design && !excludes.includes(data.algorithm.id)) {
separator = design.value === 'additive' ? '+' : '*';
}
params.algorithm.parameters.push({
name: 'x',
label: 'x',
value: data.coVariables.join(separator),
});
}
if (data.variables) {
let variables = data.variables.join(',');
if (data.algorithm.id === 'TTEST_PAIRED') {
const varCount = data.variables.length;
variables = data.variables
?.reduce(
(vectors: string, v, i) =>
(i + 1) % 2 === 0
? `${vectors}${v},`
: varCount === i + 1
? `${vectors}${v}-${data.variables[0]}`
: `${vectors}${v}-`,
'',
)
.replace(/,$/, '');
}
params.algorithm.parameters.push({
name: 'y',
label: 'y',
value: variables,
});
}
return params;
};
export const descriptiveDataToTableResult = (
data: ResultExperiment,
): GroupsResult[] => {
const result = new GroupsResult();
result.groups = [
new GroupResult({
name: 'Variables',
description: 'Descriptive statistics for the variables of interest.',
results: descriptiveSingleToTables.evaluate(data),
}),
];
result.groups.push(
new GroupResult({
name: 'Model',
description:
'Intersection table for the variables of interest as it appears in the experiment.',
results: descriptiveModelToTables.evaluate(data),
}),
);
return [result];
};
export const dataToExperiment = (
data: ExperimentData,
): Experiment | undefined => {
try {
const expTransform = transformToExperiment.evaluate(data);
const exp: Experiment = {
...expTransform,
results: [],
};
exp.results = data.result
? data.result
.map((result) => dataToResult(result, exp.algorithm.name))
.filter((r) => r.length > 0)
.flat()
: [];
return exp;
} catch (e) {
return {
id: data.uuid,
name: data.name,
status: 'error',
variables: [],
domain: data['domain'] ?? '',
results: [
{
rawdata: {
type: 'text/plain+error',
data: 'Error when parsing experiment data from the Engine',
},
},
],
datasets: [],
algorithm: {
name: 'unknown',
},
};
}
};
export const dataToRaw = (
algo: string,
result: ResultExperiment,
): RawResult[] => {
let data = result;
if (algo === 'CART') {
data = { ...data, type: MIME_TYPES.JSONBTREE };
}
return [
{
rawdata: data,
},
];
};
export const dataToResult = (
result: ResultExperiment,
algo: string,
): Array<typeof ResultUnion> => {
switch (result.type.toLowerCase()) {
case 'application/json':
return dataJSONtoResult(result, algo);
case 'application/vnd.highcharts+json':
return dataHighchartToResult(result as ResultChartExperiment, algo);
default:
return dataToRaw(algo, result);
}
};
export const dataJSONtoResult = (
result: ResultExperiment,
algo: string,
): Array<typeof ResultUnion> => {
switch (algo.toLowerCase()) {
case 'descriptive_stats':
case 'cart':
case 'id3':
return descriptiveDataToTableResult(result);
default:
return [];
}
};
export const dataHighchartToResult = (
result: ResultChartExperiment,
algo: string,
): Array<typeof ResultUnion> => {
switch (result.data.chart.type) {
case 'heatmap':
return [dataToHeatmap.evaluate(result) as HeatMapResult];
case 'area':
return [dataROCToLineResult.evaluate(result) as LineChartResult];
default:
return dataToRaw(algo, result);
}
};