2022 CDC Clinical Practice Guideline for Prescribing Opioids Implementation Guide
2022.1.0 - CI Build

2022 CDC Clinical Practice Guideline for Prescribing Opioids Implementation Guide, published by Centers for Disease Control and Prevention (CDC). This guide is not an authorized publication; it is the continuous build for version 2022.1.0 built by the FHIR (HL7® FHIR® Standard) CI Build. This version is based on the current content of https://github.com/cqframework/opioid-cds-r4/ and changes regularly. See the Directory of published versions

Library: Morphine Milligram Equivalent (MME) Calculator for FHIR R4

Official URL: http://fhir.org/guides/cdc/opioid-cds/Library/MMECalculator Version: 2022.1.0
Active as of 2021-11-25 Realm: Unknown region code '840' Computable Name: MMECalculator

Usage:Clinical Focus: Medication requested (situation), Clinical Focus: Chronic pain (finding)

Copyright/Legal: Copyright 2019+ Centers for Disease Control and Prevention (CDC)

This library contains logic to surface the MME calculation functionality provided by the OMTKLogic library by extracting appropriate information from FHIR R4 MedicationRequest resource.

Id: MMECalculator
Url: http://fhir.org/guides/cdc/opioid-cds/Library/MMECalculator
Version: 3.0.0
Name: MMECalculator
Title: Morphine Milligram Equivalent (MME) Calculator for FHIR R4
Status: active
Experimental: false
Type:

system: http://terminology.hl7.org/CodeSystem/library-type

code: logic-library

Date: 2021-11-25T15:15:41+11:00
Publisher: Alphora
Description: This library contains logic to surface the MME calculation functionality provided by the OMTKLogic library by extracting appropriate information from FHIR R4 MedicationRequest resource.
Knowledge Capability: shareable computable publishable executable
Knowledge Representation Level: structured
Use Context:
codevaluedisplay
focus 182888003 Medication requested (situation)
focus 82423001 Chronic pain (finding)
Jurisdiction: 840
Usage: NOTE: Do not use the calculated dose in MMEs to determine dosage for converting one opioid to another—the new opioid should be lower to avoid unintentional overdose caused by incomplete cross-tolerance and individual differences in opioid pharmacokinetics. Consult the medication label.
Copyright: Copyright 2019+ Centers for Disease Control and Prevention (CDC)
Last Review Date: 2020-09-26
Related Artifacts:

Documentation

