Skip to content

Commit

Permalink
Merge pull request #16 from MeasureAuthoringTool/MAT-6901
Browse files Browse the repository at this point in the history
MAT- 6901 fix HQMF issues
  • Loading branch information
adongare authored Mar 11, 2024
2 parents 0797806 + 866137d commit 4de7d59
Show file tree
Hide file tree
Showing 6 changed files with 347 additions and 59 deletions.
22 changes: 22 additions & 0 deletions src/main/java/generated/gov/cms/madie/simplexml/ClauseType.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
* <element name="cqlaggfunction" type="{}cqlaggfunctionType" minOccurs="0"/>
* </choice>
* </sequence>
* <attribute name="associatedPopulationUUID" type="{http://www.w3.org/2001/XMLSchema}string" />
* <attribute name="displayName" type="{http://www.w3.org/2001/XMLSchema}string" />
* <attribute name="isInGrouping" type="{http://www.w3.org/2001/XMLSchema}string" />
* <attribute name="type" type="{http://www.w3.org/2001/XMLSchema}string" />
Expand All @@ -44,6 +45,9 @@ public class ClauseType {
protected CqldefinitionType cqldefinition;
protected CqlaggfunctionType cqlaggfunction;

@XmlAttribute(name = "associatedPopulationUUID")
protected String associatedPopulationUUID;

@XmlAttribute(name = "displayName")
protected String displayName;

Expand Down Expand Up @@ -92,6 +96,24 @@ public void setCqlaggfunction(CqlaggfunctionType value) {
this.cqlaggfunction = value;
}

/**
* Gets the value of the associatedPopulationUUID property.
*
* @return possible object is {@link String }
*/
public String getAssociatedPopulationUUID() {
return associatedPopulationUUID;
}

/**
* Sets the value of the associatedPopulationUUID property.
*
* @param value allowed object is {@link String }
*/
public void setAssociatedPopulationUUID(String value) {
this.associatedPopulationUUID = value;
}

/**
* Gets the value of the displayName property.
*
Expand Down
1 change: 1 addition & 0 deletions src/main/java/gov/cms/madie/dto/CQLDefinition.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
@NoArgsConstructor
public class CQLDefinition {
private String id;
private String uuid;
private String definitionName;
private String definitionLogic;
private String context = "Patient";
Expand Down
159 changes: 117 additions & 42 deletions src/main/java/gov/cms/madie/services/MeasureMapper.java
Original file line number Diff line number Diff line change
Expand Up @@ -47,20 +47,28 @@ public interface MeasureMapper {

@Mapping(target = "cqlLookUp", source = "cqlLookups")
@Mapping(target = "measureDetails", source = "measure")
@Mapping(target = "measureGrouping", source = "measure")
@Mapping(
target = "measureGrouping",
expression = "java(measureToMeasureGroupingType(measure, cqlLookups))")
@Mapping(target = "elementLookUp", source = "cqlLookups.elementLookups")
@Mapping(target = "supplementalDataElements", source = "measure.supplementalData")
@Mapping(target = "riskAdjustmentVariables", source = "measure.riskAdjustments")
@Mapping(
target = "supplementalDataElements",
expression =
"java(supplementalDataToSupplementalDataElementsType(measure.getSupplementalData(), cqlLookups.getDefinitions()))")
@Mapping(
target = "riskAdjustmentVariables",
expression =
"java(riskAdjustmentsToRiskAdjustmentVariablesType(measure.getRiskAdjustments(), cqlLookups.getDefinitions()))")
@Mapping(target = "allUsedCQLLibs", source = "cqlLookups.includeLibraries")
MeasureType measureToMeasureType(QdmMeasure measure, CqlLookups cqlLookups);

@Mapping(target = "uuid", expression = "java(java.util.UUID.randomUUID().toString())")
@Mapping(target = "cqlUUID", expression = "java(measure.getMeasureSetId())")
@Mapping(target = "uuid", source = "versionId")
@Mapping(target = "cqlUUID", expression = "java(java.util.UUID.randomUUID().toString())")
@Mapping(target = "title", source = "measureName")
@Mapping(target = "measureModel", source = "model")
@Mapping(target = "shortTitle", source = "ecqmTitle")
@Mapping(target = "emeasureid", source = "cmsId")
@Mapping(target = "guid", source = "versionId")
@Mapping(target = "guid", source = "measureSetId")
@Mapping(
target = "cbeid",
source = "measure.measureMetaData.endorsements",
Expand Down Expand Up @@ -131,8 +139,10 @@ public interface MeasureMapper {
@Mapping(target = "uuid", source = "measureSetId")
QualityMeasureSetType measureToQualityMeasureSet(QdmMeasure measure);

default MeasureGroupingType measureToMeasureGroupingType(QdmMeasure measure) {
if (measure == null || CollectionUtils.isEmpty(measure.getGroups())) {
// measureGrouping mappings
default MeasureGroupingType measureToMeasureGroupingType(
QdmMeasure measure, CqlLookups cqlLookups) {
if (measure == null || CollectionUtils.isEmpty(measure.getGroups()) || cqlLookups == null) {
return null;
}

Expand All @@ -142,82 +152,135 @@ default MeasureGroupingType measureToMeasureGroupingType(QdmMeasure measure) {
.getGroup()
.addAll(
IntStream.range(0, groups.size())
.mapToObj(i -> groupToGroupType(groups.get(i), i + 1))
.mapToObj(i -> groupToGroupType(groups.get(i), i + 1, cqlLookups))
.toList());

return measureGroupingType;
}

@Mapping(target = "sequence", source = "sequence")
@Mapping(target = "clause", source = "group")
@Mapping(target = "clause", expression = "java(groupToClauseTypes(group, cqlLookups))")
@Mapping(target = "ucum", source = "group.scoringUnit", qualifiedByName = "scoringUnitToUcum")
GroupType groupToGroupType(Group group, int sequence);
GroupType groupToGroupType(Group group, int sequence, CqlLookups cqlLookups);

default List<ClauseType> groupToClauseTypes(Group group) {
default List<ClauseType> groupToClauseTypes(Group group, CqlLookups cqlLookups) {
if (group == null) {
return null;
}

Set<CQLDefinition> cqlDefinitions = cqlLookups.getDefinitions();
// Clauses are listed in the order Populations, Observations, Stratums
List<ClauseType> clauses = new ArrayList<>();
if (!CollectionUtils.isEmpty(group.getPopulations())) {
clauses.addAll(group.getPopulations().stream().map(this::populationToClauseType).toList());
clauses.addAll(
group.getPopulations().stream()
.map(
population -> {
CQLDefinition cqlDefinition =
getCqlDefinition(population.getDefinition(), cqlDefinitions);
return populationToClauseType(population, cqlDefinition);
})
.toList());
}
if (!CollectionUtils.isEmpty(group.getMeasureObservations())) {
clauses.addAll(
group.getMeasureObservations().stream().map(this::observationToClauseType).toList());
group.getMeasureObservations().stream()
.map(
observation -> {
CQLDefinition cqlDefinition =
getCqlDefinition(observation.getDefinition(), cqlDefinitions);
String associatedPopulationUUID = "";
if ("Ratio".equals(group.getScoring())) {
Population associatedPopulation =
group.getPopulations().stream()
.filter(
population ->
population.getId().equals(observation.getCriteriaReference()))
.findFirst()
.orElse(null);
associatedPopulationUUID =
associatedPopulation != null ? associatedPopulation.getId() : "";
}
return observationToClauseType(
observation, cqlDefinition, associatedPopulationUUID);
})
.toList());
}
if (!CollectionUtils.isEmpty(group.getStratifications())) {
clauses.addAll(
group.getStratifications().stream().map(this::stratificationToClauseType).toList());
group.getStratifications().stream()
.map(
stratification -> {
CQLDefinition cqlDefinition =
getCqlDefinition(stratification.getCqlDefinition(), cqlDefinitions);
return stratificationToClauseType(stratification, cqlDefinition);
})
.toList());
}
return CollectionUtils.isEmpty(clauses) ? null : clauses;
}

default CQLDefinition getCqlDefinition(String definition, Set<CQLDefinition> cqlDefinitions) {
return cqlDefinitions.stream()
.filter(cqlDefinition -> definition.equals(cqlDefinition.getDefinitionName()))
.findFirst()
.orElse(null);
}

// population mappings
@Mapping(
target = "isInGrouping",
expression =
"java(String.valueOf(org.apache.commons.lang3.StringUtils.isNotBlank(population.getDefinition())))")
@Mapping(target = "uuid", expression = "java(java.util.UUID.randomUUID().toString())")
@Mapping(target = "cqldefinition", source = "population")
@Mapping(target = "uuid", source = "population.id")
@Mapping(
target = "cqldefinition",
expression = "java(populationToCqlDefinition(population, cqlDefinition))")
@Mapping(
target = "type",
expression = "java(gov.cms.madie.util.MappingUtil.getPopulationType(population.getName()))")
@Mapping(target = "displayName", expression = "java(population.getName().getDisplay())")
ClauseType populationToClauseType(Population population);
ClauseType populationToClauseType(Population population, CQLDefinition cqlDefinition);

@Mapping(target = "displayName", source = "name.display")
@Mapping(target = "uuid", expression = "java(java.util.UUID.randomUUID().toString())")
CqldefinitionType populationToCqlDefinition(Population population);
@Mapping(target = "displayName", source = "population.name.display")
@Mapping(target = "uuid", source = "cqlDefinition.uuid")
CqldefinitionType populationToCqlDefinition(Population population, CQLDefinition cqlDefinition);

// observation mappings
@Mapping(
target = "isInGrouping",
expression =
"java(String.valueOf(org.apache.commons.lang3.StringUtils.isNotBlank(observation.getDefinition())))")
@Mapping(target = "uuid", expression = "java(java.util.UUID.randomUUID().toString())")
@Mapping(target = "uuid", source = "observation.id")
@Mapping(target = "type", constant = "measureObservation")
@Mapping(target = "displayName", constant = "Measure Observation")
@Mapping(target = "cqlaggfunction", source = "observation")
ClauseType observationToClauseType(MeasureObservation observation);

@Mapping(target = "displayName", source = "aggregateMethod")
@Mapping(target = "cqlfunction", source = "observation")
CqlaggfunctionType observationToCqlAggFunction(MeasureObservation observation);
@Mapping(target = "associatedPopulationUUID", source = "associatedPopulationUUID")
@Mapping(
target = "cqlaggfunction",
expression = "java(observationToCqlAggFunction(observation, cqlDefinition))")
ClauseType observationToClauseType(
MeasureObservation observation, CQLDefinition cqlDefinition, String associatedPopulationUUID);

@Mapping(target = "displayName", source = "definition")
@Mapping(target = "uuid", expression = "java(java.util.UUID.randomUUID().toString())")
CqlfunctionType observationToCqlFunction(MeasureObservation observation);
@Mapping(target = "displayName", source = "observation.aggregateMethod")
@Mapping(
target = "cqlfunction",
expression = "java(observationToCqlFunction(observation, cqlDefinition))")
CqlaggfunctionType observationToCqlAggFunction(
MeasureObservation observation, CQLDefinition cqlDefinition);

// TODO: map observation to definition/aggregate function
@Mapping(target = "displayName", source = "observation.definition")
@Mapping(target = "uuid", source = "cqlDefinition.uuid")
CqlfunctionType observationToCqlFunction(
MeasureObservation observation, CQLDefinition cqlDefinition);

// stratification mappings
@Mapping(
target = "isInGrouping",
expression =
"java(String.valueOf(org.apache.commons.lang3.StringUtils.isNotBlank(stratification.getCqlDefinition())))")
@Mapping(target = "uuid", expression = "java(java.util.UUID.randomUUID().toString())")
@Mapping(target = "type", constant = "stratum")
@Mapping(target = "displayName", constant = "stratum")
ClauseType stratificationToClauseType(Stratification stratification);
ClauseType stratificationToClauseType(Stratification stratification, CQLDefinition cqlDefinition);

// TODO: map stratification to definition/aggregate function

Expand All @@ -243,10 +306,15 @@ default String scoringUnitToUcum(Object scoringUnit) {
ScoringType scoringToScoringType(String scoring);

default SupplementalDataElementsType supplementalDataToSupplementalDataElementsType(
List<DefDescPair> supplementalData) {
List<DefDescPair> supplementalData, Set<CQLDefinition> cqlDefinitions) {
List<CqldefinitionType> defs =
Optional.ofNullable(supplementalData).orElse(List.of()).stream()
.map(this::defDescPairToCqldefinitionType)
.map(
sde -> {
CQLDefinition cqlDefinition =
getCqlDefinition(sde.getDefinition(), cqlDefinitions);
return defDescPairToCqldefinitionType(sde, cqlDefinition);
})
.toList();
SupplementalDataElementsType supplementalDataElementsType = new SupplementalDataElementsType();
supplementalDataElementsType.getCqldefinition().addAll(defs);
Expand Down Expand Up @@ -274,10 +342,15 @@ default ElementLookUpType elementLookupsToElementLookupType(Set<ElementLookup> e
QdmType elementLookupToQdmType(ElementLookup elementLookup);

default RiskAdjustmentVariablesType riskAdjustmentsToRiskAdjustmentVariablesType(
List<DefDescPair> riskAdjustments) {
List<DefDescPair> riskAdjustments, Set<CQLDefinition> cqlDefinitions) {
List<CqldefinitionType> defs =
Optional.ofNullable(riskAdjustments).orElse(List.of()).stream()
.map(this::defDescPairToCqldefinitionType)
.map(
rav -> {
CQLDefinition cqlDefinition =
getCqlDefinition(rav.getDefinition(), cqlDefinitions);
return defDescPairToCqldefinitionType(rav, cqlDefinition);
})
.toList();
RiskAdjustmentVariablesType riskAdjustmentVariablesType = new RiskAdjustmentVariablesType();
riskAdjustmentVariablesType.getCqldefinition().addAll(defs);
Expand Down Expand Up @@ -338,9 +411,10 @@ default EndorsementType endorsementsToEndorsementType(List<Endorsement> endorsem
@Mapping(target = "id", source = "organization.oid")
DeveloperType organizationToDeveloperType(Organization organization);

@Mapping(target = "displayName", source = "definition")
@Mapping(target = "uuid", expression = "java(java.util.UUID.randomUUID().toString())")
CqldefinitionType defDescPairToCqldefinitionType(DefDescPair defDescPair);
@Mapping(target = "displayName", source = "defDescPair.definition")
@Mapping(target = "uuid", source = "definition.uuid")
CqldefinitionType defDescPairToCqldefinitionType(
DefDescPair defDescPair, CQLDefinition definition);

default TypesType baseConfigurationTypesToTypesTypes(
List<BaseConfigurationTypes> baseConfigurationTypes) {
Expand Down Expand Up @@ -502,11 +576,12 @@ default FunctionsType cqlDefinitionsToFunctionsType(Set<CQLDefinition> cqlDefini

List<FunctionType> cqlDefinitionsToFunctionTypes(Set<CQLDefinition> cqlDefinitions);

@Mapping(target = "id", expression = "java(java.util.UUID.randomUUID().toString())")
@Mapping(target = "id", source = "uuid")
@Mapping(target = "name", source = "definitionName")
@Mapping(target = "logic", source = "definitionLogic")
DefinitionType cqlDefinitionToDefinitionType(CQLDefinition cqlDefinition);

@Mapping(target = "id", source = "uuid")
@Mapping(target = "logic", source = "definitionLogic")
@Mapping(target = "name", source = "definitionName")
@Mapping(target = "arguments", source = "functionArguments")
Expand Down
1 change: 1 addition & 0 deletions src/main/resources/schemas/SimpleXML-QDM-5-6.xsd
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,7 @@
<xs:element type="cqlaggfunctionType" name="cqlaggfunction" minOccurs="0"/>
</xs:choice>
</xs:sequence>
<xs:attribute type="xs:string" name="associatedPopulationUUID"/>
<xs:attribute type="xs:string" name="displayName"/>
<xs:attribute type="xs:string" name="isInGrouping"/>
<xs:attribute type="xs:string" name="type"/>
Expand Down
18 changes: 9 additions & 9 deletions src/main/resources/xsl/qdm_v5_6_measure_details.xsl
Original file line number Diff line number Diff line change
Expand Up @@ -192,17 +192,17 @@
<id root="{cqlUUID}"/>
<text mediaType="text/cql">
<reference
value="https://emeasuretool.cms.gov/libraries/{../measureDetails/guid}/{$msrAbbrName}-v{$libraryVersion}-QDM-{$modelVersion}.cql"/>
value="https://madie.cms.gov/libraries/{../measureDetails/guid}/{$msrAbbrName}-v{$libraryVersion}-QDM-{$modelVersion}.cql"/>
<translation mediaType="application/elm+xml">
<reference
value="https://emeasuretool.cms.gov/libraries/{../measureDetails/guid}/{$msrAbbrName}-v{$libraryVersion}-QDM-{$modelVersion}.xml"/>
value="https://madie.cms.gov/libraries/{../measureDetails/guid}/{$msrAbbrName}-v{$libraryVersion}-QDM-{$modelVersion}.xml"/>
</translation>
<translation mediaType="application/elm+json">
<reference
value="https://emeasuretool.cms.gov/libraries/{../measureDetails/guid}/{$msrAbbrName}-v{$libraryVersion}-QDM-{$modelVersion}.json"/>
value="https://madie.cms.gov/libraries/{../measureDetails/guid}/{$msrAbbrName}-v{$libraryVersion}-QDM-{$modelVersion}.json"/>
</translation>
</text>
<setId root="https://emeasuretool.cms.gov/libraries" extension="{../measureDetails/guid}"
<setId root="https://madie.cms.gov/libraries" extension="{../measureDetails/guid}"
identifierName="{translate(/measure/cqlLookUp/library,'_','-')}"/>
<versionNumber value="{../cqlLookUp/version}"/>
</expressionDocument>
Expand All @@ -214,17 +214,17 @@
<id root="{@id}"/>
<text mediaType="text/cql">
<reference
value="https://emeasuretool.cms.gov/libraries/{@setId}/{translate(@name,'_','-')}-v{translate(@version,'.','-')}-QDM-{$modelVersion}.cql"/>
value="https://madie.cms.gov/libraries/{@setId}/{translate(@name,'_','-')}-v{translate(@version,'.','-')}-QDM-{$modelVersion}.cql"/>
<translation mediaType="application/elm+xml">
<reference
value="https://emeasuretool.cms.gov/libraries/{@setId}/{translate(@name,'_','-')}-v{translate(@version,'.','-')}-QDM-{$modelVersion}.xml"/>
value="https://madie.cms.gov/libraries/{@setId}/{translate(@name,'_','-')}-v{translate(@version,'.','-')}-QDM-{$modelVersion}.xml"/>
</translation>
<translation mediaType="application/elm+json">
<reference
value="https://emeasuretool.cms.gov/libraries/{@setId}/{translate(@name,'_','-')}-v{translate(@version,'.','-')}-QDM-{$modelVersion}.json"/>
value="https://madie.cms.gov/libraries/{@setId}/{translate(@name,'_','-')}-v{translate(@version,'.','-')}-QDM-{$modelVersion}.json"/>
</translation>
</text>
<setId root="https://emeasuretool.cms.gov/libraries" extension="{@setId}"
<setId root="https://madie.cms.gov/libraries" extension="{@setId}"
identifierName="{translate(@name,'_','-')}"/>
<versionNumber value="{@version}"/>
</expressionDocument>
Expand Down Expand Up @@ -884,7 +884,7 @@

<xsl:template name="trim">
<xsl:param name="textString"/>
<xsl:value-of select="replace(replace($textString,'\s+$',''),'^\s+','')"/>
<xsl:value-of select="normalize-space($textString)"/>
</xsl:template>

<xsl:template name="constructExt">
Expand Down
Loading

0 comments on commit 4de7d59

Please sign in to comment.