CQL Examples - BD2KOnFHIR/FHIROntopOHDSI GitHub Wiki

Userful Links

CQL2SPARQL Transformation Example

CQL Header

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

0. set parameter MeasurementPeriod

    private static String measure_start_date = "2010-01-01";
    private static String measure_end_date = "2099-01-01";

1. define InDemographic

define InDemographic:
    AgeInYearsAt(start of MeasurementPeriod) >= 2 and AgeInYearsAt(start of MeasurementPeriod) < 18

SPARQL

    ?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)  

2. define Pharyngitis

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' )
}

3. define Antibiotics

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' )

4. define MeasurementPeriodEncounters

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"))

An Example of CQL Using FHIR

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]





⚠️ **GitHub.com Fallback** ⚠️