use of com.ibm.cohort.cql.evaluation.CqlExpressionConfiguration in project quality-measure-and-cohort-service by Alvearie.
the class SparkCqlEvaluator method evaluate.
/**
* Evaluate the input CQL for a single context + data pair.
*
* @param rowsByContext In-memory data for all datatypes related to a single
* context
* @param contextName Name of the context used to select measure evaluations.
* @param resultsSchema StructType containing the schema data for the output table
* that will be created.
* @param evaluator configured CQLEvaluator (data provider, term provider,
* library provider all previously setup)
* @param requests CqlEvaluationRequests containing lists of libraries,
* expressions, and parameters to evaluate
* @param columnEncoder Encoder used to calculate output column names for
* evaluation results
* @param perContextAccum Spark accumulator that tracks each individual context
* evaluation
* @param errorAccum Spark accumulator that tracks CQL evaluation errors
* @param batchRunTime Single unified timestamp for all contexts
* @return Evaluation results for all expressions evaluated keyed by the context
* ID. Expression names are automatically namespaced according to the
* library name to avoid issues arising for expression names matching
* between libraries (e.g. LibraryName.ExpressionName).
*/
protected Iterator<Tuple2<Object, Row>> evaluate(Tuple2<Object, List<Row>> rowsByContext, String contextName, StructType resultsSchema, CqlEvaluator evaluator, CqlEvaluationRequests requests, SparkOutputColumnEncoder columnEncoder, LongAccumulator perContextAccum, CollectionAccumulator<EvaluationError> errorAccum, ZonedDateTime batchRunTime) {
perContextAccum.add(1);
List<CqlEvaluationRequest> requestsForContext = requests.getEvaluationsForContext(contextName);
// parameters json -> {columnName, result}
Map<String, Map<String, Object>> expressionResultsByParameters = new HashMap<>();
for (CqlEvaluationRequest request : requestsForContext) {
String parametersJson = encodedParametersCache.getKeyParametersColumnData(request);
Map<String, Object> expressionResults = expressionResultsByParameters.computeIfAbsent(parametersJson, x -> new HashMap<>());
for (CqlExpressionConfiguration expression : request.getExpressions()) {
CqlEvaluationRequest singleRequest = new CqlEvaluationRequest(request);
singleRequest.setExpressions(Collections.singleton(expression));
try {
CqlEvaluationResult result = evaluator.evaluate(singleRequest, args.debug ? CqlDebug.DEBUG : CqlDebug.NONE, batchRunTime);
for (Map.Entry<String, Object> entry : result.getExpressionResults().entrySet()) {
String outputColumnKey = columnEncoder.getColumnName(request, entry.getKey());
expressionResults.put(outputColumnKey, typeConverter.toSparkType(entry.getValue()));
}
} catch (Throwable th) {
if (args.haltOnError) {
throw new RuntimeException(String.format("CQL evaluation failed for ContextName: %s, OutputColumn: %s", String.valueOf(contextName), singleRequest.getExpressionNames()), th);
} else {
Object contextId = rowsByContext._1();
errorAccum.add(new EvaluationError(contextName, contextId, singleRequest.getExpressionNames().iterator().next(), th.getMessage()));
}
}
}
}
List<Tuple2<Object, Row>> rows = new ArrayList<>();
for (Map.Entry<String, Map<String, Object>> entry : expressionResultsByParameters.entrySet()) {
Object contextKey = rowsByContext._1();
Map<String, Object> results = entry.getValue();
Object[] data = new Object[resultsSchema.fields().length];
data[0] = contextKey;
data[1] = entry.getKey();
for (int i = 2; i < resultsSchema.fieldNames().length; i++) {
data[i] = results.get(resultsSchema.fieldNames()[i]);
}
rows.add(new Tuple2<Object, Row>(contextKey, RowFactory.create(data)));
}
return rows.iterator();
}
use of com.ibm.cohort.cql.evaluation.CqlExpressionConfiguration in project quality-measure-and-cohort-service by Alvearie.
the class ContextColumnNameEncoder method getDefineToOutputNameMap.
protected static Map<String, String> getDefineToOutputNameMap(CqlEvaluationRequest request, String defaultColumnDelimiter) {
HashMap<String, String> defineToOutputNameMap = new HashMap<>();
DefaultSparkOutputColumnEncoder encoder = new DefaultSparkOutputColumnEncoder(defaultColumnDelimiter);
Set<String> outputColumns = new HashSet<>();
CqlLibraryDescriptor descriptor = request.getDescriptor();
if (descriptor == null || descriptor.getLibraryId() == null || descriptor.getLibraryId().isEmpty()) {
throw new IllegalArgumentException("A library descriptor must be defined for each configured evaluation request.");
}
String libraryId = descriptor.getLibraryId();
for (CqlExpressionConfiguration expression : request.getExpressions()) {
String expressionName = expression.getName();
String outputColumn = expression.getOutputColumn();
if (defineToOutputNameMap.containsKey(expressionName)) {
throw new IllegalArgumentException("Evaluation request contains duplicate expression " + expressionName + " for the library " + libraryId);
}
if (outputColumn == null) {
outputColumn = encoder.getColumnName(request, expressionName);
}
if (outputColumns.contains(outputColumn)) {
throw new IllegalArgumentException("Evaluation request contains duplicate outputColumn " + outputColumn);
}
outputColumns.add(outputColumn);
defineToOutputNameMap.put(expressionName, outputColumn);
}
return defineToOutputNameMap;
}
use of com.ibm.cohort.cql.evaluation.CqlExpressionConfiguration in project quality-measure-and-cohort-service by Alvearie.
the class ContextColumnNameEncoderTest method testMultipleRequestsColumnNames.
@Test
public void testMultipleRequestsColumnNames() {
CqlLibraryDescriptor libraryDescriptor1 = new CqlLibraryDescriptor();
libraryDescriptor1.setLibraryId("lib1");
CqlEvaluationRequest request = new CqlEvaluationRequest();
request.setDescriptor(libraryDescriptor1);
request.setId(1);
CqlExpressionConfiguration expressionConfiguration1 = new CqlExpressionConfiguration();
expressionConfiguration1.setName("abcd");
CqlExpressionConfiguration expressionConfiguration2 = new CqlExpressionConfiguration();
expressionConfiguration2.setName("efgh");
expressionConfiguration2.setOutputColumn("A2");
request.setExpressions(new HashSet<>(Arrays.asList(expressionConfiguration1, expressionConfiguration2)));
CqlLibraryDescriptor libraryDescriptor2 = new CqlLibraryDescriptor();
libraryDescriptor2.setLibraryId("lib2");
CqlEvaluationRequest request2 = new CqlEvaluationRequest();
request2.setDescriptor(libraryDescriptor2);
request2.setId(2);
CqlExpressionConfiguration expressionConfiguration3 = new CqlExpressionConfiguration();
expressionConfiguration3.setName("ijkl");
expressionConfiguration3.setOutputColumn("A3");
CqlExpressionConfiguration expressionConfiguration4 = new CqlExpressionConfiguration();
expressionConfiguration4.setName("mnop");
request2.setExpressions(new HashSet<>(Arrays.asList(expressionConfiguration3, expressionConfiguration4)));
ContextColumnNameEncoder contextColumnNameEncoder = ContextColumnNameEncoder.create(Arrays.asList(request, request2), "|");
assertEquals("lib1|abcd", contextColumnNameEncoder.getColumnName(request, "abcd"));
assertEquals("A2", contextColumnNameEncoder.getColumnName(request, "efgh"));
assertEquals("A3", contextColumnNameEncoder.getColumnName(request2, "ijkl"));
assertEquals("lib2|mnop", contextColumnNameEncoder.getColumnName(request2, "mnop"));
}
use of com.ibm.cohort.cql.evaluation.CqlExpressionConfiguration in project quality-measure-and-cohort-service by Alvearie.
the class SparkCqlEvaluatorTest method testParameterMatrixOutputDisabledRowsGroupingSuccess.
@Test
public void testParameterMatrixOutputDisabledRowsGroupingSuccess() throws Exception {
String outputLocation = "target/output/param-matrix-group-disabled/patient_cohort";
CqlEvaluationRequest template = new CqlEvaluationRequest();
template.setDescriptor(new CqlLibraryDescriptor().setLibraryId("SampleLibrary").setVersion("1.0.0"));
template.setExpressionsByNames(Collections.singleton("IsFemale"));
template.setContextKey("Patient");
template.setContextValue("NA");
CqlEvaluationRequests requests = new CqlEvaluationRequests();
requests.setEvaluations(new ArrayList<>());
List<Integer> ages = Arrays.asList(15, 17, 18);
for (Integer age : ages) {
Map<String, Parameter> parameters = new HashMap<>();
parameters.put("MinimumAge", new IntegerParameter(age));
CqlExpressionConfiguration renamed = new CqlExpressionConfiguration();
renamed.setName("IsFemale");
renamed.setOutputColumn("IsFemale" + age);
CqlEvaluationRequest request = new CqlEvaluationRequest(template);
request.setExpressions(Collections.singleton(renamed));
request.setParameters(parameters);
requests.getEvaluations().add(request);
}
ObjectMapper om = new ObjectMapper();
File jobsFile = new File("target/output/param-matrix-simple/cql-jobs.json");
if (!jobsFile.exists()) {
jobsFile.getParentFile().mkdirs();
}
FileUtils.write(jobsFile, om.writeValueAsString(requests), StandardCharsets.UTF_8);
try {
String[] args = new String[] { "-d", "src/test/resources/simple-job/context-definitions.json", "-j", jobsFile.getPath(), "-m", "src/test/resources/simple-job/modelinfo/simple-modelinfo-1.0.0.xml", "-c", "src/test/resources/simple-job/cql", "-i", "Patient=" + new File("src/test/resources/simple-job/testdata/patient").toURI().toString(), "-o", "Patient=" + new File(outputLocation).toURI().toString(), "--output-format", "delta", "--overwrite-output-for-contexts", "--metadata-output-path", outputLocation, "--disable-result-grouping" };
SparkCqlEvaluator.main(args);
validateOutputCountsAndColumns(outputLocation, new HashSet<>(Arrays.asList("id", "parameters", "IsFemale15", "IsFemale17", "IsFemale18")), 10, "delta");
} finally {
jobsFile.delete();
}
}
use of com.ibm.cohort.cql.evaluation.CqlExpressionConfiguration in project quality-measure-and-cohort-service by Alvearie.
the class ConfigurableOutputColumnNameEncoderTest method testOutputColumnsRepeatedInContextThrowsError.
@Test
public void testOutputColumnsRepeatedInContextThrowsError() {
CqlLibraryDescriptor libraryDescriptor1 = new CqlLibraryDescriptor();
libraryDescriptor1.setLibraryId("lib1");
CqlEvaluationRequest request = new CqlEvaluationRequest();
request.setDescriptor(libraryDescriptor1);
request.setId(1);
CqlExpressionConfiguration expressionConfiguration1 = new CqlExpressionConfiguration();
expressionConfiguration1.setName("abcd");
expressionConfiguration1.setOutputColumn("A1");
CqlExpressionConfiguration expressionConfiguration2 = new CqlExpressionConfiguration();
expressionConfiguration2.setName("efgh");
expressionConfiguration2.setOutputColumn("A1");
request.setExpressions(new HashSet<>(Arrays.asList(expressionConfiguration1, expressionConfiguration2)));
request.setContextKey("context1");
CqlEvaluationRequests evaluationRequests = new CqlEvaluationRequests();
evaluationRequests.setEvaluations(Collections.singletonList(request));
IllegalArgumentException ex = assertThrows(IllegalArgumentException.class, () -> ConfigurableOutputColumnNameEncoder.create(evaluationRequests, "|"));
assertTrue(ex.getMessage().contains("Evaluation request contains duplicate outputColumn"));
}
Aggregations