From 761b31405510c16980585911406327eae8794db4 Mon Sep 17 00:00:00 2001 From: Bryn Rhodes Date: Tue, 11 Jul 2023 11:15:35 -0600 Subject: [PATCH] Br fixes 2023 07 10 (#1177) * #1156: Added test cases for CMS143 and CMS149 to validate data requirements output * #1147: Fixed invalid let ref during data requirements inference * #1146: Added test for MedicationRequest to ensure expected ELM output * #1109: Fixed newlines being stripped incorrectly in mixed single- and multi-line comments --- .../cql/cql2elm/Cql2ElmVisitor.java | 25 +- .../cqframework/cql/cql2elm/CommentTests.java | 57 ++ .../cql/cql2elm/qicore/v411/BaseTest.java | 27 + .../cqframework/cql/cql2elm/TestComments.cql | 8 + .../qicore/v411/TestMedicationRequest.cql | 12 + .../requirements/ElmExpressionDefContext.java | 2 +- .../fhir/DataRequirementsProcessorTest.java | 37 + .../fhir/CMS143/cql/CQMCommon-1.0.000.cql | 383 ++++++++ .../fhir/CMS143/cql/FHIRCommon-4.1.000.cql | 278 ++++++ .../fhir/CMS143/cql/FHIRHelpers-4.1.000.cql | 512 +++++++++++ .../POAGOpticNerveEvaluationFHIR-0.0.003.cql | 96 ++ .../fhir/CMS143/cql/QICoreCommon-1.2.000.cql | 370 ++++++++ .../cql/SupplementalDataElements-3.1.000.cql | 49 ++ .../Library-EffectiveDataRequirements.json | 247 ++++++ .../fhir/CMS149/cql/CQMCommon-1.0.000.cql | 383 ++++++++ ...ementiaCognitiveAssessmentFHIR-0.0.003.cql | 100 +++ .../fhir/CMS149/cql/FHIRHelpers-4.1.000.cql | 512 +++++++++++ .../fhir/CMS149/cql/QICoreCommon-1.2.000.cql | 370 ++++++++ .../cql/SupplementalDataElements-3.1.000.cql | 49 ++ .../Library-EffectiveDataRequirements.json | 313 +++++++ .../CMS645-ModuleDefinitionLibrary.json | 40 + .../requirements/fhir/CMS645/CMS645Test.cql | 67 ++ .../requirements/fhir/CMS645/FHIRHelpers.cql | 827 ++++++++++++++++++ 23 files changed, 4754 insertions(+), 10 deletions(-) create mode 100644 Src/java/cql-to-elm/src/test/resources/org/cqframework/cql/cql2elm/qicore/v411/TestMedicationRequest.cql create mode 100644 Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS143/cql/CQMCommon-1.0.000.cql create mode 100644 Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS143/cql/FHIRCommon-4.1.000.cql create mode 100644 Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS143/cql/FHIRHelpers-4.1.000.cql create mode 100644 Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS143/cql/POAGOpticNerveEvaluationFHIR-0.0.003.cql create mode 100644 Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS143/cql/QICoreCommon-1.2.000.cql create mode 100644 Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS143/cql/SupplementalDataElements-3.1.000.cql create mode 100644 Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS143/resources/Library-EffectiveDataRequirements.json create mode 100644 Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS149/cql/CQMCommon-1.0.000.cql create mode 100644 Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS149/cql/DementiaCognitiveAssessmentFHIR-0.0.003.cql create mode 100644 Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS149/cql/FHIRHelpers-4.1.000.cql create mode 100644 Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS149/cql/QICoreCommon-1.2.000.cql create mode 100644 Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS149/cql/SupplementalDataElements-3.1.000.cql create mode 100644 Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS149/resources/Library-EffectiveDataRequirements.json create mode 100644 Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS645/CMS645-ModuleDefinitionLibrary.json create mode 100644 Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS645/CMS645Test.cql create mode 100644 Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS645/FHIRHelpers.cql diff --git a/Src/java/cql-to-elm/src/main/java/org/cqframework/cql/cql2elm/Cql2ElmVisitor.java b/Src/java/cql-to-elm/src/main/java/org/cqframework/cql/cql2elm/Cql2ElmVisitor.java index 745fb0f74..2fa93641a 100755 --- a/Src/java/cql-to-elm/src/main/java/org/cqframework/cql/cql2elm/Cql2ElmVisitor.java +++ b/Src/java/cql-to-elm/src/main/java/org/cqframework/cql/cql2elm/Cql2ElmVisitor.java @@ -576,25 +576,32 @@ private Narrative buildNarrative(Chunk chunk) { else { String chunkContent = tokenStream.getText(chunk.getInterval()); if (chunk.isHeaderChunk()) { - chunkContent = chunkContent.trim(); + chunkContent = stripLeading(chunkContent); } chunkContent = normalizeWhitespace(chunkContent); - chunkContent = makeSeparationBetweenCommentAndDefinition(chunkContent); narrative.getContent().add(chunkContent); } return narrative; } - private String normalizeWhitespace(String input) { - return input.replace("\r\n", "\n"); + // TODO: Should just use String.stripLeading() but that is only available in 11+ + private String stripLeading(String s) { + int index = 0; + while (index < s.length()) { + if (!Character.isWhitespace(s.charAt(index))) { + break; + } + index++; + } + if (index == s.length()) { + return ""; + } + return s.substring(index); } - private String makeSeparationBetweenCommentAndDefinition(String input) { - if(StringUtils.startsWith(input, "//") || StringUtils.endsWith(input, "*/")) { - return input + "\n"; - } - return input; + private String normalizeWhitespace(String input) { + return input.replace("\r\n", "\n"); } private boolean hasChunks(Narrative narrative) { diff --git a/Src/java/cql-to-elm/src/test/java/org/cqframework/cql/cql2elm/CommentTests.java b/Src/java/cql-to-elm/src/test/java/org/cqframework/cql/cql2elm/CommentTests.java index ae276dc36..344c3e3b2 100644 --- a/Src/java/cql-to-elm/src/test/java/org/cqframework/cql/cql2elm/CommentTests.java +++ b/Src/java/cql-to-elm/src/test/java/org/cqframework/cql/cql2elm/CommentTests.java @@ -2,16 +2,22 @@ import org.cqframework.cql.cql2elm.model.CompiledLibrary; import org.hl7.cql_annotations.r1.Annotation; +import org.hl7.cql_annotations.r1.CqlToElmBase; +import org.hl7.cql_annotations.r1.Narrative; import org.hl7.cql_annotations.r1.Tag; import org.hl7.elm.r1.ExpressionDef; import org.hl7.elm.r1.FunctionDef; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; +import javax.xml.bind.JAXBElement; import java.io.IOException; +import java.util.HashMap; +import java.util.Map; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.*; +import static org.junit.Assert.assertTrue; public class CommentTests { @BeforeClass @@ -25,6 +31,57 @@ public void testComments() throws IOException { CqlTranslator translator = TestUtils.runSemanticTest("TestComments.cql", 0, CqlTranslatorOptions.Options.EnableAnnotations); CompiledLibrary library = translator.getTranslatedLibrary(); assertThat(library.getLibrary().getAnnotation(), notNullValue()); + + Map defs = new HashMap<>(); + + if (library.getLibrary().getStatements() != null) { + for (ExpressionDef def : library.getLibrary().getStatements().getDef()) { + defs.put(def.getName(), def); + } + } + + // Validate that boolIpp has appropriate comment value + // Comment should be: "/* Multi-line works fine */\n// Single-line comment does not work\n" + ExpressionDef def = defs.get("boolIpp"); + assertThat(def, notNullValue()); + assertThat(def.getAnnotation(), notNullValue()); + assertThat(def.getAnnotation().size(), is(1)); + assertThat(def.getAnnotation().get(0), instanceOf(Annotation.class)); + Annotation a = (Annotation)def.getAnnotation().get(0); + assertThat(a.getS().getContent(), notNullValue()); + assertThat(a.getS().getContent().size(), is(2)); + assertThat(a.getS().getContent().get(0), instanceOf(JAXBElement.class)); + JAXBElement e = (JAXBElement)a.getS().getContent().get(0); + assertThat(e, notNullValue()); + assertThat(e.getValue(), instanceOf(Narrative.class)); + Narrative n = (Narrative)e.getValue(); + assertThat(n.getContent(), notNullValue()); + assertThat(n.getContent().size(), is(4)); + assertThat(n.getContent().get(0), instanceOf(String.class)); + String s = (String)n.getContent().get(0); + assertThat(s, is("/* Multi-line works fine */\n// Single-line comment does not work\n")); + + + // Validate that singleLineCommentTest has appropriate comment value + // Comment should be: "// Unmixed single-line comment works\n" + def = defs.get("singleLineCommentTest"); + assertThat(def, notNullValue()); + assertThat(def.getAnnotation(), notNullValue()); + assertThat(def.getAnnotation().size(), is(1)); + assertThat(def.getAnnotation().get(0), instanceOf(Annotation.class)); + a = (Annotation)def.getAnnotation().get(0); + assertThat(a.getS().getContent(), notNullValue()); + assertThat(a.getS().getContent().size(), is(2)); + assertThat(a.getS().getContent().get(0), instanceOf(JAXBElement.class)); + e = (JAXBElement)a.getS().getContent().get(0); + assertThat(e, notNullValue()); + assertThat(e.getValue(), instanceOf(Narrative.class)); + n = (Narrative)e.getValue(); + assertThat(n.getContent(), notNullValue()); + assertThat(n.getContent().size(), is(4)); + assertThat(n.getContent().get(0), instanceOf(String.class)); + s = (String)n.getContent().get(0); + assertThat(s, is("// Unmixed single-line comment works\n")); } @Test diff --git a/Src/java/cql-to-elm/src/test/java/org/cqframework/cql/cql2elm/qicore/v411/BaseTest.java b/Src/java/cql-to-elm/src/test/java/org/cqframework/cql/cql2elm/qicore/v411/BaseTest.java index f8c8ebea4..dda2b9040 100644 --- a/Src/java/cql-to-elm/src/test/java/org/cqframework/cql/cql2elm/qicore/v411/BaseTest.java +++ b/Src/java/cql-to-elm/src/test/java/org/cqframework/cql/cql2elm/qicore/v411/BaseTest.java @@ -292,6 +292,33 @@ public void testPapTestWithResults() throws IOException { assertThat(p.getScope(), equalTo("PapTest")); } + @Test + public void TestMedicationRequest() throws IOException { + CqlTranslator translator = TestUtils.runSemanticTest("qicore/v411/TestMedicationRequest.cql", 0); + Library library = translator.toELM(); + Map defs = new HashMap<>(); + + if (library.getStatements() != null) { + for (ExpressionDef def : library.getStatements().getDef()) { + defs.put(def.getName(), def); + } + } + + ExpressionDef def = defs.get("Antithrombotic Therapy at Discharge"); + assertThat(def, notNullValue()); + assertThat(def.getExpression(), instanceOf(Query.class)); + Query q = (Query)def.getExpression(); + assertThat(q.getSource().size(), is(1)); + assertThat(q.getSource().get(0).getExpression(), instanceOf(Retrieve.class)); + Retrieve r = (Retrieve)q.getSource().get(0).getExpression(); + assertThat(r.getTemplateId(), is("http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-medicationrequest")); + assertThat(r.getCodeProperty(), is("medication")); + assertThat(r.getCodeComparator(), is("in")); + assertThat(r.getCodes(), instanceOf(ValueSetRef.class)); + ValueSetRef vsr = (ValueSetRef)r.getCodes(); + assertThat(vsr.getName(), is("Antithrombotic Therapy")); + } + @Test public void TestChoiceUnion() throws IOException { CqlTranslator translator = TestUtils.runSemanticTest("qicore/v411/TestChoiceUnion.cql", 0); diff --git a/Src/java/cql-to-elm/src/test/resources/org/cqframework/cql/cql2elm/TestComments.cql b/Src/java/cql-to-elm/src/test/resources/org/cqframework/cql/cql2elm/TestComments.cql index 1e9d15708..088696583 100644 --- a/Src/java/cql-to-elm/src/test/resources/org/cqframework/cql/cql2elm/TestComments.cql +++ b/Src/java/cql-to-elm/src/test/resources/org/cqframework/cql/cql2elm/TestComments.cql @@ -49,3 +49,11 @@ to ensure overlapping intervals do not contribute multiple times to the result# define function CumulativeDuration(Intervals List>): Sum((collapse Intervals) X return all duration in days of X) +/* Multi-line works fine */ +// Single-line comment does not work +define "boolIpp": + exists ["Encounter"] E where E.period.start during MeasurementPeriod + +// Unmixed single-line comment works +define "singleLineCommentTest": + exists ["Encounter"] E where E.period.start during "MeasurementPeriod" \ No newline at end of file diff --git a/Src/java/cql-to-elm/src/test/resources/org/cqframework/cql/cql2elm/qicore/v411/TestMedicationRequest.cql b/Src/java/cql-to-elm/src/test/resources/org/cqframework/cql/cql2elm/qicore/v411/TestMedicationRequest.cql new file mode 100644 index 000000000..74667dc00 --- /dev/null +++ b/Src/java/cql-to-elm/src/test/resources/org/cqframework/cql/cql2elm/qicore/v411/TestMedicationRequest.cql @@ -0,0 +1,12 @@ +library TestMedicationRequest + +using QICore version '4.1.1' + +include FHIRHelpers version '4.0.1' + +valueset "Antithrombotic Therapy": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113762.1.4.1110.62' + +context Patient + +define "Antithrombotic Therapy at Discharge": + ["MedicationRequest": medication in "Antithrombotic Therapy"] Antithrombotic diff --git a/Src/java/elm-fhir/src/main/java/org/cqframework/cql/elm/requirements/ElmExpressionDefContext.java b/Src/java/elm-fhir/src/main/java/org/cqframework/cql/elm/requirements/ElmExpressionDefContext.java index 15c000305..6a9730bf9 100644 --- a/Src/java/elm-fhir/src/main/java/org/cqframework/cql/elm/requirements/ElmExpressionDefContext.java +++ b/Src/java/elm-fhir/src/main/java/org/cqframework/cql/elm/requirements/ElmExpressionDefContext.java @@ -62,7 +62,7 @@ public ElmQueryLetContext resolveLet(String letName) { ElmQueryLetContext letContext = null; for (ElmQueryContext queryContext : queryStack) { letContext = queryContext.resolveLet(letName); - if (letName != null) { + if (letContext != null) { break; } } diff --git a/Src/java/elm-fhir/src/test/java/org/cqframework/cql/elm/requirements/fhir/DataRequirementsProcessorTest.java b/Src/java/elm-fhir/src/test/java/org/cqframework/cql/elm/requirements/fhir/DataRequirementsProcessorTest.java index 6e81d4782..412875539 100644 --- a/Src/java/elm-fhir/src/test/java/org/cqframework/cql/elm/requirements/fhir/DataRequirementsProcessorTest.java +++ b/Src/java/elm-fhir/src/test/java/org/cqframework/cql/elm/requirements/fhir/DataRequirementsProcessorTest.java @@ -1661,6 +1661,7 @@ private void assertEqualToExpectedModuleDefinitionLibrary(org.hl7.fhir.r5.model. IParser parser = context.newJsonParser(); org.hl7.fhir.r5.model.Library expectedModuleDefinitionLibrary = (org.hl7.fhir.r5.model.Library)parser.parseResource(DataRequirementsProcessorTest.class.getResourceAsStream(pathToExpectedModuleDefinitionLibrary)); assertNotNull(expectedModuleDefinitionLibrary); + //outputModuleDefinitionLibrary(actualModuleDefinitionLibrary); actualModuleDefinitionLibrary.setDate(null); expectedModuleDefinitionLibrary.setDate(null); assertTrue(actualModuleDefinitionLibrary.equalsDeep(expectedModuleDefinitionLibrary)); @@ -1690,6 +1691,42 @@ public void TestWithDependencies() throws IOException { //outputModuleDefinitionLibrary(moduleDefinitionLibrary); } + @Test + public void TestCMS645() throws IOException { + CqlTranslatorOptions translatorOptions = getTranslatorOptions(); + translatorOptions.setAnalyzeDataRequirements(false); + CqlTranslator translator = setupDataRequirementsAnalysis("CMS645/CMS645Test.cql", translatorOptions); + org.hl7.fhir.r5.model.Library moduleDefinitionLibrary = getModuleDefinitionLibrary(translator, translatorOptions, new HashMap(), ZonedDateTime.of(2023, 1, 16, 0, 0, 0, 0, ZoneId.of("UTC"))); + assertNotNull(moduleDefinitionLibrary); + assertEqualToExpectedModuleDefinitionLibrary(moduleDefinitionLibrary, "CMS645/CMS645-ModuleDefinitionLibrary.json"); + + //outputModuleDefinitionLibrary(moduleDefinitionLibrary); + } + + @Test + public void TestCMS143() throws IOException { + CqlTranslatorOptions translatorOptions = getTranslatorOptions(); + translatorOptions.setAnalyzeDataRequirements(false); + CqlTranslator translator = setupDataRequirementsAnalysis("CMS143/cql/POAGOpticNerveEvaluationFHIR-0.0.003.cql", translatorOptions); + org.hl7.fhir.r5.model.Library moduleDefinitionLibrary = getModuleDefinitionLibrary(translator, translatorOptions, new HashMap(), ZonedDateTime.of(2023, 1, 16, 0, 0, 0, 0, ZoneId.of("UTC"))); + assertNotNull(moduleDefinitionLibrary); + assertEqualToExpectedModuleDefinitionLibrary(moduleDefinitionLibrary, "CMS143/resources/Library-EffectiveDataRequirements.json"); + + //outputModuleDefinitionLibrary(moduleDefinitionLibrary); + } + + @Test + public void TestCMS149() throws IOException { + CqlTranslatorOptions translatorOptions = getTranslatorOptions(); + translatorOptions.setAnalyzeDataRequirements(false); + CqlTranslator translator = setupDataRequirementsAnalysis("CMS149/cql/DementiaCognitiveAssessmentFHIR-0.0.003.cql", translatorOptions); + org.hl7.fhir.r5.model.Library moduleDefinitionLibrary = getModuleDefinitionLibrary(translator, translatorOptions, new HashMap(), ZonedDateTime.of(2023, 1, 16, 0, 0, 0, 0, ZoneId.of("UTC"))); + assertNotNull(moduleDefinitionLibrary); + assertEqualToExpectedModuleDefinitionLibrary(moduleDefinitionLibrary, "CMS149/resources/Library-EffectiveDataRequirements.json"); + + //outputModuleDefinitionLibrary(moduleDefinitionLibrary); + } + @Test public void TestDataRequirementsProcessorWithPertinence() { CqlTranslatorOptions cqlTranslatorOptions = new CqlTranslatorOptions(); diff --git a/Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS143/cql/CQMCommon-1.0.000.cql b/Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS143/cql/CQMCommon-1.0.000.cql new file mode 100644 index 000000000..218261f21 --- /dev/null +++ b/Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS143/cql/CQMCommon-1.0.000.cql @@ -0,0 +1,383 @@ +library CQMCommon version '1.0.000' + +using QICore version '4.1.1' + +include FHIRHelpers version '4.1.000' called FHIRHelpers +include QICoreCommon version '1.2.000' called QICoreCommon + +valueset "Emergency Department Visit": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.117.1.7.1.292' +valueset "Encounter Inpatient": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.666.5.307' +valueset "Intensive Care Unit": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113762.1.4.1029.206' +valueset "Observation Services": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113762.1.4.1111.143' +valueset "Outpatient Surgery Service": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113762.1.4.1110.38' +valueset "Present on Admission or Clinically Undetermined": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113762.1.4.1147.197' + +parameter "Measurement Period" Interval + default Interval[@2022-01-01T00:00:00.0, @2023-01-01T00:00:00.0) + +context Patient + +define "Inpatient Encounter": + [Encounter: "Encounter Inpatient"] EncounterInpatient + where EncounterInpatient.status = 'finished' + and "LengthInDays"(EncounterInpatient.period) <= 120 + and EncounterInpatient.period ends during day of "Measurement Period" + +/* +@description: Returns an interval of date values extracted from the input interval of date-time values +@comment: This function returns an interval constructed using the `date from` extractor on the start +and end values of the input date-time interval. Note that using a precision specifier such as `day of` +as part of a timing phrase is preferred to communicate intent to perform day-level comparison, as well +as for general readability. +*/ +define function "ToDateInterval"(period Interval): + Interval[date from start of period, date from end of period] + +/* +Calculates the difference in calendar days between the start and end of the given interval. +*/ +define function "LengthInDays"(Value Interval ): + difference in days between start of Value and end of Value + +/* +Calculates the difference in calendar days between the start and end of the given interval. +*/ +define fluent function lengthInDays(Value Interval ): + difference in days between start of Value and end of Value + +/* +Returns the most recent emergency department visit, if any, that occurs 1 hour or less prior to the given encounter. +*/ +define function "ED Visit"(TheEncounter Encounter ): + Last( + [Encounter: "Emergency Department Visit"] EDVisit + where EDVisit.status = 'finished' + and EDVisit.period ends 1 hour or less on or before start of TheEncounter.period + sort by end of period + ) + +/* +Returns the most recent emergency department visit, if any, that occurs 1 hour or less prior to the given encounter. +*/ +define fluent function edVisit(TheEncounter Encounter ): + Last( + [Encounter: "Emergency Department Visit"] EDVisit + where EDVisit.status = 'finished' + and EDVisit.period ends 1 hour or less on or before start of TheEncounter.period + sort by end of period + ) + +/* +Hospitalization returns the total interval for admission to discharge for the given encounter, or for the admission of any immediately prior emergency department visit to the discharge of the given encounter. +*/ +define function "Hospitalization"(TheEncounter Encounter ): + ( "ED Visit"(TheEncounter) ) X + return + if X is null then TheEncounter.period + else Interval[start of X.period, end of TheEncounter.period) + +/* +Hospitalization returns the total interval for admission to discharge for the given encounter, or for the admission of any immediately prior emergency department visit to the discharge of the given encounter. +*/ +define fluent function hospitalization(TheEncounter Encounter ): + ( "ED Visit"(TheEncounter) ) X + return + if X is null then TheEncounter.period + else Interval[start of X.period, end of TheEncounter.period] + +/* +Returns list of all locations within an encounter, including locations for immediately prior ED visit. +*/ +define function "Hospitalization Locations"(TheEncounter Encounter ): + ( "ED Visit"(TheEncounter) ) EDEncounter + return + if EDEncounter is null then TheEncounter.location + else flatten { EDEncounter.location, TheEncounter.location } + +/* +Returns list of all locations within an encounter, including locations for immediately prior ED visit. +*/ +define fluent function hospitalizationLocations(TheEncounter Encounter ): + ( "ED Visit"(TheEncounter) ) EDEncounter + return + if EDEncounter is null then TheEncounter.location + else flatten { EDEncounter.location, TheEncounter.location } + +/* +Returns the length of stay in days (i.e. the number of days between admission and discharge) for the given encounter, or from the admission of any immediately prior emergency department visit to the discharge of the encounter +*/ +define function "Hospitalization Length of Stay"(TheEncounter Encounter ): + LengthInDays("Hospitalization"(TheEncounter)) + +/* +Returns the length of stay in days (i.e. the number of days between admission and discharge) for the given encounter, or from the admission of any immediately prior emergency department visit to the discharge of the encounter +*/ +define fluent function hospitalizationLengthOfStay(TheEncounter Encounter ): + LengthInDays("Hospitalization"(TheEncounter)) + +/* +Returns admission time for an encounter or for immediately prior emergency department visit. +*/ +define function "Hospital Admission Time"(TheEncounter Encounter ): + start of "Hospitalization"(TheEncounter) + +/* +Returns admission time for an encounter or for immediately prior emergency department visit. +*/ +define fluent function hospitalAdmissionTime(TheEncounter Encounter ): + start of "Hospitalization"(TheEncounter) + +/* +Hospital Discharge Time returns the discharge time for an encounter +*/ +define function "Hospital Discharge Time"(TheEncounter Encounter ): + end of TheEncounter.period + +/* +Hospital Discharge Time returns the discharge time for an encounter +*/ +define fluent function hospitalDischargeTime(TheEncounter Encounter ): + end of TheEncounter.period + +/* +Returns earliest arrival time for an encounter including any prior ED visit. +*/ +define function "Hospital Arrival Time"(TheEncounter Encounter ): + start of First( + ( "Hospitalization Locations"(TheEncounter) ) HospitalLocation + sort by start of period + ).period + +/* +Returns earliest arrival time for an encounter including any prior ED visit. +*/ +define fluent function hospitalArrivalTime(TheEncounter Encounter ): + start of First( + ( "Hospitalization Locations"(TheEncounter) ) HospitalLocation + sort by start of period + ).period + +/* +Returns the latest departure time for encounter including any prior ED visit. +*/ +define function "Hospital Departure Time"(TheEncounter Encounter): + end of Last( + ( "Hospitalization Locations"(TheEncounter) ) HospitalLocation + sort by start of period + ).period + +/* +Returns the latest departure time for encounter including any prior ED visit. +*/ +define fluent function hospitalDepartureTime(TheEncounter Encounter): + end of Last( + ( "Hospitalization Locations"(TheEncounter) ) HospitalLocation + sort by start of period + ).period + +define function "Emergency Department Arrival Time"(TheEncounter Encounter): + start of ( + singleton from ( + ( "Hospitalization Locations"(TheEncounter) ) HospitalLocation + where GetLocation(HospitalLocation.location).type in "Emergency Department Visit" + ) + ).period + +define fluent function emergencyDepartmentArrivalTime(TheEncounter Encounter): + start of ( + singleton from ( + ( "Hospitalization Locations"(TheEncounter) ) HospitalLocation + where GetLocation(HospitalLocation.location).type in "Emergency Department Visit" + ) + ).period + +/* +Hospitalization with Observation and Outpatient Surgery Service returns the total interval from the start of any immediately prior emergency department visit, outpatient surgery visit or observation visit to the discharge of the given encounter. +*/ +define function "HospitalizationWithObservationAndOutpatientSurgeryService"(TheEncounter "Encounter" ): + TheEncounter Visit + let ObsVisit: Last([Encounter: "Observation Services"] LastObs + where LastObs.status = 'finished' + and LastObs.period ends 1 hour or less on or before start of Visit.period + sort by end of period + ), + VisitStart: Coalesce(start of ObsVisit.period, start of Visit.period), + EDVisit: Last([Encounter: "Emergency Department Visit"] LastED + where LastED.status = 'finished' + and LastED.period ends 1 hour or less on or before VisitStart + sort by end of period + ), + VisitStartWithED: Coalesce(start of EDVisit.period, VisitStart), + OutpatientSurgeryVisit: Last([Encounter: "Outpatient Surgery Service"] LastSurgeryOP + where LastSurgeryOP.period ends 1 hour or less on or before VisitStartWithED + sort by end of period + ) + return Interval[Coalesce(start of OutpatientSurgeryVisit.period, VisitStartWithED), end of Visit.period] + +/* +Hospitalization with Observation and Outpatient Surgery Service returns the total interval from the start of any immediately prior emergency department visit, outpatient surgery visit or observation visit to the discharge of the given encounter. +*/ +define fluent function hospitalizationWithObservationAndOutpatientSurgeryService(TheEncounter "Encounter" ): + TheEncounter Visit + let ObsVisit: Last([Encounter: "Observation Services"] LastObs + where LastObs.status = 'finished' + and LastObs.period ends 1 hour or less on or before start of Visit.period + sort by end of period + ), + VisitStart: Coalesce(start of ObsVisit.period, start of Visit.period), + EDVisit: Last([Encounter: "Emergency Department Visit"] LastED + where LastED.status = 'finished' + and LastED.period ends 1 hour or less on or before VisitStart + sort by end of period + ), + VisitStartWithED: Coalesce(start of EDVisit.period, VisitStart), + OutpatientSurgeryVisit: Last([Encounter: "Outpatient Surgery Service"] LastSurgeryOP + where LastSurgeryOP.period ends 1 hour or less on or before VisitStartWithED + sort by end of period + ) + return Interval[Coalesce(start of OutpatientSurgeryVisit.period, VisitStartWithED), end of Visit.period] + +/* +Hospitalization with Observation returns the total interval from the start of any immediately prior emergency department visit through the observation visit to the discharge of the given encounter +*/ +define function "HospitalizationWithObservation"(TheEncounter Encounter ): + TheEncounter Visit + let ObsVisit: Last([Encounter: "Observation Services"] LastObs + where LastObs.status = 'finished' + and LastObs.period ends 1 hour or less on or before start of Visit.period + sort by end of period + ), + VisitStart: Coalesce(start of ObsVisit.period, start of Visit.period), + EDVisit: Last([Encounter: "Emergency Department Visit"] LastED + where LastED.status = 'finished' + and LastED.period ends 1 hour or less on or before VisitStart + sort by end of period + ) + return Interval[Coalesce(start of EDVisit.period, VisitStart), end of Visit.period] + +/* +Hospitalization with Observation returns the total interval from the start of any immediately prior emergency department visit through the observation visit to the discharge of the given encounter +*/ +define fluent function hospitalizationWithObservation(TheEncounter Encounter ): + TheEncounter Visit + let ObsVisit: Last([Encounter: "Observation Services"] LastObs + where LastObs.status = 'finished' + and LastObs.period ends 1 hour or less on or before start of Visit.period + sort by end of period + ), + VisitStart: Coalesce(start of ObsVisit.period, start of Visit.period), + EDVisit: Last([Encounter: "Emergency Department Visit"] LastED + where LastED.status = 'finished' + and LastED.period ends 1 hour or less on or before VisitStart + sort by end of period + ) + return Interval[Coalesce(start of EDVisit.period, VisitStart), end of Visit.period] + +/* +Hospitalization with Observation Length of Stay returns the length in days from the start of any immediately prior emergency department visit through the observation visit to the discharge of the given encounter +*/ +define function "HospitalizationWithObservationLengthofStay"(TheEncounter "Encounter" ): + "LengthInDays"("HospitalizationWithObservation"(TheEncounter)) + +/* +Hospitalization with Observation Length of Stay returns the length in days from the start of any immediately prior emergency department visit through the observation visit to the discharge of the given encounter +*/ +define fluent function hospitalizationWithObservationLengthofStay(TheEncounter "Encounter" ): + "LengthInDays"("HospitalizationWithObservation"(TheEncounter)) + +/* +First Inpatient Intensive Care Unit returns the first intensive care unit for the given encounter, without considering any immediately prior emergency department visit. +*/ +define function "FirstInpatientIntensiveCareUnit"(Encounter Encounter ): + First((Encounter.location)HospitalLocation + where GetLocation(HospitalLocation.location).type in "Intensive Care Unit" + and HospitalLocation.period during Encounter.period + sort by start of period + ) + +/* +First Inpatient Intensive Care Unit returns the first intensive care unit for the given encounter, without considering any immediately prior emergency department visit. +*/ +define fluent function firstInpatientIntensiveCareUnit(Encounter Encounter ): + First((Encounter.location)HospitalLocation + where GetLocation(HospitalLocation.location).type in "Intensive Care Unit" + and HospitalLocation.period during Encounter.period + sort by start of period + ) + +/* +Returns the Condition resources referenced by the diagnosis element of the Encounter +*/ +define function "EncounterDiagnosis"(Encounter Encounter ): + Encounter.diagnosis D + return singleton from ([Condition] C where C.id = D.condition.reference.getId()) + +/* +Returns the Condition resources referenced by the diagnosis element of the Encounter +*/ +define fluent function encounterDiagnosis(Encounter Encounter ): + Encounter.diagnosis D + return singleton from ([Condition] C where C.id = D.condition.reference.getId()) + +/* +Returns the Condition resource for the given reference +@deprecated +*/ +define function "GetCondition"(reference Reference): + singleton from ([Condition] C where C.id = reference.reference.getId()) + +/* +Returns the Condition resource for the given reference +*/ +define fluent function getCondition(reference Reference): + singleton from ([Condition] C where C.id = reference.reference.getId()) + +/* +Returns the condition that is specified as the principal diagnosis for the encounter +*/ +define function "PrincipalDiagnosis"(Encounter Encounter ): + singleton from ((Encounter.diagnosis D where D.rank = 1) PD + return singleton from ([Condition] C where C.id = PD.condition.reference.getId()) + ) + +/* +Returns the condition that is specified as the principal diagnosis for the encounter +*/ +define fluent function principalDiagnosis(Encounter Encounter ): + singleton from ((Encounter.diagnosis D where D.rank = 1) PD + return singleton from ([Condition] C where C.id = PD.condition.reference.getId()) + ) + +/* +Returns the Location resource specified by the given reference +*/ +define function "GetLocation"(reference Reference ): + singleton from ( + [Location] L where L.id = reference.reference.getId() + ) + +/* +Returns the Location resource specified by the given reference +*/ +define fluent function getLocation(reference Reference ): + singleton from ( + [Location] L where L.id = reference.reference.getId() + ) + +/* +Returns the medication code for the given MedicationRequest +*/ +define function "GetMedicationCode"(request MedicationRequest ): + if request.medication is Concept then + request.medication as Concept + else + (singleton from ([Medication] M where M.id = (request.medication as Reference).reference.getId())).code + +/* +Returns the medication code for the given MedicationRequest +*/ +define fluent function getMedicationCode(request MedicationRequest ): + if request.medication is Concept then + request.medication as Concept + else + (singleton from ([Medication] M where M.id = (request.medication as Reference).reference.getId())).code \ No newline at end of file diff --git a/Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS143/cql/FHIRCommon-4.1.000.cql b/Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS143/cql/FHIRCommon-4.1.000.cql new file mode 100644 index 000000000..a48875ae5 --- /dev/null +++ b/Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS143/cql/FHIRCommon-4.1.000.cql @@ -0,0 +1,278 @@ +library FHIRCommon version '4.1.000' + +using FHIR version '4.0.1' + +include FHIRHelpers version '4.1.000' + + +codesystem "LOINC": 'http://loinc.org' +codesystem "SNOMEDCT": 'http://snomed.info/sct' +codesystem "RoleCode": 'http://terminology.hl7.org/CodeSystem/v3-RoleCode' +codesystem "Diagnosis Role": 'http://terminology.hl7.org/CodeSystem/diagnosis-role' +codesystem "RequestIntent": 'http://terminology.hl7.org/CodeSystem/request-intent' +codesystem "MedicationRequestCategory": 'http://terminology.hl7.org/CodeSystem/medicationrequest-category' +codesystem "ConditionClinicalStatusCodes": 'http://terminology.hl7.org/CodeSystem/condition-clinical' +codesystem "ConditionVerificationStatusCodes": 'http://terminology.hl7.org/CodeSystem/condition-ver-status' +codesystem "AllergyIntoleranceClinicalStatusCodes": 'http://terminology.hl7.org/CodeSystem/allergyintolerance-clinical' +codesystem "AllergyIntoleranceVerificationStatusCodes": 'http://terminology.hl7.org/CodeSystem/allergyintolerance-verification' + +//Currently unresolveable in VSAC: +//valueset "Active Condition": 'http://fhir.org/guides/cqf/common/ValueSet/active-condition' +//valueset "Inactive Condition": 'http://fhir.org/guides/cqf/common/ValueSet/inactive-condition' + +code "Birthdate": '21112-8' from "LOINC" display 'Birth date' +code "Dead": '419099009' from "SNOMEDCT" display 'Dead' +code "ER": 'ER' from "RoleCode" display 'Emergency room' +code "ICU": 'ICU' from "RoleCode" display 'Intensive care unit' +code "Billing": 'billing' from "Diagnosis Role" display 'Billing' + +// Condition Clinical Status Codes - Consider value sets for these +code "active": 'active' from "ConditionClinicalStatusCodes" +code "recurrence": 'recurrence' from "ConditionClinicalStatusCodes" +code "relapse": 'relapse' from "ConditionClinicalStatusCodes" +code "inactive": 'inactive' from "ConditionClinicalStatusCodes" +code "remission": 'remission' from "ConditionClinicalStatusCodes" +code "resolved": 'resolved' from "ConditionClinicalStatusCodes" + +// Condition Verification Status Codes - Consider value sets for these +code "unconfirmed": 'unconfirmed' from ConditionVerificationStatusCodes +code "provisional": 'provisional' from ConditionVerificationStatusCodes +code "differential": 'differential' from ConditionVerificationStatusCodes +code "confirmed": 'confirmed' from ConditionVerificationStatusCodes +code "refuted": 'refuted' from ConditionVerificationStatusCodes +code "entered-in-error": 'entered-in-error' from ConditionVerificationStatusCodes + +code "allergy-active": 'active' from "AllergyIntoleranceClinicalStatusCodes" +code "allergy-inactive": 'inactive' from "AllergyIntoleranceClinicalStatusCodes" +code "allergy-resolved": 'resolved' from "AllergyIntoleranceClinicalStatusCodes" + +// Allergy/Intolerance Verification Status Codes - Consider value sets for these +code "allergy-unconfirmed": 'unconfirmed' from AllergyIntoleranceVerificationStatusCodes +code "allergy-confirmed": 'confirmed' from AllergyIntoleranceVerificationStatusCodes +code "allergy-refuted": 'refuted' from AllergyIntoleranceVerificationStatusCodes + +// MedicationRequest Category Codes +code "Community": 'community' from "MedicationRequestCategory" display 'Community' +code "Discharge": 'discharge' from "MedicationRequestCategory" display 'Discharge' + +// Diagnosis Role Codes +code "AD": 'AD' from "Diagnosis Role" display 'Admission diagnosis' +code "DD": 'DD' from "Diagnosis Role" display 'Discharge diagnosis' +code "CC": 'CC' from "Diagnosis Role" display 'Chief complaint' +code "CM": 'CM' from "Diagnosis Role" display 'Comorbidity diagnosis' +code "pre-op": 'pre-op' from "Diagnosis Role" display 'pre-op diagnosis' +code "post-op": 'post-op' from "Diagnosis Role" display 'post-op diagnosis' +code "billing": 'billing' from "Diagnosis Role" display 'billing diagnosis' + +context Patient + +/* +@description: Normalizes a value that is a choice of timing-valued types to an equivalent interval +@comment: Normalizes a choice type of FHIR.dateTime, FHIR.Period, FHIR.Timing, FHIR.instance, FHIR.string, FHIR.Age, or FHIR.Range types +to an equivalent interval. This selection of choice types is a superset of the majority of choice types that are used as possible +representations for timing-valued elements in FHIR, allowing this function to be used across any resource. NOTE: Due to the +complexity of determining a single interval from a Timing or String type, this function will throw a run-time exception if it is used +with a Timing or String. +*/ +define function ToInterval(choice Choice): + case + when choice is FHIR.dateTime then + Interval[FHIRHelpers.ToDateTime(choice as FHIR.dateTime), FHIRHelpers.ToDateTime(choice as FHIR.dateTime)] + when choice is FHIR.Period then + FHIRHelpers.ToInterval(choice as FHIR.Period) + when choice is FHIR.instant then + Interval[FHIRHelpers.ToDateTime(choice as FHIR.instant), FHIRHelpers.ToDateTime(choice as FHIR.instant)] + when choice is FHIR.Age then + Interval[FHIRHelpers.ToDate(Patient.birthDate) + FHIRHelpers.ToQuantity(choice as FHIR.Age), + FHIRHelpers.ToDate(Patient.birthDate) + FHIRHelpers.ToQuantity(choice as FHIR.Age) + 1 year) + when choice is FHIR.Range then + Interval[FHIRHelpers.ToDate(Patient.birthDate) + FHIRHelpers.ToQuantity((choice as FHIR.Range).low), + FHIRHelpers.ToDate(Patient.birthDate) + FHIRHelpers.ToQuantity((choice as FHIR.Range).high) + 1 year) + when choice is FHIR.Timing then + Message(null as Interval, true, '1', 'Error', 'Cannot compute a single interval from a Timing type') + when choice is FHIR.string then + Message(null as Interval, true, '1', 'Error', 'Cannot compute an interval from a String value') + else + null as Interval + end + +/* +@description: Returns an interval representing the normalized Abatement of a given Condition resource. +@comment: NOTE: Due to the complexity of determining an interval from a String, this function will throw +a run-time exception if used with a Condition instance that has a String as the abatement value. +*/ +define function ToAbatementInterval(condition Condition): + if condition.abatement is FHIR.dateTime then + Interval[FHIRHelpers.ToDateTime(condition.abatement as FHIR.dateTime), FHIRHelpers.ToDateTime(condition.abatement as FHIR.dateTime)] + else if condition.abatement is FHIR.Period then + FHIRHelpers.ToInterval(condition.abatement as FHIR.Period) + else if condition.abatement is FHIR.string then + Message(null as Interval, true, '1', 'Error', 'Cannot compute an interval from a String value') + else if condition.abatement is FHIR.Age then + Interval[FHIRHelpers.ToDate(Patient.birthDate) + FHIRHelpers.ToQuantity(condition.abatement as FHIR.Age), + FHIRHelpers.ToDate(Patient.birthDate) + FHIRHelpers.ToQuantity(condition.abatement as FHIR.Age) + 1 year) + else if condition.abatement is FHIR.Range then + Interval[FHIRHelpers.ToDate(Patient.birthDate) + FHIRHelpers.ToQuantity((condition.abatement as FHIR.Range).low), + FHIRHelpers.ToDate(Patient.birthDate) + FHIRHelpers.ToQuantity((condition.abatement as FHIR.Range).high) + 1 year) + else if condition.abatement is FHIR.boolean then + Interval[end of ToInterval(condition.onset), condition.recordedDate) + else null + +/* +@description: Returns an interval representing the normalized prevalence period of a given Condition resource. +@comment: Uses the ToInterval and ToAbatementInterval functions to determine the widest potential interval from +onset to abatement as specified in the given Condition. +*/ +define function ToPrevalenceInterval(condition Condition): +if condition.clinicalStatus ~ "active" + or condition.clinicalStatus ~ "recurrence" + or condition.clinicalStatus ~ "relapse" then + Interval[start of ToInterval(condition.onset), end of ToAbatementInterval(condition)] +else + Interval[start of ToInterval(condition.onset), end of ToAbatementInterval(condition)) + +/* +@description: Returns any extensions defined on the given resource with the specified url. +@comment: NOTE: Extensions are not the preferred approach, but are used as a way to access +content that is defined by extensions but not yet surfaced in the +CQL model info. +*/ +define function Extensions(domainResource DomainResource, url String): + domainResource.extension E + where E.url = url + return E + +/* +@description: Returns the single extension (if present) on the given resource with the specified url. +@comment: This function uses singleton from to ensure that a run-time exception is thrown if there +is more than one extension on the given resource with the specified url. +*/ +define function Extension(domainResource DomainResource, url String): + singleton from "Extensions"(domainResource, url) + +/* +@description: Returns any extensions defined on the given element with the specified url. +@comment: NOTE: Extensions are not the preferred approach, but are used as a way to access +content that is defined by extensions but not yet surfaced in the CQL model info. +*/ +define function Extensions(element Element, url String): + element.extension E + where E.url = url + return E + +/* +@description: Returns the single extension (if present) on the given element with the specified url. +@comment: This function uses singleton from to ensure that a run-time exception is thrown if there +is more than one extension on the given resource with the specified url. +*/ +define function Extension(element Element, url String): + singleton from Extensions(element, url) + +/* +@description: Returns any modifier extensions defined on the given resource with the specified url. +@comment: NOTE: Extensions are not the preferred approach, but are used as a way to access +content that is defined by extensions but not yet surfaced in the +CQL model info. +*/ +define function ModifierExtensions(domainResource DomainResource, url String): + domainResource.modifierExtension E + where E.url = url + return E + +/* +@description: Returns the single modifier extension (if present) on the given resource with the specified url. +@comment: This function uses singleton from to ensure that a run-time exception is thrown if there +is more than one extension on the given resource with the specified url. +*/ +define function ModifierExtension(domainResource DomainResource, url String): + singleton from ModifierExtensions(domainResource, url) + +/* +@description: Returns any modifier extensions defined on the given element with the specified url. +@comment: NOTE: Extensions are not the preferred approach, but are used as a way to access +content that is defined by extensions but not yet surfaced in the CQL model info. +*/ +define function ModifierExtensions(element BackboneElement, url String): + element.modifierExtension E + where E.url = url + return E + +/* +@description: Returns the single modifier extension (if present) on the given element with the specified url. +@comment: This function uses singleton from to ensure that a run-time exception is thrown if there +is more than one extension on the given resource with the specified url. +*/ +define function ModifierExtension(element BackboneElement, url String): + singleton from ModifierExtensions(element, url) + +/* +@description: Returns any base-FHIR extensions defined on the given resource with the specified id. +@comment: NOTE: Extensions are not the preferred approach, but are used as a way to access +content that is defined by extensions but not yet surfaced in the CQL model info. +*/ +define function BaseExtensions(domainResource DomainResource, id String): + domainResource.extension E + where E.url = ('http://hl7.org/fhir/StructureDefinition/' + id) + return E + +/* +@description: Returns the single base-FHIR extension (if present) on the given resource with the specified id. +@comment: This function uses singleton from to ensure that a run-time exception is thrown if there +is more than one extension on the given resource with the specified url. +*/ +define function BaseExtension(domainResource DomainResource, id String): + singleton from BaseExtensions(domainResource, id) + +/* +@description: Returns any base-FHIR extensions defined on the given element with the specified id. +@comment: NOTE: Extensions are not the preferred approach, but are used as a way to access +content that is defined by extensions but not yet surfaced in the CQL model info. +*/ +define function BaseExtensions(element Element, id String): + element.extension E + where E.url = ('http://hl7.org/fhir/StructureDefinition/' + id) + return E + +/* +@description: Returns the single base-FHIR extension (if present) on the given element with the specified id. +@comment: This function uses singleton from to ensure that a run-time exception is thrown if there +is more than one extension on the given resource with the specified url. +*/ +define function BaseExtension(element Element, id String): + singleton from BaseExtensions(element, id) + +/* +@description: Returns any base-FHIR modifier extensions defined on the given resource with the specified id. +@comment: NOTE: Extensions are not the preferred approach, but are used as a way to access +content that is defined by extensions but not yet surfaced in the CQL model info. +*/ +define function BaseModifierExtensions(domainResource DomainResource, id String): + domainResource.modifierExtension E + where E.url = ('http://hl7.org/fhir/StructureDefinition/' + id) + return E + +/* +@description: Returns the single base-FHIR modifier extension (if present) on the given resource with the specified id. +@comment: This function uses singleton from to ensure that a run-time exception is thrown if there +is more than one extension on the given resource with the specified url. +*/ +define function BaseModifierExtension(domainResource DomainResource, id String): + singleton from BaseModifierExtensions(domainResource, id) + +/* +@description: Returns any base-FHIR modifier extensions defined on the given element with the specified id. +@comment: NOTE: Extensions are not the preferred approach, but are used as a way to access +content that is defined by extensions but not yet surfaced in the CQL model info. +*/ +define function BaseModifierExtensions(element BackboneElement, id String): + element.modifierExtension E + where E.url = ('http://hl7.org/fhir/StructureDefinition/' + id) + return E + +/* +@description: Returns the single base-FHIR extension (if present) on the given element with the specified id. +@comment: This function uses singleton from to ensure that a run-time exception is thrown if there +is more than one extension on the given resource with the specified url. +*/ +define function BaseModifierExtension(element BackboneElement, id String): + singleton from BaseModifierExtensions(element, id) \ No newline at end of file diff --git a/Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS143/cql/FHIRHelpers-4.1.000.cql b/Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS143/cql/FHIRHelpers-4.1.000.cql new file mode 100644 index 000000000..f3975bb89 --- /dev/null +++ b/Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS143/cql/FHIRHelpers-4.1.000.cql @@ -0,0 +1,512 @@ +library FHIRHelpers version '4.1.000' + +using FHIR version '4.0.1' + +define function ToInterval(period FHIR.Period): + if period is null then + null + else + if period."start" is null then + Interval(period."start".value, period."end".value] + else + Interval[period."start".value, period."end".value] + +define function ToCalendarUnit(unit System.String): + case unit + when 'ms' then 'millisecond' + when 's' then 'second' + when 'min' then 'minute' + when 'h' then 'hour' + when 'd' then 'day' + when 'wk' then 'week' + when 'mo' then 'month' + when 'a' then 'year' + else unit + end + +define function ToQuantity(quantity FHIR.Quantity): + case + when quantity is null then null + when quantity.value is null then null + when quantity.comparator is not null then + Message(null, true, 'FHIRHelpers.ToQuantity.ComparatorQuantityNotSupported', 'Error', 'FHIR Quantity value has a comparator and cannot be converted to a System.Quantity value.') + when quantity.system is null or quantity.system.value = 'http://unitsofmeasure.org' + or quantity.system.value = 'http://hl7.org/fhirpath/CodeSystem/calendar-units' then + System.Quantity { value: quantity.value.value, unit: ToCalendarUnit(Coalesce(quantity.code.value, quantity.unit.value, '1')) } + else + Message(null, true, 'FHIRHelpers.ToQuantity.InvalidFHIRQuantity', 'Error', 'Invalid FHIR Quantity code: ' & quantity.unit.value & ' (' & quantity.system.value & '|' & quantity.code.value & ')') + end + +define function ToQuantityIgnoringComparator(quantity FHIR.Quantity): + case + when quantity is null then null + when quantity.value is null then null + when quantity.system is null or quantity.system.value = 'http://unitsofmeasure.org' + or quantity.system.value = 'http://hl7.org/fhirpath/CodeSystem/calendar-units' then + System.Quantity { value: quantity.value.value, unit: ToCalendarUnit(Coalesce(quantity.code.value, quantity.unit.value, '1')) } + else + Message(null, true, 'FHIRHelpers.ToQuantity.InvalidFHIRQuantity', 'Error', 'Invalid FHIR Quantity code: ' & quantity.unit.value & ' (' & quantity.system.value & '|' & quantity.code.value & ')') + end + +define function ToInterval(quantity FHIR.Quantity): + if quantity is null then null else + case quantity.comparator.value + when '<' then + Interval[ + null, + ToQuantityIgnoringComparator(quantity) + ) + when '<=' then + Interval[ + null, + ToQuantityIgnoringComparator(quantity) + ] + when '>=' then + Interval[ + ToQuantityIgnoringComparator(quantity), + null + ] + when '>' then + Interval( + ToQuantityIgnoringComparator(quantity), + null + ] + else + Interval[ToQuantity(quantity), ToQuantity(quantity)] + end + +define function ToRatio(ratio FHIR.Ratio): + if ratio is null then + null + else + System.Ratio { numerator: ToQuantity(ratio.numerator), denominator: ToQuantity(ratio.denominator) } + +define function ToInterval(range FHIR.Range): + if range is null then + null + else + Interval[ToQuantity(range.low), ToQuantity(range.high)] + +define function ToCode(coding FHIR.Coding): + if coding is null then + null + else + System.Code { + code: coding.code.value, + system: coding.system.value, + version: coding.version.value, + display: coding.display.value + } + +define function ToConcept(concept FHIR.CodeableConcept): + if concept is null then + null + else + System.Concept { + codes: concept.coding C return ToCode(C), + display: concept.text.value + } + +define function ToValueSet(uri String): + if uri is null then + null + else + System.ValueSet { + id: uri + } + +define function reference(reference String): + if reference is null then + null + else + Reference { reference: string { value: reference } } + +define function ToValue(value Choice): + case + when value is base64Binary then (value as base64Binary).value + when value is boolean then (value as boolean).value + when value is canonical then (value as canonical).value + when value is code then (value as code).value + when value is date then (value as date).value + when value is dateTime then (value as dateTime).value + when value is decimal then (value as decimal).value + when value is id then (value as id).value + when value is instant then (value as instant).value + when value is integer then (value as integer).value + when value is markdown then (value as markdown).value + when value is oid then (value as oid).value + when value is positiveInt then (value as positiveInt).value + when value is string then (value as string).value + when value is time then (value as time).value + when value is unsignedInt then (value as unsignedInt).value + when value is uri then (value as uri).value + when value is url then (value as url).value + when value is uuid then (value as uuid).value + when value is Age then ToQuantity(value as Age) + when value is CodeableConcept then ToConcept(value as CodeableConcept) + when value is Coding then ToCode(value as Coding) + when value is Count then ToQuantity(value as Count) + when value is Distance then ToQuantity(value as Distance) + when value is Duration then ToQuantity(value as Duration) + when value is Quantity then ToQuantity(value as Quantity) + when value is Range then ToInterval(value as Range) + when value is Period then ToInterval(value as Period) + when value is Ratio then ToRatio(value as Ratio) + else value as Choice + end + +define function resolve(reference String) returns Resource: external +define function resolve(reference Reference) returns Resource: external +define function reference(resource Resource) returns Reference: external +define function extension(element Element, url String) returns List: external +define function extension(resource DomainResource, url String) returns List: external +define function modifierExtension(element BackboneElement, url String) returns List: external +define function modifierExtension(resource DomainResource, url String) returns List: external +define function hasValue(element Element) returns Boolean: external +define function getValue(element Element) returns Any: external +define function ofType(identifier String) returns List: external +define function is(identifier String) returns Boolean: external +define function as(identifier String) returns Any: external +define function elementDefinition(element Element) returns ElementDefinition: external +define function slice(element Element, url String, name String) returns List: external +define function checkModifiers(resource Resource) returns Resource: external +define function checkModifiers(resource Resource, modifier String) returns Resource: external +define function checkModifiers(element Element) returns Element: external +define function checkModifiers(element Element, modifier String) returns Element: external +define function conformsTo(resource Resource, structure String) returns Boolean: external +define function memberOf(code code, valueSet String) returns Boolean: external +define function memberOf(coding Coding, valueSet String) returns Boolean: external +define function memberOf(concept CodeableConcept, valueSet String) returns Boolean: external +define function subsumes(coding Coding, subsumedCoding Coding) returns Boolean: external +define function subsumes(concept CodeableConcept, subsumedConcept CodeableConcept) returns Boolean: external +define function subsumedBy(coding Coding, subsumingCoding Coding) returns Boolean: external +define function subsumedBy(concept CodeableConcept, subsumingConcept CodeableConcept) returns Boolean: external +define function htmlChecks(element Element) returns Boolean: external + +define function ToString(value AccountStatus): value.value +define function ToString(value ActionCardinalityBehavior): value.value +define function ToString(value ActionConditionKind): value.value +define function ToString(value ActionGroupingBehavior): value.value +define function ToString(value ActionParticipantType): value.value +define function ToString(value ActionPrecheckBehavior): value.value +define function ToString(value ActionRelationshipType): value.value +define function ToString(value ActionRequiredBehavior): value.value +define function ToString(value ActionSelectionBehavior): value.value +define function ToString(value ActivityDefinitionKind): value.value +define function ToString(value ActivityParticipantType): value.value +define function ToString(value AddressType): value.value +define function ToString(value AddressUse): value.value +define function ToString(value AdministrativeGender): value.value +define function ToString(value AdverseEventActuality): value.value +define function ToString(value AggregationMode): value.value +define function ToString(value AllergyIntoleranceCategory): value.value +define function ToString(value AllergyIntoleranceCriticality): value.value +define function ToString(value AllergyIntoleranceSeverity): value.value +define function ToString(value AllergyIntoleranceType): value.value +define function ToString(value AppointmentStatus): value.value +define function ToString(value AssertionDirectionType): value.value +define function ToString(value AssertionOperatorType): value.value +define function ToString(value AssertionResponseTypes): value.value +define function ToString(value AuditEventAction): value.value +define function ToString(value AuditEventAgentNetworkType): value.value +define function ToString(value AuditEventOutcome): value.value +define function ToString(value BindingStrength): value.value +define function ToString(value BiologicallyDerivedProductCategory): value.value +define function ToString(value BiologicallyDerivedProductStatus): value.value +define function ToString(value BiologicallyDerivedProductStorageScale): value.value +define function ToString(value BundleType): value.value +define function ToString(value CapabilityStatementKind): value.value +define function ToString(value CarePlanActivityKind): value.value +define function ToString(value CarePlanActivityStatus): value.value +define function ToString(value CarePlanIntent): value.value +define function ToString(value CarePlanStatus): value.value +define function ToString(value CareTeamStatus): value.value +define function ToString(value CatalogEntryRelationType): value.value +define function ToString(value ChargeItemDefinitionPriceComponentType): value.value +define function ToString(value ChargeItemStatus): value.value +define function ToString(value ClaimResponseStatus): value.value +define function ToString(value ClaimStatus): value.value +define function ToString(value ClinicalImpressionStatus): value.value +define function ToString(value CodeSearchSupport): value.value +define function ToString(value CodeSystemContentMode): value.value +define function ToString(value CodeSystemHierarchyMeaning): value.value +define function ToString(value CommunicationPriority): value.value +define function ToString(value CommunicationRequestStatus): value.value +define function ToString(value CommunicationStatus): value.value +define function ToString(value CompartmentCode): value.value +define function ToString(value CompartmentType): value.value +define function ToString(value CompositionAttestationMode): value.value +define function ToString(value CompositionStatus): value.value +define function ToString(value ConceptMapEquivalence): value.value +define function ToString(value ConceptMapGroupUnmappedMode): value.value +define function ToString(value ConditionalDeleteStatus): value.value +define function ToString(value ConditionalReadStatus): value.value +define function ToString(value ConsentDataMeaning): value.value +define function ToString(value ConsentProvisionType): value.value +define function ToString(value ConsentState): value.value +define function ToString(value ConstraintSeverity): value.value +define function ToString(value ContactPointSystem): value.value +define function ToString(value ContactPointUse): value.value +define function ToString(value ContractPublicationStatus): value.value +define function ToString(value ContractStatus): value.value +define function ToString(value ContributorType): value.value +define function ToString(value CoverageStatus): value.value +define function ToString(value CurrencyCode): value.value +define function ToString(value DayOfWeek): value.value +define function ToString(value DaysOfWeek): value.value +define function ToString(value DetectedIssueSeverity): value.value +define function ToString(value DetectedIssueStatus): value.value +define function ToString(value DeviceMetricCalibrationState): value.value +define function ToString(value DeviceMetricCalibrationType): value.value +define function ToString(value DeviceMetricCategory): value.value +define function ToString(value DeviceMetricColor): value.value +define function ToString(value DeviceMetricOperationalStatus): value.value +define function ToString(value DeviceNameType): value.value +define function ToString(value DeviceRequestStatus): value.value +define function ToString(value DeviceUseStatementStatus): value.value +define function ToString(value DiagnosticReportStatus): value.value +define function ToString(value DiscriminatorType): value.value +define function ToString(value DocumentConfidentiality): value.value +define function ToString(value DocumentMode): value.value +define function ToString(value DocumentReferenceStatus): value.value +define function ToString(value DocumentRelationshipType): value.value +define function ToString(value EligibilityRequestPurpose): value.value +define function ToString(value EligibilityRequestStatus): value.value +define function ToString(value EligibilityResponsePurpose): value.value +define function ToString(value EligibilityResponseStatus): value.value +define function ToString(value EnableWhenBehavior): value.value +define function ToString(value EncounterLocationStatus): value.value +define function ToString(value EncounterStatus): value.value +define function ToString(value EndpointStatus): value.value +define function ToString(value EnrollmentRequestStatus): value.value +define function ToString(value EnrollmentResponseStatus): value.value +define function ToString(value EpisodeOfCareStatus): value.value +define function ToString(value EventCapabilityMode): value.value +define function ToString(value EventTiming): value.value +define function ToString(value EvidenceVariableType): value.value +define function ToString(value ExampleScenarioActorType): value.value +define function ToString(value ExplanationOfBenefitStatus): value.value +define function ToString(value ExposureState): value.value +define function ToString(value ExtensionContextType): value.value +define function ToString(value FHIRAllTypes): value.value +define function ToString(value FHIRDefinedType): value.value +define function ToString(value FHIRDeviceStatus): value.value +define function ToString(value FHIRResourceType): value.value +define function ToString(value FHIRSubstanceStatus): value.value +define function ToString(value FHIRVersion): value.value +define function ToString(value FamilyHistoryStatus): value.value +define function ToString(value FilterOperator): value.value +define function ToString(value FlagStatus): value.value +define function ToString(value GoalLifecycleStatus): value.value +define function ToString(value GraphCompartmentRule): value.value +define function ToString(value GraphCompartmentUse): value.value +define function ToString(value GroupMeasure): value.value +define function ToString(value GroupType): value.value +define function ToString(value GuidanceResponseStatus): value.value +define function ToString(value GuidePageGeneration): value.value +define function ToString(value GuideParameterCode): value.value +define function ToString(value HTTPVerb): value.value +define function ToString(value IdentifierUse): value.value +define function ToString(value IdentityAssuranceLevel): value.value +define function ToString(value ImagingStudyStatus): value.value +define function ToString(value ImmunizationEvaluationStatus): value.value +define function ToString(value ImmunizationStatus): value.value +define function ToString(value InvoicePriceComponentType): value.value +define function ToString(value InvoiceStatus): value.value +define function ToString(value IssueSeverity): value.value +define function ToString(value IssueType): value.value +define function ToString(value LinkType): value.value +define function ToString(value LinkageType): value.value +define function ToString(value ListMode): value.value +define function ToString(value ListStatus): value.value +define function ToString(value LocationMode): value.value +define function ToString(value LocationStatus): value.value +define function ToString(value MeasureReportStatus): value.value +define function ToString(value MeasureReportType): value.value +define function ToString(value MediaStatus): value.value +define function ToString(value MedicationAdministrationStatus): value.value +define function ToString(value MedicationDispenseStatus): value.value +define function ToString(value MedicationKnowledgeStatus): value.value +define function ToString(value MedicationRequestIntent): value.value +define function ToString(value MedicationRequestPriority): value.value +define function ToString(value MedicationRequestStatus): value.value +define function ToString(value MedicationStatementStatus): value.value +define function ToString(value MedicationStatus): value.value +define function ToString(value MessageSignificanceCategory): value.value +define function ToString(value Messageheader_Response_Request): value.value +define function ToString(value MimeType): value.value +define function ToString(value NameUse): value.value +define function ToString(value NamingSystemIdentifierType): value.value +define function ToString(value NamingSystemType): value.value +define function ToString(value NarrativeStatus): value.value +define function ToString(value NoteType): value.value +define function ToString(value NutritiionOrderIntent): value.value +define function ToString(value NutritionOrderStatus): value.value +define function ToString(value ObservationDataType): value.value +define function ToString(value ObservationRangeCategory): value.value +define function ToString(value ObservationStatus): value.value +define function ToString(value OperationKind): value.value +define function ToString(value OperationParameterUse): value.value +define function ToString(value OrientationType): value.value +define function ToString(value ParameterUse): value.value +define function ToString(value ParticipantRequired): value.value +define function ToString(value ParticipantStatus): value.value +define function ToString(value ParticipationStatus): value.value +define function ToString(value PaymentNoticeStatus): value.value +define function ToString(value PaymentReconciliationStatus): value.value +define function ToString(value ProcedureStatus): value.value +define function ToString(value PropertyRepresentation): value.value +define function ToString(value PropertyType): value.value +define function ToString(value ProvenanceEntityRole): value.value +define function ToString(value PublicationStatus): value.value +define function ToString(value QualityType): value.value +define function ToString(value QuantityComparator): value.value +define function ToString(value QuestionnaireItemOperator): value.value +define function ToString(value QuestionnaireItemType): value.value +define function ToString(value QuestionnaireResponseStatus): value.value +define function ToString(value ReferenceHandlingPolicy): value.value +define function ToString(value ReferenceVersionRules): value.value +define function ToString(value ReferredDocumentStatus): value.value +define function ToString(value RelatedArtifactType): value.value +define function ToString(value RemittanceOutcome): value.value +define function ToString(value RepositoryType): value.value +define function ToString(value RequestIntent): value.value +define function ToString(value RequestPriority): value.value +define function ToString(value RequestStatus): value.value +define function ToString(value ResearchElementType): value.value +define function ToString(value ResearchStudyStatus): value.value +define function ToString(value ResearchSubjectStatus): value.value +define function ToString(value ResourceType): value.value +define function ToString(value ResourceVersionPolicy): value.value +define function ToString(value ResponseType): value.value +define function ToString(value RestfulCapabilityMode): value.value +define function ToString(value RiskAssessmentStatus): value.value +define function ToString(value SPDXLicense): value.value +define function ToString(value SearchComparator): value.value +define function ToString(value SearchEntryMode): value.value +define function ToString(value SearchModifierCode): value.value +define function ToString(value SearchParamType): value.value +define function ToString(value SectionMode): value.value +define function ToString(value SequenceType): value.value +define function ToString(value ServiceRequestIntent): value.value +define function ToString(value ServiceRequestPriority): value.value +define function ToString(value ServiceRequestStatus): value.value +define function ToString(value SlicingRules): value.value +define function ToString(value SlotStatus): value.value +define function ToString(value SortDirection): value.value +define function ToString(value SpecimenContainedPreference): value.value +define function ToString(value SpecimenStatus): value.value +define function ToString(value Status): value.value +define function ToString(value StrandType): value.value +define function ToString(value StructureDefinitionKind): value.value +define function ToString(value StructureMapContextType): value.value +define function ToString(value StructureMapGroupTypeMode): value.value +define function ToString(value StructureMapInputMode): value.value +define function ToString(value StructureMapModelMode): value.value +define function ToString(value StructureMapSourceListMode): value.value +define function ToString(value StructureMapTargetListMode): value.value +define function ToString(value StructureMapTransform): value.value +define function ToString(value SubscriptionChannelType): value.value +define function ToString(value SubscriptionStatus): value.value +define function ToString(value SupplyDeliveryStatus): value.value +define function ToString(value SupplyRequestStatus): value.value +define function ToString(value SystemRestfulInteraction): value.value +define function ToString(value TaskIntent): value.value +define function ToString(value TaskPriority): value.value +define function ToString(value TaskStatus): value.value +define function ToString(value TestReportActionResult): value.value +define function ToString(value TestReportParticipantType): value.value +define function ToString(value TestReportResult): value.value +define function ToString(value TestReportStatus): value.value +define function ToString(value TestScriptRequestMethodCode): value.value +define function ToString(value TriggerType): value.value +define function ToString(value TypeDerivationRule): value.value +define function ToString(value TypeRestfulInteraction): value.value +define function ToString(value UDIEntryType): value.value +define function ToString(value UnitsOfTime): value.value +define function ToString(value Use): value.value +define function ToString(value VariableType): value.value +define function ToString(value VisionBase): value.value +define function ToString(value VisionEyes): value.value +define function ToString(value VisionStatus): value.value +define function ToString(value XPathUsageType): value.value +define function ToString(value base64Binary): value.value +define function ToBoolean(value boolean): value.value +define function ToDate(value date): value.value +define function ToDateTime(value dateTime): value.value +define function ToDecimal(value decimal): value.value +define function ToDateTime(value instant): value.value +define function ToInteger(value integer): value.value +define function ToString(value string): value.value +define function ToTime(value time): value.value +define function ToString(value uri): value.value +define function ToString(value xhtml): value.value \ No newline at end of file diff --git a/Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS143/cql/POAGOpticNerveEvaluationFHIR-0.0.003.cql b/Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS143/cql/POAGOpticNerveEvaluationFHIR-0.0.003.cql new file mode 100644 index 000000000..5db790d13 --- /dev/null +++ b/Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS143/cql/POAGOpticNerveEvaluationFHIR-0.0.003.cql @@ -0,0 +1,96 @@ +library POAGOpticNerveEvaluationFHIR version '0.0.003' + +using QICore version '4.1.1' + +include FHIRHelpers version '4.1.000' called FHIRHelpers +include SupplementalDataElements version '3.1.000' called SDE +include CQMCommon version '1.0.000' called CQMCommon +include FHIRCommon version '4.1.000' called FHIRCommon +include QICoreCommon version '1.2.000' called QICoreCommon + +codesystem "ActCode": 'http://terminology.hl7.org/CodeSystem/v3-ActCode' + +valueset "Care Services in Long-Term Residential Facility": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.464.1003.101.12.1014' +valueset "Cup to Disc Ratio": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1333' +valueset "Face-to-Face Interaction": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.464.1003.101.12.1048' +valueset "Medical Reason": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1007' +valueset "Nursing Facility Visit": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.464.1003.101.12.1012' +valueset "Office Visit": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.464.1003.101.12.1001' +valueset "Ophthalmological Services": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1285' +valueset "Optic Disc Exam for Structural Abnormalities": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1334' +valueset "Outpatient Consultation": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.464.1003.101.12.1008' +valueset "Primary Open-Angle Glaucoma": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.326' + +code "virtual": 'VR' from "ActCode" display 'virtual' +code "AMB": 'AMB' from "ActCode" display 'Ambulatory' + +parameter "Measurement Period" Interval + +context Patient + +define "SDE Ethnicity": + SDE."SDE Ethnicity" + +define "SDE Payer": + SDE."SDE Payer" + +define "SDE Race": + SDE."SDE Race" + +define "SDE Sex": + SDE."SDE Sex" + +define "Denominator": + "Initial Population" + +define "Denominator Exceptions": + exists "Medical Reason for Not Performing Cup to Disc Ratio" + or exists "Medical Reason for Not Performing Optic Disc Exam" + +define "Qualifying Encounter During Measurement Period": + ( ["Encounter": "Office Visit"] + union ["Encounter": "Ophthalmological Services"] + union ["Encounter": "Outpatient Consultation"] + union ["Encounter": "Nursing Facility Visit"] + union ["Encounter": "Care Services in Long-Term Residential Facility"] ) QualifyingEncounter + where QualifyingEncounter.period during "Measurement Period" + and QualifyingEncounter.class !~ "virtual" + and QualifyingEncounter.class ~ "AMB" + +define "Initial Population": + AgeInYearsAt(date from start of "Measurement Period") >= 18 + and exists "Primary Open Angle Glaucoma Encounter" + +define "Primary Open Angle Glaucoma Encounter": + "Qualifying Encounter During Measurement Period" ValidQualifyingEncounter + with ["Condition": "Primary Open-Angle Glaucoma"] PrimaryOpenAngleGlaucoma + such that QICoreCommon."ToPrevalenceInterval" ( PrimaryOpenAngleGlaucoma ) overlaps ValidQualifyingEncounter.period //Encounterperiod + + +define "Cup to Disc Ratio Performed with Result": + ["Observation": "Cup to Disc Ratio"] CupToDiscExamPerformed + with "Primary Open Angle Glaucoma Encounter" EncounterWithPOAG + such that QICoreCommon."ToInterval" ( CupToDiscExamPerformed.effective ) during EncounterWithPOAG.period + where CupToDiscExamPerformed.value is not null + +define "Optic Disc Exam Performed with Result": + ["Observation": "Optic Disc Exam for Structural Abnormalities"] OpticDiscExamPerformed + with "Primary Open Angle Glaucoma Encounter" EncounterWithPOAG + such that QICoreCommon."ToInterval" ( OpticDiscExamPerformed.effective ) during EncounterWithPOAG.period + where OpticDiscExamPerformed.value is not null + +define "Numerator": + exists "Cup to Disc Ratio Performed with Result" + and exists "Optic Disc Exam Performed with Result" + +define "Medical Reason for Not Performing Cup to Disc Ratio": + ["ObservationNotDone": "Cup to Disc Ratio"] CupToDiscExamNotPerformed + with "Primary Open Angle Glaucoma Encounter" EncounterWithPOAG + such that CupToDiscExamNotPerformed.issued during EncounterWithPOAG.period + where CupToDiscExamNotPerformed.notDoneReason in "Medical Reason" + +define "Medical Reason for Not Performing Optic Disc Exam": + ["ObservationNotDone": "Optic Disc Exam for Structural Abnormalities"] OpticDiscExamNotPerformed + with "Primary Open Angle Glaucoma Encounter" EncounterWithPOAG + such that OpticDiscExamNotPerformed.issued during EncounterWithPOAG.period + where OpticDiscExamNotPerformed.notDoneReason in "Medical Reason" \ No newline at end of file diff --git a/Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS143/cql/QICoreCommon-1.2.000.cql b/Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS143/cql/QICoreCommon-1.2.000.cql new file mode 100644 index 000000000..c65f36ae4 --- /dev/null +++ b/Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS143/cql/QICoreCommon-1.2.000.cql @@ -0,0 +1,370 @@ +library QICoreCommon version '1.2.000' + +using QICore version '4.1.1' + +include FHIRHelpers version '4.1.000' + +codesystem "LOINC": 'http://loinc.org' +codesystem "SNOMEDCT": 'http://snomed.info/sct' +codesystem "ICD10CM": 'http://hl7.org/fhir/sid/icd-10-cm' +codesystem "RoleCode": 'http://terminology.hl7.org/CodeSystem/v3-RoleCode' +codesystem "Diagnosis Role": 'http://terminology.hl7.org/CodeSystem/diagnosis-role' +codesystem "RequestIntent": 'http://terminology.hl7.org/CodeSystem/request-intent' +codesystem "MedicationRequestCategory": 'http://terminology.hl7.org/CodeSystem/medicationrequest-category' +codesystem "ConditionClinicalStatusCodes": 'http://terminology.hl7.org/CodeSystem/condition-clinical' +codesystem "ConditionVerificationStatusCodes": 'http://terminology.hl7.org/CodeSystem/condition-ver-status' +codesystem "AllergyIntoleranceClinicalStatusCodes": 'http://terminology.hl7.org/CodeSystem/allergyintolerance-clinical' +codesystem "AllergyIntoleranceVerificationStatusCodes": 'http://terminology.hl7.org/CodeSystem/allergyintolerance-verification' +codesystem "ConditionCategoryCodes": 'http://terminology.hl7.org/CodeSystem/condition-category' +codesystem "ObservationCategoryCodes": 'http://terminology.hl7.org/CodeSystem/observation-category' + +//Currently unresolveable in VSAC +//valueset "Active Condition": 'http://fhir.org/guides/cqf/common/ValueSet/active-condition' +//valueset "Inactive Condition": 'http://fhir.org/guides/cqf/common/ValueSet/inactive-condition' + +code "Birthdate": '21112-8' from "LOINC" display 'Birth date' +code "Dead": '419099009' from "SNOMEDCT" display 'Dead' +code "ER": 'ER' from "RoleCode" display 'Emergency room' +code "ICU": 'ICU' from "RoleCode" display 'Intensive care unit' +code "Billing": 'billing' from "Diagnosis Role" display 'Billing' + +// Condition Clinical Status Codes - Consider value sets for these +code "active": 'active' from "ConditionClinicalStatusCodes" +code "recurrence": 'recurrence' from "ConditionClinicalStatusCodes" +code "relapse": 'relapse' from "ConditionClinicalStatusCodes" +code "inactive": 'inactive' from "ConditionClinicalStatusCodes" +code "remission": 'remission' from "ConditionClinicalStatusCodes" +code "resolved": 'resolved' from "ConditionClinicalStatusCodes" + +// Condition Verification Status Codes - Consider value sets for these +code "unconfirmed": 'unconfirmed' from ConditionVerificationStatusCodes +code "provisional": 'provisional' from ConditionVerificationStatusCodes +code "differential": 'differential' from ConditionVerificationStatusCodes +code "confirmed": 'confirmed' from ConditionVerificationStatusCodes +code "refuted": 'refuted' from ConditionVerificationStatusCodes +code "entered-in-error": 'entered-in-error' from ConditionVerificationStatusCodes + +code "allergy-active": 'active' from "AllergyIntoleranceClinicalStatusCodes" +code "allergy-inactive": 'inactive' from "AllergyIntoleranceClinicalStatusCodes" +code "allergy-resolved": 'resolved' from "AllergyIntoleranceClinicalStatusCodes" + +// Allergy/Intolerance Verification Status Codes - Consider value sets for these +code "allergy-unconfirmed": 'unconfirmed' from AllergyIntoleranceVerificationStatusCodes +code "allergy-confirmed": 'confirmed' from AllergyIntoleranceVerificationStatusCodes +code "allergy-refuted": 'refuted' from AllergyIntoleranceVerificationStatusCodes + +// MedicationRequest Category Codes +code "Community": 'community' from "MedicationRequestCategory" display 'Community' +code "Discharge": 'discharge' from "MedicationRequestCategory" display 'Discharge' + +// Diagnosis Role Codes +code "AD": 'AD' from "Diagnosis Role" display 'Admission diagnosis' +code "DD": 'DD' from "Diagnosis Role" display 'Discharge diagnosis' +code "CC": 'CC' from "Diagnosis Role" display 'Chief complaint' +code "CM": 'CM' from "Diagnosis Role" display 'Comorbidity diagnosis' +code "pre-op": 'pre-op' from "Diagnosis Role" display 'pre-op diagnosis' +code "post-op": 'post-op' from "Diagnosis Role" display 'post-op diagnosis' +code "billing": 'billing' from "Diagnosis Role" display 'billing diagnosis' + +// Observation Category Codes +code "social-history": 'social-history' from "ObservationCategoryCodes" display 'Social History' +code "vital-signs": 'vital-signs' from "ObservationCategoryCodes" display 'Vital Signs' +code "imaging": 'imaging' from "ObservationCategoryCodes" display 'Imaging' +code "laboratory": 'laboratory' from "ObservationCategoryCodes" display 'Laboratory' +code "procedure": 'procedure' from "ObservationCategoryCodes" display 'Procedure' +code "survey": 'survey' from "ObservationCategoryCodes" display 'Survey' +code "exam": 'exam' from "ObservationCategoryCodes" display 'Exam' +code "therapy": 'therapy' from "ObservationCategoryCodes" display 'Therapy' +code "activity": 'activity' from "ObservationCategoryCodes" display 'Activity' + +// Condition Category Codes +code "problem-list-item": 'problem-list-item' from "ConditionCategoryCodes" display 'Problem List Item' +code "encounter-diagnosis": 'encounter-diagnosis' from "ConditionCategoryCodes" display 'Encounter Diagnosis' + +context Patient + +/* +@description: Normalizes a value that is a choice of timing-valued types to an equivalent interval +@comment: Normalizes a choice type of DateTime, Quanitty, Interval, or Interval types +to an equivalent interval. This selection of choice types is a superset of the majority of choice types that are used as possible +representations for timing-valued elements in QICore, allowing this function to be used across any resource. +The input can be provided as a DateTime, Quantity, Interval or Interval. +The intent of this function is to provide a clear and concise mechanism to treat single +elements that have multiple possible representations as intervals so that logic doesn't have to account +for the variability. More complex calculations (such as medication request period or dispense period +calculation) need specific guidance and consideration. That guidance may make use of this function, but +the focus of this function is on single element calculations where the semantics are unambiguous. +If the input is a DateTime, the result a DateTime Interval beginning and ending on that DateTime. +If the input is a Quantity, the quantity is expected to be a calendar-duration interpreted as an Age, +and the result is a DateTime Interval beginning on the Date the patient turned that age and ending immediately before one year later. +If the input is a DateTime Interval, the result is the input. +If the input is a Quantity Interval, the quantities are expected to be calendar-durations interpreted as an Age, and the result +is a DateTime Interval beginning on the date the patient turned the age given as the start of the quantity interval, and ending +immediately before one year later than the date the patient turned the age given as the end of the quantity interval. +Any other input will reslt in a null DateTime Interval +*/ +define function ToInterval(choice Choice, Interval>): + case + when choice is DateTime then + Interval[choice as DateTime, choice as DateTime] + when choice is Interval then + choice as Interval + when choice is Quantity then + Interval[Patient.birthDate + (choice as Quantity), + Patient.birthDate + (choice as Quantity) + 1 year) + when choice is Interval then + Interval[Patient.birthDate + (choice.low as Quantity), + Patient.birthDate + (choice.high as Quantity) + 1 year) + else + null as Interval + end + +/* +@description: Normalizes a value that is a choice of timing-valued types to an equivalent interval +@comment: Normalizes a choice type of DateTime, Quanitty, Interval, or Interval types +to an equivalent interval. This selection of choice types is a superset of the majority of choice types that are used as possible +representations for timing-valued elements in QICore, allowing this function to be used across any resource. +The input can be provided as a DateTime, Quantity, Interval or Interval. +The intent of this function is to provide a clear and concise mechanism to treat single +elements that have multiple possible representations as intervals so that logic doesn't have to account +for the variability. More complex calculations (such as medication request period or dispense period +calculation) need specific guidance and consideration. That guidance may make use of this function, but +the focus of this function is on single element calculations where the semantics are unambiguous. +If the input is a DateTime, the result a DateTime Interval beginning and ending on that DateTime. +If the input is a Quantity, the quantity is expected to be a calendar-duration interpreted as an Age, +and the result is a DateTime Interval beginning on the Date the patient turned that age and ending immediately before one year later. +If the input is a DateTime Interval, the result is the input. +If the input is a Quantity Interval, the quantities are expected to be calendar-durations interpreted as an Age, and the result +is a DateTime Interval beginning on the date the patient turned the age given as the start of the quantity interval, and ending +immediately before one year later than the date the patient turned the age given as the end of the quantity interval. +Any other input will reslt in a null DateTime Interval +*/ +define fluent function toInterval(choice Choice, Interval>): + case + when choice is DateTime then + Interval[choice as DateTime, choice as DateTime] + when choice is Interval then + choice as Interval + when choice is Quantity then + Interval[Patient.birthDate + (choice as Quantity), + Patient.birthDate + (choice as Quantity) + 1 year) + when choice is Interval then + Interval[Patient.birthDate + (choice.low as Quantity), + Patient.birthDate + (choice.high as Quantity) + 1 year) + else + null as Interval + end + +/* +@description: Returns an interval representing the normalized abatement of a given Condition. +@comment: If the abatement element of the Condition is represented as a DateTime, the result +is an interval beginning and ending on that DateTime. +If the abatement is represented as a Quantity, the quantity is expected to be a calendar-duration and is interpreted as the age of the patient. The +result is an interval from the date the patient turned that age to immediately before one year later. +If the abatement is represented as a Quantity Interval, the quantities are expected to be calendar-durations and are interpreted as an age range during +which the abatement occurred. The result is an interval from the date the patient turned the starting age of the quantity interval, and ending immediately +before one year later than the date the patient turned the ending age of the quantity interval. +*/ +define function ToAbatementInterval(condition Condition): + if condition.abatement is DateTime then + Interval[condition.abatement as DateTime, condition.abatement as DateTime] + else if condition.abatement is Quantity then + Interval[Patient.birthDate + (condition.abatement as Quantity), + Patient.birthDate + (condition.abatement as Quantity) + 1 year) + else if condition.abatement is Interval then + Interval[Patient.birthDate + (condition.abatement.low as Quantity), + Patient.birthDate + (condition.abatement.high as Quantity) + 1 year) + else if condition.abatement is Interval then + Interval[condition.abatement.low, condition.abatement.high) + else null as Interval + +/* +@description: Returns an interval representing the normalized abatement of a given Condition. +@comment: If the abatement element of the Condition is represented as a DateTime, the result +is an interval beginning and ending on that DateTime. +If the abatement is represented as a Quantity, the quantity is expected to be a calendar-duration and is interpreted as the age of the patient. The +result is an interval from the date the patient turned that age to immediately before one year later. +If the abatement is represented as a Quantity Interval, the quantities are expected to be calendar-durations and are interpreted as an age range during +which the abatement occurred. The result is an interval from the date the patient turned the starting age of the quantity interval, and ending immediately +before one year later than the date the patient turned the ending age of the quantity interval. +*/ +define fluent function toAbatementInterval(condition Condition): + if condition.abatement is DateTime then + Interval[condition.abatement as DateTime, condition.abatement as DateTime] + else if condition.abatement is Quantity then + Interval[Patient.birthDate + (condition.abatement as Quantity), + Patient.birthDate + (condition.abatement as Quantity) + 1 year) + else if condition.abatement is Interval then + Interval[Patient.birthDate + (condition.abatement.low as Quantity), + Patient.birthDate + (condition.abatement.high as Quantity) + 1 year) + else if condition.abatement is Interval then + Interval[condition.abatement.low, condition.abatement.high) + else null as Interval + +/* +@description: Returns an interval representing the normalized prevalence period of a given Condition. +@comment: Uses the ToInterval and ToAbatementInterval functions to determine the widest potential interval from +onset to abatement as specified in the given Condition. If the condition is active, the resulting interval will have +a closed ending boundary. If the condition is not active, the resulting interval will have an open ending boundary. +*/ +define function ToPrevalenceInterval(condition Condition): +if condition.clinicalStatus ~ "active" + or condition.clinicalStatus ~ "recurrence" + or condition.clinicalStatus ~ "relapse" then + Interval[start of ToInterval(condition.onset), end of ToAbatementInterval(condition)] +else + Interval[start of ToInterval(condition.onset), end of ToAbatementInterval(condition)) + +/* +@description: Returns an interval representing the normalized prevalence period of a given Condition. +@comment: Uses the ToInterval and ToAbatementInterval functions to determine the widest potential interval from +onset to abatement as specified in the given Condition. If the condition is active, the resulting interval will have +a closed ending boundary. If the condition is not active, the resulting interval will have an open ending boundary. +*/ +define fluent function toPrevalenceInterval(condition Condition): +if condition.clinicalStatus ~ "active" + or condition.clinicalStatus ~ "recurrence" + or condition.clinicalStatus ~ "relapse" then + Interval[start of ToInterval(condition.onset), end of ToAbatementInterval(condition)] +else + Interval[start of ToInterval(condition.onset), end of ToAbatementInterval(condition)) + +/* +@description: Returns the tail of the given uri (i.e. everything after the last slash in the URI). +@comment: This function can be used to determine the logical id of a given resource. It can be used in +a single-server environment to trace references. However, this function does not attempt to resolve +or distinguish the base of the given url, and so cannot be used safely in multi-server environments. +*/ +define function GetId(uri String ): + Last(Split(uri, '/')) + +/* +@description: Returns the tail of the given uri (i.e. everything after the last slash in the URI). +@comment: This function can be used to determine the logical id of a given resource. It can be used in +a single-server environment to trace references. However, this function does not attempt to resolve +or distinguish the base of the given url, and so cannot be used safely in multi-server environments. +*/ +define fluent function getId(uri String): + Last(Split(uri, '/')) + +/* +@description: Given an interval, return true if the interval has a starting boundary specified +(i.e. the start of the interval is not null and not the minimum DateTime value) +*/ +define function "HasStart"(period Interval ): + not ( start of period is null + or start of period = minimum DateTime + ) + +/* +@description: Given an interval, return true if the interval has a starting boundary specified +(i.e. the start of the interval is not null and not the minimum DateTime value) +*/ +define fluent function hasStart(period Interval ): + not ( start of period is null + or start of period = minimum DateTime + ) + +/* +@description: Given an interval, returns true if the interval has an ending boundary specified +(i.e. the end of the interval is not null and not the maximum DateTime value) +*/ +define function "HasEnd"(period Interval ): + not ( + end of period is null + or end of period = maximum DateTime + ) + +/* +@description: Given an interval, returns true if the interval has an ending boundary specified +(i.e. the end of the interval is not null and not the maximum DateTime value) +*/ +define fluent function hasEnd(period Interval ): + not ( + end of period is null + or end of period = maximum DateTime + ) + +/* +@description: Given an interval, returns the ending point if the interval has an ending boundary specified, +otherwise, returns the starting point +*/ +define function "Latest"(choice Choice, Interval> ): + (choice.toInterval()) period + return + if (HasEnd(period)) then end of period + else start of period + +/* +@description: Given an interval, returns the ending point if the interval has an ending boundary specified, +otherwise, returns the starting point +*/ +define fluent function latest(choice Choice, Interval> ): + (choice.toInterval()) period + return + if (HasEnd(period)) then end of period + else start of period + +/* +@description: Given an interval, return the starting point if the interval has a starting boundary specified, +otherwise, return the ending point +*/ +define function "Earliest"(choice Choice, Interval> ): + (choice.toInterval()) period + return + if (HasStart(period)) then start of period + else end of period + +/* +@description: Given an interval, return the starting point if the interval has a starting boundary specified, +otherwise, return the ending point +*/ +define fluent function earliest(choice Choice, Interval> ): + (choice.toInterval()) period + return + if (HasStart(period)) then start of period + else end of period + +/* +@description: Creates a list of integers from 1 to how many days are in the interval. Note, this wont create an index for +the final day if it is less than 24 hours. This also includes the first 24 hour period. +*/ +define function "Interval To Day Numbers"(Period Interval): + ( expand { Interval[1, duration in days between start of Period and end of Period]} ) DayNumber + return end of DayNumber + +/* +@description: Creates a list of integers from 1 to how many days are in the interval. Note, this wont create an index for +the final day if it is less than 24 hours. This also includes the first 24 hour period. +*/ +define fluent function toDayNumbers(Period Interval): + ( expand { Interval[1, duration in days between start of Period and end of Period]} ) DayNumber + return end of DayNumber + +/* +@description: Creates a list of 24 hour long intervals in an interval paired with the index (1 indexed) to which 24 hour interval it is. +Note that the result will include intervals that are closed at the beginning and open at the end +*/ +define function "Days In Period"(Period Interval): + ( "Interval To Day Numbers"(Period)) DayIndex + let startPeriod: start of Period + (24 hours * (DayIndex - 1)), + endPeriod: if (hours between startPeriod and end of Period < 24) then startPeriod + else start of Period + (24 hours * DayIndex) + return Tuple { + dayIndex: DayIndex, + dayPeriod: Interval[startPeriod, endPeriod) + } + +/* +@description: Creates a list of 24 hour long intervals in an interval paired with the index (1 indexed) to which 24 hour interval it is. +Note that the result will include intervals that are closed at the beginning and open at the end +*/ +define fluent function daysInPeriod(Period Interval): + ( "Interval To Day Numbers"(Period)) DayIndex + let startPeriod: start of Period + (24 hours * (DayIndex - 1)), + endPeriod: if (hours between startPeriod and end of Period < 24) then startPeriod + else start of Period + (24 hours * DayIndex) + return Tuple { + dayIndex: DayIndex, + dayPeriod: Interval[startPeriod, endPeriod) + } \ No newline at end of file diff --git a/Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS143/cql/SupplementalDataElements-3.1.000.cql b/Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS143/cql/SupplementalDataElements-3.1.000.cql new file mode 100644 index 000000000..04be4f8a1 --- /dev/null +++ b/Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS143/cql/SupplementalDataElements-3.1.000.cql @@ -0,0 +1,49 @@ +/* +@update: BTR 2020-03-31 -> +Incremented version to 2.0.0 + +@update: BTR 2022-05-26 -> +Updated FHIR version to 4.0.1 +Updated FHIRHelpers version to 4.0.002 +Updated for AU 2022 Content +*/ +library SupplementalDataElements version '3.1.000' + +using QICore version '4.1.1' + +include FHIRHelpers version '4.1.000' called FHIRHelpers + +valueset "Ethnicity": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.114222.4.11.837' +valueset "ONC Administrative Sex": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113762.1.4.1' +valueset "Payer": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.114222.4.11.3591' +valueset "Race": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.114222.4.11.836' + +context Patient + +define "SDE Ethnicity": + Patient.ethnicity E + return Tuple { + codes: { E.ombCategory } union E.detailed, + display: E.text + } + +define "SDE Payer": + [Coverage: type in "Payer"] Payer + return { + code: Payer.type, + period: Payer.period + } + +define "SDE Race": + Patient.race R + return Tuple { + codes: R.ombCategory union R.detailed, + display: R.text + } + +define "SDE Sex": + case + when Patient.gender = 'male' then Code { code: 'M', system: 'http://hl7.org/fhir/v3/AdministrativeGender', display: 'Male' } + when Patient.gender = 'female' then Code { code: 'F', system: 'http://hl7.org/fhir/v3/AdministrativeGender', display: 'Female' } + else null + end \ No newline at end of file diff --git a/Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS143/resources/Library-EffectiveDataRequirements.json b/Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS143/resources/Library-EffectiveDataRequirements.json new file mode 100644 index 000000000..109ba8aef --- /dev/null +++ b/Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS143/resources/Library-EffectiveDataRequirements.json @@ -0,0 +1,247 @@ +{ + "resourceType": "Library", + "extension": [ { + "url": "http://hl7.org/fhir/us/cqfmeasures/StructureDefinition/cqfm-directReferenceCode", + "valueCoding": { + "system": "http://terminology.hl7.org/CodeSystem/v3-ActCode", + "code": "VR", + "display": "virtual" + } + }, { + "url": "http://hl7.org/fhir/us/cqfmeasures/StructureDefinition/cqfm-directReferenceCode", + "valueCoding": { + "system": "http://terminology.hl7.org/CodeSystem/v3-ActCode", + "code": "AMB", + "display": "Ambulatory" + } + } ], + "status": "active", + "type": { + "coding": [ { + "system": "http://terminology.hl7.org/CodeSystem/library-type", + "code": "module-definition" + } ] + }, + "relatedArtifact": [ { + "type": "depends-on", + "display": "QICore model information", + "resource": "http://hl7.org/fhir/Library/QICore-ModelInfo" + }, { + "type": "depends-on", + "display": "Library FHIRHelpers", + "resource": "Library/FHIRHelpers|4.1.000" + }, { + "type": "depends-on", + "display": "Library SDE", + "resource": "Library/SupplementalDataElements|3.1.000" + }, { + "type": "depends-on", + "display": "Library CQMCommon", + "resource": "Library/CQMCommon|1.0.000" + }, { + "type": "depends-on", + "display": "Library FHIRCommon", + "resource": "Library/FHIRCommon|4.1.000" + }, { + "type": "depends-on", + "display": "Library QICoreCommon", + "resource": "Library/QICoreCommon|1.2.000" + }, { + "type": "depends-on", + "display": "Code system ActCode", + "resource": "http://terminology.hl7.org/CodeSystem/v3-ActCode" + }, { + "type": "depends-on", + "display": "Value set Care Services in Long-Term Residential Facility", + "resource": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.464.1003.101.12.1014" + }, { + "type": "depends-on", + "display": "Value set Cup to Disc Ratio", + "resource": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1333" + }, { + "type": "depends-on", + "display": "Value set Face-to-Face Interaction", + "resource": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.464.1003.101.12.1048" + }, { + "type": "depends-on", + "display": "Value set Medical Reason", + "resource": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1007" + }, { + "type": "depends-on", + "display": "Value set Nursing Facility Visit", + "resource": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.464.1003.101.12.1012" + }, { + "type": "depends-on", + "display": "Value set Office Visit", + "resource": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.464.1003.101.12.1001" + }, { + "type": "depends-on", + "display": "Value set Ophthalmological Services", + "resource": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1285" + }, { + "type": "depends-on", + "display": "Value set Optic Disc Exam for Structural Abnormalities", + "resource": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1334" + }, { + "type": "depends-on", + "display": "Value set Outpatient Consultation", + "resource": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.464.1003.101.12.1008" + }, { + "type": "depends-on", + "display": "Value set Primary Open-Angle Glaucoma", + "resource": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.326" + } ], + "parameter": [ { + "name": "Measurement Period", + "use": "in", + "min": 0, + "max": "1", + "type": "Period" + }, { + "name": "Patient", + "use": "out", + "min": 0, + "max": "1", + "type": "Resource" + }, { + "name": "SDE Ethnicity", + "use": "out", + "min": 0, + "max": "1", + "type": "Resource" + }, { + "name": "SDE Payer", + "use": "out", + "min": 0, + "max": "*", + "type": "Resource" + }, { + "name": "SDE Race", + "use": "out", + "min": 0, + "max": "1", + "type": "Resource" + }, { + "name": "SDE Sex", + "use": "out", + "min": 0, + "max": "1", + "type": "Coding" + }, { + "name": "Qualifying Encounter During Measurement Period", + "use": "out", + "min": 0, + "max": "*", + "type": "Resource" + }, { + "name": "Primary Open Angle Glaucoma Encounter", + "use": "out", + "min": 0, + "max": "*", + "type": "Resource" + }, { + "name": "Initial Population", + "use": "out", + "min": 0, + "max": "1", + "type": "boolean" + }, { + "name": "Denominator", + "use": "out", + "min": 0, + "max": "1", + "type": "boolean" + }, { + "name": "Medical Reason for Not Performing Cup to Disc Ratio", + "use": "out", + "min": 0, + "max": "*", + "type": "Resource" + }, { + "name": "Medical Reason for Not Performing Optic Disc Exam", + "use": "out", + "min": 0, + "max": "*", + "type": "Resource" + }, { + "name": "Denominator Exceptions", + "use": "out", + "min": 0, + "max": "1", + "type": "boolean" + }, { + "name": "Cup to Disc Ratio Performed with Result", + "use": "out", + "min": 0, + "max": "*", + "type": "Resource" + }, { + "name": "Optic Disc Exam Performed with Result", + "use": "out", + "min": 0, + "max": "*", + "type": "Resource" + }, { + "name": "Numerator", + "use": "out", + "min": 0, + "max": "1", + "type": "boolean" + } ], + "dataRequirement": [ { + "type": "Patient", + "profile": [ "http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-patient" ] + }, { + "type": "Patient", + "profile": [ "http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-patient" ], + "mustSupport": [ "url", "extension" ], + "codeFilter": [ { + "path": "url", + "code": [ { + "code": "http://hl7.org/fhir/us/core/StructureDefinition/us-core-ethnicity" + } ] + } ] + }, { + "type": "Patient", + "profile": [ "http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-patient" ], + "mustSupport": [ "url", "extension" ], + "codeFilter": [ { + "path": "url", + "code": [ { + "code": "http://hl7.org/fhir/us/core/StructureDefinition/us-core-race" + } ] + } ] + }, { + "type": "Coverage", + "profile": [ "http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-coverage" ], + "mustSupport": [ "type", "period" ], + "codeFilter": [ { + "path": "type", + "valueSet": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.114222.4.11.3591" + } ] + }, { + "type": "Condition", + "profile": [ "http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-condition" ], + "mustSupport": [ "code" ], + "codeFilter": [ { + "path": "code", + "valueSet": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.326" + } ] + }, { + "type": "Observation", + "profile": [ "http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-observation" ], + "mustSupport": [ "code", "effective", "value" ], + "codeFilter": [ { + "path": "code", + "valueSet": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1333" + } ] + }, { + "type": "Observation", + "profile": [ "http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-observation" ], + "mustSupport": [ "code", "effective", "value" ], + "codeFilter": [ { + "path": "code", + "valueSet": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1334" + } ] + } ] +} diff --git a/Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS149/cql/CQMCommon-1.0.000.cql b/Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS149/cql/CQMCommon-1.0.000.cql new file mode 100644 index 000000000..218261f21 --- /dev/null +++ b/Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS149/cql/CQMCommon-1.0.000.cql @@ -0,0 +1,383 @@ +library CQMCommon version '1.0.000' + +using QICore version '4.1.1' + +include FHIRHelpers version '4.1.000' called FHIRHelpers +include QICoreCommon version '1.2.000' called QICoreCommon + +valueset "Emergency Department Visit": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.117.1.7.1.292' +valueset "Encounter Inpatient": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.666.5.307' +valueset "Intensive Care Unit": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113762.1.4.1029.206' +valueset "Observation Services": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113762.1.4.1111.143' +valueset "Outpatient Surgery Service": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113762.1.4.1110.38' +valueset "Present on Admission or Clinically Undetermined": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113762.1.4.1147.197' + +parameter "Measurement Period" Interval + default Interval[@2022-01-01T00:00:00.0, @2023-01-01T00:00:00.0) + +context Patient + +define "Inpatient Encounter": + [Encounter: "Encounter Inpatient"] EncounterInpatient + where EncounterInpatient.status = 'finished' + and "LengthInDays"(EncounterInpatient.period) <= 120 + and EncounterInpatient.period ends during day of "Measurement Period" + +/* +@description: Returns an interval of date values extracted from the input interval of date-time values +@comment: This function returns an interval constructed using the `date from` extractor on the start +and end values of the input date-time interval. Note that using a precision specifier such as `day of` +as part of a timing phrase is preferred to communicate intent to perform day-level comparison, as well +as for general readability. +*/ +define function "ToDateInterval"(period Interval): + Interval[date from start of period, date from end of period] + +/* +Calculates the difference in calendar days between the start and end of the given interval. +*/ +define function "LengthInDays"(Value Interval ): + difference in days between start of Value and end of Value + +/* +Calculates the difference in calendar days between the start and end of the given interval. +*/ +define fluent function lengthInDays(Value Interval ): + difference in days between start of Value and end of Value + +/* +Returns the most recent emergency department visit, if any, that occurs 1 hour or less prior to the given encounter. +*/ +define function "ED Visit"(TheEncounter Encounter ): + Last( + [Encounter: "Emergency Department Visit"] EDVisit + where EDVisit.status = 'finished' + and EDVisit.period ends 1 hour or less on or before start of TheEncounter.period + sort by end of period + ) + +/* +Returns the most recent emergency department visit, if any, that occurs 1 hour or less prior to the given encounter. +*/ +define fluent function edVisit(TheEncounter Encounter ): + Last( + [Encounter: "Emergency Department Visit"] EDVisit + where EDVisit.status = 'finished' + and EDVisit.period ends 1 hour or less on or before start of TheEncounter.period + sort by end of period + ) + +/* +Hospitalization returns the total interval for admission to discharge for the given encounter, or for the admission of any immediately prior emergency department visit to the discharge of the given encounter. +*/ +define function "Hospitalization"(TheEncounter Encounter ): + ( "ED Visit"(TheEncounter) ) X + return + if X is null then TheEncounter.period + else Interval[start of X.period, end of TheEncounter.period) + +/* +Hospitalization returns the total interval for admission to discharge for the given encounter, or for the admission of any immediately prior emergency department visit to the discharge of the given encounter. +*/ +define fluent function hospitalization(TheEncounter Encounter ): + ( "ED Visit"(TheEncounter) ) X + return + if X is null then TheEncounter.period + else Interval[start of X.period, end of TheEncounter.period] + +/* +Returns list of all locations within an encounter, including locations for immediately prior ED visit. +*/ +define function "Hospitalization Locations"(TheEncounter Encounter ): + ( "ED Visit"(TheEncounter) ) EDEncounter + return + if EDEncounter is null then TheEncounter.location + else flatten { EDEncounter.location, TheEncounter.location } + +/* +Returns list of all locations within an encounter, including locations for immediately prior ED visit. +*/ +define fluent function hospitalizationLocations(TheEncounter Encounter ): + ( "ED Visit"(TheEncounter) ) EDEncounter + return + if EDEncounter is null then TheEncounter.location + else flatten { EDEncounter.location, TheEncounter.location } + +/* +Returns the length of stay in days (i.e. the number of days between admission and discharge) for the given encounter, or from the admission of any immediately prior emergency department visit to the discharge of the encounter +*/ +define function "Hospitalization Length of Stay"(TheEncounter Encounter ): + LengthInDays("Hospitalization"(TheEncounter)) + +/* +Returns the length of stay in days (i.e. the number of days between admission and discharge) for the given encounter, or from the admission of any immediately prior emergency department visit to the discharge of the encounter +*/ +define fluent function hospitalizationLengthOfStay(TheEncounter Encounter ): + LengthInDays("Hospitalization"(TheEncounter)) + +/* +Returns admission time for an encounter or for immediately prior emergency department visit. +*/ +define function "Hospital Admission Time"(TheEncounter Encounter ): + start of "Hospitalization"(TheEncounter) + +/* +Returns admission time for an encounter or for immediately prior emergency department visit. +*/ +define fluent function hospitalAdmissionTime(TheEncounter Encounter ): + start of "Hospitalization"(TheEncounter) + +/* +Hospital Discharge Time returns the discharge time for an encounter +*/ +define function "Hospital Discharge Time"(TheEncounter Encounter ): + end of TheEncounter.period + +/* +Hospital Discharge Time returns the discharge time for an encounter +*/ +define fluent function hospitalDischargeTime(TheEncounter Encounter ): + end of TheEncounter.period + +/* +Returns earliest arrival time for an encounter including any prior ED visit. +*/ +define function "Hospital Arrival Time"(TheEncounter Encounter ): + start of First( + ( "Hospitalization Locations"(TheEncounter) ) HospitalLocation + sort by start of period + ).period + +/* +Returns earliest arrival time for an encounter including any prior ED visit. +*/ +define fluent function hospitalArrivalTime(TheEncounter Encounter ): + start of First( + ( "Hospitalization Locations"(TheEncounter) ) HospitalLocation + sort by start of period + ).period + +/* +Returns the latest departure time for encounter including any prior ED visit. +*/ +define function "Hospital Departure Time"(TheEncounter Encounter): + end of Last( + ( "Hospitalization Locations"(TheEncounter) ) HospitalLocation + sort by start of period + ).period + +/* +Returns the latest departure time for encounter including any prior ED visit. +*/ +define fluent function hospitalDepartureTime(TheEncounter Encounter): + end of Last( + ( "Hospitalization Locations"(TheEncounter) ) HospitalLocation + sort by start of period + ).period + +define function "Emergency Department Arrival Time"(TheEncounter Encounter): + start of ( + singleton from ( + ( "Hospitalization Locations"(TheEncounter) ) HospitalLocation + where GetLocation(HospitalLocation.location).type in "Emergency Department Visit" + ) + ).period + +define fluent function emergencyDepartmentArrivalTime(TheEncounter Encounter): + start of ( + singleton from ( + ( "Hospitalization Locations"(TheEncounter) ) HospitalLocation + where GetLocation(HospitalLocation.location).type in "Emergency Department Visit" + ) + ).period + +/* +Hospitalization with Observation and Outpatient Surgery Service returns the total interval from the start of any immediately prior emergency department visit, outpatient surgery visit or observation visit to the discharge of the given encounter. +*/ +define function "HospitalizationWithObservationAndOutpatientSurgeryService"(TheEncounter "Encounter" ): + TheEncounter Visit + let ObsVisit: Last([Encounter: "Observation Services"] LastObs + where LastObs.status = 'finished' + and LastObs.period ends 1 hour or less on or before start of Visit.period + sort by end of period + ), + VisitStart: Coalesce(start of ObsVisit.period, start of Visit.period), + EDVisit: Last([Encounter: "Emergency Department Visit"] LastED + where LastED.status = 'finished' + and LastED.period ends 1 hour or less on or before VisitStart + sort by end of period + ), + VisitStartWithED: Coalesce(start of EDVisit.period, VisitStart), + OutpatientSurgeryVisit: Last([Encounter: "Outpatient Surgery Service"] LastSurgeryOP + where LastSurgeryOP.period ends 1 hour or less on or before VisitStartWithED + sort by end of period + ) + return Interval[Coalesce(start of OutpatientSurgeryVisit.period, VisitStartWithED), end of Visit.period] + +/* +Hospitalization with Observation and Outpatient Surgery Service returns the total interval from the start of any immediately prior emergency department visit, outpatient surgery visit or observation visit to the discharge of the given encounter. +*/ +define fluent function hospitalizationWithObservationAndOutpatientSurgeryService(TheEncounter "Encounter" ): + TheEncounter Visit + let ObsVisit: Last([Encounter: "Observation Services"] LastObs + where LastObs.status = 'finished' + and LastObs.period ends 1 hour or less on or before start of Visit.period + sort by end of period + ), + VisitStart: Coalesce(start of ObsVisit.period, start of Visit.period), + EDVisit: Last([Encounter: "Emergency Department Visit"] LastED + where LastED.status = 'finished' + and LastED.period ends 1 hour or less on or before VisitStart + sort by end of period + ), + VisitStartWithED: Coalesce(start of EDVisit.period, VisitStart), + OutpatientSurgeryVisit: Last([Encounter: "Outpatient Surgery Service"] LastSurgeryOP + where LastSurgeryOP.period ends 1 hour or less on or before VisitStartWithED + sort by end of period + ) + return Interval[Coalesce(start of OutpatientSurgeryVisit.period, VisitStartWithED), end of Visit.period] + +/* +Hospitalization with Observation returns the total interval from the start of any immediately prior emergency department visit through the observation visit to the discharge of the given encounter +*/ +define function "HospitalizationWithObservation"(TheEncounter Encounter ): + TheEncounter Visit + let ObsVisit: Last([Encounter: "Observation Services"] LastObs + where LastObs.status = 'finished' + and LastObs.period ends 1 hour or less on or before start of Visit.period + sort by end of period + ), + VisitStart: Coalesce(start of ObsVisit.period, start of Visit.period), + EDVisit: Last([Encounter: "Emergency Department Visit"] LastED + where LastED.status = 'finished' + and LastED.period ends 1 hour or less on or before VisitStart + sort by end of period + ) + return Interval[Coalesce(start of EDVisit.period, VisitStart), end of Visit.period] + +/* +Hospitalization with Observation returns the total interval from the start of any immediately prior emergency department visit through the observation visit to the discharge of the given encounter +*/ +define fluent function hospitalizationWithObservation(TheEncounter Encounter ): + TheEncounter Visit + let ObsVisit: Last([Encounter: "Observation Services"] LastObs + where LastObs.status = 'finished' + and LastObs.period ends 1 hour or less on or before start of Visit.period + sort by end of period + ), + VisitStart: Coalesce(start of ObsVisit.period, start of Visit.period), + EDVisit: Last([Encounter: "Emergency Department Visit"] LastED + where LastED.status = 'finished' + and LastED.period ends 1 hour or less on or before VisitStart + sort by end of period + ) + return Interval[Coalesce(start of EDVisit.period, VisitStart), end of Visit.period] + +/* +Hospitalization with Observation Length of Stay returns the length in days from the start of any immediately prior emergency department visit through the observation visit to the discharge of the given encounter +*/ +define function "HospitalizationWithObservationLengthofStay"(TheEncounter "Encounter" ): + "LengthInDays"("HospitalizationWithObservation"(TheEncounter)) + +/* +Hospitalization with Observation Length of Stay returns the length in days from the start of any immediately prior emergency department visit through the observation visit to the discharge of the given encounter +*/ +define fluent function hospitalizationWithObservationLengthofStay(TheEncounter "Encounter" ): + "LengthInDays"("HospitalizationWithObservation"(TheEncounter)) + +/* +First Inpatient Intensive Care Unit returns the first intensive care unit for the given encounter, without considering any immediately prior emergency department visit. +*/ +define function "FirstInpatientIntensiveCareUnit"(Encounter Encounter ): + First((Encounter.location)HospitalLocation + where GetLocation(HospitalLocation.location).type in "Intensive Care Unit" + and HospitalLocation.period during Encounter.period + sort by start of period + ) + +/* +First Inpatient Intensive Care Unit returns the first intensive care unit for the given encounter, without considering any immediately prior emergency department visit. +*/ +define fluent function firstInpatientIntensiveCareUnit(Encounter Encounter ): + First((Encounter.location)HospitalLocation + where GetLocation(HospitalLocation.location).type in "Intensive Care Unit" + and HospitalLocation.period during Encounter.period + sort by start of period + ) + +/* +Returns the Condition resources referenced by the diagnosis element of the Encounter +*/ +define function "EncounterDiagnosis"(Encounter Encounter ): + Encounter.diagnosis D + return singleton from ([Condition] C where C.id = D.condition.reference.getId()) + +/* +Returns the Condition resources referenced by the diagnosis element of the Encounter +*/ +define fluent function encounterDiagnosis(Encounter Encounter ): + Encounter.diagnosis D + return singleton from ([Condition] C where C.id = D.condition.reference.getId()) + +/* +Returns the Condition resource for the given reference +@deprecated +*/ +define function "GetCondition"(reference Reference): + singleton from ([Condition] C where C.id = reference.reference.getId()) + +/* +Returns the Condition resource for the given reference +*/ +define fluent function getCondition(reference Reference): + singleton from ([Condition] C where C.id = reference.reference.getId()) + +/* +Returns the condition that is specified as the principal diagnosis for the encounter +*/ +define function "PrincipalDiagnosis"(Encounter Encounter ): + singleton from ((Encounter.diagnosis D where D.rank = 1) PD + return singleton from ([Condition] C where C.id = PD.condition.reference.getId()) + ) + +/* +Returns the condition that is specified as the principal diagnosis for the encounter +*/ +define fluent function principalDiagnosis(Encounter Encounter ): + singleton from ((Encounter.diagnosis D where D.rank = 1) PD + return singleton from ([Condition] C where C.id = PD.condition.reference.getId()) + ) + +/* +Returns the Location resource specified by the given reference +*/ +define function "GetLocation"(reference Reference ): + singleton from ( + [Location] L where L.id = reference.reference.getId() + ) + +/* +Returns the Location resource specified by the given reference +*/ +define fluent function getLocation(reference Reference ): + singleton from ( + [Location] L where L.id = reference.reference.getId() + ) + +/* +Returns the medication code for the given MedicationRequest +*/ +define function "GetMedicationCode"(request MedicationRequest ): + if request.medication is Concept then + request.medication as Concept + else + (singleton from ([Medication] M where M.id = (request.medication as Reference).reference.getId())).code + +/* +Returns the medication code for the given MedicationRequest +*/ +define fluent function getMedicationCode(request MedicationRequest ): + if request.medication is Concept then + request.medication as Concept + else + (singleton from ([Medication] M where M.id = (request.medication as Reference).reference.getId())).code \ No newline at end of file diff --git a/Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS149/cql/DementiaCognitiveAssessmentFHIR-0.0.003.cql b/Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS149/cql/DementiaCognitiveAssessmentFHIR-0.0.003.cql new file mode 100644 index 000000000..5457fcc98 --- /dev/null +++ b/Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS149/cql/DementiaCognitiveAssessmentFHIR-0.0.003.cql @@ -0,0 +1,100 @@ +library DementiaCognitiveAssessmentFHIR version '0.0.003' + +using QICore version '4.1.1' + +/*This spec aligns with AU2022/PY2023 QDM version*/ + + +include FHIRHelpers version '4.1.000' called FHIRHelpers +include SupplementalDataElements version '3.1.000' called SDE +include CQMCommon version '1.0.000' called CQMCommon +include QICoreCommon version '1.2.000' called QICoreCommon + +codesystem "ActCode": 'http://terminology.hl7.org/CodeSystem/v3-ActCode' + +valueset "Behavioral/Neuropsych Assessment": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1023' +valueset "Care Services in Long Term Residential Facility": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.464.1003.101.12.1014' +valueset "Cognitive Assessment": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1332' +valueset "Dementia & Mental Degenerations": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1005' +valueset "Face-to-Face Interaction": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.464.1003.101.12.1048' +valueset "Home Healthcare Services": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.464.1003.101.12.1016' +valueset "Nursing Facility Visit": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.464.1003.101.12.1012' +valueset "Occupational Therapy Evaluation": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1011' +valueset "Office Visit": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.464.1003.101.12.1001' +valueset "Outpatient Consultation": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.464.1003.101.12.1008' +valueset "Patient Provider Interaction": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1012' +valueset "Patient Reason": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1008' +valueset "Psych Visit Diagnostic Evaluation": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1492' +valueset "Psych Visit Psychotherapy": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1496' +valueset "Standardized Tools for Assessment of Cognition": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1006' + +code "virtual": 'VR' from "ActCode" display 'virtual' +code "AMB": 'AMB' from "ActCode" display 'Ambulatory' + +parameter "Measurement Period" Interval + +context Patient + +define "SDE Ethnicity": + SDE."SDE Ethnicity" + +define "SDE Race": + SDE."SDE Race" + +define "SDE Sex": + SDE."SDE Sex" + +define "SDE Payer": + SDE."SDE Payer" + +define "Initial Population": + exists "Dementia Encounter During Measurement Period" + and ( Count("Qualifying Encounter During Measurement Period") >= 2 ) + +define "Denominator": + "Initial Population" + +define "Numerator": + exists "Assessment of Cognition Using Standardized Tools or Alternate Methods" + +define "Denominator Exceptions": + exists "Patient Reason for Not Performing Assessment of Cognition Using Standardized Tools or Alternate Methods" + +define "Encounter to Assess Cognition": + ["Encounter": "Psych Visit Diagnostic Evaluation"] + union ["Encounter": "Nursing Facility Visit"] + union ["Encounter": "Care Services in Long Term Residential Facility"] + union ["Encounter": "Home Healthcare Services"] + union ["Encounter": "Psych Visit Psychotherapy"] + union ["Encounter": "Behavioral/Neuropsych Assessment"] + union ["Encounter": "Occupational Therapy Evaluation"] + union ["Encounter": "Office Visit"] + union ["Encounter": "Outpatient Consultation"] + +define "Qualifying Encounter During Measurement Period": + ( "Encounter to Assess Cognition" + union ["Encounter": "Patient Provider Interaction"] ) ValidEncounter + where ValidEncounter.period during "Measurement Period" + and ValidEncounter.class ~ "AMB" + and ValidEncounter.status = 'finished' + +define "Patient Reason for Not Performing Assessment of Cognition Using Standardized Tools or Alternate Methods": + ( [ObservationNotDone: code in "Standardized Tools for Assessment of Cognition"] + union [ObservationNotDone: code in "Cognitive Assessment"] ) NoCognitiveAssessment + with "Dementia Encounter During Measurement Period" EncounterDementia + such that NoCognitiveAssessment.issued during EncounterDementia.period + where NoCognitiveAssessment.status = 'cancelled' + and NoCognitiveAssessment.notDoneReason in "Patient Reason" + +define "Assessment of Cognition Using Standardized Tools or Alternate Methods": + ( ["Observation": "Standardized Tools for Assessment of Cognition"] + union ["Observation": "Cognitive Assessment"] ) CognitiveAssessment + with "Dementia Encounter During Measurement Period" EncounterDementia + such that QICoreCommon."ToInterval" ( CognitiveAssessment.issued ) starts 12 months or less on or before day of end of EncounterDementia.period + where CognitiveAssessment.value is not null + +define "Dementia Encounter During Measurement Period": + "Encounter to Assess Cognition" EncounterAssessCognition + with [Condition: "Dementia & Mental Degenerations"] Dementia + such that CQMCommon."ToDateInterval" ( EncounterAssessCognition.period ) during "Measurement Period" + and QICoreCommon."ToPrevalenceInterval" ( Dementia ) overlaps EncounterAssessCognition.period \ No newline at end of file diff --git a/Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS149/cql/FHIRHelpers-4.1.000.cql b/Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS149/cql/FHIRHelpers-4.1.000.cql new file mode 100644 index 000000000..f3975bb89 --- /dev/null +++ b/Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS149/cql/FHIRHelpers-4.1.000.cql @@ -0,0 +1,512 @@ +library FHIRHelpers version '4.1.000' + +using FHIR version '4.0.1' + +define function ToInterval(period FHIR.Period): + if period is null then + null + else + if period."start" is null then + Interval(period."start".value, period."end".value] + else + Interval[period."start".value, period."end".value] + +define function ToCalendarUnit(unit System.String): + case unit + when 'ms' then 'millisecond' + when 's' then 'second' + when 'min' then 'minute' + when 'h' then 'hour' + when 'd' then 'day' + when 'wk' then 'week' + when 'mo' then 'month' + when 'a' then 'year' + else unit + end + +define function ToQuantity(quantity FHIR.Quantity): + case + when quantity is null then null + when quantity.value is null then null + when quantity.comparator is not null then + Message(null, true, 'FHIRHelpers.ToQuantity.ComparatorQuantityNotSupported', 'Error', 'FHIR Quantity value has a comparator and cannot be converted to a System.Quantity value.') + when quantity.system is null or quantity.system.value = 'http://unitsofmeasure.org' + or quantity.system.value = 'http://hl7.org/fhirpath/CodeSystem/calendar-units' then + System.Quantity { value: quantity.value.value, unit: ToCalendarUnit(Coalesce(quantity.code.value, quantity.unit.value, '1')) } + else + Message(null, true, 'FHIRHelpers.ToQuantity.InvalidFHIRQuantity', 'Error', 'Invalid FHIR Quantity code: ' & quantity.unit.value & ' (' & quantity.system.value & '|' & quantity.code.value & ')') + end + +define function ToQuantityIgnoringComparator(quantity FHIR.Quantity): + case + when quantity is null then null + when quantity.value is null then null + when quantity.system is null or quantity.system.value = 'http://unitsofmeasure.org' + or quantity.system.value = 'http://hl7.org/fhirpath/CodeSystem/calendar-units' then + System.Quantity { value: quantity.value.value, unit: ToCalendarUnit(Coalesce(quantity.code.value, quantity.unit.value, '1')) } + else + Message(null, true, 'FHIRHelpers.ToQuantity.InvalidFHIRQuantity', 'Error', 'Invalid FHIR Quantity code: ' & quantity.unit.value & ' (' & quantity.system.value & '|' & quantity.code.value & ')') + end + +define function ToInterval(quantity FHIR.Quantity): + if quantity is null then null else + case quantity.comparator.value + when '<' then + Interval[ + null, + ToQuantityIgnoringComparator(quantity) + ) + when '<=' then + Interval[ + null, + ToQuantityIgnoringComparator(quantity) + ] + when '>=' then + Interval[ + ToQuantityIgnoringComparator(quantity), + null + ] + when '>' then + Interval( + ToQuantityIgnoringComparator(quantity), + null + ] + else + Interval[ToQuantity(quantity), ToQuantity(quantity)] + end + +define function ToRatio(ratio FHIR.Ratio): + if ratio is null then + null + else + System.Ratio { numerator: ToQuantity(ratio.numerator), denominator: ToQuantity(ratio.denominator) } + +define function ToInterval(range FHIR.Range): + if range is null then + null + else + Interval[ToQuantity(range.low), ToQuantity(range.high)] + +define function ToCode(coding FHIR.Coding): + if coding is null then + null + else + System.Code { + code: coding.code.value, + system: coding.system.value, + version: coding.version.value, + display: coding.display.value + } + +define function ToConcept(concept FHIR.CodeableConcept): + if concept is null then + null + else + System.Concept { + codes: concept.coding C return ToCode(C), + display: concept.text.value + } + +define function ToValueSet(uri String): + if uri is null then + null + else + System.ValueSet { + id: uri + } + +define function reference(reference String): + if reference is null then + null + else + Reference { reference: string { value: reference } } + +define function ToValue(value Choice): + case + when value is base64Binary then (value as base64Binary).value + when value is boolean then (value as boolean).value + when value is canonical then (value as canonical).value + when value is code then (value as code).value + when value is date then (value as date).value + when value is dateTime then (value as dateTime).value + when value is decimal then (value as decimal).value + when value is id then (value as id).value + when value is instant then (value as instant).value + when value is integer then (value as integer).value + when value is markdown then (value as markdown).value + when value is oid then (value as oid).value + when value is positiveInt then (value as positiveInt).value + when value is string then (value as string).value + when value is time then (value as time).value + when value is unsignedInt then (value as unsignedInt).value + when value is uri then (value as uri).value + when value is url then (value as url).value + when value is uuid then (value as uuid).value + when value is Age then ToQuantity(value as Age) + when value is CodeableConcept then ToConcept(value as CodeableConcept) + when value is Coding then ToCode(value as Coding) + when value is Count then ToQuantity(value as Count) + when value is Distance then ToQuantity(value as Distance) + when value is Duration then ToQuantity(value as Duration) + when value is Quantity then ToQuantity(value as Quantity) + when value is Range then ToInterval(value as Range) + when value is Period then ToInterval(value as Period) + when value is Ratio then ToRatio(value as Ratio) + else value as Choice + end + +define function resolve(reference String) returns Resource: external +define function resolve(reference Reference) returns Resource: external +define function reference(resource Resource) returns Reference: external +define function extension(element Element, url String) returns List: external +define function extension(resource DomainResource, url String) returns List: external +define function modifierExtension(element BackboneElement, url String) returns List: external +define function modifierExtension(resource DomainResource, url String) returns List: external +define function hasValue(element Element) returns Boolean: external +define function getValue(element Element) returns Any: external +define function ofType(identifier String) returns List: external +define function is(identifier String) returns Boolean: external +define function as(identifier String) returns Any: external +define function elementDefinition(element Element) returns ElementDefinition: external +define function slice(element Element, url String, name String) returns List: external +define function checkModifiers(resource Resource) returns Resource: external +define function checkModifiers(resource Resource, modifier String) returns Resource: external +define function checkModifiers(element Element) returns Element: external +define function checkModifiers(element Element, modifier String) returns Element: external +define function conformsTo(resource Resource, structure String) returns Boolean: external +define function memberOf(code code, valueSet String) returns Boolean: external +define function memberOf(coding Coding, valueSet String) returns Boolean: external +define function memberOf(concept CodeableConcept, valueSet String) returns Boolean: external +define function subsumes(coding Coding, subsumedCoding Coding) returns Boolean: external +define function subsumes(concept CodeableConcept, subsumedConcept CodeableConcept) returns Boolean: external +define function subsumedBy(coding Coding, subsumingCoding Coding) returns Boolean: external +define function subsumedBy(concept CodeableConcept, subsumingConcept CodeableConcept) returns Boolean: external +define function htmlChecks(element Element) returns Boolean: external + +define function ToString(value AccountStatus): value.value +define function ToString(value ActionCardinalityBehavior): value.value +define function ToString(value ActionConditionKind): value.value +define function ToString(value ActionGroupingBehavior): value.value +define function ToString(value ActionParticipantType): value.value +define function ToString(value ActionPrecheckBehavior): value.value +define function ToString(value ActionRelationshipType): value.value +define function ToString(value ActionRequiredBehavior): value.value +define function ToString(value ActionSelectionBehavior): value.value +define function ToString(value ActivityDefinitionKind): value.value +define function ToString(value ActivityParticipantType): value.value +define function ToString(value AddressType): value.value +define function ToString(value AddressUse): value.value +define function ToString(value AdministrativeGender): value.value +define function ToString(value AdverseEventActuality): value.value +define function ToString(value AggregationMode): value.value +define function ToString(value AllergyIntoleranceCategory): value.value +define function ToString(value AllergyIntoleranceCriticality): value.value +define function ToString(value AllergyIntoleranceSeverity): value.value +define function ToString(value AllergyIntoleranceType): value.value +define function ToString(value AppointmentStatus): value.value +define function ToString(value AssertionDirectionType): value.value +define function ToString(value AssertionOperatorType): value.value +define function ToString(value AssertionResponseTypes): value.value +define function ToString(value AuditEventAction): value.value +define function ToString(value AuditEventAgentNetworkType): value.value +define function ToString(value AuditEventOutcome): value.value +define function ToString(value BindingStrength): value.value +define function ToString(value BiologicallyDerivedProductCategory): value.value +define function ToString(value BiologicallyDerivedProductStatus): value.value +define function ToString(value BiologicallyDerivedProductStorageScale): value.value +define function ToString(value BundleType): value.value +define function ToString(value CapabilityStatementKind): value.value +define function ToString(value CarePlanActivityKind): value.value +define function ToString(value CarePlanActivityStatus): value.value +define function ToString(value CarePlanIntent): value.value +define function ToString(value CarePlanStatus): value.value +define function ToString(value CareTeamStatus): value.value +define function ToString(value CatalogEntryRelationType): value.value +define function ToString(value ChargeItemDefinitionPriceComponentType): value.value +define function ToString(value ChargeItemStatus): value.value +define function ToString(value ClaimResponseStatus): value.value +define function ToString(value ClaimStatus): value.value +define function ToString(value ClinicalImpressionStatus): value.value +define function ToString(value CodeSearchSupport): value.value +define function ToString(value CodeSystemContentMode): value.value +define function ToString(value CodeSystemHierarchyMeaning): value.value +define function ToString(value CommunicationPriority): value.value +define function ToString(value CommunicationRequestStatus): value.value +define function ToString(value CommunicationStatus): value.value +define function ToString(value CompartmentCode): value.value +define function ToString(value CompartmentType): value.value +define function ToString(value CompositionAttestationMode): value.value +define function ToString(value CompositionStatus): value.value +define function ToString(value ConceptMapEquivalence): value.value +define function ToString(value ConceptMapGroupUnmappedMode): value.value +define function ToString(value ConditionalDeleteStatus): value.value +define function ToString(value ConditionalReadStatus): value.value +define function ToString(value ConsentDataMeaning): value.value +define function ToString(value ConsentProvisionType): value.value +define function ToString(value ConsentState): value.value +define function ToString(value ConstraintSeverity): value.value +define function ToString(value ContactPointSystem): value.value +define function ToString(value ContactPointUse): value.value +define function ToString(value ContractPublicationStatus): value.value +define function ToString(value ContractStatus): value.value +define function ToString(value ContributorType): value.value +define function ToString(value CoverageStatus): value.value +define function ToString(value CurrencyCode): value.value +define function ToString(value DayOfWeek): value.value +define function ToString(value DaysOfWeek): value.value +define function ToString(value DetectedIssueSeverity): value.value +define function ToString(value DetectedIssueStatus): value.value +define function ToString(value DeviceMetricCalibrationState): value.value +define function ToString(value DeviceMetricCalibrationType): value.value +define function ToString(value DeviceMetricCategory): value.value +define function ToString(value DeviceMetricColor): value.value +define function ToString(value DeviceMetricOperationalStatus): value.value +define function ToString(value DeviceNameType): value.value +define function ToString(value DeviceRequestStatus): value.value +define function ToString(value DeviceUseStatementStatus): value.value +define function ToString(value DiagnosticReportStatus): value.value +define function ToString(value DiscriminatorType): value.value +define function ToString(value DocumentConfidentiality): value.value +define function ToString(value DocumentMode): value.value +define function ToString(value DocumentReferenceStatus): value.value +define function ToString(value DocumentRelationshipType): value.value +define function ToString(value EligibilityRequestPurpose): value.value +define function ToString(value EligibilityRequestStatus): value.value +define function ToString(value EligibilityResponsePurpose): value.value +define function ToString(value EligibilityResponseStatus): value.value +define function ToString(value EnableWhenBehavior): value.value +define function ToString(value EncounterLocationStatus): value.value +define function ToString(value EncounterStatus): value.value +define function ToString(value EndpointStatus): value.value +define function ToString(value EnrollmentRequestStatus): value.value +define function ToString(value EnrollmentResponseStatus): value.value +define function ToString(value EpisodeOfCareStatus): value.value +define function ToString(value EventCapabilityMode): value.value +define function ToString(value EventTiming): value.value +define function ToString(value EvidenceVariableType): value.value +define function ToString(value ExampleScenarioActorType): value.value +define function ToString(value ExplanationOfBenefitStatus): value.value +define function ToString(value ExposureState): value.value +define function ToString(value ExtensionContextType): value.value +define function ToString(value FHIRAllTypes): value.value +define function ToString(value FHIRDefinedType): value.value +define function ToString(value FHIRDeviceStatus): value.value +define function ToString(value FHIRResourceType): value.value +define function ToString(value FHIRSubstanceStatus): value.value +define function ToString(value FHIRVersion): value.value +define function ToString(value FamilyHistoryStatus): value.value +define function ToString(value FilterOperator): value.value +define function ToString(value FlagStatus): value.value +define function ToString(value GoalLifecycleStatus): value.value +define function ToString(value GraphCompartmentRule): value.value +define function ToString(value GraphCompartmentUse): value.value +define function ToString(value GroupMeasure): value.value +define function ToString(value GroupType): value.value +define function ToString(value GuidanceResponseStatus): value.value +define function ToString(value GuidePageGeneration): value.value +define function ToString(value GuideParameterCode): value.value +define function ToString(value HTTPVerb): value.value +define function ToString(value IdentifierUse): value.value +define function ToString(value IdentityAssuranceLevel): value.value +define function ToString(value ImagingStudyStatus): value.value +define function ToString(value ImmunizationEvaluationStatus): value.value +define function ToString(value ImmunizationStatus): value.value +define function ToString(value InvoicePriceComponentType): value.value +define function ToString(value InvoiceStatus): value.value +define function ToString(value IssueSeverity): value.value +define function ToString(value IssueType): value.value +define function ToString(value LinkType): value.value +define function ToString(value LinkageType): value.value +define function ToString(value ListMode): value.value +define function ToString(value ListStatus): value.value +define function ToString(value LocationMode): value.value +define function ToString(value LocationStatus): value.value +define function ToString(value MeasureReportStatus): value.value +define function ToString(value MeasureReportType): value.value +define function ToString(value MediaStatus): value.value +define function ToString(value MedicationAdministrationStatus): value.value +define function ToString(value MedicationDispenseStatus): value.value +define function ToString(value MedicationKnowledgeStatus): value.value +define function ToString(value MedicationRequestIntent): value.value +define function ToString(value MedicationRequestPriority): value.value +define function ToString(value MedicationRequestStatus): value.value +define function ToString(value MedicationStatementStatus): value.value +define function ToString(value MedicationStatus): value.value +define function ToString(value MessageSignificanceCategory): value.value +define function ToString(value Messageheader_Response_Request): value.value +define function ToString(value MimeType): value.value +define function ToString(value NameUse): value.value +define function ToString(value NamingSystemIdentifierType): value.value +define function ToString(value NamingSystemType): value.value +define function ToString(value NarrativeStatus): value.value +define function ToString(value NoteType): value.value +define function ToString(value NutritiionOrderIntent): value.value +define function ToString(value NutritionOrderStatus): value.value +define function ToString(value ObservationDataType): value.value +define function ToString(value ObservationRangeCategory): value.value +define function ToString(value ObservationStatus): value.value +define function ToString(value OperationKind): value.value +define function ToString(value OperationParameterUse): value.value +define function ToString(value OrientationType): value.value +define function ToString(value ParameterUse): value.value +define function ToString(value ParticipantRequired): value.value +define function ToString(value ParticipantStatus): value.value +define function ToString(value ParticipationStatus): value.value +define function ToString(value PaymentNoticeStatus): value.value +define function ToString(value PaymentReconciliationStatus): value.value +define function ToString(value ProcedureStatus): value.value +define function ToString(value PropertyRepresentation): value.value +define function ToString(value PropertyType): value.value +define function ToString(value ProvenanceEntityRole): value.value +define function ToString(value PublicationStatus): value.value +define function ToString(value QualityType): value.value +define function ToString(value QuantityComparator): value.value +define function ToString(value QuestionnaireItemOperator): value.value +define function ToString(value QuestionnaireItemType): value.value +define function ToString(value QuestionnaireResponseStatus): value.value +define function ToString(value ReferenceHandlingPolicy): value.value +define function ToString(value ReferenceVersionRules): value.value +define function ToString(value ReferredDocumentStatus): value.value +define function ToString(value RelatedArtifactType): value.value +define function ToString(value RemittanceOutcome): value.value +define function ToString(value RepositoryType): value.value +define function ToString(value RequestIntent): value.value +define function ToString(value RequestPriority): value.value +define function ToString(value RequestStatus): value.value +define function ToString(value ResearchElementType): value.value +define function ToString(value ResearchStudyStatus): value.value +define function ToString(value ResearchSubjectStatus): value.value +define function ToString(value ResourceType): value.value +define function ToString(value ResourceVersionPolicy): value.value +define function ToString(value ResponseType): value.value +define function ToString(value RestfulCapabilityMode): value.value +define function ToString(value RiskAssessmentStatus): value.value +define function ToString(value SPDXLicense): value.value +define function ToString(value SearchComparator): value.value +define function ToString(value SearchEntryMode): value.value +define function ToString(value SearchModifierCode): value.value +define function ToString(value SearchParamType): value.value +define function ToString(value SectionMode): value.value +define function ToString(value SequenceType): value.value +define function ToString(value ServiceRequestIntent): value.value +define function ToString(value ServiceRequestPriority): value.value +define function ToString(value ServiceRequestStatus): value.value +define function ToString(value SlicingRules): value.value +define function ToString(value SlotStatus): value.value +define function ToString(value SortDirection): value.value +define function ToString(value SpecimenContainedPreference): value.value +define function ToString(value SpecimenStatus): value.value +define function ToString(value Status): value.value +define function ToString(value StrandType): value.value +define function ToString(value StructureDefinitionKind): value.value +define function ToString(value StructureMapContextType): value.value +define function ToString(value StructureMapGroupTypeMode): value.value +define function ToString(value StructureMapInputMode): value.value +define function ToString(value StructureMapModelMode): value.value +define function ToString(value StructureMapSourceListMode): value.value +define function ToString(value StructureMapTargetListMode): value.value +define function ToString(value StructureMapTransform): value.value +define function ToString(value SubscriptionChannelType): value.value +define function ToString(value SubscriptionStatus): value.value +define function ToString(value SupplyDeliveryStatus): value.value +define function ToString(value SupplyRequestStatus): value.value +define function ToString(value SystemRestfulInteraction): value.value +define function ToString(value TaskIntent): value.value +define function ToString(value TaskPriority): value.value +define function ToString(value TaskStatus): value.value +define function ToString(value TestReportActionResult): value.value +define function ToString(value TestReportParticipantType): value.value +define function ToString(value TestReportResult): value.value +define function ToString(value TestReportStatus): value.value +define function ToString(value TestScriptRequestMethodCode): value.value +define function ToString(value TriggerType): value.value +define function ToString(value TypeDerivationRule): value.value +define function ToString(value TypeRestfulInteraction): value.value +define function ToString(value UDIEntryType): value.value +define function ToString(value UnitsOfTime): value.value +define function ToString(value Use): value.value +define function ToString(value VariableType): value.value +define function ToString(value VisionBase): value.value +define function ToString(value VisionEyes): value.value +define function ToString(value VisionStatus): value.value +define function ToString(value XPathUsageType): value.value +define function ToString(value base64Binary): value.value +define function ToBoolean(value boolean): value.value +define function ToDate(value date): value.value +define function ToDateTime(value dateTime): value.value +define function ToDecimal(value decimal): value.value +define function ToDateTime(value instant): value.value +define function ToInteger(value integer): value.value +define function ToString(value string): value.value +define function ToTime(value time): value.value +define function ToString(value uri): value.value +define function ToString(value xhtml): value.value \ No newline at end of file diff --git a/Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS149/cql/QICoreCommon-1.2.000.cql b/Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS149/cql/QICoreCommon-1.2.000.cql new file mode 100644 index 000000000..c65f36ae4 --- /dev/null +++ b/Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS149/cql/QICoreCommon-1.2.000.cql @@ -0,0 +1,370 @@ +library QICoreCommon version '1.2.000' + +using QICore version '4.1.1' + +include FHIRHelpers version '4.1.000' + +codesystem "LOINC": 'http://loinc.org' +codesystem "SNOMEDCT": 'http://snomed.info/sct' +codesystem "ICD10CM": 'http://hl7.org/fhir/sid/icd-10-cm' +codesystem "RoleCode": 'http://terminology.hl7.org/CodeSystem/v3-RoleCode' +codesystem "Diagnosis Role": 'http://terminology.hl7.org/CodeSystem/diagnosis-role' +codesystem "RequestIntent": 'http://terminology.hl7.org/CodeSystem/request-intent' +codesystem "MedicationRequestCategory": 'http://terminology.hl7.org/CodeSystem/medicationrequest-category' +codesystem "ConditionClinicalStatusCodes": 'http://terminology.hl7.org/CodeSystem/condition-clinical' +codesystem "ConditionVerificationStatusCodes": 'http://terminology.hl7.org/CodeSystem/condition-ver-status' +codesystem "AllergyIntoleranceClinicalStatusCodes": 'http://terminology.hl7.org/CodeSystem/allergyintolerance-clinical' +codesystem "AllergyIntoleranceVerificationStatusCodes": 'http://terminology.hl7.org/CodeSystem/allergyintolerance-verification' +codesystem "ConditionCategoryCodes": 'http://terminology.hl7.org/CodeSystem/condition-category' +codesystem "ObservationCategoryCodes": 'http://terminology.hl7.org/CodeSystem/observation-category' + +//Currently unresolveable in VSAC +//valueset "Active Condition": 'http://fhir.org/guides/cqf/common/ValueSet/active-condition' +//valueset "Inactive Condition": 'http://fhir.org/guides/cqf/common/ValueSet/inactive-condition' + +code "Birthdate": '21112-8' from "LOINC" display 'Birth date' +code "Dead": '419099009' from "SNOMEDCT" display 'Dead' +code "ER": 'ER' from "RoleCode" display 'Emergency room' +code "ICU": 'ICU' from "RoleCode" display 'Intensive care unit' +code "Billing": 'billing' from "Diagnosis Role" display 'Billing' + +// Condition Clinical Status Codes - Consider value sets for these +code "active": 'active' from "ConditionClinicalStatusCodes" +code "recurrence": 'recurrence' from "ConditionClinicalStatusCodes" +code "relapse": 'relapse' from "ConditionClinicalStatusCodes" +code "inactive": 'inactive' from "ConditionClinicalStatusCodes" +code "remission": 'remission' from "ConditionClinicalStatusCodes" +code "resolved": 'resolved' from "ConditionClinicalStatusCodes" + +// Condition Verification Status Codes - Consider value sets for these +code "unconfirmed": 'unconfirmed' from ConditionVerificationStatusCodes +code "provisional": 'provisional' from ConditionVerificationStatusCodes +code "differential": 'differential' from ConditionVerificationStatusCodes +code "confirmed": 'confirmed' from ConditionVerificationStatusCodes +code "refuted": 'refuted' from ConditionVerificationStatusCodes +code "entered-in-error": 'entered-in-error' from ConditionVerificationStatusCodes + +code "allergy-active": 'active' from "AllergyIntoleranceClinicalStatusCodes" +code "allergy-inactive": 'inactive' from "AllergyIntoleranceClinicalStatusCodes" +code "allergy-resolved": 'resolved' from "AllergyIntoleranceClinicalStatusCodes" + +// Allergy/Intolerance Verification Status Codes - Consider value sets for these +code "allergy-unconfirmed": 'unconfirmed' from AllergyIntoleranceVerificationStatusCodes +code "allergy-confirmed": 'confirmed' from AllergyIntoleranceVerificationStatusCodes +code "allergy-refuted": 'refuted' from AllergyIntoleranceVerificationStatusCodes + +// MedicationRequest Category Codes +code "Community": 'community' from "MedicationRequestCategory" display 'Community' +code "Discharge": 'discharge' from "MedicationRequestCategory" display 'Discharge' + +// Diagnosis Role Codes +code "AD": 'AD' from "Diagnosis Role" display 'Admission diagnosis' +code "DD": 'DD' from "Diagnosis Role" display 'Discharge diagnosis' +code "CC": 'CC' from "Diagnosis Role" display 'Chief complaint' +code "CM": 'CM' from "Diagnosis Role" display 'Comorbidity diagnosis' +code "pre-op": 'pre-op' from "Diagnosis Role" display 'pre-op diagnosis' +code "post-op": 'post-op' from "Diagnosis Role" display 'post-op diagnosis' +code "billing": 'billing' from "Diagnosis Role" display 'billing diagnosis' + +// Observation Category Codes +code "social-history": 'social-history' from "ObservationCategoryCodes" display 'Social History' +code "vital-signs": 'vital-signs' from "ObservationCategoryCodes" display 'Vital Signs' +code "imaging": 'imaging' from "ObservationCategoryCodes" display 'Imaging' +code "laboratory": 'laboratory' from "ObservationCategoryCodes" display 'Laboratory' +code "procedure": 'procedure' from "ObservationCategoryCodes" display 'Procedure' +code "survey": 'survey' from "ObservationCategoryCodes" display 'Survey' +code "exam": 'exam' from "ObservationCategoryCodes" display 'Exam' +code "therapy": 'therapy' from "ObservationCategoryCodes" display 'Therapy' +code "activity": 'activity' from "ObservationCategoryCodes" display 'Activity' + +// Condition Category Codes +code "problem-list-item": 'problem-list-item' from "ConditionCategoryCodes" display 'Problem List Item' +code "encounter-diagnosis": 'encounter-diagnosis' from "ConditionCategoryCodes" display 'Encounter Diagnosis' + +context Patient + +/* +@description: Normalizes a value that is a choice of timing-valued types to an equivalent interval +@comment: Normalizes a choice type of DateTime, Quanitty, Interval, or Interval types +to an equivalent interval. This selection of choice types is a superset of the majority of choice types that are used as possible +representations for timing-valued elements in QICore, allowing this function to be used across any resource. +The input can be provided as a DateTime, Quantity, Interval or Interval. +The intent of this function is to provide a clear and concise mechanism to treat single +elements that have multiple possible representations as intervals so that logic doesn't have to account +for the variability. More complex calculations (such as medication request period or dispense period +calculation) need specific guidance and consideration. That guidance may make use of this function, but +the focus of this function is on single element calculations where the semantics are unambiguous. +If the input is a DateTime, the result a DateTime Interval beginning and ending on that DateTime. +If the input is a Quantity, the quantity is expected to be a calendar-duration interpreted as an Age, +and the result is a DateTime Interval beginning on the Date the patient turned that age and ending immediately before one year later. +If the input is a DateTime Interval, the result is the input. +If the input is a Quantity Interval, the quantities are expected to be calendar-durations interpreted as an Age, and the result +is a DateTime Interval beginning on the date the patient turned the age given as the start of the quantity interval, and ending +immediately before one year later than the date the patient turned the age given as the end of the quantity interval. +Any other input will reslt in a null DateTime Interval +*/ +define function ToInterval(choice Choice, Interval>): + case + when choice is DateTime then + Interval[choice as DateTime, choice as DateTime] + when choice is Interval then + choice as Interval + when choice is Quantity then + Interval[Patient.birthDate + (choice as Quantity), + Patient.birthDate + (choice as Quantity) + 1 year) + when choice is Interval then + Interval[Patient.birthDate + (choice.low as Quantity), + Patient.birthDate + (choice.high as Quantity) + 1 year) + else + null as Interval + end + +/* +@description: Normalizes a value that is a choice of timing-valued types to an equivalent interval +@comment: Normalizes a choice type of DateTime, Quanitty, Interval, or Interval types +to an equivalent interval. This selection of choice types is a superset of the majority of choice types that are used as possible +representations for timing-valued elements in QICore, allowing this function to be used across any resource. +The input can be provided as a DateTime, Quantity, Interval or Interval. +The intent of this function is to provide a clear and concise mechanism to treat single +elements that have multiple possible representations as intervals so that logic doesn't have to account +for the variability. More complex calculations (such as medication request period or dispense period +calculation) need specific guidance and consideration. That guidance may make use of this function, but +the focus of this function is on single element calculations where the semantics are unambiguous. +If the input is a DateTime, the result a DateTime Interval beginning and ending on that DateTime. +If the input is a Quantity, the quantity is expected to be a calendar-duration interpreted as an Age, +and the result is a DateTime Interval beginning on the Date the patient turned that age and ending immediately before one year later. +If the input is a DateTime Interval, the result is the input. +If the input is a Quantity Interval, the quantities are expected to be calendar-durations interpreted as an Age, and the result +is a DateTime Interval beginning on the date the patient turned the age given as the start of the quantity interval, and ending +immediately before one year later than the date the patient turned the age given as the end of the quantity interval. +Any other input will reslt in a null DateTime Interval +*/ +define fluent function toInterval(choice Choice, Interval>): + case + when choice is DateTime then + Interval[choice as DateTime, choice as DateTime] + when choice is Interval then + choice as Interval + when choice is Quantity then + Interval[Patient.birthDate + (choice as Quantity), + Patient.birthDate + (choice as Quantity) + 1 year) + when choice is Interval then + Interval[Patient.birthDate + (choice.low as Quantity), + Patient.birthDate + (choice.high as Quantity) + 1 year) + else + null as Interval + end + +/* +@description: Returns an interval representing the normalized abatement of a given Condition. +@comment: If the abatement element of the Condition is represented as a DateTime, the result +is an interval beginning and ending on that DateTime. +If the abatement is represented as a Quantity, the quantity is expected to be a calendar-duration and is interpreted as the age of the patient. The +result is an interval from the date the patient turned that age to immediately before one year later. +If the abatement is represented as a Quantity Interval, the quantities are expected to be calendar-durations and are interpreted as an age range during +which the abatement occurred. The result is an interval from the date the patient turned the starting age of the quantity interval, and ending immediately +before one year later than the date the patient turned the ending age of the quantity interval. +*/ +define function ToAbatementInterval(condition Condition): + if condition.abatement is DateTime then + Interval[condition.abatement as DateTime, condition.abatement as DateTime] + else if condition.abatement is Quantity then + Interval[Patient.birthDate + (condition.abatement as Quantity), + Patient.birthDate + (condition.abatement as Quantity) + 1 year) + else if condition.abatement is Interval then + Interval[Patient.birthDate + (condition.abatement.low as Quantity), + Patient.birthDate + (condition.abatement.high as Quantity) + 1 year) + else if condition.abatement is Interval then + Interval[condition.abatement.low, condition.abatement.high) + else null as Interval + +/* +@description: Returns an interval representing the normalized abatement of a given Condition. +@comment: If the abatement element of the Condition is represented as a DateTime, the result +is an interval beginning and ending on that DateTime. +If the abatement is represented as a Quantity, the quantity is expected to be a calendar-duration and is interpreted as the age of the patient. The +result is an interval from the date the patient turned that age to immediately before one year later. +If the abatement is represented as a Quantity Interval, the quantities are expected to be calendar-durations and are interpreted as an age range during +which the abatement occurred. The result is an interval from the date the patient turned the starting age of the quantity interval, and ending immediately +before one year later than the date the patient turned the ending age of the quantity interval. +*/ +define fluent function toAbatementInterval(condition Condition): + if condition.abatement is DateTime then + Interval[condition.abatement as DateTime, condition.abatement as DateTime] + else if condition.abatement is Quantity then + Interval[Patient.birthDate + (condition.abatement as Quantity), + Patient.birthDate + (condition.abatement as Quantity) + 1 year) + else if condition.abatement is Interval then + Interval[Patient.birthDate + (condition.abatement.low as Quantity), + Patient.birthDate + (condition.abatement.high as Quantity) + 1 year) + else if condition.abatement is Interval then + Interval[condition.abatement.low, condition.abatement.high) + else null as Interval + +/* +@description: Returns an interval representing the normalized prevalence period of a given Condition. +@comment: Uses the ToInterval and ToAbatementInterval functions to determine the widest potential interval from +onset to abatement as specified in the given Condition. If the condition is active, the resulting interval will have +a closed ending boundary. If the condition is not active, the resulting interval will have an open ending boundary. +*/ +define function ToPrevalenceInterval(condition Condition): +if condition.clinicalStatus ~ "active" + or condition.clinicalStatus ~ "recurrence" + or condition.clinicalStatus ~ "relapse" then + Interval[start of ToInterval(condition.onset), end of ToAbatementInterval(condition)] +else + Interval[start of ToInterval(condition.onset), end of ToAbatementInterval(condition)) + +/* +@description: Returns an interval representing the normalized prevalence period of a given Condition. +@comment: Uses the ToInterval and ToAbatementInterval functions to determine the widest potential interval from +onset to abatement as specified in the given Condition. If the condition is active, the resulting interval will have +a closed ending boundary. If the condition is not active, the resulting interval will have an open ending boundary. +*/ +define fluent function toPrevalenceInterval(condition Condition): +if condition.clinicalStatus ~ "active" + or condition.clinicalStatus ~ "recurrence" + or condition.clinicalStatus ~ "relapse" then + Interval[start of ToInterval(condition.onset), end of ToAbatementInterval(condition)] +else + Interval[start of ToInterval(condition.onset), end of ToAbatementInterval(condition)) + +/* +@description: Returns the tail of the given uri (i.e. everything after the last slash in the URI). +@comment: This function can be used to determine the logical id of a given resource. It can be used in +a single-server environment to trace references. However, this function does not attempt to resolve +or distinguish the base of the given url, and so cannot be used safely in multi-server environments. +*/ +define function GetId(uri String ): + Last(Split(uri, '/')) + +/* +@description: Returns the tail of the given uri (i.e. everything after the last slash in the URI). +@comment: This function can be used to determine the logical id of a given resource. It can be used in +a single-server environment to trace references. However, this function does not attempt to resolve +or distinguish the base of the given url, and so cannot be used safely in multi-server environments. +*/ +define fluent function getId(uri String): + Last(Split(uri, '/')) + +/* +@description: Given an interval, return true if the interval has a starting boundary specified +(i.e. the start of the interval is not null and not the minimum DateTime value) +*/ +define function "HasStart"(period Interval ): + not ( start of period is null + or start of period = minimum DateTime + ) + +/* +@description: Given an interval, return true if the interval has a starting boundary specified +(i.e. the start of the interval is not null and not the minimum DateTime value) +*/ +define fluent function hasStart(period Interval ): + not ( start of period is null + or start of period = minimum DateTime + ) + +/* +@description: Given an interval, returns true if the interval has an ending boundary specified +(i.e. the end of the interval is not null and not the maximum DateTime value) +*/ +define function "HasEnd"(period Interval ): + not ( + end of period is null + or end of period = maximum DateTime + ) + +/* +@description: Given an interval, returns true if the interval has an ending boundary specified +(i.e. the end of the interval is not null and not the maximum DateTime value) +*/ +define fluent function hasEnd(period Interval ): + not ( + end of period is null + or end of period = maximum DateTime + ) + +/* +@description: Given an interval, returns the ending point if the interval has an ending boundary specified, +otherwise, returns the starting point +*/ +define function "Latest"(choice Choice, Interval> ): + (choice.toInterval()) period + return + if (HasEnd(period)) then end of period + else start of period + +/* +@description: Given an interval, returns the ending point if the interval has an ending boundary specified, +otherwise, returns the starting point +*/ +define fluent function latest(choice Choice, Interval> ): + (choice.toInterval()) period + return + if (HasEnd(period)) then end of period + else start of period + +/* +@description: Given an interval, return the starting point if the interval has a starting boundary specified, +otherwise, return the ending point +*/ +define function "Earliest"(choice Choice, Interval> ): + (choice.toInterval()) period + return + if (HasStart(period)) then start of period + else end of period + +/* +@description: Given an interval, return the starting point if the interval has a starting boundary specified, +otherwise, return the ending point +*/ +define fluent function earliest(choice Choice, Interval> ): + (choice.toInterval()) period + return + if (HasStart(period)) then start of period + else end of period + +/* +@description: Creates a list of integers from 1 to how many days are in the interval. Note, this wont create an index for +the final day if it is less than 24 hours. This also includes the first 24 hour period. +*/ +define function "Interval To Day Numbers"(Period Interval): + ( expand { Interval[1, duration in days between start of Period and end of Period]} ) DayNumber + return end of DayNumber + +/* +@description: Creates a list of integers from 1 to how many days are in the interval. Note, this wont create an index for +the final day if it is less than 24 hours. This also includes the first 24 hour period. +*/ +define fluent function toDayNumbers(Period Interval): + ( expand { Interval[1, duration in days between start of Period and end of Period]} ) DayNumber + return end of DayNumber + +/* +@description: Creates a list of 24 hour long intervals in an interval paired with the index (1 indexed) to which 24 hour interval it is. +Note that the result will include intervals that are closed at the beginning and open at the end +*/ +define function "Days In Period"(Period Interval): + ( "Interval To Day Numbers"(Period)) DayIndex + let startPeriod: start of Period + (24 hours * (DayIndex - 1)), + endPeriod: if (hours between startPeriod and end of Period < 24) then startPeriod + else start of Period + (24 hours * DayIndex) + return Tuple { + dayIndex: DayIndex, + dayPeriod: Interval[startPeriod, endPeriod) + } + +/* +@description: Creates a list of 24 hour long intervals in an interval paired with the index (1 indexed) to which 24 hour interval it is. +Note that the result will include intervals that are closed at the beginning and open at the end +*/ +define fluent function daysInPeriod(Period Interval): + ( "Interval To Day Numbers"(Period)) DayIndex + let startPeriod: start of Period + (24 hours * (DayIndex - 1)), + endPeriod: if (hours between startPeriod and end of Period < 24) then startPeriod + else start of Period + (24 hours * DayIndex) + return Tuple { + dayIndex: DayIndex, + dayPeriod: Interval[startPeriod, endPeriod) + } \ No newline at end of file diff --git a/Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS149/cql/SupplementalDataElements-3.1.000.cql b/Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS149/cql/SupplementalDataElements-3.1.000.cql new file mode 100644 index 000000000..04be4f8a1 --- /dev/null +++ b/Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS149/cql/SupplementalDataElements-3.1.000.cql @@ -0,0 +1,49 @@ +/* +@update: BTR 2020-03-31 -> +Incremented version to 2.0.0 + +@update: BTR 2022-05-26 -> +Updated FHIR version to 4.0.1 +Updated FHIRHelpers version to 4.0.002 +Updated for AU 2022 Content +*/ +library SupplementalDataElements version '3.1.000' + +using QICore version '4.1.1' + +include FHIRHelpers version '4.1.000' called FHIRHelpers + +valueset "Ethnicity": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.114222.4.11.837' +valueset "ONC Administrative Sex": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113762.1.4.1' +valueset "Payer": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.114222.4.11.3591' +valueset "Race": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.114222.4.11.836' + +context Patient + +define "SDE Ethnicity": + Patient.ethnicity E + return Tuple { + codes: { E.ombCategory } union E.detailed, + display: E.text + } + +define "SDE Payer": + [Coverage: type in "Payer"] Payer + return { + code: Payer.type, + period: Payer.period + } + +define "SDE Race": + Patient.race R + return Tuple { + codes: R.ombCategory union R.detailed, + display: R.text + } + +define "SDE Sex": + case + when Patient.gender = 'male' then Code { code: 'M', system: 'http://hl7.org/fhir/v3/AdministrativeGender', display: 'Male' } + when Patient.gender = 'female' then Code { code: 'F', system: 'http://hl7.org/fhir/v3/AdministrativeGender', display: 'Female' } + else null + end \ No newline at end of file diff --git a/Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS149/resources/Library-EffectiveDataRequirements.json b/Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS149/resources/Library-EffectiveDataRequirements.json new file mode 100644 index 000000000..056b1c2d9 --- /dev/null +++ b/Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS149/resources/Library-EffectiveDataRequirements.json @@ -0,0 +1,313 @@ +{ + "resourceType": "Library", + "extension": [ { + "url": "http://hl7.org/fhir/us/cqfmeasures/StructureDefinition/cqfm-directReferenceCode", + "valueCoding": { + "system": "http://terminology.hl7.org/CodeSystem/v3-ActCode", + "code": "VR", + "display": "virtual" + } + }, { + "url": "http://hl7.org/fhir/us/cqfmeasures/StructureDefinition/cqfm-directReferenceCode", + "valueCoding": { + "system": "http://terminology.hl7.org/CodeSystem/v3-ActCode", + "code": "AMB", + "display": "Ambulatory" + } + } ], + "status": "active", + "type": { + "coding": [ { + "system": "http://terminology.hl7.org/CodeSystem/library-type", + "code": "module-definition" + } ] + }, + "relatedArtifact": [ { + "type": "depends-on", + "display": "QICore model information", + "resource": "http://hl7.org/fhir/Library/QICore-ModelInfo" + }, { + "type": "depends-on", + "display": "Library FHIRHelpers", + "resource": "Library/FHIRHelpers|4.1.000" + }, { + "type": "depends-on", + "display": "Library SDE", + "resource": "Library/SupplementalDataElements|3.1.000" + }, { + "type": "depends-on", + "display": "Library CQMCommon", + "resource": "Library/CQMCommon|1.0.000" + }, { + "type": "depends-on", + "display": "Library QICoreCommon", + "resource": "Library/QICoreCommon|1.2.000" + }, { + "type": "depends-on", + "display": "Code system ActCode", + "resource": "http://terminology.hl7.org/CodeSystem/v3-ActCode" + }, { + "type": "depends-on", + "display": "Value set Behavioral/Neuropsych Assessment", + "resource": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1023" + }, { + "type": "depends-on", + "display": "Value set Care Services in Long Term Residential Facility", + "resource": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.464.1003.101.12.1014" + }, { + "type": "depends-on", + "display": "Value set Cognitive Assessment", + "resource": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1332" + }, { + "type": "depends-on", + "display": "Value set Dementia & Mental Degenerations", + "resource": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1005" + }, { + "type": "depends-on", + "display": "Value set Face-to-Face Interaction", + "resource": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.464.1003.101.12.1048" + }, { + "type": "depends-on", + "display": "Value set Home Healthcare Services", + "resource": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.464.1003.101.12.1016" + }, { + "type": "depends-on", + "display": "Value set Nursing Facility Visit", + "resource": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.464.1003.101.12.1012" + }, { + "type": "depends-on", + "display": "Value set Occupational Therapy Evaluation", + "resource": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1011" + }, { + "type": "depends-on", + "display": "Value set Office Visit", + "resource": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.464.1003.101.12.1001" + }, { + "type": "depends-on", + "display": "Value set Outpatient Consultation", + "resource": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.464.1003.101.12.1008" + }, { + "type": "depends-on", + "display": "Value set Patient Provider Interaction", + "resource": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1012" + }, { + "type": "depends-on", + "display": "Value set Patient Reason", + "resource": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1008" + }, { + "type": "depends-on", + "display": "Value set Psych Visit Diagnostic Evaluation", + "resource": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1492" + }, { + "type": "depends-on", + "display": "Value set Psych Visit Psychotherapy", + "resource": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1496" + }, { + "type": "depends-on", + "display": "Value set Standardized Tools for Assessment of Cognition", + "resource": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1006" + } ], + "parameter": [ { + "name": "Measurement Period", + "use": "in", + "min": 0, + "max": "1", + "type": "Period" + }, { + "name": "Patient", + "use": "out", + "min": 0, + "max": "1", + "type": "Resource" + }, { + "name": "SDE Ethnicity", + "use": "out", + "min": 0, + "max": "1", + "type": "Resource" + }, { + "name": "SDE Race", + "use": "out", + "min": 0, + "max": "1", + "type": "Resource" + }, { + "name": "SDE Sex", + "use": "out", + "min": 0, + "max": "1", + "type": "Coding" + }, { + "name": "SDE Payer", + "use": "out", + "min": 0, + "max": "*", + "type": "Resource" + }, { + "name": "Encounter to Assess Cognition", + "use": "out", + "min": 0, + "max": "*", + "type": "Resource" + }, { + "name": "Dementia Encounter During Measurement Period", + "use": "out", + "min": 0, + "max": "*", + "type": "Resource" + }, { + "name": "Qualifying Encounter During Measurement Period", + "use": "out", + "min": 0, + "max": "*", + "type": "Resource" + }, { + "name": "Initial Population", + "use": "out", + "min": 0, + "max": "1", + "type": "boolean" + }, { + "name": "Denominator", + "use": "out", + "min": 0, + "max": "1", + "type": "boolean" + }, { + "name": "Assessment of Cognition Using Standardized Tools or Alternate Methods", + "use": "out", + "min": 0, + "max": "*", + "type": "Resource" + }, { + "name": "Numerator", + "use": "out", + "min": 0, + "max": "1", + "type": "boolean" + }, { + "name": "Patient Reason for Not Performing Assessment of Cognition Using Standardized Tools or Alternate Methods", + "use": "out", + "min": 0, + "max": "*", + "type": "Resource" + }, { + "name": "Denominator Exceptions", + "use": "out", + "min": 0, + "max": "1", + "type": "boolean" + } ], + "dataRequirement": [ { + "type": "Patient", + "profile": [ "http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-patient" ] + }, { + "type": "Patient", + "profile": [ "http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-patient" ], + "mustSupport": [ "url", "extension" ], + "codeFilter": [ { + "path": "url", + "code": [ { + "code": "http://hl7.org/fhir/us/core/StructureDefinition/us-core-ethnicity" + } ] + } ] + }, { + "type": "Patient", + "profile": [ "http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-patient" ], + "mustSupport": [ "url", "extension" ], + "codeFilter": [ { + "path": "url", + "code": [ { + "code": "http://hl7.org/fhir/us/core/StructureDefinition/us-core-race" + } ] + } ] + }, { + "type": "Coverage", + "profile": [ "http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-coverage" ], + "mustSupport": [ "type", "period" ], + "codeFilter": [ { + "path": "type", + "valueSet": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.114222.4.11.3591" + } ] + }, { + "type": "Encounter", + "profile": [ "http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-encounter" ], + "mustSupport": [ "type" ], + "codeFilter": [ { + "path": "type", + "valueSet": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1492" + } ] + }, { + "type": "Encounter", + "profile": [ "http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-encounter" ], + "mustSupport": [ "type" ], + "codeFilter": [ { + "path": "type", + "valueSet": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.464.1003.101.12.1012" + } ] + }, { + "type": "Encounter", + "profile": [ "http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-encounter" ], + "mustSupport": [ "type" ], + "codeFilter": [ { + "path": "type", + "valueSet": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.464.1003.101.12.1014" + } ] + }, { + "type": "Encounter", + "profile": [ "http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-encounter" ], + "mustSupport": [ "type" ], + "codeFilter": [ { + "path": "type", + "valueSet": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.464.1003.101.12.1016" + } ] + }, { + "type": "Encounter", + "profile": [ "http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-encounter" ], + "mustSupport": [ "type" ], + "codeFilter": [ { + "path": "type", + "valueSet": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1496" + } ] + }, { + "type": "Encounter", + "profile": [ "http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-encounter" ], + "mustSupport": [ "type" ], + "codeFilter": [ { + "path": "type", + "valueSet": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1023" + } ] + }, { + "type": "Encounter", + "profile": [ "http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-encounter" ], + "mustSupport": [ "type" ], + "codeFilter": [ { + "path": "type", + "valueSet": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1011" + } ] + }, { + "type": "Encounter", + "profile": [ "http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-encounter" ], + "mustSupport": [ "type" ], + "codeFilter": [ { + "path": "type", + "valueSet": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.464.1003.101.12.1001" + } ] + }, { + "type": "Encounter", + "profile": [ "http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-encounter" ], + "mustSupport": [ "type" ], + "codeFilter": [ { + "path": "type", + "valueSet": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.464.1003.101.12.1008" + } ] + }, { + "type": "Condition", + "profile": [ "http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-condition" ], + "mustSupport": [ "code" ], + "codeFilter": [ { + "path": "code", + "valueSet": "http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113883.3.526.3.1005" + } ] + } ] +} diff --git a/Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS645/CMS645-ModuleDefinitionLibrary.json b/Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS645/CMS645-ModuleDefinitionLibrary.json new file mode 100644 index 000000000..066627322 --- /dev/null +++ b/Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS645/CMS645-ModuleDefinitionLibrary.json @@ -0,0 +1,40 @@ +{ + "resourceType": "Library", + "status": "active", + "type": { + "coding": [ { + "system": "http://terminology.hl7.org/CodeSystem/library-type", + "code": "module-definition" + } ] + }, + "relatedArtifact": [ { + "type": "depends-on", + "display": "QICore model information", + "resource": "http://hl7.org/fhir/Library/QICore-ModelInfo" + }, { + "type": "depends-on", + "display": "Library FHIRHelpers", + "resource": "Library/FHIRHelpers|4.0.001" + }, { + "type": "depends-on", + "display": "Value set Androgen deprivation therapy for Urology Care", + "resource": "tbd" + } ], + "parameter": [ { + "name": "Patient", + "use": "out", + "min": 0, + "max": "1", + "type": "Resource" + }, { + "name": "test", + "use": "out", + "min": 0, + "max": "*", + "type": "dateTime" + } ], + "dataRequirement": [ { + "type": "Patient", + "profile": [ "http://hl7.org/fhir/us/qicore/StructureDefinition/qicore-patient" ] + } ] +} diff --git a/Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS645/CMS645Test.cql b/Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS645/CMS645Test.cql new file mode 100644 index 000000000..bde9d30fc --- /dev/null +++ b/Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS645/CMS645Test.cql @@ -0,0 +1,67 @@ +library CMS645Test + +using QICore version '4.1.1' + +include FHIRHelpers version '4.0.001' + +valueset "Androgen deprivation therapy for Urology Care": 'tbd' + +context Patient + +define "test": + [MedicationRequest: "Androgen deprivation therapy for Urology Care"] ADTActive + where ADTActive.status in { 'active', 'completed' } + and ADTActive.intent in { 'order', 'original-order', 'reflex-order', 'filler-order', 'instance-order' } + and ADTActive.doNotPerform is not true + return "Earliest"( + "NormalizePeriod"( + First( + (ADTActive.dosageInstruction DoseInstruction + let DoseTiming: DoseInstruction.timing, + FirstDoseEventInTiming: First(DoseTiming.event DoseEvent return DoseEvent sort ascending) + return FirstDoseEventInTiming + ) DoseTimingEvent + return DoseTimingEvent + sort ascending + ), + First( + ( collapse (ADTActive.dosageInstruction.timing.repeat.bounds DoseTime + return DoseTime.toInterval()) + ) DrugPeriod + sort by start of $this + ) + ) + ) + +define function "HasStart"(period Interval ): + not ( start of period is null + or start of period = minimum DateTime + ) + +define function "Earliest"(choice Choice, Interval> ): + (choice.toInterval()) period + return + if (HasStart(period)) then start of period + else end of period + +define function "NormalizePeriod"(pointInTime DateTime, dateTimeInterval Interval): + if pointInTime is not null then Interval[pointInTime, pointInTime] + else if dateTimeInterval is not null then dateTimeInterval + else null as Interval + +define fluent function toInterval(choice Choice, Interval>): + case + when choice is DateTime then + Interval[choice as DateTime, choice as DateTime] + when choice is Interval then + choice as Interval + when choice is Quantity then + Interval[Patient.birthDate + (choice as Quantity), + Patient.birthDate + (choice as Quantity) + 1 year) + when choice is Interval then + Interval[Patient.birthDate + (choice.low as Quantity), + Patient.birthDate + (choice.high as Quantity) + 1 year) + else + null as Interval + end + diff --git a/Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS645/FHIRHelpers.cql b/Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS645/FHIRHelpers.cql new file mode 100644 index 000000000..02f82c4f6 --- /dev/null +++ b/Src/java/elm-fhir/src/test/resources/org/cqframework/cql/elm/requirements/fhir/CMS645/FHIRHelpers.cql @@ -0,0 +1,827 @@ +library FHIRHelpers version '4.0.001' + +using FHIR version '4.0.1' + +context Patient + +define function "ToInterval"(period FHIR.Period ): + if period is null then + null + else + Interval[period."start".value, period."end".value] + +define function "ToQuantity"(quantity FHIR.Quantity ): + if quantity is null then + null + else + System.Quantity { value: quantity.value.value, unit: quantity.unit.value } + +define function "ToRatio"(ratio FHIR.Ratio ): + if ratio is null then + null + else + System.Ratio { numerator: ToQuantity(ratio.numerator), denominator: ToQuantity(ratio.denominator) } + +define function "ToInterval"(range FHIR.Range ): + if range is null then + null + else + Interval[ToQuantity(range.low), ToQuantity(range.high)] + +define function "ToCode"(coding FHIR.Coding ): + if coding is null then + null + else + System.Code { + code: coding.code.value, + system: coding.system.value, + version: coding.version.value, + display: coding.display.value + } + +define function "ToConcept"(concept FHIR.CodeableConcept ): + if concept is null then + null + else + System.Concept { + codes: concept.coding C return ToCode(C), + display: concept.text.value + } + +define function "ToString"(value AccountStatus ): + value.value + +define function "ToString"(value ActionCardinalityBehavior ): + value.value + +define function "ToString"(value ActionConditionKind ): + value.value + +define function "ToString"(value ActionGroupingBehavior ): + value.value + +define function "ToString"(value ActionParticipantType ): + value.value + +define function "ToString"(value ActionPrecheckBehavior ): + value.value + +define function "ToString"(value ActionRelationshipType ): + value.value + +define function "ToString"(value ActionRequiredBehavior ): + value.value + +define function "ToString"(value ActionSelectionBehavior ): + value.value + +define function "ToString"(value ActivityDefinitionKind ): + value.value + +define function "ToString"(value ActivityParticipantType ): + value.value + +define function "ToString"(value AddressType ): + value.value + +define function "ToString"(value AddressUse ): + value.value + +define function "ToString"(value AdministrativeGender ): + value.value + +define function "ToString"(value AdverseEventActuality ): + value.value + +define function "ToString"(value AggregationMode ): + value.value + +define function "ToString"(value AllergyIntoleranceCategory ): + value.value + +define function "ToString"(value AllergyIntoleranceCriticality ): + value.value + +define function "ToString"(value AllergyIntoleranceSeverity ): + value.value + +define function "ToString"(value AllergyIntoleranceType ): + value.value + +define function "ToString"(value AppointmentStatus ): + value.value + +define function "ToString"(value AssertionDirectionType ): + value.value + +define function "ToString"(value AssertionOperatorType ): + value.value + +define function "ToString"(value AssertionResponseTypes ): + value.value + +define function "ToString"(value AuditEventAction ): + value.value + +define function "ToString"(value AuditEventAgentNetworkType ): + value.value + +define function "ToString"(value AuditEventOutcome ): + value.value + +define function "ToString"(value BindingStrength ): + value.value + +define function "ToString"(value BiologicallyDerivedProductCategory ): + value.value + +define function "ToString"(value BiologicallyDerivedProductStatus ): + value.value + +define function "ToString"(value BiologicallyDerivedProductStorageScale ): + value.value + +define function "ToString"(value BundleType ): + value.value + +define function "ToString"(value CapabilityStatementKind ): + value.value + +define function "ToString"(value CarePlanActivityKind ): + value.value + +define function "ToString"(value CarePlanActivityStatus ): + value.value + +define function "ToString"(value CarePlanIntent ): + value.value + +define function "ToString"(value CarePlanStatus ): + value.value + +define function "ToString"(value CareTeamStatus ): + value.value + +define function "ToString"(value CatalogEntryRelationType ): + value.value + +define function "ToString"(value ChargeItemDefinitionPriceComponentType ): + value.value + +define function "ToString"(value ChargeItemStatus ): + value.value + +define function "ToString"(value ClaimResponseStatus ): + value.value + +define function "ToString"(value ClaimStatus ): + value.value + +define function "ToString"(value ClinicalImpressionStatus ): + value.value + +define function "ToString"(value CodeSearchSupport ): + value.value + +define function "ToString"(value CodeSystemContentMode ): + value.value + +define function "ToString"(value CodeSystemHierarchyMeaning ): + value.value + +define function "ToString"(value CommunicationPriority ): + value.value + +define function "ToString"(value CommunicationRequestStatus ): + value.value + +define function "ToString"(value CommunicationStatus ): + value.value + +define function "ToString"(value CompartmentCode ): + value.value + +define function "ToString"(value CompartmentType ): + value.value + +define function "ToString"(value CompositionAttestationMode ): + value.value + +define function "ToString"(value CompositionStatus ): + value.value + +define function "ToString"(value ConceptMapEquivalence ): + value.value + +define function "ToString"(value ConceptMapGroupUnmappedMode ): + value.value + +define function "ToString"(value ConditionalDeleteStatus ): + value.value + +define function "ToString"(value ConditionalReadStatus ): + value.value + +define function "ToString"(value ConsentDataMeaning ): + value.value + +define function "ToString"(value ConsentProvisionType ): + value.value + +define function "ToString"(value ConsentState ): + value.value + +define function "ToString"(value ConstraintSeverity ): + value.value + +define function "ToString"(value ContactPointSystem ): + value.value + +define function "ToString"(value ContactPointUse ): + value.value + +define function "ToString"(value ContractPublicationStatus ): + value.value + +define function "ToString"(value ContractStatus ): + value.value + +define function "ToString"(value ContributorType ): + value.value + +define function "ToString"(value CoverageStatus ): + value.value + +define function "ToString"(value CurrencyCode ): + value.value + +define function "ToString"(value DayOfWeek ): + value.value + +define function "ToString"(value DaysOfWeek ): + value.value + +define function "ToString"(value DetectedIssueSeverity ): + value.value + +define function "ToString"(value DetectedIssueStatus ): + value.value + +define function "ToString"(value DeviceMetricCalibrationState ): + value.value + +define function "ToString"(value DeviceMetricCalibrationType ): + value.value + +define function "ToString"(value DeviceMetricCategory ): + value.value + +define function "ToString"(value DeviceMetricColor ): + value.value + +define function "ToString"(value DeviceMetricOperationalStatus ): + value.value + +define function "ToString"(value DeviceNameType ): + value.value + +define function "ToString"(value DeviceRequestStatus ): + value.value + +define function "ToString"(value DeviceUseStatementStatus ): + value.value + +define function "ToString"(value DiagnosticReportStatus ): + value.value + +define function "ToString"(value DiscriminatorType ): + value.value + +define function "ToString"(value DocumentConfidentiality ): + value.value + +define function "ToString"(value DocumentMode ): + value.value + +define function "ToString"(value DocumentReferenceStatus ): + value.value + +define function "ToString"(value DocumentRelationshipType ): + value.value + +define function "ToString"(value EligibilityRequestPurpose ): + value.value + +define function "ToString"(value EligibilityRequestStatus ): + value.value + +define function "ToString"(value EligibilityResponsePurpose ): + value.value + +define function "ToString"(value EligibilityResponseStatus ): + value.value + +define function "ToString"(value EnableWhenBehavior ): + value.value + +define function "ToString"(value EncounterLocationStatus ): + value.value + +define function "ToString"(value EncounterStatus ): + value.value + +define function "ToString"(value EndpointStatus ): + value.value + +define function "ToString"(value EnrollmentRequestStatus ): + value.value + +define function "ToString"(value EnrollmentResponseStatus ): + value.value + +define function "ToString"(value EpisodeOfCareStatus ): + value.value + +define function "ToString"(value EventCapabilityMode ): + value.value + +define function "ToString"(value EventTiming ): + value.value + +define function "ToString"(value EvidenceVariableType ): + value.value + +define function "ToString"(value ExampleScenarioActorType ): + value.value + +define function "ToString"(value ExplanationOfBenefitStatus ): + value.value + +define function "ToString"(value ExposureState ): + value.value + +define function "ToString"(value ExtensionContextType ): + value.value + +define function "ToString"(value FHIRAllTypes ): + value.value + +define function "ToString"(value FHIRDefinedType ): + value.value + +define function "ToString"(value FHIRDeviceStatus ): + value.value + +define function "ToString"(value FHIRResourceType ): + value.value + +define function "ToString"(value FHIRSubstanceStatus ): + value.value + +define function "ToString"(value FHIRVersion ): + value.value + +define function "ToString"(value FamilyHistoryStatus ): + value.value + +define function "ToString"(value FilterOperator ): + value.value + +define function "ToString"(value FlagStatus ): + value.value + +define function "ToString"(value GoalLifecycleStatus ): + value.value + +define function "ToString"(value GraphCompartmentRule ): + value.value + +define function "ToString"(value GraphCompartmentUse ): + value.value + +define function "ToString"(value GroupMeasure ): + value.value + +define function "ToString"(value GroupType ): + value.value + +define function "ToString"(value GuidanceResponseStatus ): + value.value + +define function "ToString"(value GuidePageGeneration ): + value.value + +define function "ToString"(value GuideParameterCode ): + value.value + +define function "ToString"(value HTTPVerb ): + value.value + +define function "ToString"(value IdentifierUse ): + value.value + +define function "ToString"(value IdentityAssuranceLevel ): + value.value + +define function "ToString"(value ImagingStudyStatus ): + value.value + +define function "ToString"(value ImmunizationEvaluationStatus ): + value.value + +define function "ToString"(value ImmunizationStatus ): + value.value + +define function "ToString"(value InvoicePriceComponentType ): + value.value + +define function "ToString"(value InvoiceStatus ): + value.value + +define function "ToString"(value IssueSeverity ): + value.value + +define function "ToString"(value IssueType ): + value.value + +define function "ToString"(value LinkType ): + value.value + +define function "ToString"(value LinkageType ): + value.value + +define function "ToString"(value ListMode ): + value.value + +define function "ToString"(value ListStatus ): + value.value + +define function "ToString"(value LocationMode ): + value.value + +define function "ToString"(value LocationStatus ): + value.value + +define function "ToString"(value MeasureReportStatus ): + value.value + +define function "ToString"(value MeasureReportType ): + value.value + +define function "ToString"(value MediaStatus ): + value.value + +define function "ToString"(value MedicationAdministrationStatus ): + value.value + +define function "ToString"(value MedicationDispenseStatus ): + value.value + +define function "ToString"(value MedicationKnowledgeStatus ): + value.value + +define function "ToString"(value MedicationRequestIntent ): + value.value + +define function "ToString"(value MedicationRequestPriority ): + value.value + +define function "ToString"(value MedicationRequestStatus ): + value.value + +define function "ToString"(value MedicationStatementStatus ): + value.value + +define function "ToString"(value MedicationStatus ): + value.value + +define function "ToString"(value MessageSignificanceCategory ): + value.value + +define function "ToString"(value Messageheader_Response_Request ): + value.value + +define function "ToString"(value MimeType ): + value.value + +define function "ToString"(value NameUse ): + value.value + +define function "ToString"(value NamingSystemIdentifierType ): + value.value + +define function "ToString"(value NamingSystemType ): + value.value + +define function "ToString"(value NarrativeStatus ): + value.value + +define function "ToString"(value NoteType ): + value.value + +define function "ToString"(value NutritiionOrderIntent ): + value.value + +define function "ToString"(value NutritionOrderStatus ): + value.value + +define function "ToString"(value ObservationDataType ): + value.value + +define function "ToString"(value ObservationRangeCategory ): + value.value + +define function "ToString"(value ObservationStatus ): + value.value + +define function "ToString"(value OperationKind ): + value.value + +define function "ToString"(value OperationParameterUse ): + value.value + +define function "ToString"(value OrientationType ): + value.value + +define function "ToString"(value ParameterUse ): + value.value + +define function "ToString"(value ParticipantRequired ): + value.value + +define function "ToString"(value ParticipantStatus ): + value.value + +define function "ToString"(value ParticipationStatus ): + value.value + +define function "ToString"(value PaymentNoticeStatus ): + value.value + +define function "ToString"(value PaymentReconciliationStatus ): + value.value + +define function "ToString"(value ProcedureStatus ): + value.value + +define function "ToString"(value PropertyRepresentation ): + value.value + +define function "ToString"(value PropertyType ): + value.value + +define function "ToString"(value ProvenanceEntityRole ): + value.value + +define function "ToString"(value PublicationStatus ): + value.value + +define function "ToString"(value QualityType ): + value.value + +define function "ToString"(value QuantityComparator ): + value.value + +define function "ToString"(value QuestionnaireItemOperator ): + value.value + +define function "ToString"(value QuestionnaireItemType ): + value.value + +define function "ToString"(value QuestionnaireResponseStatus ): + value.value + +define function "ToString"(value ReferenceHandlingPolicy ): + value.value + +define function "ToString"(value ReferenceVersionRules ): + value.value + +define function "ToString"(value ReferredDocumentStatus ): + value.value + +define function "ToString"(value RelatedArtifactType ): + value.value + +define function "ToString"(value RemittanceOutcome ): + value.value + +define function "ToString"(value RepositoryType ): + value.value + +define function "ToString"(value RequestIntent ): + value.value + +define function "ToString"(value RequestPriority ): + value.value + +define function "ToString"(value RequestStatus ): + value.value + +define function "ToString"(value ResearchElementType ): + value.value + +define function "ToString"(value ResearchStudyStatus ): + value.value + +define function "ToString"(value ResearchSubjectStatus ): + value.value + +define function "ToString"(value ResourceType ): + value.value + +define function "ToString"(value ResourceVersionPolicy ): + value.value + +define function "ToString"(value ResponseType ): + value.value + +define function "ToString"(value RestfulCapabilityMode ): + value.value + +define function "ToString"(value RiskAssessmentStatus ): + value.value + +define function "ToString"(value SPDXLicense ): + value.value + +define function "ToString"(value SearchComparator ): + value.value + +define function "ToString"(value SearchEntryMode ): + value.value + +define function "ToString"(value SearchModifierCode ): + value.value + +define function "ToString"(value SearchParamType ): + value.value + +define function "ToString"(value SectionMode ): + value.value + +define function "ToString"(value SequenceType ): + value.value + +define function "ToString"(value ServiceRequestIntent ): + value.value + +define function "ToString"(value ServiceRequestPriority ): + value.value + +define function "ToString"(value ServiceRequestStatus ): + value.value + +define function "ToString"(value SlicingRules ): + value.value + +define function "ToString"(value SlotStatus ): + value.value + +define function "ToString"(value SortDirection ): + value.value + +define function "ToString"(value SpecimenContainedPreference ): + value.value + +define function "ToString"(value SpecimenStatus ): + value.value + +define function "ToString"(value Status ): + value.value + +define function "ToString"(value StrandType ): + value.value + +define function "ToString"(value StructureDefinitionKind ): + value.value + +define function "ToString"(value StructureMapContextType ): + value.value + +define function "ToString"(value StructureMapGroupTypeMode ): + value.value + +define function "ToString"(value StructureMapInputMode ): + value.value + +define function "ToString"(value StructureMapModelMode ): + value.value + +define function "ToString"(value StructureMapSourceListMode ): + value.value + +define function "ToString"(value StructureMapTargetListMode ): + value.value + +define function "ToString"(value StructureMapTransform ): + value.value + +define function "ToString"(value SubscriptionChannelType ): + value.value + +define function "ToString"(value SubscriptionStatus ): + value.value + +define function "ToString"(value SupplyDeliveryStatus ): + value.value + +define function "ToString"(value SupplyRequestStatus ): + value.value + +define function "ToString"(value SystemRestfulInteraction ): + value.value + +define function "ToString"(value TaskIntent ): + value.value + +define function "ToString"(value TaskPriority ): + value.value + +define function "ToString"(value TaskStatus ): + value.value + +define function "ToString"(value TestReportActionResult ): + value.value + +define function "ToString"(value TestReportParticipantType ): + value.value + +define function "ToString"(value TestReportResult ): + value.value + +define function "ToString"(value TestReportStatus ): + value.value + +define function "ToString"(value TestScriptRequestMethodCode ): + value.value + +define function "ToString"(value TriggerType ): + value.value + +define function "ToString"(value TypeDerivationRule ): + value.value + +define function "ToString"(value TypeRestfulInteraction ): + value.value + +define function "ToString"(value UDIEntryType ): + value.value + +define function "ToString"(value UnitsOfTime ): + value.value + +define function "ToString"(value Use ): + value.value + +define function "ToString"(value VariableType ): + value.value + +define function "ToString"(value VisionBase ): + value.value + +define function "ToString"(value VisionEyes ): + value.value + +define function "ToString"(value VisionStatus ): + value.value + +define function "ToString"(value XPathUsageType ): + value.value + +define function "ToString"(value base64Binary ): + value.value + +define function "ToString"(value id ): + value.value + +define function "ToBoolean"(value boolean ): + value.value + +define function "ToDate"(value date ): + value.value + +define function "ToDateTime"(value dateTime ): + value.value + +define function "ToDecimal"(value decimal ): + value.value + +define function "ToDateTime"(value instant ): + value.value + +define function "ToInteger"(value integer ): + value.value + +define function "ToString"(value string ): + value.value + +define function "ToTime"(value time ): + value.value + +define function "ToString"(value uri ): + value.value + +define function "ToString"(value xhtml ): + value.value +