Skip to content

Commit

Permalink
Refactoring: Implementing FHIRPahts for boolean, Quantity and Coding …
Browse files Browse the repository at this point in the history
…literals.
  • Loading branch information
piotrszul committed Oct 24, 2023
1 parent 305504b commit 7d311a4
Show file tree
Hide file tree
Showing 8 changed files with 210 additions and 74 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,52 @@ void testExtractView() {
System.out.println(resultDataset.queryExecution().optimizedPlan());

}



@Test
void testExtractFGPDView() {
final List<String> expressions = List.of(
//"name.family",
//"name.given",
"id"
);

final List<String> filters = List.of(
"reverseResolve(Observation.subject).where(code.subsumedBy(http://snomed.info/sct|424144002)).exists(valueQuantity >= 18 'a' and valueQuantity <= 75 'a')",
"reverseResolve(MedicationRequest.subject).medicationCodeableConcept.subsumedBy(http://fhir.de/CodeSystem/bfarm/atc|A10B|2022).anyTrue()",
"reverseResolve(MedicationRequest.subject).medicationCodeableConcept.subsumedBy(http://fhir.de/CodeSystem/bfarm/atc|A10A|2022).anyTrue()",
"reverseResolve(Condition.subject).code.subsumedBy(http://fhir.de/CodeSystem/bfarm/icd-10-gm|E11).anyTrue()",
"reverseResolve(Observation.subject).where(code.subsumedBy(http://loinc.org|4548-4)).exists(valueQuantity >= 6 '%' and valueQuantity <= 10 '%')",
"reverseResolve(Condition.subject).code.subsumedBy(http://fhir.de/CodeSystem/bfarm/icd-10-gm|E10).allFalse()",
"reverseResolve(Condition.subject).code.subsumedBy(http://fhir.de/CodeSystem/bfarm/icd-10-gm|N17).allFalse()"
);

System.out.println("### Expressions: ###");
expressions.forEach(System.out::println);
System.out.println("### Filters: ###");
filters.forEach(System.out::println);


final ExtractRequest extractRequest = ExtractRequest.fromUserInput(
ResourceType.PATIENT,
Optional.of(expressions),
Optional.of(filters),
Optional.empty()
);

final QueryParser queryParser = new QueryParser(new Parser());
final ExtractView extractView = queryParser.toView(extractRequest);
System.out.println("## Extract view ##");
extractView.printTree();
final Dataset<Row> resultDataset = extractView.evaluate(newContext());
resultDataset.show(false);
System.out.println(resultDataset.logicalPlan());
System.out.println(resultDataset.queryExecution().executedPlan());

System.out.println(resultDataset.queryExecution().optimizedPlan());

}

