Skip to content

Commit

Permalink
🌲 Resolve references once up front.
Browse files Browse the repository at this point in the history
  • Loading branch information
psbrandt committed Dec 17, 2019
1 parent d861210 commit 1d4f290
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 62 deletions.
7 changes: 7 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,13 @@
<artifactId>circe</artifactId>
<version>${ohdsi.circe.version}</version>
</dependency>

<!-- PhEMA dependencies -->
<dependency>
<groupId>edu.phema</groupId>
<artifactId>elm-utils</artifactId>
<version>0.0.7</version>
</dependency>
</dependencies>

<build>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import edu.phema.elm_to_omop.helper.CirceUtil;
import edu.phema.elm_to_omop.translate.map.NumericRangeOperatorMap;
import edu.phema.elm_to_omop.vocabulary.phema.PhemaConceptSet;
import edu.phema.transform.ElmTransformer;
import org.hl7.cql.model.ClassType;
import org.hl7.cql.model.DataType;
import org.hl7.cql.model.ListType;
Expand Down Expand Up @@ -45,7 +46,10 @@ public static ExpressionDef getExpressionDefByName(Library library, String expre
public static CohortExpression generateCohortExpression(Library library, ExpressionDef expressionDef, List<PhemaConceptSet> conceptSets) throws Exception {
List<InclusionRule> inclusionRules = new ArrayList<>();

Expression expression = expressionDef.getExpression();
ElmTransformer elmTransformer = new ElmTransformer();
ExpressionDef singleTreeExpressionDef = elmTransformer.resolveReferences(library, expressionDef);

Expression expression = singleTreeExpressionDef.getExpression();

CriteriaGroup criteriaGroup;
if (isNumericComparison(expression)) {
Expand Down Expand Up @@ -74,8 +78,6 @@ public static CohortExpression generateCohortExpression(Library library, Express
}
} else if (expression instanceof BinaryExpression) {
criteriaGroup = getCriteriaGroupForBinaryExpression((BinaryExpression) expression, library, conceptSets);
} else if (expression instanceof ExpressionRef) {
criteriaGroup = generateCriteriaGroupForExpression(expression, library, conceptSets);
} else {
throw new Exception(String.format("The translator is currently unable to generate OHDSI inclusion rules for this type of expression: %s", expression.getClass().getName()));
}
Expand Down Expand Up @@ -210,9 +212,6 @@ else if (secondaryAlias.equals(property.getScope())) {
}
} else if (expression instanceof Exists) {
Exists exists = (Exists) expression;
if (exists.getOperand() instanceof ExpressionRef) {
return generateCriteriaGroupForExpression(expression, library, conceptSets);
}
retrieveExpression = getExistsRetrieveExpression(exists);
} else if (expression instanceof Retrieve) {
retrieveExpression = (Retrieve) expression;
Expand Down Expand Up @@ -311,11 +310,6 @@ private static CriteriaGroup getCriteriaGroupForBinaryExpression(BinaryExpressio
for (Expression operand : expression.getOperand()) {
Expression operandExp = operand;

// Resolve expression reference
if (operandExp instanceof ExpressionRef) {
operandExp = getExpressionReferenceTarget((ExpressionRef) operandExp, library);
}

if (isDemographicExpression(operandExp)) {
DemographicCriteria demographicCriteria = generateDemographicCriteria(operandExp);

Expand Down Expand Up @@ -380,7 +374,7 @@ private static Criteria generateCriteria(PhemaConceptSet conceptSet, CriteriaGro
}

/**
* Given an ExpressionRef from CQL/ELM, convert it into an OHDSI CorelatedCriteria.
* Given an Expression from CQL/ELM, convert it into an OHDSI CorelatedCriteria.
*
* @param expression The ELM expression
* @param library The ELM library
Expand All @@ -389,25 +383,20 @@ private static Criteria generateCriteria(PhemaConceptSet conceptSet, CriteriaGro
* @throws Exception
*/
private static CorelatedCriteria generateCorelatedCriteriaForExpression(Expression expression, Library library, List<PhemaConceptSet> conceptSets) throws Exception {
Expression referencedExp = expression;
if (expression instanceof ExpressionRef) {
referencedExp = getExpressionReferenceTarget((ExpressionRef) expression, library);
}

Retrieve retrieveExpression = null;
Occurrence occurrence = CirceUtil.defaultOccurrence();

DataType dt = referencedExp.getResultType();

if (referencedExp instanceof Retrieve) {
retrieveExpression = (Retrieve) referencedExp;
} else if (referencedExp instanceof Exists) {
return generateCorelatedCriteriaForExpression(((Exists) referencedExp).getOperand(), library, conceptSets);
} else if (referencedExp instanceof Query) {
retrieveExpression = getQueryRetrieveExpression((Query) referencedExp);
} else if (isNumericComparison(referencedExp)) {
occurrence = getNumericComparisonOccurrence((BinaryExpression) referencedExp);
retrieveExpression = getBinaryExpressionRetrieveExpression((BinaryExpression) referencedExp);
DataType dt = expression.getResultType();

if (expression instanceof Retrieve) {
retrieveExpression = (Retrieve) expression;
} else if (expression instanceof Exists) {
return generateCorelatedCriteriaForExpression(((Exists) expression).getOperand(), library, conceptSets);
} else if (expression instanceof Query) {
retrieveExpression = getQueryRetrieveExpression((Query) expression);
} else if (isNumericComparison(expression)) {
occurrence = getNumericComparisonOccurrence((BinaryExpression) expression);
retrieveExpression = getBinaryExpressionRetrieveExpression((BinaryExpression) expression);
} else {
// TODO - Need to handle more than simple query types
throw new PhemaNotImplementedException(String.format("Unable to generate CorelatedCriteria for type: %s", expression.getClass().getName()));
Expand Down Expand Up @@ -483,25 +472,20 @@ private static CriteriaGroup generateCriteriaGroupForDemographicExpression(Expre
}

private static CriteriaGroup generateCriteriaGroupForExpression(Expression expression, Library library, List<PhemaConceptSet> conceptSets) throws Exception {
Expression referencedExp = expression;
if (expression instanceof ExpressionRef) {
referencedExp = getExpressionReferenceTarget((ExpressionRef) expression, library);
}

Retrieve retrieveExpression = null;
Occurrence occurrence = CirceUtil.defaultOccurrence();

if (isDemographicExpression(referencedExp)) {
return generateCriteriaGroupForDemographicExpression(referencedExp);
} else if (referencedExp instanceof Retrieve) {
retrieveExpression = (Retrieve) referencedExp;
} else if (referencedExp instanceof Exists) {
return generateCriteriaGroupForExpression(((Exists) referencedExp).getOperand(), library, conceptSets);
} else if (referencedExp instanceof Query) {
retrieveExpression = getQueryRetrieveExpression((Query) referencedExp);
} else if (isNumericComparison(referencedExp)) {
occurrence = getNumericComparisonOccurrence((BinaryExpression) referencedExp);
retrieveExpression = getBinaryExpressionRetrieveExpression((BinaryExpression) referencedExp);
if (isDemographicExpression(expression)) {
return generateCriteriaGroupForDemographicExpression(expression);
} else if (expression instanceof Retrieve) {
retrieveExpression = (Retrieve) expression;
} else if (expression instanceof Exists) {
return generateCriteriaGroupForExpression(((Exists) expression).getOperand(), library, conceptSets);
} else if (expression instanceof Query) {
retrieveExpression = getQueryRetrieveExpression((Query) expression);
} else if (isNumericComparison(expression)) {
occurrence = getNumericComparisonOccurrence((BinaryExpression) expression);
retrieveExpression = getBinaryExpressionRetrieveExpression((BinaryExpression) expression);
} else {
// TODO - Need to handle more than simple query types
throw new PhemaNotImplementedException(String.format("Currently the translator is only able to process Query and Retrieve expressions"));
Expand All @@ -519,24 +503,6 @@ private static CriteriaGroup generateCriteriaGroupForExpression(Expression expre
return criteriaGroup;
}

/**
* Helper method to take an expression reference, and track back to the object that it refers to.
*
* @param expressionRef
* @param library
* @return
* @throws Exception
*/
private static Expression getExpressionReferenceTarget(ExpressionRef expressionRef, Library library) throws Exception {
Optional<ExpressionDef> referencedExpDef = library.getStatements().getDef().stream().filter(x -> x.getName().equals(expressionRef.getName())).findFirst();
if (!referencedExpDef.isPresent()) {
// TODO - This could be because things are referenced in other libraries. Will need to handle that situation.
throw new Exception(String.format("Could not find the referenced expression %s in the library", expressionRef.getName()));
}

return referencedExpDef.get().getExpression();
}

/**
* Helper method to extract a Retrieve expression from within a BinaryExpression. This is assuming that the
* BinaryExpression is of a type that contains a Count (e.g., Greater, Less).
Expand Down

0 comments on commit 1d4f290

Please sign in to comment.