use of org.opencds.cqf.cql.engine.runtime.Interval in project cqf-ruler by DBCG.
the class LibraryEvaluationProvider method evaluate.
@SuppressWarnings({ "unchecked" })
@Operation(name = "$evaluate", idempotent = true, type = Library.class)
public Bundle evaluate(@IdParam IdType theId, @OperationParam(name = "patientId") String patientId, @OperationParam(name = "periodStart") String periodStart, @OperationParam(name = "periodEnd") String periodEnd, @OperationParam(name = "productLine") String productLine, @OperationParam(name = "terminologyEndpoint") Endpoint terminologyEndpoint, @OperationParam(name = "dataEndpoint") Endpoint dataEndpoint, @OperationParam(name = "context") String contextParam, @OperationParam(name = "executionResults") String executionResults, @OperationParam(name = "parameters") Parameters parameters, @OperationParam(name = "additionalData") Bundle additionalData, RequestDetails theRequestDetails) {
log.info("Library evaluation started..");
if (patientId == null && contextParam != null && contextParam.equals("Patient")) {
log.error("Patient id null");
throw new IllegalArgumentException("Must specify a patientId when executing in Patient context.");
}
Bundle libraryBundle = new Bundle();
Library theResource = null;
if (additionalData != null) {
for (Bundle.BundleEntryComponent entry : additionalData.getEntry()) {
if (entry.getResource().fhirType().equals("Library")) {
libraryBundle.addEntry(entry);
if (entry.getResource().getIdElement().equals(theId)) {
theResource = (Library) entry.getResource();
}
}
}
}
if (theResource == null) {
theResource = read(theId, theRequestDetails);
}
VersionedIdentifier libraryIdentifier = new VersionedIdentifier().withId(theResource.getName()).withVersion(theResource.getVersion());
TerminologyProvider terminologyProvider;
if (terminologyEndpoint != null) {
IGenericClient client = Clients.forEndpoint(getFhirContext(), terminologyEndpoint);
terminologyProvider = new R4FhirTerminologyProvider(client);
} else {
terminologyProvider = myJpaTerminologyProviderFactory.create(new SystemRequestDetails());
}
DataProvider dataProvider;
if (dataEndpoint != null) {
List<RetrieveProvider> retrieveProviderList = new ArrayList<>();
IGenericClient client = Clients.forEndpoint(dataEndpoint);
RestFhirRetrieveProvider retriever = new RestFhirRetrieveProvider(new SearchParameterResolver(getFhirContext()), client);
retriever.setTerminologyProvider(terminologyProvider);
if (terminologyEndpoint == null || (terminologyEndpoint != null && !terminologyEndpoint.getAddress().equals(dataEndpoint.getAddress()))) {
retriever.setExpandValueSets(true);
}
retrieveProviderList.add(retriever);
if (additionalData != null) {
BundleRetrieveProvider bundleProvider = new BundleRetrieveProvider(getFhirContext(), additionalData);
bundleProvider.setTerminologyProvider(terminologyProvider);
retrieveProviderList.add(bundleProvider);
PriorityRetrieveProvider priorityProvider = new PriorityRetrieveProvider(retrieveProviderList);
dataProvider = new CompositeDataProvider(myModelResolver, priorityProvider);
} else {
dataProvider = new CompositeDataProvider(myModelResolver, retriever);
}
} else {
List<RetrieveProvider> retrieveProviderList = new ArrayList<>();
JpaFhirRetrieveProvider retriever = new JpaFhirRetrieveProvider(getDaoRegistry(), new SearchParameterResolver(getFhirContext()));
retriever.setTerminologyProvider(terminologyProvider);
// Assume it's a different server, therefore need to expand.
if (terminologyEndpoint != null) {
retriever.setExpandValueSets(true);
}
retrieveProviderList.add(retriever);
if (additionalData != null) {
BundleRetrieveProvider bundleProvider = new BundleRetrieveProvider(getFhirContext(), additionalData);
bundleProvider.setTerminologyProvider(terminologyProvider);
retrieveProviderList.add(bundleProvider);
PriorityRetrieveProvider priorityProvider = new PriorityRetrieveProvider(retrieveProviderList);
dataProvider = new CompositeDataProvider(myModelResolver, priorityProvider);
} else {
dataProvider = new CompositeDataProvider(myModelResolver, retriever);
}
}
LibraryContentProvider bundleLibraryProvider = new BundleFhirLibraryContentProvider(this.getFhirContext(), libraryBundle, adapterFactory, libraryVersionSelector);
LibraryContentProvider jpaLibraryContentProvider = this.myJpaLibraryContentProviderFactory.create(theRequestDetails);
List<LibraryContentProvider> sourceProviders = new ArrayList<LibraryContentProvider>(Arrays.asList(bundleLibraryProvider, jpaLibraryContentProvider));
LibraryLoader libraryLoader = this.myLibraryLoaderFactory.create(sourceProviders);
CqlEngine engine = new CqlEngine(libraryLoader, Collections.singletonMap("http://hl7.org/fhir", dataProvider), terminologyProvider);
Map<String, Object> resolvedParameters = new HashMap<>();
if (parameters != null) {
for (Parameters.ParametersParameterComponent pc : parameters.getParameter()) {
resolvedParameters.put(pc.getName(), pc.getValue());
}
}
if (periodStart != null && periodEnd != null) {
// resolve the measurement period
Interval measurementPeriod = new Interval(Operations.resolveRequestDate(periodStart, true), true, Operations.resolveRequestDate(periodEnd, false), true);
resolvedParameters.put("Measurement Period", new Interval(DateTime.fromJavaDate((Date) measurementPeriod.getStart()), true, DateTime.fromJavaDate((Date) measurementPeriod.getEnd()), true));
}
if (productLine != null) {
resolvedParameters.put("Product Line", productLine);
}
EvaluationResult evalResult = engine.evaluate(libraryIdentifier, null, Pair.of(contextParam != null ? contextParam : "Unspecified", patientId == null ? "null" : patientId), resolvedParameters, this.getDebugMap());
List<Resource> results = new ArrayList<>();
FhirMeasureBundler bundler = new FhirMeasureBundler();
if (evalResult != null && evalResult.expressionResults != null) {
for (Map.Entry<String, Object> def : evalResult.expressionResults.entrySet()) {
Parameters result = new Parameters();
try {
result.setId(def.getKey());
Object res = def.getValue();
if (res == null) {
result.addParameter().setName("value").setValue(new StringType("null"));
} else if (res instanceof List<?>) {
if (((List<?>) res).size() > 0 && ((List<?>) res).get(0) instanceof Resource) {
if (executionResults != null && executionResults.equals("Summary")) {
result.addParameter().setName("value").setValue(new StringType(((Resource) ((List<?>) res).get(0)).getIdElement().getResourceType() + "/" + ((Resource) ((List<?>) res).get(0)).getIdElement().getIdPart()));
} else {
result.addParameter().setName("value").setResource(bundler.bundle((Iterable<Resource>) res, theRequestDetails.getFhirServerBase()));
}
} else {
result.addParameter().setName("value").setValue(new StringType(res.toString()));
}
} else if (res instanceof Iterable) {
result.addParameter().setName("value").setResource(bundler.bundle((Iterable<Resource>) res, theRequestDetails.getFhirServerBase()));
} else if (res instanceof Resource) {
if (executionResults != null && executionResults.equals("Summary")) {
result.addParameter().setName("value").setValue(new StringType(((Resource) res).getIdElement().getResourceType() + "/" + ((Resource) res).getIdElement().getIdPart()));
} else {
result.addParameter().setName("value").setResource((Resource) res);
}
} else if (res instanceof Type) {
result.addParameter().setName("value").setValue((Type) res);
} else {
result.addParameter().setName("value").setValue(new StringType(res.toString()));
}
result.addParameter().setName("resultType").setValue(new StringType(resolveType(res)));
} catch (RuntimeException re) {
re.printStackTrace();
String message = re.getMessage() != null ? re.getMessage() : re.getClass().getName();
result.addParameter().setName("error").setValue(new StringType(message));
}
results.add(result);
}
}
return bundler.bundle(results, theRequestDetails.getFhirServerBase());
}
use of org.opencds.cqf.cql.engine.runtime.Interval in project cqf-ruler by DBCG.
the class PrefetchDataProviderR4 method retrieve.
@Override
public Iterable<Object> retrieve(String context, String contextPath, Object contextValue, String dataType, String templateId, String codePath, Iterable<Code> codes, String valueSet, String datePath, String dateLowPath, String dateHighPath, Interval dateRange) {
if (codePath == null && (codes != null || valueSet != null)) {
throw new IllegalArgumentException("A code path must be provided when filtering on codes or a valueset.");
}
if (dataType == null) {
throw new IllegalArgumentException("A data type (i.e. Procedure, Valueset, etc...) must be specified for clinical data retrieval");
}
// not be in the pre-fetch bundle, or might required a lookup by Id
if (context.equals("Patient") && contextPath == null) {
return Collections.emptyList();
}
List<Object> resourcesOfType = prefetchResources.get(dataType);
if (resourcesOfType == null) {
return Collections.emptyList();
}
// no resources or no filtering -> return list
if (resourcesOfType.isEmpty() || (dateRange == null && codePath == null)) {
return resourcesOfType;
}
List<Object> returnList = new ArrayList<>();
for (Object resource : resourcesOfType) {
boolean includeResource = true;
if (dateRange != null) {
if (datePath != null) {
if (dateHighPath != null || dateLowPath != null) {
throw new IllegalArgumentException("If the datePath is specified, the dateLowPath and dateHighPath attributes must not be present.");
}
Object dateObject = PrefetchDataProviderHelper.getR4DateTime(this.resolver.resolvePath(resource, datePath));
DateTime date = dateObject instanceof DateTime ? (DateTime) dateObject : null;
Interval dateInterval = dateObject instanceof Interval ? (Interval) dateObject : null;
String precision = PrefetchDataProviderHelper.getPrecision(Arrays.asList(dateRange, date));
if (date != null && !(InEvaluator.in(date, dateRange, precision))) {
includeResource = false;
} else // TODO - add precision to includes evaluator
if (dateInterval != null && !(IncludesEvaluator.includes(dateRange, dateInterval, precision))) {
includeResource = false;
}
} else {
if (dateHighPath == null && dateLowPath == null) {
throw new IllegalArgumentException("If the datePath is not given, either the lowDatePath or highDatePath must be provided.");
}
DateTime lowDate = dateLowPath == null ? null : (DateTime) PrefetchDataProviderHelper.getR4DateTime(this.resolver.resolvePath(resource, dateLowPath));
DateTime highDate = dateHighPath == null ? null : (DateTime) PrefetchDataProviderHelper.getR4DateTime(this.resolver.resolvePath(resource, dateHighPath));
String precision = PrefetchDataProviderHelper.getPrecision(Arrays.asList(dateRange, lowDate, highDate));
Interval interval = new Interval(lowDate, true, highDate, true);
// TODO - add precision to includes evaluator
if (!IncludesEvaluator.includes(dateRange, interval, precision)) {
includeResource = false;
}
}
}
if (codePath != null && !codePath.equals("") && includeResource) {
if (valueSet != null && terminologyProvider != null) {
if (valueSet.startsWith("urn:oid:")) {
valueSet = valueSet.replace("urn:oid:", "");
}
ValueSetInfo valueSetInfo = new ValueSetInfo().withId(valueSet);
codes = terminologyProvider.expand(valueSetInfo);
}
if (codes != null) {
Object codeObject = PrefetchDataProviderHelper.getR4Code(this.resolver.resolvePath(resource, codePath));
includeResource = PrefetchDataProviderHelper.checkCodeMembership(codes, codeObject, this.codeUtil);
}
}
if (includeResource) {
returnList.add(resource);
}
}
return returnList;
}
use of org.opencds.cqf.cql.engine.runtime.Interval in project cqf-ruler by DBCG.
the class PrefetchDataProviderStu3 method retrieve.
@Override
public Iterable<Object> retrieve(String context, String contextPath, Object contextValue, String dataType, String templateId, String codePath, Iterable<Code> codes, String valueSet, String datePath, String dateLowPath, String dateHighPath, Interval dateRange) {
if (codePath == null && (codes != null || valueSet != null)) {
throw new IllegalArgumentException("A code path must be provided when filtering on codes or a valueset.");
}
if (dataType == null) {
throw new IllegalArgumentException("A data type (i.e. Procedure, Valueset, etc...) must be specified for clinical data retrieval");
}
// not be in the pre-fetch bundle, or might required a lookup by Id
if (context.equals("Patient") && contextPath == null) {
return Collections.emptyList();
}
List<Object> resourcesOfType = prefetchResources.get(dataType);
if (resourcesOfType == null) {
return Collections.emptyList();
}
// no resources or no filtering -> return list
if (resourcesOfType.isEmpty() || (dateRange == null && codePath == null)) {
return resourcesOfType;
}
List<Object> returnList = new ArrayList<>();
for (Object resource : resourcesOfType) {
boolean includeResource = true;
if (dateRange != null) {
if (datePath != null) {
if (dateHighPath != null || dateLowPath != null) {
throw new IllegalArgumentException("If the datePath is specified, the dateLowPath and dateHighPath attributes must not be present.");
}
Object dateObject = PrefetchDataProviderHelper.getStu3DateTime(this.resolver.resolvePath(resource, datePath));
DateTime date = dateObject instanceof DateTime ? (DateTime) dateObject : null;
Interval dateInterval = dateObject instanceof Interval ? (Interval) dateObject : null;
String precision = PrefetchDataProviderHelper.getPrecision(Arrays.asList(dateRange, date));
if (date != null && !(InEvaluator.in(date, dateRange, precision))) {
includeResource = false;
} else // TODO - add precision to includes evaluator
if (dateInterval != null && !(IncludesEvaluator.includes(dateRange, dateInterval, precision))) {
includeResource = false;
}
} else {
if (dateHighPath == null && dateLowPath == null) {
throw new IllegalArgumentException("If the datePath is not given, either the lowDatePath or highDatePath must be provided.");
}
DateTime lowDate = dateLowPath == null ? null : (DateTime) PrefetchDataProviderHelper.getStu3DateTime(this.resolver.resolvePath(resource, dateLowPath));
DateTime highDate = dateHighPath == null ? null : (DateTime) PrefetchDataProviderHelper.getStu3DateTime(this.resolver.resolvePath(resource, dateHighPath));
String precision = PrefetchDataProviderHelper.getPrecision(Arrays.asList(dateRange, lowDate, highDate));
Interval interval = new Interval(lowDate, true, highDate, true);
// TODO - add precision to includes evaluator
if (!IncludesEvaluator.includes(dateRange, interval, precision)) {
includeResource = false;
}
}
}
if (codePath != null && !codePath.equals("") && includeResource) {
if (valueSet != null && terminologyProvider != null) {
if (valueSet.startsWith("urn:oid:")) {
valueSet = valueSet.replace("urn:oid:", "");
}
ValueSetInfo valueSetInfo = new ValueSetInfo().withId(valueSet);
codes = terminologyProvider.expand(valueSetInfo);
}
if (codes != null) {
Object codeObject = PrefetchDataProviderHelper.getStu3Code(this.resolver.resolvePath(resource, codePath));
includeResource = PrefetchDataProviderHelper.checkCodeMembership(codes, codeObject, this.codeUtil);
}
}
if (includeResource) {
returnList.add(resource);
}
}
return returnList;
}
use of org.opencds.cqf.cql.engine.runtime.Interval in project cqf-ruler by DBCG.
the class PrefetchDataProviderDstu2 method retrieve.
@Override
public Iterable<Object> retrieve(String context, String contextPath, Object contextValue, String dataType, String templateId, String codePath, Iterable<Code> codes, String valueSet, String datePath, String dateLowPath, String dateHighPath, Interval dateRange) {
if (codePath == null && (codes != null || valueSet != null)) {
throw new IllegalArgumentException("A code path must be provided when filtering on codes or a valueset.");
}
if (dataType == null) {
throw new IllegalArgumentException("A data type (i.e. Procedure, Valueset, etc...) must be specified for clinical data retrieval");
}
// not be in the pre-fetch bundle, or might required a lookup by Id
if (context.equals("Patient") && contextPath == null) {
return Collections.emptyList();
}
List<Object> resourcesOfType = prefetchResources.get(dataType);
if (resourcesOfType == null) {
return Collections.emptyList();
}
// no resources or no filtering -> return list
if (resourcesOfType.isEmpty() || (dateRange == null && codePath == null)) {
return resourcesOfType;
}
List<Object> returnList = new ArrayList<>();
for (Object resource : resourcesOfType) {
boolean includeResource = true;
if (dateRange != null) {
if (datePath != null) {
if (dateHighPath != null || dateLowPath != null) {
throw new IllegalArgumentException("If the datePath is specified, the dateLowPath and dateHighPath attributes must not be present.");
}
Object dateObject = PrefetchDataProviderHelper.getDstu2DateTime(this.resolver.resolvePath(resource, datePath));
DateTime date = dateObject instanceof DateTime ? (DateTime) dateObject : null;
Interval dateInterval = dateObject instanceof Interval ? (Interval) dateObject : null;
String precision = PrefetchDataProviderHelper.getPrecision(Arrays.asList(dateRange, date));
if (date != null && !(InEvaluator.in(date, dateRange, precision))) {
includeResource = false;
} else // TODO - add precision to includes evaluator
if (dateInterval != null && !(IncludesEvaluator.includes(dateRange, dateInterval, precision))) {
includeResource = false;
}
} else {
if (dateHighPath == null && dateLowPath == null) {
throw new IllegalArgumentException("If the datePath is not given, either the lowDatePath or highDatePath must be provided.");
}
DateTime lowDate = dateLowPath == null ? null : (DateTime) PrefetchDataProviderHelper.getDstu2DateTime(this.resolver.resolvePath(resource, dateLowPath));
DateTime highDate = dateHighPath == null ? null : (DateTime) PrefetchDataProviderHelper.getDstu2DateTime(this.resolver.resolvePath(resource, dateHighPath));
String precision = PrefetchDataProviderHelper.getPrecision(Arrays.asList(dateRange, lowDate, highDate));
Interval interval = new Interval(lowDate, true, highDate, true);
// TODO - add precision to includes evaluator
if (!IncludesEvaluator.includes(dateRange, interval, precision)) {
includeResource = false;
}
}
}
if (codePath != null && !codePath.equals("") && includeResource) {
if (valueSet != null && terminologyProvider != null) {
if (valueSet.startsWith("urn:oid:")) {
valueSet = valueSet.replace("urn:oid:", "");
}
ValueSetInfo valueSetInfo = new ValueSetInfo().withId(valueSet);
codes = terminologyProvider.expand(valueSetInfo);
}
if (codes != null) {
Object codeObject = PrefetchDataProviderHelper.getDstu2Code(this.resolver.resolvePath(resource, codePath));
includeResource = PrefetchDataProviderHelper.checkCodeMembership(codes, codeObject, this.codeUtil);
}
}
if (includeResource) {
returnList.add(resource);
}
}
return returnList;
}
use of org.opencds.cqf.cql.engine.runtime.Interval in project quality-measure-and-cohort-service by Alvearie.
the class CQLToFHIRMeasureReportHelperTest method testIntervalDate_shouldReturnNull.
@Test
public void testIntervalDate_shouldReturnNull() {
Interval interval = new Interval(new Date("2020-01-02"), true, new Date("2020-06-04"), true);
assertNull(CQLToFHIRMeasureReportHelper.getFhirTypeValue(interval));
}
Aggregations