@Test
void testAggregation() {

Expand Down Expand Up @@ -439,7 +484,6 @@ void mockResource(final ResourceType... resourceTypes) {
}



@Test
void testExtractViewWithReverseResolve() {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ static Function<QuantityCollection, Collection> buildDateArithmeticOperation(

final Column valueColumn = functions.callUDF(functionName, source.getColumn(),
target.getColumn());
return DateTimeCollection.build(valueColumn, Optional.empty(), true);
return DateTimeCollection.build(valueColumn, Optional.empty());
};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,11 @@ protected DateTimeCollection(@Nonnull final Column column,
*
* @param column The column to use
* @param definition The definition to use
* @param singular Whether the collection is singular
* @return A new instance of {@link DateTimeCollection}
*/
@Nonnull
public static DateTimeCollection build(@Nonnull final Column column,
@Nonnull final Optional<NodeDefinition> definition, final boolean singular) {
@Nonnull final Optional<NodeDefinition> definition) {
return new DateTimeCollection(column, Optional.of(FhirPathType.DATETIME),
Optional.of(FHIRDefinedType.DATETIME), definition);
}
Expand All @@ -87,7 +86,7 @@ public static DateTimeCollection build(@Nonnull final Column column,
public static DateTimeCollection fromLiteral(@Nonnull final String fhirPath)
throws ParseException {
final String dateString = fhirPath.replaceFirst("^@", "");
return DateTimeCollection.build(lit(dateString), Optional.empty(), true);
return DateTimeCollection.build(lit(dateString), Optional.empty());
}

@Nonnull
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ public class QuantityCollection extends Collection implements Comparable, Numeri
public QuantityCollection(@Nonnull final Column column,
@Nonnull final Optional<FhirPathType> type,
@Nonnull final Optional<FHIRDefinedType> fhirType,
@Nonnull final Optional<? extends NodeDefinition> definition, final boolean singular) {
@Nonnull final Optional<? extends NodeDefinition> definition) {
super(column, type, fhirType, definition);
}

Expand All @@ -68,14 +68,13 @@ public QuantityCollection(@Nonnull final Column column,
*
* @param column The column to use
* @param definition The definition to use
* @param singular Whether the collection is singular
* @return A new instance of {@link QuantityCollection}
*/
@Nonnull
public static QuantityCollection build(@Nonnull final Column column,
@Nonnull final Optional<NodeDefinition> definition, final boolean singular) {
@Nonnull final Optional<NodeDefinition> definition) {
return new QuantityCollection(column, Optional.of(FhirPathType.QUANTITY),
Optional.of(FHIRDefinedType.QUANTITY), definition, singular);
Optional.of(FHIRDefinedType.QUANTITY), definition);
}

/**
Expand Down Expand Up @@ -122,7 +121,7 @@ public static QuantityCollection fromUcumString(@Nonnull final String fhirPath,
public static QuantityCollection fromCalendarDurationString(@Nonnull final String fhirPath) {

final Column column = QuantityEncoding.encodeLiteral(parseCalendarDuration(fhirPath));
return QuantityCollection.build(column, Optional.empty(), true);
return QuantityCollection.build(column, Optional.empty());
}

@Nonnull
Expand Down Expand Up @@ -206,8 +205,7 @@ private static QuantityCollection buildLiteralPath(@Nonnull final BigDecimal dec
quantity.setCode(unit);
display.ifPresent(quantity::setUnit);

return QuantityCollection.build(QuantityEncoding.encodeLiteral(quantity), Optional.empty(),
true);
return QuantityCollection.build(QuantityEncoding.encodeLiteral(quantity), Optional.empty());
}

@Nonnull
Expand Down Expand Up @@ -265,7 +263,7 @@ public Function<Numeric, Collection> getMathOperation(@Nonnull final MathOperati
final Column resultQuantityColumn = when(sourceContext.isNull().or(targetContext.isNull()),
null).otherwise(validResult);

return QuantityCollection.build(resultQuantityColumn, Optional.empty(), true);
return QuantityCollection.build(resultQuantityColumn, Optional.empty());
};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,11 @@ public TimeCollection(@Nonnull final Column column, @Nonnull final Optional<Fhir
*
* @param column The column to use
* @param definition The definition to use
* @param singular Whether the collection is singular
* @return A new instance of {@link TimeCollection}
*/
@Nonnull
public static TimeCollection build(@Nonnull final Column column,
@Nonnull final Optional<NodeDefinition> definition, final boolean singular) {
@Nonnull final Optional<NodeDefinition> definition) {
return new TimeCollection(column, Optional.of(FhirPathType.TIME),
Optional.of(FHIRDefinedType.TIME), definition);
}
Expand All @@ -70,7 +69,7 @@ public static TimeCollection build(@Nonnull final Column column,
@Nonnull
public static TimeCollection fromLiteral(@Nonnull final String literal) {
final String timeString = literal.replaceFirst("^@T", "");
return TimeCollection.build(lit(timeString), Optional.empty(), true);
return TimeCollection.build(lit(timeString), Optional.empty());
}

@Nonnull
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,13 @@

import static java.util.Objects.requireNonNull;

import au.csiro.pathling.encoders.terminology.ucum.Ucum;
import au.csiro.pathling.errors.InvalidUserInputError;
import au.csiro.pathling.fhirpath.FhirPath;
import au.csiro.pathling.fhirpath.collection.BooleanCollection;
import au.csiro.pathling.fhirpath.collection.CodingCollection;
import au.csiro.pathling.fhirpath.collection.Collection;
import au.csiro.pathling.fhirpath.collection.DateCollection;
import au.csiro.pathling.fhirpath.collection.DateTimeCollection;
import au.csiro.pathling.fhirpath.collection.DecimalCollection;
import au.csiro.pathling.fhirpath.collection.IntegerCollection;
import au.csiro.pathling.fhirpath.collection.QuantityCollection;
import au.csiro.pathling.fhirpath.collection.TimeCollection;
import au.csiro.pathling.fhirpath.parser.generated.FhirPathBaseVisitor;
import au.csiro.pathling.fhirpath.parser.generated.FhirPathParser.BooleanLiteralContext;
Expand All @@ -41,13 +37,16 @@
import au.csiro.pathling.fhirpath.parser.generated.FhirPathParser.QuantityLiteralContext;
import au.csiro.pathling.fhirpath.parser.generated.FhirPathParser.StringLiteralContext;
import au.csiro.pathling.fhirpath.parser.generated.FhirPathParser.TimeLiteralContext;
import au.csiro.pathling.fhirpath.path.Literals.BooleanLiteral;
import au.csiro.pathling.fhirpath.path.Literals.CalendarDurationLiteral;
import au.csiro.pathling.fhirpath.path.Literals.CodingLiteral;
import au.csiro.pathling.fhirpath.path.Literals.StringLiteral;
import au.csiro.pathling.fhirpath.path.Literals.UcumQuantityLiteral;
import au.csiro.pathling.fhirpath.path.PureFhirPath;
import java.text.ParseException;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import au.csiro.pathling.fhirpath.path.Paths.StringLiteral;
import au.csiro.pathling.fhirpath.path.PureFhirPath;
import org.antlr.v4.runtime.tree.TerminalNode;
import org.fhir.ucum.UcumException;

/**
* This class deals with terms that are literal expressions.
Expand Down Expand Up @@ -130,11 +129,7 @@ public PureFhirPath<Collection> visitNumberLiteral(
@Nonnull
public PureFhirPath<Collection> visitBooleanLiteral(
@Nullable final BooleanLiteralContext ctx) {
requireNonNull(ctx);
@Nullable final String fhirPath = ctx.getText();
requireNonNull(fhirPath);

return (input, context) -> BooleanCollection.fromLiteral(fhirPath);
return new BooleanLiteral(requireNonNull(requireNonNull(ctx).getText()));
}

@Override
Expand All @@ -151,38 +146,17 @@ public PureFhirPath<Collection> visitQuantityLiteral(
@Nullable final String number = ctx.quantity().NUMBER().getText();
requireNonNull(number);
@Nullable final TerminalNode ucumUnit = ctx.quantity().unit().STRING();

return (input, context) -> {
if (ucumUnit == null) {
// Create a calendar duration literal.
final String fhirPath = String.format("%s %s", number, ctx.quantity().unit().getText());
return QuantityCollection.fromCalendarDurationString(fhirPath);
} else {
// Create a UCUM Quantity literal.
final String fhirPath = String.format("%s %s", number, ucumUnit.getText());
try {
return QuantityCollection.fromUcumString(fhirPath, Ucum.service());
} catch (final UcumException e) {
throw new RuntimeException(e);
}
}
};
return (ucumUnit == null)
? new CalendarDurationLiteral(
String.format("%s %s", number, ctx.quantity().unit().getText()))
: new UcumQuantityLiteral(String.format("%s %s", number, ucumUnit.getText()));
}

@Override
@Nonnull
public PureFhirPath<Collection> visitCodingLiteral(
@Nullable final CodingLiteralContext ctx) {
@Nullable final String fhirPath = requireNonNull(ctx).getText();
requireNonNull(fhirPath);

return (input, context) -> {
try {
return CodingCollection.fromLiteral(fhirPath);
} catch (final IllegalArgumentException e) {
throw new InvalidUserInputError(e.getMessage(), e);
}
};
return new CodingLiteral(requireNonNull(requireNonNull(ctx).getText()));
}

}
Loading

0 comments on commit 7d311a4

Please sign in to comment.