Skip to content

Commit

Permalink
Merge pull request #172 from MeasureAuthoringTool/MAT-6269_AddinDRCEx…
Browse files Browse the repository at this point in the history
…tensionsForCode

MAT-6269: Generating DRC Extensions in Bundle for Code entries in CQL
  • Loading branch information
gregory-akins authored Oct 26, 2023
2 parents 95237f1 + 00e50ff commit 12ad2cc
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ public static final class CqfMeasures {

public static final String CODE_SYSTEM_MEASURE_DATA_USAGE_URI =
"http://terminology.hl7.org/CodeSystem/measure-data-usage";

public static final String DIRECT_REFERENCE_CODE_URI =
"http://hl7.org/fhir/us/cqfmeasures/StructureDefinition/cqfm-directReferenceCode";
}

public static final class CqfTestCases {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package gov.cms.madie.madiefhirservice.cql;

import gov.cms.madie.madiefhirservice.constants.UriConstants;
import gov.cms.madie.madiefhirservice.utils.FhirResourceHelpers;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
Expand All @@ -8,12 +9,15 @@
import org.apache.commons.lang3.tuple.Pair;
import org.cqframework.cql.gen.cqlBaseVisitor;
import org.cqframework.cql.gen.cqlParser;
import org.hl7.fhir.r4.model.CodeableConcept;
import org.hl7.fhir.r4.model.Coding;
import org.hl7.fhir.r4.model.DataRequirement;
import org.hl7.fhir.r4.model.Extension;
import org.hl7.fhir.r4.model.Library;
import org.hl7.fhir.r4.model.RelatedArtifact;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
Expand All @@ -31,6 +35,7 @@ public class LibraryCqlVisitor extends cqlBaseVisitor<String> {
private final List<cqlParser.CodesystemDefinitionContext> codeSystems = new ArrayList<>();
private final ReadableArtifacts readableArtifacts = new ReadableArtifacts();
private final List<DataRequirement> dataRequirements = new ArrayList<>();
private final List<Extension> drcExtensions = new ArrayList<>();
private final List<RelatedArtifact> relatedArtifacts = new ArrayList<>();
private final Map<String, Pair<Library, LibraryCqlVisitor>> libMap = new HashMap<>();
private final Map<Integer, Library> libraryCacheMap = new HashMap<>();
Expand All @@ -48,6 +53,7 @@ public class LibraryCqlVisitor extends cqlBaseVisitor<String> {
@Override
public String visitLibraryDefinition(cqlParser.LibraryDefinitionContext ctx) {
name = ctx.qualifiedIdentifier().getText();
log.warn("###### library Definition Name {}", name);
version = trim1(ctx.versionSpecifier().getText());
return null;
}
Expand Down Expand Up @@ -119,9 +125,11 @@ public String visitCodesystemDefinition(cqlParser.CodesystemDefinitionContext ct

@Override
public String visitCodeDefinition(cqlParser.CodeDefinitionContext ctx) {

String codeSystemName = getUnquotedFullText(ctx.codesystemIdentifier());
String code = getUnquotedFullText(ctx.codeId());
String codeName = getUnquotedFullText(ctx.identifier());
log.warn("###### codeName {}", codeName);
codeSystems.stream()
.filter(cs -> StringUtils.equals(getUnquotedFullText(cs.identifier()), codeSystemName))
.findFirst()
Expand All @@ -130,6 +138,12 @@ public String visitCodeDefinition(cqlParser.CodeDefinitionContext ctx) {
String csName = getUnquotedFullText(cs.identifier());
String csUri = getUnquotedFullText(cs.codesystemId());
String csVersionUri = getUnquotedFullText(cs.versionSpecifier());

Extension ext = new Extension(UriConstants.CqfMeasures.DIRECT_REFERENCE_CODE_URI);

ext.setValue(buildCoding(code, csUri, codeName));

this.getDrcExtensions().add(ext);
readableArtifacts
.getTerminologyCodeModels()
.add(
Expand Down Expand Up @@ -167,15 +181,12 @@ public String visitRetrieve(cqlParser.RetrieveContext ctx) {
trimQuotes(ctx.getChild(1).getText()),
ctx.getChild(3).getText(),
trimQuotes(ctx.getChild(5).getText()));

} else if (matchesNonPathRetrieve(ctx)) {
handleDataRequirement(
trimQuotes(ctx.getChild(1).getText()), "code", trimQuotes(ctx.getChild(3).getText()));
} else if (matchesTypeRetrieve(ctx)) {
handleTypeDataRequirement(trimQuotes(ctx.getChild(1).getText()));
log.debug("Added type retrieve: " + ctx.getText());
}

return null;
}

Expand All @@ -191,7 +202,7 @@ protected String defaultResult() {
*/
private boolean matchesTypeRetrieve(cqlParser.RetrieveContext ctx) {
// define FirstInpatientEncounter:
// First([Encounter] E where E.class = 'inpatient' sort by period.start desc)
// First([Encounter] E where E.class = 'inpatient' sort by period.start desc)
return ctx.getChildCount() == 3
&& ctx.getChild(0).getText().equals("[")
&& ctx.getChild(2).getText().equals("]");
Expand Down Expand Up @@ -222,21 +233,22 @@ private boolean matchesNonPathRetrieve(cqlParser.RetrieveContext ctx) {

private void handleTypeDataRequirement(String type) {
// define FirstInpatientEncounter:
// First([Encounter] E where E.class = 'inpatient' sort by period.start desc)
// First([Encounter] E where E.class = 'inpatient' sort by period.start desc)
var result = new DataRequirement();
result.setType(type);
dataRequirements.add(result);
readableArtifacts.getDataReqTypes().add(TypeModel.builder().type(type).build());
}

private void handleDataRequirement(String type, String path, String valueSetOrCodeName) {

var result = new DataRequirement();
result.setType(type);
var filter = new DataRequirement.DataRequirementCodeFilterComponent();
filter.setPath(path);
result.setCodeFilter(Collections.singletonList(filter));

var hrVs = getValueSetUrl(valueSetOrCodeName);

filter.setValueSet(valueSetNameUri.get(valueSetOrCodeName));

if (hrVs != null) {
Expand All @@ -245,11 +257,13 @@ private void handleDataRequirement(String type, String path, String valueSetOrCo
.getDataReqValueSets()
.add(new ValuesetModel(valueSetOrCodeName, hrVs.getOid(), hrVs.getVersion(), type));
} else {

CodeModel hrCode = getCode(valueSetOrCodeName);
if (hrCode != null) {
filter.setCode(
Collections.singletonList(
new Coding(hrCode.getCodeSystemOid(), hrCode.getOid(), hrCode.getName())));

readableArtifacts
.getDataReqCodes()
.add(
Expand All @@ -274,6 +288,17 @@ private void handleDataRequirement(String type, String path, String valueSetOrCo
dataRequirements.add(result);
}

private CodeableConcept buildCodeableConcept(String code, String system, String display) {
CodeableConcept codeableConcept = new CodeableConcept();
codeableConcept.setCoding(new ArrayList<>());
codeableConcept.getCoding().add(buildCoding(code, system, display));
return codeableConcept;
}

private Coding buildCoding(String code, String system, String display) {
return new Coding().setCode(code).setSystem(system).setDisplay(display);
}

public ValuesetModel getValueSetUrl(String valueSetName) {
ValuesetModel result = null;
if (isInIncludeLib(valueSetName)) {
Expand All @@ -287,11 +312,12 @@ public ValuesetModel getValueSetUrl(String valueSetName) {
log.debug("Could not find valueset with name " + valueSetName);
}
} /*
* else { // Check to see if its a lib reference like TJC."value set id" int periodIndex =
* valueSetName.indexOf("."); if (periodIndex != -1) { String alias =
* valueSetName.substring(0, periodIndex); String remaining =
* trimQuotes(valueSetName.substring(periodIndex + 1)); var childLib = libMap.get(alias); if
* (childLib != null) { result = childLib.getRight().getValueSetUrl(remaining); } } }
* else { // Check to see if its a lib reference like TJC."value set id" int
* periodIndex = valueSetName.indexOf("."); if (periodIndex != -1) { String
* alias = valueSetName.substring(0, periodIndex); String remaining =
* trimQuotes(valueSetName.substring(periodIndex + 1)); var childLib =
* libMap.get(alias); if (childLib != null) { result =
* childLib.getRight().getValueSetUrl(remaining); } } }
*/
return result;
}
Expand All @@ -309,11 +335,11 @@ public CodeModel getCode(String codeName) {
log.error("Could not find code with code name " + codeName);
}
} /*
* else { // Check to see if its a lib reference like TJC."value set id" int periodIndex =
* codeName.indexOf("."); if (periodIndex != -1) { String alias = codeName.substring(0,
* periodIndex); String remaining = codeName.substring(periodIndex + 1); var childLib =
* libMap.get(alias); if (childLib != null) { result =
* childLib.getRight().getCode(remaining); } } }
* else { // Check to see if its a lib reference like TJC."value set id" int
* periodIndex = codeName.indexOf("."); if (periodIndex != -1) { String alias =
* codeName.substring(0, periodIndex); String remaining =
* codeName.substring(periodIndex + 1); var childLib = libMap.get(alias); if
* (childLib != null) { result = childLib.getRight().getCode(remaining); } } }
*/
return result;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ public Library convertToFhirLibrary(CqlLibrary cqlLibrary) {
library.setUrl(
FhirResourceHelpers.buildResourceFullUrl("Library", cqlLibrary.getCqlLibraryName()));
library.setDataRequirement(distinctDataRequirements(visitor.getDataRequirements()));

library.getExtension().addAll(visitor.getDrcExtensions());
library.setRelatedArtifact(distinctArtifacts(visitor.getRelatedArtifacts()));
library.setMeta(createLibraryMeta());
library.setTitle(cqlLibrary.getCqlLibraryName());
Expand Down

0 comments on commit 12ad2cc

Please sign in to comment.