References

  • Nelson SJ, Zeng K, Kilbourne J, Powell T, Moore R. Normalized names for clinical drugs: RxNorm at 6 years.
    J Am Med Inform Assoc. 2011 Jul-Aug;18(4)441-8. doi: 10.1136/amiajnl-2011-000116.
    Epub 2011 Apr 21. PubMed PMID: 21515544; PubMed Central PMCID: PMC3128404.
    [Full Text](https://www.ncbi.nlm.nih.gov/pmc/articles/PMC3128404/)
    https://www.ncbi.nlm.nih.gov/pmc/articles/PMC3128404/
  • Schadow G, McDonald CJ. The Unified Code for Units of Measure. Regenstrief Institute, Inc. and the UCUM Organization, 2017. Version 2.1, Revision 442. http://unitsofmeasure.org
    http://unitsofmeasure.org
  • Dowell D, Haegerich TM, Chou R. CDC Guideline for Prescribing Opioids for Chronic Pain — United States, 2016. MMWR Recomm Rep 2016;65(No. RR-1):1–49. DOI: http://dx.doi.org/10.15585/mmwr.rr6501e1
    http://dx.doi.org/10.15585/mmwr.rr6501e1
  • National Center for Injury Prevention and Control. Calculating total daily dose of opioids for safer dosage.
    Atlanta, GA: Centers for Disease Control and Prevention; https://www.cdc.gov/drugoverdose/pdf/calculating_total_daily_dose-a.pdf, accessed November 19th, 2020
    https://www.cdc.gov/drugoverdose/pdf/calculating_total_daily_dose-a.pdf

Dependencies

  • http://fhir.org/guides/cdc/opioid-mme-r4/Library/OMTKLogic|3.0.0
  • http://fhir.org/guides/cdc/opioid-mme-r4/Library/OMTKData|3.0.0
  • http://fhir.org/guides/cdc/opioid-mme-r4/Library/ConversionFactors|3.0.0
  • http://terminology.hl7.org/CodeSystem/usage-context-type
  • http://fhir.org/guides/cdc/opioid-mme-r4/CodeSystem/CDCMMEUsageContextCodes
Parameters:
NameTypeMinMaxIn/Out
ErrorLevelstring01in
ConversionFactorSupplementNamestring01in
PatientPatient01out
Data Requirements:
TypeProfileMSCode Filter
Patient http://hl7.org/fhir/StructureDefinition/Patient
Content: text/cql
library MMECalculator version '3.0.0'

/*
This library contains logic to surface the MME calculation functionality provided
by the OMTKLogic library by extracting appropriate information from FHIR R4
MedicationRequest resource.
*/

using FHIR version '4.0.1'

include FHIRHelpers version '4.0.1'
include OMTKLogic version '3.0.0'

parameter ErrorLevel String default 'Warning'

context Patient

/*
Helper function to force the choice of the FHIR.Range value.
This avoids the need for the _is_ and _as_ operators on choices,
which is not implemented in the JavaScript CQL engine.
*/
define function ToFHIRRange(range FHIR.Range):
  range

/*
Helper function to force the choice of the FHIR.SimpleQuantity value.
This avoids the need for the _is_ and _as_ operators on choices,
which is not implemented in the JavaScript CQL engine.
*/
define function ToFHIRQuantity(quantity FHIR.SimpleQuantity):
  quantity

/*
Helper function to force the choice of the FHIR.CodeableConcept value.
This avoids the need for the _is_ and _as_ operators on choices,
which is not implemented in the JavaScript CQL engine.
*/
define function ToFHIRCodeableConcept(codeableConcept FHIR.CodeableConcept):
  codeableConcept

/*
FHIRHelpers ToQuantity logic incorrectly uses the unit element of the FHIR Quantity,
when it should be using the code element as the actual coded unit.
https://github.com/cqframework/clinical_quality_language/issues/557

Until the above issue is addressed, this function provides ToQuantity functionality for this library
*/
define function ToQuantity(quantity FHIR.SimpleQuantity):
  case
    when quantity is null then null
    when quantity.value is null then null
    when quantity.system is null or quantity.system = 'http://unitsofmeasure.org' then
      System.Quantity {
        value: quantity.value.value,
        unit: quantity.code.value
      }
    else
      Message(null, true, 'MMECalculator.ToQuantity.InvalidFHIRQuantity', ErrorLevel, 'Invalid FHIR Quantity code: ' & quantity.code.value)
  end

/*
Extracts the relevant information for prescription calculation from a list of
FHIR MedicationRequest resources. This assumes a MedicationRequest that conforms
to the MMEMedicationRequest profile, specifically:
* 1 and only 1 dosageInstruction
* 1 and only 1 doseAndRate
* 1 timing with 1 repeat
* frequency, frequencyMax, defaulting to 1
* period, periodUnit, defaulting to 1 'd'
* doseQuantity or doseRange
* timeOfDay

Note that if timeOfDay is specified in addition to frequency and period, it is ignored (i.e. assumed to be consistent with the specified frequency and period).
TimeOfDay is only used to determine timesPerDay if frequency and period are not specified.
*/
define function Prescriptions(Orders List<MedicationRequest>):
  Orders O
    let
      rxNormCode: OMTKLogic.GetMedicationCode(O.medication),
      medicationName: OMTKLogic.GetMedicationName(rxNormCode),
      // NOTE: Assuming a single dosage instruction element
      dosageInstruction: singleton from O.dosageInstruction,
      // NOTE: Assuming a single dose and rate element
      doseAndRate: singleton from dosageInstruction.doseAndRate,
      repeat: dosageInstruction.timing.repeat,
      frequency: Coalesce(repeat.frequencyMax.value, repeat.frequency.value),
      period: OMTKLogic.Quantity(repeat.period.value, repeat.periodUnit.value),
      doseRange: ToFHIRRange(doseAndRate.dose),
      doseQuantity: ToFHIRQuantity(doseAndRate.dose),
      timesPerDay: Count(repeat.timeOfDay),
      doseDescription:
        Coalesce(
          ToString(ToQuantity(doseQuantity)),
          ToString(doseRange.low.value.value) + '-' + ToString(doseRange.high.value.value) + ' ' + doseRange.high.unit.value
        ),
      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,
      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 then ' PRN' else ''),
      dose: ToQuantity(Coalesce(doseQuantity, doseRange.high)),
      dosesPerDay: Coalesce(OMTKLogic.ToDaily(frequency, period), timesPerDay, 1.0)
    }

/*
Calculates Morphine Milligram Equivalent (MME) for each medication in the given
list. The calculation assumes the most aggresive dosing, and is performed for all
medications in the given list (i.e. no additional filtering for status is performed).
*/
define function MME(prescriptions List<MedicationRequest>):
  (Prescriptions(prescriptions)) P
    let mmePerIngredient: 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: Combine(mmePerIngredient X return X.dailyDoseDescription, '\r\n'),
      mme: Sum(mmePerIngredient X return X.mme)
    }

/*
Calculates total Morphine Milligram Equivalent (MME) for the given list of medications.
The calculation assumes the most aggressive dosing, and is performed for all
medications in the given list (i.e. no additional filtering for status is performed).
*/
define function TotalMME(prescriptions List<MedicationRequest>):
  OMTKLogic.Quantity(
    Sum((MME(prescriptions)) M return M.mme.value),
    '{MME}/d'
  )
Content: application/elm+xml
Encoded data (123452 characters)
Content: application/elm+json
Encoded data (660424 characters)