Search in sources :

Example 1 with CqlExpressionConfiguration

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();
}
Also used : HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) CqlEvaluationRequest(com.ibm.cohort.cql.evaluation.CqlEvaluationRequest) CqlEvaluationResult(com.ibm.cohort.cql.evaluation.CqlEvaluationResult) CqlExpressionConfiguration(com.ibm.cohort.cql.evaluation.CqlExpressionConfiguration) Tuple2(scala.Tuple2) EvaluationError(com.ibm.cohort.cql.spark.errors.EvaluationError) SparkDataRow(com.ibm.cohort.cql.spark.data.SparkDataRow) DataRow(com.ibm.cohort.datarow.model.DataRow) Row(org.apache.spark.sql.Row) Map(java.util.Map) HashMap(java.util.HashMap)

Example 2 with CqlExpressionConfiguration

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;
}
Also used : HashMap(java.util.HashMap) CqlExpressionConfiguration(com.ibm.cohort.cql.evaluation.CqlExpressionConfiguration) CqlLibraryDescriptor(com.ibm.cohort.cql.library.CqlLibraryDescriptor) HashSet(java.util.HashSet)

Example 3 with CqlExpressionConfiguration

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"));
}
Also used : CqlEvaluationRequest(com.ibm.cohort.cql.evaluation.CqlEvaluationRequest) CqlExpressionConfiguration(com.ibm.cohort.cql.evaluation.CqlExpressionConfiguration) CqlLibraryDescriptor(com.ibm.cohort.cql.library.CqlLibraryDescriptor) Test(org.junit.Test)

Example 4 with CqlExpressionConfiguration

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();
    }
}
Also used : IntegerParameter(com.ibm.cohort.cql.evaluation.parameters.IntegerParameter) HashMap(java.util.HashMap) CqlEvaluationRequest(com.ibm.cohort.cql.evaluation.CqlEvaluationRequest) CqlExpressionConfiguration(com.ibm.cohort.cql.evaluation.CqlExpressionConfiguration) IntegerParameter(com.ibm.cohort.cql.evaluation.parameters.IntegerParameter) DateParameter(com.ibm.cohort.cql.evaluation.parameters.DateParameter) Parameter(com.ibm.cohort.cql.evaluation.parameters.Parameter) IntervalParameter(com.ibm.cohort.cql.evaluation.parameters.IntervalParameter) DecimalParameter(com.ibm.cohort.cql.evaluation.parameters.DecimalParameter) StringParameter(com.ibm.cohort.cql.evaluation.parameters.StringParameter) CqlEvaluationRequests(com.ibm.cohort.cql.evaluation.CqlEvaluationRequests) CqlLibraryDescriptor(com.ibm.cohort.cql.library.CqlLibraryDescriptor) File(java.io.File) ObjectMapper(com.fasterxml.jackson.databind.ObjectMapper) Test(org.junit.Test)

Example 5 with CqlExpressionConfiguration

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"));
}
Also used : CqlEvaluationRequest(com.ibm.cohort.cql.evaluation.CqlEvaluationRequest) CqlExpressionConfiguration(com.ibm.cohort.cql.evaluation.CqlExpressionConfiguration) CqlEvaluationRequests(com.ibm.cohort.cql.evaluation.CqlEvaluationRequests) CqlLibraryDescriptor(com.ibm.cohort.cql.library.CqlLibraryDescriptor) Test(org.junit.Test)

Aggregations

CqlExpressionConfiguration (com.ibm.cohort.cql.evaluation.CqlExpressionConfiguration)15 CqlEvaluationRequest (com.ibm.cohort.cql.evaluation.CqlEvaluationRequest)14 CqlLibraryDescriptor (com.ibm.cohort.cql.library.CqlLibraryDescriptor)14 Test (org.junit.Test)13 CqlEvaluationRequests (com.ibm.cohort.cql.evaluation.CqlEvaluationRequests)7 HashMap (java.util.HashMap)6 ObjectMapper (com.fasterxml.jackson.databind.ObjectMapper)3 DateParameter (com.ibm.cohort.cql.evaluation.parameters.DateParameter)3 DecimalParameter (com.ibm.cohort.cql.evaluation.parameters.DecimalParameter)3 IntegerParameter (com.ibm.cohort.cql.evaluation.parameters.IntegerParameter)3 IntervalParameter (com.ibm.cohort.cql.evaluation.parameters.IntervalParameter)3 Parameter (com.ibm.cohort.cql.evaluation.parameters.Parameter)3 StringParameter (com.ibm.cohort.cql.evaluation.parameters.StringParameter)3 File (java.io.File)3 CqlEvaluationResult (com.ibm.cohort.cql.evaluation.CqlEvaluationResult)1 SparkDataRow (com.ibm.cohort.cql.spark.data.SparkDataRow)1 EvaluationError (com.ibm.cohort.cql.spark.errors.EvaluationError)1 DataRow (com.ibm.cohort.datarow.model.DataRow)1 ArrayList (java.util.ArrayList)1 HashSet (java.util.HashSet)1