CQL Examples - BD2KOnFHIR/FHIROntopOHDSI GitHub Wiki
- https://github.com/cqframework/clinical_quality_language
- https://stackoverflow.com/questions/26252591/mac-os-x-and-multiple-java-versions
- https://github.com/anqit/spanqit/wiki
- CQL Education Materials: https://ecqi.healthit.gov/cql/cql-educational-resources
- CQL Engine: https://github.com/DBCG/cql_engine
- CQL Development: https://github.com/esacinc
- CQL-Formatting-and-Usage-Wiki: https://github.com/esacinc/CQL-Formatting-and-Usage-Wiki
- MAT: https://www.emeasuretool.cms.gov/
- Programming with RDF4J: http://docs.rdf4j.org/programming/
- Jena SPARQL: https://jena.apache.org/documentation/query/manipulating_sparql_using_arq.html
- XML Text Editor: https://github.com/kdekooter/xml-text-editor/
- How to Create an Executable JAR with Maven http://www.baeldung.com/executable-jar-with-maven
using FHIR
valueset "Acute Pharyngitis": '2.16.840.1.113883.3.464.1003.102.12.1011'
valueset "Acute Tonsillitis": '2.16.840.1.113883.3.464.1003.102.12.1012'
valueset "Ambulatory/ED Visit": '2.16.840.1.113883.3.464.1003.101.12.1061'
valueset "Antibiotic Medications": '2.16.840.1.113883.3.464.1003.196.12.1001'
valueset "Group A Streptococcus Test": '2.16.840.1.113883.3.464.1003.198.12.1012'
parameter MeasurementPeriod Interval<DateTime>
context Patient
private static String measure_start_date = "2010-01-01";
private static String measure_end_date = "2099-01-01";
define InDemographic:
AgeInYearsAt(start of MeasurementPeriod) >= 2 and AgeInYearsAt(start of MeasurementPeriod) < 18SPARQL
?patient fhir:Patient.birthDate ?bn_birthdate .
?bn_birthdate fhir:value ?birthdate .
FILTER ( (YEAR(?birthdate) - YEAR("2010-01-01")) >= 2 && (YEAR(?birthdate) - YEAR("2010-01-01")) < 18) define Pharyngitis:
[Condition: "Acute Pharyngitis"] union [Condition: "Acute Tonsillitis"]SPARQL
{ ?condition fhir:Condition.subject ?patient .
?condition fhir:Condition.code ?coding_code .
?coding_code fhir:Coding.code ?bn_code .
?bn_code fhir:value ?code .
FILTER (str(?code) = '1532007' || str(?code) = '195655000' || str(?code) = '195656004' || str(?code) = '195657008' || str(?code) = '195658003' || str(?code) = '195659006' || str(?code) = '195660001' || str(?code) = '195662009' || str(?code) = '232399005' || str(?code) = '232400003' || str(?code) = '363746003' || str(?code) = '40766000' || str(?code) = '43878008' || str(?code) = '58031004' || str(?code) = 'J02.0' || str(?code) = 'J02.8' || str(?code) = 'J02.9' )
?coding_code fhir:Coding.system ?bn_system .
?bn_system fhir:value ?system .
FILTER (str(?system) = 'SNOMEDCT' || str(?system) = 'ICD10CM' )
}
UNION
{ ?condition fhir:Condition.subject ?patient .
?condition fhir:Condition.code ?coding_code .
?coding_code fhir:Coding.code ?bn_code .
?bn_code fhir:value ?code .
FILTER (str(?code) = '10629271000119107' || str(?code) = '17741008' || str(?code) = '195666007' || str(?code) = '195668008' || str(?code) = '195669000' || str(?code) = '195670004' || str(?code) = '195671000' || str(?code) = '195672007' || str(?code) = '195673002' || str(?code) = '195676005' || str(?code) = '195677001' || str(?code) = '302911003' || str(?code) = 'J03.00' || str(?code) = 'J03.01' || str(?code) = 'J03.80' || str(?code) = 'J03.81' || str(?code) = 'J03.90' || str(?code) = 'J03.91' )
?coding_code fhir:Coding.sytem ?bn_system .
?bn_system fhir:value ?system .
FILTER (str(?system) = 'SNOMEDCT' || str(?system) = 'ICD10CM' )
}
define Antibiotics:
[MedicationRequest: "Antibiotic Medications"]
SPARQL
?medicationrequest fhir:MedicationRequest.subject ?patient .
?medicationrequest fhir:MedicationRequest.medicationCodeableConcept ?coding_code .
?coding_code fhir:Coding.code ?bn_code .
?bn_code fhir:value ?code .
FILTER (str(?code) = '1013659' || str(?code) = '1013662' || str(?code) = '1013665' || str(?code) = '1043022' || str(?code) = '1043027' || str(?code) = '1043030' || str(?code) = '105171' || str(?code) = '1088677' || str(?code) = '1148107' || str(?code) = '1302650' || str(?code) = '1302659' || str(?code) = '1302664' || str(?code) = '1302669' || str(?code) = '1302674' || str(?code) = '1373014' || str(?code) = '141963' || str(?code) = '142118' || str(?code) = '1423080' || str(?code) = '1648755' || str(?code) = '1648759' || str(?code) = '1649401' || str(?code) = '1649405' || str(?code) = '1649425' || str(?code) = '1649429' || str(?code) = '1649988' || str(?code) = '1649990' || str(?code) = '1650030' || str(?code) = '1650142' || str(?code) = '1650143' || str(?code) = '1650444' || str(?code) = '1650446' || str(?code) = '1652673' || str(?code) = '1652674' || str(?code) = '1653433' || str(?code) = '1656313' || str(?code) = '1656318' || str(?code) = '1659131' || str(?code) = '1659137' || str(?code) = '1659149' || str(?code) = '1659278' || str(?code) = '1659283' || str(?code) = '1659287' || str(?code) = '1659592' || str(?code) = '1659598' || str(?code) = '1662283' || str(?code) = '1662285' || str(?code) = '1664981' || str(?code) = '1664986' || str(?code) = '1665005' || str(?code) = '1665021' || str(?code) = '1665046' || str(?code) = '1665050' || str(?code) = '1665052' || str(?code) = '1665060' || str(?code) = '1665088' || str(?code) = '1665093' || str(?code) = '1665097' || str(?code) = '1665102' || str(?code) = '1665107' || str(?code) = '1665210' || str(?code) = '1665212' || str(?code) = '1665227' || str(?code) = '1665229' || str(?code) = '1665444' || str(?code) = '1665449' || str(?code) = '1665497' || str(?code) = '1665507' || str(?code) = '1665515' || str(?code) = '1665517' || str(?code) = '1665519' || str(?code) = '1668238' || str(?code) = '1668264' || str(?code) = '1721458' || str(?code) = '1721460' || str(?code) = '1721473' || str(?code) = '1721474' || str(?code) = '1721475' || str(?code) = '1721476' || str(?code) = '1722916' || str(?code) = '1722919' || str(?code) = '1722921' || str(?code) = '1723156' || str(?code) = '1723160' || str(?code) = '1727174' || str(?code) = '1728082' || str(?code) = '1728087' || str(?code) = '1737244' || str(?code) = '1737578' || str(?code) = '1737581' || str(?code) = '1739890' || str(?code) = '1743547' || str(?code) = '1743549' || str(?code) = '1747115' || str(?code) = '1747121' || str(?code) = '1791505' || str(?code) = '1801138' || str(?code) = '1801142' || str(?code) = '1807508' || str(?code) = '1807510' || str(?code) = '1807511' || str(?code) = '1807513' || str(?code) = '1807516' || str(?code) = '1807518' || str(?code) = '1870631' || str(?code) = '1870633' || str(?code) = '1870650' || str(?code) = '1870676' || str(?code) = '1870681' || str(?code) = '1870685' || str(?code) = '1870686' || str(?code) = '197449' || str(?code) = '197451' || str(?code) = '197452' || str(?code) = '197453' || str(?code) = '197454' || str(?code) = '197511' || str(?code) = '197512' || str(?code) = '197516' || str(?code) = '197517' || str(?code) = '197518' || str(?code) = '197595' || str(?code) = '197596' || str(?code) = '197650' || str(?code) = '197984' || str(?code) = '197985' || str(?code) = '198044' || str(?code) = '198048' || str(?code) = '198049' || str(?code) = '198050' || str(?code) = '198201' || str(?code) = '198202' || str(?code) = '198250' || str(?code) = '198252' || str(?code) = '198332' || str(?code) = '198334' || str(?code) = '198335' || str(?code) = '199055' || str(?code) = '199327' || str(?code) = '199332' || str(?code) = '199370' || str(?code) = '199620' || str(?code) = '199802' || str(?code) = '199884' || str(?code) = '199885' || str(?code) = '200346' || str(?code) = '204466' || str(?code) = '204844' || str(?code) = '205964' || str(?code) = '207362' || str(?code) = '207364' || str(?code) = '207390' || str(?code) = '207391' || str(?code) = '226633' || str(?code) = '239189' || str(?code) = '239191' || str(?code) = '239204' || str(?code) = '239209' || str(?code) = '240637' || str(?code) = '240741' || str(?code) = '240984' || str(?code) = '242800' || str(?code) = '242825' || str(?code) = '245240' || str(?code) = '245837' || str(?code) = '247673' || str(?code) = '248656' || str(?code) = '259290' || str(?code) = '283535' || str(?code) = '284215' || str(?code) = '308177' || str(?code) = '308181' || str(?code) = '308182' || str(?code) = '308188' || str(?code) = '308189' || str(?code) = '308191' || str(?code) = '308192' || str(?code) = '308194' || str(?code) = '308207' || str(?code) = '308210' || str(?code) = '308212' || str(?code) = '308459' || str(?code) = '308460' || str(?code) = '309040' || str(?code) = '309043' || str(?code) = '309044' || str(?code) = '309045' || str(?code) = '309047' || str(?code) = '309048' || str(?code) = '309049' || str(?code) = '309054' || str(?code) = '309058' || str(?code) = '309065' || str(?code) = '309068' || str(?code) = '309072' || str(?code) = '309076' || str(?code) = '309077' || str(?code) = '309078' || str(?code) = '309079' || str(?code) = '309080' || str(?code) = '309081' || str(?code) = '309085' || str(?code) = '309086' || str(?code) = '309087' || str(?code) = '309090' || str(?code) = '309092' || str(?code) = '309095' || str(?code) = '309096' || str(?code) = '309097' || str(?code) = '309098' || str(?code) = '309101' || str(?code) = '309110' || str(?code) = '309112' || str(?code) = '309113' || str(?code) = '309114' || str(?code) = '309115' || str(?code) = '309308' || str(?code) = '309309' || str(?code) = '309310' || str(?code) = '309322' || str(?code) = '309329' || str(?code) = '309335' || str(?code) = '309336' || str(?code) = '309339' || str(?code) = '310026' || str(?code) = '310027' || str(?code) = '310028' || str(?code) = '310154' || str(?code) = '310155' || str(?code) = '310157' || str(?code) = '311296' || str(?code) = '311681' || str(?code) = '311787' || str(?code) = '311989' || str(?code) = '311991' || str(?code) = '311994' || str(?code) = '311995' || str(?code) = '312127' || str(?code) = '312128' || str(?code) = '312447' || str(?code) = '313115' || str(?code) = '313134' || str(?code) = '313137' || str(?code) = '313416' || str(?code) = '313570' || str(?code) = '313571' || str(?code) = '313572' || str(?code) = '313797' || str(?code) = '313799' || str(?code) = '313800' || str(?code) = '313850' || str(?code) = '313888' || str(?code) = '313920' || str(?code) = '313926' || str(?code) = '313996' || str(?code) = '314106' || str(?code) = '314108' || str(?code) = '315090' || str(?code) = '315209' || str(?code) = '317127' || str(?code) = '348869' || str(?code) = '348870' || str(?code) = '351127' || str(?code) = '351156' || str(?code) = '359383' || str(?code) = '359385' || str(?code) = '388510' || str(?code) = '403840' || str(?code) = '403920' || str(?code) = '403921' || str(?code) = '406524' || str(?code) = '409823' || str(?code) = '419849' || str(?code) = '434018' || str(?code) = '476576' || str(?code) = '477391' || str(?code) = '562251' || str(?code) = '562266' || str(?code) = '562508' || str(?code) = '562707' || str(?code) = '577378' || str(?code) = '597455' || str(?code) = '597761' || str(?code) = '597823' || str(?code) = '598006' || str(?code) = '598025' || str(?code) = '617296' || str(?code) = '617302' || str(?code) = '617309' || str(?code) = '617316' || str(?code) = '617322' || str(?code) = '617423' || str(?code) = '617430' || str(?code) = '617993' || str(?code) = '617995' || str(?code) = '629695' || str(?code) = '629697' || str(?code) = '629699' || str(?code) = '636559' || str(?code) = '637173' || str(?code) = '637560' || str(?code) = '645617' || str(?code) = '686355' || str(?code) = '686383' || str(?code) = '686400' || str(?code) = '686405' || str(?code) = '686406' || str(?code) = '686418' || str(?code) = '700408' || str(?code) = '728207' || str(?code) = '731538' || str(?code) = '731564' || str(?code) = '731567' || str(?code) = '731570' || str(?code) = '745302' || str(?code) = '745462' || str(?code) = '745560' || str(?code) = '749780' || str(?code) = '749783' || str(?code) = '757460' || str(?code) = '757464' || str(?code) = '757466' || str(?code) = '761979' || str(?code) = '789980' || str(?code) = '799048' || str(?code) = '802550' || str(?code) = '834040' || str(?code) = '834046' || str(?code) = '834061' || str(?code) = '834102' || str(?code) = '835341' || str(?code) = '835700' || str(?code) = '836306' || str(?code) = '847360' || str(?code) = '858062' || str(?code) = '858372' || str(?code) = '863538' || str(?code) = '877486' || str(?code) = '901399' )
?coding_code fhir:Coding.system ?bn_system .
?bn_system fhir:value ?system .
FILTER (str(?system) = 'RXNORM' )
define MeasurementPeriodEncounters:
[Encounter: "Ambulatory/ED Visit"] E
where InDemographic and Interval[E.period."start".value, E.period."end".value] during MeasurementPeriod
SPARQL
?encounter fhir:Encounter.subject ?patient .
?encounter fhir:Encounter.type ?coding_code .
?coding_code fhir:Coding.code ?bn_code .
?bn_code fhir:value ?code .
FILTER (str(?code) = '12843005' || str(?code) = '18170008' || str(?code) = '185349003' || str(?code) = '185463005' || str(?code) = '185465003' || str(?code) = '19681004' || str(?code) = '207195004' || str(?code) = '270427003' || str(?code) = '270430005' || str(?code) = '308335008' || str(?code) = '390906007' || str(?code) = '406547006' || str(?code) = '439708006' || str(?code) = '87790002' || str(?code) = '90526000' || str(?code) = '99201' || str(?code) = '99202' || str(?code) = '99203' || str(?code) = '99204' || str(?code) = '99205' || str(?code) = '99212' || str(?code) = '99213' || str(?code) = '99214' || str(?code) = '99215' || str(?code) = '99217' || str(?code) = '99218' || str(?code) = '99219' || str(?code) = '99220' || str(?code) = '99241' || str(?code) = '99242' || str(?code) = '99243' || str(?code) = '99244' || str(?code) = '99245' || str(?code) = '99281' || str(?code) = '99282' || str(?code) = '99283' || str(?code) = '99284' || str(?code) = '99285' || str(?code) = '99341' || str(?code) = '99342' || str(?code) = '99343' || str(?code) = '99344' || str(?code) = '99345' || str(?code) = '99347' || str(?code) = '99348' || str(?code) = '99349' || str(?code) = '99350' || str(?code) = '99381' || str(?code) = '99382' || str(?code) = '99383' || str(?code) = '99384' || str(?code) = '99385' || str(?code) = '99386' || str(?code) = '99387' || str(?code) = '99391' || str(?code) = '99392' || str(?code) = '99393' || str(?code) = '99394' || str(?code) = '99395' || str(?code) = '99396' || str(?code) = '99397' || str(?code) = '99401' || str(?code) = '99402' || str(?code) = '99403' || str(?code) = '99404' || str(?code) = '99411' || str(?code) = '99412' || str(?code) = '99429' || str(?code) = '99455' || str(?code) = '99456' )
?coding_code fhir:Coding.system ?bn_system .
?bn_system fhir:value ?system .
FILTER (str(?system) = 'SNOMEDCT' || str(?system) = 'CPT' )
?patient fhir:Patient.birthDate ?bn_birthdate .
?bn_birthdate fhir:value ?birthdate .
FILTER ( (YEAR(?birthdate) - YEAR("2010-01-01")) >= 2 && (YEAR(?birthdate) - YEAR("2099-01-01")) < 18)
?encounter fhir:Encounter.period ?bn_period .
?bn_period fhir:Period.start ?bn_start .
?bn_start fhir:value ?start_date .
?bn_period fhir:Period.end ?bn_end .
?bn_end fhir:value ?end_date .
FILTER ( YEAR(?start_date) >= YEAR("2010-01-01") && YEAR(?end_date) <= YEAR("2099-01-01"))
library CMS146 version '2'
/* CMS 146v2
*
* ============================================================================
* QDM Logic
* ============================================================================
* Initial Patient Population =
* AND: "Patient Characteristic Birthdate: birth date" >= 2 year(s) starts before start of "Measurement Period"
* AND: "Patient Characteristic Birthdate: birth date" < 18 year(s) starts before start of "Measurement Period"
* AND:
* AND: "Occurrence A of Encounter, Performed: Ambulatory/ED Visit" during "Measurement Period"
* AND: "Medication, Order: Antibiotic Medications" <= 3 day(s) starts after start of "Occurrence A of Encounter, Performed: Ambulatory/ED Visit"
* AND:
* OR: "Occurrence A of Encounter, Performed: Ambulatory/ED Visit" during
* OR: "Occurrence A of Diagnosis, Active: Acute Pharyngitis"
* OR: "Occurrence A of Diagnosis, Active: Acute Tonsillitis"
* OR:
* OR: "Occurrence A of Diagnosis, Active: Acute Pharyngitis"
* OR: "Occurrence A of Diagnosis, Active: Acute Tonsillitis"
* starts during "Occurrence A of Encounter, Performed: Ambulatory/ED Visit"
*
* Denominator =
* AND: "Initial Patient Population"
*
* Denominator Exclusions =
* AND: "Medication, Active: Antibiotic Medications" <= 30 day(s) starts before start of
* OR: "Occurrence A of Diagnosis, Active: Acute Pharyngitis"
* OR: "Occurrence A of Diagnosis, Active: Acute Tonsillitis"
*
* Numerator =
* AND:
* OR: "Laboratory Test, Result: Group A Streptococcus Test (result)" <= 3 day(s) starts before or during "Occurrence A of Encounter, Performed: Ambulatory/ED Visit"
* OR: "Laboratory Test, Result: Group A Streptococcus Test (result)" <= 3 day(s) starts after end of "Occurrence A of Encounter, Performed: Ambulatory/ED Visit"
*
* Denominator Exceptions =
* None
* ============================================================================
*/
using FHIR
valueset "Acute Pharyngitis": '2.16.840.1.113883.3.464.1003.102.12.1011'
valueset "Acute Tonsillitis": '2.16.840.1.113883.3.464.1003.102.12.1012'
valueset "Ambulatory/ED Visit": '2.16.840.1.113883.3.464.1003.101.12.1061'
valueset "Antibiotic Medications": '2.16.840.1.113883.3.464.1003.196.12.1001'
valueset "Group A Streptococcus Test": '2.16.840.1.113883.3.464.1003.198.12.1012'
parameter MeasurementPeriod Interval<DateTime>
context Patient
define InDemographic:
AgeInYearsAt(start of MeasurementPeriod) >= 2 and AgeInYearsAt(start of MeasurementPeriod) < 18
define Pharyngitis:
[Condition: "Acute Pharyngitis"] union [Condition: "Acute Tonsillitis"]
define Antibiotics:
[MedicationRequest: "Antibiotic Medications"]
define MeasurementPeriodEncounters:
[Encounter: "Ambulatory/ED Visit"] E
where InDemographic and Interval[E.period."start".value, E.period."end".value] during MeasurementPeriod
define PharyngitisEncounters:
MeasurementPeriodEncounters E
with Pharyngitis P
such that Interval[P.onsetDateTime.value, P.abatementDateTime.value] includes Interval[E.period."start".value, E.period."end".value]
or P.onsetDateTime.value in E.period
with Antibiotics A such that A.dateWritten 3 days or less after start of E.period
define PharyngitisWithPriorAntibiotics:
Pharyngitis P
with Antibiotics A such that A.dateWritten 30 days or less before P.onsetDateTime
define ExcludedEncounters:
PharyngitisEncounters E
with PharyngitisWithPriorAntibiotics P
such that Interval[P.onsetDateTime, P.abatementDate] includes E.period
or P.onsetDateTime in E.period
define StrepTestEncounters:
PharyngitisEncounters E
with [DiagnosticReport: "Group A Streptococcus Test"] T
such that T.result is not null
and T.issued in Interval[start of E.period - 3 days, end of E.period + 3 days]