Generated Narrative: Library OpioidCDSR4Common Participants Author Kensaku Kawamoto, MD, PhD, MHS Author Bryn Rhodes Author Floyd Eisenberg, MD, MPH Author Robert McClure, MD, MPH Related Artifacts Documentation CDC guideline for prescribing opioids for chronic pain https://www.cdc.gov/mmwr/volumes/65/rr/rr6501e1.htm?CDC_AA_refVal=https%3A%2F%2Fwww.cdc.gov%2Fmmwr%2Fvolumes%2F65%2Frr%2Frr6501e1er.htm Depends On Library OMTKLogic http://cqframework.org/cpg-example-opioids/Library/OMTKLogic|0.0.0 Depends On Code System SNOMED SNOMED CT (all versions) Depends On Code System Medication Request Category Codes MedicationRequest Category Codes Depends On Value Set Active Condition CPG Active Condition Value Set Depends On Value Set Benzodiazepines http://fhir.org/guides/cdc/opioid-cds/ValueSet/benzodiazepines-medications Depends On Value Set End of Life Conditions http://fhir.org/guides/cdc/opioid-cds/ValueSet/end-of-life-conditions Depends On Value Set Hospice Disposition http://fhir.org/guides/cdc/opioid-cds/ValueSet/hospice-disposition Depends On Value Set Hospice Finding Codes http://fhir.org/guides/cdc/opioid-cds/ValueSet/hospice-finding Depends On Value Set Hospice Procedure Codes http://fhir.org/guides/cdc/opioid-cds/ValueSet/hospice-procedure Depends On Value Set Illicit Drug Screening http://fhir.org/guides/cdc/opioid-cds/ValueSet/illicit-drug-urine-screening Depends On Value Set Limited Life Expectancy Conditions http://fhir.org/guides/cdc/opioid-cds/ValueSet/limited-life-expectancy-conditions Depends On Value Set Long Acting Opioids http://fhir.org/guides/cdc/opioid-cds/ValueSet/long-acting-opioids Depends On Value Set Naloxone http://fhir.org/guides/cdc/opioid-cds/ValueSet/naloxone-medications Depends On Value Set Risk Assessment http://fhir.org/guides/cdc/opioid-cds/ValueSet/opioid-abuse-assessment Depends On Value Set Opioid Drug Screening http://fhir.org/guides/cdc/opioid-cds/ValueSet/opioid-urine-screening Depends On Value Set Ambulatory Abuse Potential Opioids http://fhir.org/guides/cdc/opioid-cds/ValueSet/opioids-abused-in-ambulatory-care Depends On Value Set Substance Abuse http://fhir.org/guides/cdc/opioid-cds/ValueSet/substance-abuse Parameters IsForChronicPain out 0 1 boolean Active Ambulatory Opioid Rx out 0 * MedicationRequest Active Ambulatory Benzodiazepine Rx out 0 * MedicationRequest Active Ambulatory Naloxone Rx out 0 * MedicationRequest Ambulatory Opioid Rx out 0 * MedicationRequest End of Life Assessment out 0 1 boolean Data Requirements Type: MedicationRequest Filter Value medication In ValueSet http://fhir.org/guides/cdc/opioid-cds/ValueSet/opioids-abused-in-ambulatory-care Type: MedicationRequest Type: Medication Type: MedicationRequest Filter Value medication In ValueSet http://fhir.org/guides/cdc/opioid-cds/ValueSet/benzodiazepines-medications Type: MedicationRequest Type: Medication Type: MedicationRequest Filter Value medication In ValueSet http://fhir.org/guides/cdc/opioid-cds/ValueSet/naloxone-medications Type: MedicationRequest Type: Medication Type: MedicationRequest Filter Value medication In ValueSet http://fhir.org/guides/cdc/opioid-cds/ValueSet/opioids-abused-in-ambulatory-care Type: MedicationRequest Type: Medication Type: Condition Filter Value code In ValueSet http://fhir.org/guides/cdc/opioid-cds/ValueSet/end-of-life-conditions Type: Condition Filter Value code In ValueSet http://fhir.org/guides/cdc/opioid-cds/ValueSet/limited-life-expectancy-conditions Type: ServiceRequest Filter Value code One of these codes: SNOMED CT 306205009: Referral to hospice Type: ServiceRequest Filter Value code In ValueSet http://fhir.org/guides/cdc/opioid-cds/ValueSet/hospice-procedure Type: ServiceRequest Filter Value code In ValueSet http://fhir.org/guides/cdc/opioid-cds/ValueSet/hospice-procedure Type: Observation Filter Value code In ValueSet http://fhir.org/guides/cdc/opioid-cds/ValueSet/hospice-finding Type: Encounter Contents text/cql library OpioidCDSR4Common version '0.1.0' using FHIR version '4.0.0' include FHIRHelpers version '4.0.0' called FHIRHelpers include OMTKLogic version '0.0.0' called OMTKLogic codesystem "SNOMED": 'http://snomed.info/sct' codesystem "Medication Request Category Codes": 'http://terminology.hl7.org/CodeSystem/medicationrequest-category' valueset "Active Condition": 'http://hl7.org/fhir/uv/cpg/ValueSet/cpg-active-condition-vs' valueset "Benzodiazepines": 'http://fhir.org/guides/cdc/opioid-cds/ValueSet/benzodiazepines-medications' // TODO: Fix this name valueset "End of Life Conditions": 'http://fhir.org/guides/cdc/opioid-cds/ValueSet/end-of-life-conditions' // Harvested from VSAC - OID: 2.16.840.1.113762.1.4.1108.15 // NOTE: This harvest note is incorrect, none of the following 3 value sets contain any of the codes in the above referenced valueset // Rob will construct an appropriate hospice value set aligned with current eCQM program usage and we will use that when available valueset "Hospice Disposition": 'http://fhir.org/guides/cdc/opioid-cds/ValueSet/hospice-disposition' valueset "Hospice Finding Codes": 'http://fhir.org/guides/cdc/opioid-cds/ValueSet/hospice-finding' valueset "Hospice Procedure Codes": 'http://fhir.org/guides/cdc/opioid-cds/ValueSet/hospice-procedure' valueset "Illicit Drug Screening": 'http://fhir.org/guides/cdc/opioid-cds/ValueSet/illicit-drug-urine-screening' // Harvested from VSAC - OID: 2.16.840.1.113883.3.526.3.1259 valueset "Limited Life Expectancy Conditions": 'http://fhir.org/guides/cdc/opioid-cds/ValueSet/limited-life-expectancy-conditions' valueset "Long Acting Opioids": 'http://fhir.org/guides/cdc/opioid-cds/ValueSet/long-acting-opioids' valueset "Naloxone": 'http://fhir.org/guides/cdc/opioid-cds/ValueSet/naloxone-medications' valueset "Risk Assessment": 'http://fhir.org/guides/cdc/opioid-cds/ValueSet/opioid-abuse-assessment' valueset "Opioid Drug Screening": 'http://fhir.org/guides/cdc/opioid-cds/ValueSet/opioid-urine-screening' valueset "Ambulatory Abuse Potential Opioids": 'http://fhir.org/guides/cdc/opioid-cds/ValueSet/opioids-abused-in-ambulatory-care' valueset "Substance Abuse": 'http://fhir.org/guides/cdc/opioid-cds/ValueSet/substance-abuse' // TODO: Turn this into a valueset code "Referral to Hospice": '306205009' from "SNOMED" // TODO: Turn this into a valueset code "Outpatient": 'outpatient' from "Medication Request Category Codes" // TODO: Capture process decisions for long-term opioid use define IsForChronicPain: true define "Active Ambulatory Opioid Rx": [MedicationRequest: "Ambulatory Abuse Potential Opioids"] Rx where Rx.status = 'active' and ToCodes(Rx.category.coding) contains "Outpatient" define "Active Ambulatory Benzodiazepine Rx": [MedicationRequest: "Benzodiazepines"] Rx where Rx.status = 'active' and ToCodes(Rx.category.coding) contains "Outpatient" define "Active Ambulatory Naloxone Rx": [MedicationRequest: "Naloxone"] Rx where Rx.status = 'active' and ToCodes(Rx.category.coding) contains "Outpatient" define "Ambulatory Opioid Rx": [MedicationRequest: "Ambulatory Abuse Potential Opioids"] Rx where ToCodes(Rx.category.coding) contains "Outpatient" define "End of Life Assessment": // 1. Conditions indicating end of life or with limited life expectancy exists ( ( [Condition: "End of Life Conditions"] C where C.clinicalStatus in "Active Condition" ) union ( [Condition: code in "Limited Life Expectancy Conditions"] C where C.clinicalStatus in "Active Condition" ) ) // 2. Admitted/referred/discharged to hospice care or exists ( ( [ServiceRequest: code in "Referral to Hospice"] RR where RR.status in { 'active', 'completed' } ) union ( [ServiceRequest: code in "Hospice Procedure Codes"] P where P.status in { 'in-progress', 'completed' } ) union ( [ServiceRequest: code in "Hospice Procedure Codes"] E where E.status in { 'planned', 'arrived', 'in-progress', 'finished', 'onleave' } ) union ( [Observation: code in "Hospice Finding Codes"] O where not (O.status in { 'unknown', 'entered-in-error', 'cancelled' }) ) union ( [Encounter] E where ( if E.hospitalization.dischargeDisposition.coding is null or not exists (E.hospitalization.dischargeDisposition.coding) then false else E.hospitalization.dischargeDisposition in "Hospice Disposition" ) and E.status in { 'planned', 'arrived', 'in-progress', 'finished', 'onleave' } ) ) define function Prescriptions(Orders List<MedicationRequest>): Orders O let // NOTE: Assuming medication is specified as a CodeableConcept with a single RxNorm code rxNormCode: ToCode(O.medication.coding[0]), medicationName: OMTKLogic.GetMedicationName(rxNormCode), // NOTE: Assuming a single dosage instruction element dosageInstruction: O.dosageInstruction[0], repeat: dosageInstruction.timing.repeat, frequency: Coalesce(repeat.frequencyMax.value, repeat.frequency.value), period: System.Quantity { value: repeat.period.value, unit: repeat.periodUnit.value }, doseDescription: Coalesce( // There should be a conversion from FHIR.SimpleQuantity to System.Quantity if dosageInstruction.doseAndRate[0].dose is FHIR.Range then ToString(ToQuantity(dosageInstruction.doseAndRate[0].dose.low)) + '-' + ToString(ToQuantity(dosageInstruction.doseAndRate[0].dose.high)) + dosageInstruction.doseAndRate[0].dose.high.unit.value else ToString(ToQuantity(dosageInstruction.doseAndRate[0].dose)), '' ), frequencyDescription: ToString(dosageInstruction.timing.repeat.frequency.value) + Coalesce( '-' + ToString(dosageInstruction.timing.repeat.frequencyMax.value), '' ) return { rxNormCode: rxNormCode, isDraft: O.status.value = 'draft', // NOTE: Assuming asNeeded is expressed as a boolean isPRN: dosageInstruction.asNeeded.value, prescription: if dosageInstruction.text is not null then medicationName + ' ' + dosageInstruction.text.value else // TODO: Shouldn't need the .value here on asNeededBoolean medicationName + ' ' + doseDescription + ' q' + frequencyDescription + (if dosageInstruction.asNeeded.value then ' PRN' else ''), // TODO: Shouldn't need the ToQuantity here... dose: if dosageInstruction.doseAndRate[0].dose is FHIR.Range then ToQuantity(dosageInstruction.doseAndRate[0].dose.high) else ToQuantity(dosageInstruction.doseAndRate[0].dose), dosesPerDay: Coalesce(OMTKLogic.ToDaily(frequency, period), 1.0) } define function MME(prescriptions List<MedicationRequest>): (Prescriptions(prescriptions)) P let mme: SingletonFrom(OMTKLogic.CalculateMMEs({ { rxNormCode: P.rxNormCode, doseQuantity: P.dose, dosesPerDay: P.dosesPerDay } })) return { rxNormCode: P.rxNormCode, isDraft: P.isDraft, isPRN: P.isPRN, prescription: P.prescription, dailyDose: mme.dailyDoseDescription, conversionFactor: mme.conversionFactor, mme: mme.mme } define function TotalMME(prescriptions List<MedicationRequest>): System.Quantity { value: Sum((MME(prescriptions)) M return M.mme.value), unit: 'mg/d' } define function ProbableDaysInRange(Orders List<MedicationRequest>, daysPast Integer, numDaysInDaysPast Integer): Orders orders let frequency: orders.dosageInstruction[0].timing.repeat.frequency.value, period: orders.dosageInstruction[0].timing.repeat.period.value, periodDays: GetPeriodDays(orders.dosageInstruction[0].timing.repeat.periodUnit.value), dosesPerDay: if (frequency / (period * periodDays)) >= 1.0 then 1.0 else frequency / (period * periodDays), repeat: orders.dispenseRequest.numberOfRepeatsAllowed.value, supplyDuration: GetDurationInDays(orders.dispenseRequest.expectedSupplyDuration), validityPeriod: days between orders.dispenseRequest.validityPeriod."start".value and Today(), endDifference: if orders.dispenseRequest.validityPeriod."end".value < Today() then days between orders.dispenseRequest.validityPeriod."end".value and Today() else 0 return if (repeat * supplyDuration) < numDaysInDaysPast then false else (dosesPerDay * ((repeat * supplyDuration) / validityPeriod) * (daysPast - endDifference)) >= numDaysInDaysPast define function GetPeriodDays(value System.String): case when value = 'a' then 365.0 when value = 'mo' then 30.0 when value = 'h' then 1.0/24.0 when value = 'min' then 1.0/24.0*60.0 when value = 's' then 1.0/24.0*60.0*60.0 when value = 'ms' then 1.0/24.0*60.0*60.0*1000.0 else 1.0 end define function GetDurationInDays(value FHIR.Duration): case when StartsWith(value.unit.value, 'a') then value.value.value * 365.0 when StartsWith(value.unit.value, 'mo') then value.value.value * 30.0 when StartsWith(value.unit.value, 'wk') then value.value.value * 7.0 when StartsWith(value.unit.value, 'd') then value.value.value when StartsWith(value.unit.value, 'h') then value.value.value / 24.0 when StartsWith(value.unit.value, 'min') then value.value.value / 60.0 / 24.0 when StartsWith(value.unit.value, 's') then value.value.value / 60.0 / 60.0 / 24.0 when StartsWith(value.unit.value, 'ms') then value.value.value / 60.0 / 60.0 / 24.0 / 1000.0 else Message(1000, true, 'Undefined', 'Error', 'Unsupported duration unit') end define function GetIngredient(rxNormCode Code): OMTKLogic.GetIngredients(rxNormCode).ingredientName define function GetIngredients(rxNormCodes List<Code>): rxNormCodes rnc return GetIngredient(rnc) define function GetMedicationNames(medications List<MedicationRequest>): medications M return OMTKLogic.GetIngredients(ToRxNormCode(M.medication.coding)).rxNormCode.display /* * Conversion Functions */ define function ToCode(coding FHIR.Coding): System.Code { code: coding.code.value, system: coding.system.value, version: coding.version.value, display: coding.display.value } define function ToCodes(coding List<FHIR.Coding>): coding c return ToCode(c) define function ToRxNormCode(coding List<FHIR.Coding>): singleton from ( coding C where C.system = 'http://www.nlm.nih.gov/research/umls/rxnorm' ) define function ToQuantity(quantity FHIR.Quantity): System.Quantity { value: quantity.value.value, unit: quantity.unit.value } Content not shown - (application/elm+xml, size = 286Kb )
HL7 International - Clinical Decision Support WG
Common Opioid Decision Support Logic for use in implementing CDC Opioid Prescribing Guidelines.
This library contains common logic across recommendations including MME calculations, conversions, and looking up codes in valuesets.
This library is used for decision support for opioid guideline recommendations when applying PlanDefinitions.
CDC guideline for prescribing opioids for chronic pain
Code System Medication Request Category Codes
Value Set Limited Life Expectancy Conditions
Value Set Ambulatory Abuse Potential Opioids