diff --git a/packages/client/hmi-client/src/components/model/petrinet/model-configurations/tera-stratified-matrix.vue b/packages/client/hmi-client/src/components/model/petrinet/model-configurations/tera-stratified-matrix.vue index 841429862e..b934c529be 100644 --- a/packages/client/hmi-client/src/components/model/petrinet/model-configurations/tera-stratified-matrix.vue +++ b/packages/client/hmi-client/src/components/model/petrinet/model-configurations/tera-stratified-matrix.vue @@ -99,7 +99,12 @@ import Dropdown from 'primevue/dropdown'; import Button from 'primevue/button'; import { StratifiedMatrix } from '@/types/Model'; import type { MiraMatrix, MiraModel, MiraTemplateParams } from '@/model-representation/mira/mira-common'; -import { createParameterMatrix, createInitialMatrix, collapseTemplates } from '@/model-representation/mira/mira'; +import { + createParameterMatrix, + createDiagramTemplateMatrix, + createInitialMatrix, + collapseTemplates +} from '@/model-representation/mira/mira'; import { getVariable } from '@/model-representation/service'; import { extractTemplateMatrix } from '@/model-representation/mira/mira-util'; import { logger } from '@/utils/logger'; @@ -221,8 +226,28 @@ async function getMatrixValue(variableName: string) { return (await pythonInstance.parseExpression(expressionBase)).pmathml; } +function setupMatrixOptions() { + // Find a default + if (currentMatrixtype.value) { + matrix.value = matrixMap.value[currentMatrixtype.value]; + matrixType.value = currentMatrixtype.value; + return; + } + + for (let i = 0; i < matrixTypes.length; i++) { + const typeStr = matrixTypes[i]; + + if (matrixMap.value[typeStr] && matrixMap.value[typeStr].length > 0) { + matrix.value = matrixMap.value[typeStr]; + matrixType.value = typeStr; + break; + } + } +} + function generateMatrix() { const stratifiedType = props.stratifiedMatrixType; + matrixMap.value = {}; if (stratifiedType === StratifiedMatrix.Initials) { matrix.value = createInitialMatrix(props.mmt, props.id); @@ -236,31 +261,25 @@ function generateMatrix() { other: matrices.other }; - // Find a default - if (currentMatrixtype.value) { - matrix.value = matrixMap.value[currentMatrixtype.value]; - matrixType.value = currentMatrixtype.value; - return; - } - - for (let i = 0; i < matrixTypes.length; i++) { - const typeStr = matrixTypes[i]; - - if (matrixMap.value[typeStr] && matrixMap.value[typeStr].length > 0) { - matrix.value = matrixMap.value[typeStr]; - matrixType.value = typeStr; - break; - } - } + setupMatrixOptions(); } else if (stratifiedType === StratifiedMatrix.Rates) { const templatesMap = collapseTemplates(props.mmt).matrixMap; + const matrices = createDiagramTemplateMatrix(props.mmt, props.mmtParams, props.id); const transitionMatrix = templatesMap.get(props.id); if (!transitionMatrix) { logger.error('Failed to generate transition matrix'); return; } - matrix.value = extractTemplateMatrix(transitionMatrix).matrix; + + matrixMap.value = { + subjectOutcome: extractTemplateMatrix(transitionMatrix).matrix, + subjectControllers: matrices.subjectControllers.matrix, + outcomeControllers: matrices.outcomeControllers.matrix, + other: matrices.other + }; + + setupMatrixOptions(); } } diff --git a/packages/client/hmi-client/src/model-representation/mira/mira.ts b/packages/client/hmi-client/src/model-representation/mira/mira.ts index afd91b21a1..929a6737e8 100644 --- a/packages/client/hmi-client/src/model-representation/mira/mira.ts +++ b/packages/client/hmi-client/src/model-representation/mira/mira.ts @@ -345,6 +345,75 @@ export const createInitialMatrix = (miraModel: MiraModel, key: string) => { return m2; }; +/** + * For Template Matrix only + * Assumes one-to-one with cells + * + */ +export const createDiagramTemplateMatrix = ( + miraModel: MiraModel, + miraTemplateParams: MiraTemplateParams, + param: string +) => { + const paramMap = collapseTemplates(miraModel).matrixMap; + const childrenParams = paramMap.get(param)?.map((p) => p.name); + if (!childrenParams) throw new Error(`Cannot map ${param}`); + + // Create map for mapping params to row/col of matrix + // param => [ [subject, outcome, controllers], [subject, outcome, controllers] ... ] + const paramLocationMap = new Map(); + const templateParams = Object.values(miraTemplateParams); + templateParams.forEach((templateParam) => { + if (!paramLocationMap.has(templateParam.name)) paramLocationMap.set(templateParam.name, []); + + paramLocationMap.get(templateParam.name)?.push({ + name: templateParam.name, + subject: templateParam.subject, + outcome: templateParam.outcome, + controllers: templateParam.controllers + }); + }); + + // Create map for param values + // param => value + const tempValueMap = new Map(); + Object.values(miraModel.templates).forEach((tempObj) => { + tempValueMap.set(tempObj.name, tempObj); + }); + + // Find templates with expressions that contains one or more of the params + const templates = miraModel.templates.filter((t) => { + const miraTemplateParam = miraTemplateParams[t.name]; + const intersection = _.intersection(childrenParams, [miraTemplateParam.name]); + return intersection.length > 0; + }); + const subjectControllers = extractSubjectControllersMatrix(templates, childrenParams, tempValueMap, paramLocationMap); + const outcomeControllers = extractOutcomeControllersMatrix(templates, childrenParams, tempValueMap, paramLocationMap); + + // Others, may be initial, maybe no in use ... + const other: MiraMatrix = []; + childrenParams.forEach((name, idx) => { + const row: MiraMatrixEntry[] = []; + row.push({ + row: idx, + col: 0, + rowCriteria: name, + colCriteria: '', + content: { + id: name, + value: miraModel.templates[name] + } + }); + other.push(row); + }); + + return { + subjectControllers, + outcomeControllers, + other + }; +}; + /** * Assumes one-to-one with cells *