From a3857fcdfda2542a927f20b1490268fa4570a128 Mon Sep 17 00:00:00 2001 From: Joseph Kotanchik Date: Thu, 5 Oct 2023 12:56:43 -0400 Subject: [PATCH 1/5] Extract Direct Reference Code info for data criteria while parsing cql. --- .../utils/cql/CQLTools.java | 17 ++-- .../utils/cql/parsing/Cql2ElmListener.java | 84 ++++++------------- .../utils/cql/parsing/model/CQLGraph.java | 3 +- 3 files changed, 31 insertions(+), 73 deletions(-) diff --git a/src/main/java/gov/cms/mat/cql_elm_translation/utils/cql/CQLTools.java b/src/main/java/gov/cms/mat/cql_elm_translation/utils/cql/CQLTools.java index d0589bec..47ca7d03 100644 --- a/src/main/java/gov/cms/mat/cql_elm_translation/utils/cql/CQLTools.java +++ b/src/main/java/gov/cms/mat/cql_elm_translation/utils/cql/CQLTools.java @@ -109,7 +109,7 @@ public CQLTools( /** * The CQL Filter Entry Point. * - *

This function will find all of the used CQL expressions, create a valueset - datatype map + *

This function will find all the used CQL expressions, create a valueset - datatype map * and code - datatype map, and find return types for each expression. * * @throws IOException @@ -142,6 +142,7 @@ public void generate() throws IOException { new HashMap<>(listener.getValueSetDataTypeMap()); Map>> codeMap = new HashMap<>(listener.getCodeDataTypeMap()); Map valueSetOids = new HashMap<>(listener.getValueSetOids()); + Map drcs = new HashMap<>(listener.getDrcs()); collectUsedExpressions( graph, @@ -154,10 +155,10 @@ public void generate() throws IOException { functionsSet); collectValueSetCodeDataType(valuesetMap, codeMap); collectReturnTypeMap(); - collectDataCriteria(valueSetOids); + collectDataCriteria(valueSetOids, drcs); } - private void collectDataCriteria(Map valueSetOids) { + private void collectDataCriteria(Map valueSetOids, Map drcs) { valuesetDataTypeMap .keySet() .forEach( @@ -174,15 +175,7 @@ private void collectDataCriteria(Map valueSetOids) { code -> dataCriteria .getDataCriteriaWithCodes() - .put( - CQLCode.builder() - .codeName(code) - // TODO lookup code & code system details - .codeOID("shrug") - .codeSystemName("shrug") - .codeSystemOID("shrug") - .build(), - codeDataTypeMap.get(code))); + .put(drcs.get(code), codeDataTypeMap.get(code))); } private void collectUsedExpressions( diff --git a/src/main/java/gov/cms/mat/cql_elm_translation/utils/cql/parsing/Cql2ElmListener.java b/src/main/java/gov/cms/mat/cql_elm_translation/utils/cql/parsing/Cql2ElmListener.java index 37d21d7b..40aaac30 100644 --- a/src/main/java/gov/cms/mat/cql_elm_translation/utils/cql/parsing/Cql2ElmListener.java +++ b/src/main/java/gov/cms/mat/cql_elm_translation/utils/cql/parsing/Cql2ElmListener.java @@ -6,7 +6,9 @@ import java.nio.charset.StandardCharsets; import java.util.*; +import gov.cms.mat.cql_elm_translation.utils.cql.parsing.model.CQLCode; import gov.cms.mat.cql_elm_translation.utils.cql.parsing.model.CQLGraph; +import lombok.Getter; import org.antlr.v4.runtime.CharStreams; import org.antlr.v4.runtime.CommonTokenStream; import org.antlr.v4.runtime.misc.NotNull; @@ -45,7 +47,7 @@ public class Cql2ElmListener extends cqlBaseListener { * The identifier of the current library, relative to the library that brought us here. Will be in * the form of libraryName|alias */ - private String libraryIdentifier; + private final String libraryIdentifier; /** * The include def object which we are current parsing, relative to the library that brought us @@ -54,7 +56,7 @@ public class Cql2ElmListener extends cqlBaseListener { IncludeDef libraryAccessor = null; /** The current library object from the parser */ - private CompiledLibrary library; + private final CompiledLibrary library; /** The map of the other libraries in the current library */ Map translatedLibraryMap; @@ -62,20 +64,21 @@ public class Cql2ElmListener extends cqlBaseListener { /** The current context, aka which expression are we currently in. */ private String currentContext; - private Set libraries = new HashSet<>(); - private Set valuesets = new HashSet<>(); - private Set codes = new HashSet<>(); - private Set codesystems = new HashSet<>(); - private Set parameters = new HashSet<>(); - private Set definitions = new HashSet<>(); - private Set functions = new HashSet<>(); - private HashMap valueSetOids = new HashMap<>(); - private Map>> valueSetDataTypeMap = new HashMap<>(); - private Map>> codeDataTypeMap = new HashMap<>(); + @Getter private final Set libraries = new HashSet<>(); + @Getter private final Set valuesets = new HashSet<>(); + @Getter private final Set codes = new HashSet<>(); + @Getter private final Set codesystems = new HashSet<>(); + @Getter private final Set parameters = new HashSet<>(); + @Getter private final Set definitions = new HashSet<>(); + @Getter private final Set functions = new HashSet<>(); + @Getter private final HashMap valueSetOids = new HashMap<>(); + @Getter private final HashMap drcs = new HashMap<>(); + @Getter private final Map>> valueSetDataTypeMap = new HashMap<>(); + @Getter private final Map>> codeDataTypeMap = new HashMap<>(); - private Stack namespace = new Stack<>(); + private final Stack namespace = new Stack<>(); - private CQLGraph graph; + @Getter private final CQLGraph graph; public Cql2ElmListener( CQLGraph graph, @@ -130,7 +133,7 @@ public void enterQualifiedIdentifierExpression(QualifiedIdentifierExpressionCont String qualifier = ""; if (shouldResolve(identifier)) { - // a qualified identifier can take on the form (qualifier) '.')* identifier. If there is only + // a qualified identifier can take on the form (qualifier '.')* identifier. If there is only // one qualifier, // then that could be a library. Resolve the qualifier to check if it's a library. if (CollectionUtils.isNotEmpty(ctx.qualifierExpression()) @@ -269,6 +272,7 @@ public void enterRetrieve(@NotNull cqlParser.RetrieveContext ctx) { current.get(formattedIdentifier).add(dataType); valueSetOids.putIfAbsent( formattedIdentifier, ((ValueSetDef) element).getId().substring("urn:oid:".length())); + } else if (element instanceof CodeDef) { Map> current = codeDataTypeMap.get(currentContext); if (current == null) { @@ -283,6 +287,12 @@ public void enterRetrieve(@NotNull cqlParser.RetrieveContext ctx) { } current.get(formattedIdentifier).add(dataType); + drcs.putIfAbsent(formattedIdentifier, + CQLCode.builder() + .id(((CodeDef)element).getId()) + .codeName(formattedIdentifier) + .codeSystemName(((CodeDef)element).getCodeSystem().getName()) + .build()); } } @@ -508,48 +518,4 @@ private void parseChildLibraries(IncludeDef def) throws IOException { codeDataTypeMap.putAll(listener.getCodeDataTypeMap()); valueSetOids.putAll(listener.getValueSetOids()); } - - public Set getLibraries() { - return libraries; - } - - public Set getValuesets() { - return valuesets; - } - - public Set getCodes() { - return codes; - } - - public Set getCodesystems() { - return codesystems; - } - - public Set getParameters() { - return parameters; - } - - public Set getDefinitions() { - return definitions; - } - - public Set getFunctions() { - return functions; - } - - public Map>> getValueSetDataTypeMap() { - return valueSetDataTypeMap; - } - - public Map>> getCodeDataTypeMap() { - return codeDataTypeMap; - } - - public Map getValueSetOids() { - return valueSetOids; - } - - public CQLGraph getGraph() { - return graph; - } } diff --git a/src/main/java/gov/cms/mat/cql_elm_translation/utils/cql/parsing/model/CQLGraph.java b/src/main/java/gov/cms/mat/cql_elm_translation/utils/cql/parsing/model/CQLGraph.java index 525e7245..82be9fb5 100644 --- a/src/main/java/gov/cms/mat/cql_elm_translation/utils/cql/parsing/model/CQLGraph.java +++ b/src/main/java/gov/cms/mat/cql_elm_translation/utils/cql/parsing/model/CQLGraph.java @@ -74,9 +74,8 @@ public boolean isPath(String source, String destination) { public String toString() { StringBuilder builder = new StringBuilder(); for (String node : graph.keySet()) { - builder.append(node + " ---> " + graph.get(node) + "\n"); + builder.append(node).append(" ---> ").append(graph.get(node)).append("\n"); } - return builder.toString(); } From 23d48b39ead0a7a3a416b9ac136e7dafdd247f07 Mon Sep 17 00:00:00 2001 From: Joseph Kotanchik Date: Thu, 5 Oct 2023 14:23:30 -0400 Subject: [PATCH 2/5] Extract Direct Reference Code info from included libraries. --- .../cql_elm_translation/utils/cql/parsing/Cql2ElmListener.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/gov/cms/mat/cql_elm_translation/utils/cql/parsing/Cql2ElmListener.java b/src/main/java/gov/cms/mat/cql_elm_translation/utils/cql/parsing/Cql2ElmListener.java index 40aaac30..2115a16f 100644 --- a/src/main/java/gov/cms/mat/cql_elm_translation/utils/cql/parsing/Cql2ElmListener.java +++ b/src/main/java/gov/cms/mat/cql_elm_translation/utils/cql/parsing/Cql2ElmListener.java @@ -517,5 +517,6 @@ private void parseChildLibraries(IncludeDef def) throws IOException { valueSetDataTypeMap.putAll(listener.getValueSetDataTypeMap()); codeDataTypeMap.putAll(listener.getCodeDataTypeMap()); valueSetOids.putAll(listener.getValueSetOids()); + drcs.putAll(listener.getDrcs()); } } From 7f8e67453783abd72f74a5a780fe661bd10fe401 Mon Sep 17 00:00:00 2001 From: CeciliaLiu8 Date: Mon, 9 Oct 2023 09:55:02 -0500 Subject: [PATCH 3/5] MAT-6210 add codeId for drcs --- .../mat/cql_elm_translation/dto/SourceDataCriteria.java | 2 ++ .../cql_elm_translation/service/DataCriteriaService.java | 1 + .../cms/mat/cql_elm_translation/utils/cql/CQLTools.java | 4 ++-- .../utils/cql/parsing/Cql2ElmListener.java | 7 ++++--- 4 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/main/java/gov/cms/mat/cql_elm_translation/dto/SourceDataCriteria.java b/src/main/java/gov/cms/mat/cql_elm_translation/dto/SourceDataCriteria.java index 7a17ea76..7df0672b 100644 --- a/src/main/java/gov/cms/mat/cql_elm_translation/dto/SourceDataCriteria.java +++ b/src/main/java/gov/cms/mat/cql_elm_translation/dto/SourceDataCriteria.java @@ -11,4 +11,6 @@ public class SourceDataCriteria { private String description; private String type; private boolean drc; + // MAT-6210: codeId used for drc + private String codeId; } diff --git a/src/main/java/gov/cms/mat/cql_elm_translation/service/DataCriteriaService.java b/src/main/java/gov/cms/mat/cql_elm_translation/service/DataCriteriaService.java index daae01d6..853f1760 100644 --- a/src/main/java/gov/cms/mat/cql_elm_translation/service/DataCriteriaService.java +++ b/src/main/java/gov/cms/mat/cql_elm_translation/service/DataCriteriaService.java @@ -99,6 +99,7 @@ private SourceDataCriteria buildSourceDataCriteriaForCode(CQLCode code, SetThis function will find all the used CQL expressions, create a valueset - datatype map - * and code - datatype map, and find return types for each expression. + *

This function will find all the used CQL expressions, create a valueset - datatype map and + * code - datatype map, and find return types for each expression. * * @throws IOException */ diff --git a/src/main/java/gov/cms/mat/cql_elm_translation/utils/cql/parsing/Cql2ElmListener.java b/src/main/java/gov/cms/mat/cql_elm_translation/utils/cql/parsing/Cql2ElmListener.java index 2115a16f..18c11bed 100644 --- a/src/main/java/gov/cms/mat/cql_elm_translation/utils/cql/parsing/Cql2ElmListener.java +++ b/src/main/java/gov/cms/mat/cql_elm_translation/utils/cql/parsing/Cql2ElmListener.java @@ -287,11 +287,12 @@ public void enterRetrieve(@NotNull cqlParser.RetrieveContext ctx) { } current.get(formattedIdentifier).add(dataType); - drcs.putIfAbsent(formattedIdentifier, + drcs.putIfAbsent( + formattedIdentifier, CQLCode.builder() - .id(((CodeDef)element).getId()) + .id(((CodeDef) element).getId()) .codeName(formattedIdentifier) - .codeSystemName(((CodeDef)element).getCodeSystem().getName()) + .codeSystemName(((CodeDef) element).getCodeSystem().getName()) .build()); } } From 3f6bc034710b673e2d221b51c250786f4803f90f Mon Sep 17 00:00:00 2001 From: CeciliaLiu8 Date: Mon, 9 Oct 2023 09:57:21 -0500 Subject: [PATCH 4/5] update branch --- .../service/EffectiveDataRequirementService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/gov/cms/mat/cql_elm_translation/service/EffectiveDataRequirementService.java b/src/main/java/gov/cms/mat/cql_elm_translation/service/EffectiveDataRequirementService.java index 95e70866..b719b7f5 100644 --- a/src/main/java/gov/cms/mat/cql_elm_translation/service/EffectiveDataRequirementService.java +++ b/src/main/java/gov/cms/mat/cql_elm_translation/service/EffectiveDataRequirementService.java @@ -109,7 +109,7 @@ public org.hl7.fhir.r5.model.Library getEffectiveDataRequirements( Set expressionList = getExpressions(r5Measure); var dqReqTrans = new DataRequirementsProcessor(); CqlTranslatorOptions options = CqlTranslatorOptions.defaultOptions(); - options.setCollapseDataRequirements(true); //removing duplicate data requirements + options.setCollapseDataRequirements(true); // removing duplicate data requirements org.hl7.fhir.r5.model.Library effectiveDataRequirements = dqReqTrans.gatherDataRequirements( From d18e8e9e4a0d934545e4a8ac5a076995058e84ba Mon Sep 17 00:00:00 2001 From: CeciliaLiu8 Date: Mon, 9 Oct 2023 13:17:20 -0500 Subject: [PATCH 5/5] test data criteria for drc --- .../cql_elm_translation/service/DataCriteriaServiceTest.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/test/java/gov/cms/mat/cql_elm_translation/service/DataCriteriaServiceTest.java b/src/test/java/gov/cms/mat/cql_elm_translation/service/DataCriteriaServiceTest.java index 4a7421c6..00033739 100644 --- a/src/test/java/gov/cms/mat/cql_elm_translation/service/DataCriteriaServiceTest.java +++ b/src/test/java/gov/cms/mat/cql_elm_translation/service/DataCriteriaServiceTest.java @@ -90,6 +90,11 @@ void testGetSourceDataCriteria() { assertThat( sourceDataCriteria.get(2).getDescription(), is(equalTo("Encounter, Performed: Clinical Examples"))); + + // MAT-6210 only setCodeId for direct reference code + assertThat(sourceDataCriteria.get(0).getCodeId(), is(equalTo(null))); + assertThat(sourceDataCriteria.get(1).getCodeId(), is(equalTo(null))); + assertThat(sourceDataCriteria.get(2).getCodeId(), is(equalTo("1021859"))); } @Test