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) Conversion Factors for FHIR R4

Official URL: http://fhir.org/guides/cdc/opioid-cds/Library/ConversionFactors Version: 2022.1.0
Active as of 2022-02-01 Realm: Unknown region code '840' Computable Name: ConversionFactors

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 expose configurable conversion factors for the MME calculation functionality provided by the OMTKLogic library.

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

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

code: logic-library

Date: 2022-02-01T20:35:24+00:00
Publisher: Alphora
Description: This library contains logic to expose configurable conversion factors for the MME calculation functionality provided by the OMTKLogic library.
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://terminology.hl7.org/CodeSystem/usage-context-type
  • http://fhir.org/guides/cdc/opioid-mme-r4/CodeSystem/CDCMMEUsageContextCodes
Parameters:
NameTypeMinMaxIn/Out
ErrorLevelstring01in
ConversionFactorSupplementNamestring01in
PatientPatient01out
ConversionFactorSupplementCodeSystem01out
Data Requirements:
TypeProfileMSCode Filter
Patient http://hl7.org/fhir/StructureDefinition/Patient
CodeSystem http://hl7.org/fhir/StructureDefinition/CodeSystem ;;;;;;
Content: text/cql
library ConversionFactors version '3.0.0'

/*
This library provides logic to determine the appropriate conversion factor to be
used for calculating Morphine Milligram Equivalent (MME) for a given medication.

The conversion factors are configurable using a CodeSystem supplement. This
implementation guide contains one conversion factor table:

CDCMMEClinicalConversionFactors

The Clinical Conversion Factors table uses values from CDC guidance here:
https://www.cdc.gov/drugoverdose/pdf/calculating_total_daily_dose-a.pdf

The CodeSystem supplements are configured with 3 types of properties:

* conversion-factor: Defines the conversion factor for a specific ingredient,
when the conversion factor is the same for all dose forms and dose amounts for
the ingredient. The value of this property will be the decimal representation of
the conversion factor.
* dose-form-conversion-factor: Defines the conversion factor for an ingredient
when the conversion factor varies by the dose form of the medication. The value
of this property will be a string of the form
<dose-form-code>:<conversion-factor>[@<doses-per-day>],
e.g. 970789:130, where '970789' is the RxNorm dose form code, and '130' is the
decimal representation of the conversion factor. An example of a per-day
conversion factor is fentanyl, 316987:7200@0.33333333, where 316987 is RxNorm
dose form code, 7200 is the conversion factor, and 0.33333333 is the dosesPerDay,
expressed as a decimal with a maximum of 8 digits after the decimal.
* dose-range-conversion-factor: Defines the conversion factor for an ingredient
when the conversion factor varies by the overall dose of the medication. The
value of this property will be a string of the form
<low-value>-<high-value>:<conversion-factor>,
e.g. 1-20:4. Note that the low-value or high-value may be a wildcard '*' to
indicate the range continues (e.g. '61-*:12' indicates the range is 61 or greater).

For a given ingredient, only one of 'dose-form' or 'dose-range' will be present,
with or without an ingredient-specific conversion factor. The properties together
will enable a unique conversion factor to be determined if the input is within
the expected range. If the input is outside the expected range, and there is no
ingredient-specific conversion-factor specified, implementations should indicate
a conversion factor could not be determined from the supplied information.
All conversion factors supplied in these supplements are in 'mg/d'.
*/

using FHIR version '4.0.1'

include FHIRHelpers version '4.0.1'

codesystem "Usage Context Type": 'http://terminology.hl7.org/CodeSystem/usage-context-type'
codesystem "CDC MME Usage Context Codes": 'http://fhir.org/guides/cdc/opioid-mme-r4/CodeSystem/CDCMMEUsageContextCodes'

code "Task Usage Context": 'task' from "Usage Context Type"
code "MME Calculation": 'mme-calculation' from "CDC MME Usage Context Codes"

parameter ErrorLevel String default 'Trace'

/*
If this parameter is supplied, it specifies the name of the code system supplement
to be used to supply conversion factors for the calculator. If this parameter is not
provided, the _single_ CodeSystem with a task usage context code of "mme-calculation"
from the CDCMMEUsageContextCodes code system will be used to provide conversion factors.
If neither of these configurations is available, the hard-coded conversion factors
in GetConversionFactor will be used. The hard-coded conversion factors use the
clinical conversion factors only.
*/
parameter ConversionFactorSupplementName String

context Patient

/*
Returns the conversion factor for the given ingredient

CDC Guidance:
https://www.cdc.gov/drugoverdose/pdf/calculating_total_daily_dose-a.pdf

|Opioid (strength in mg except where noted)     |MME Conversion Factor*|
|-----------------------------------------------|----------------------|
|Codeine                                        |                 0.15 |
|Fentanyl, transdermal patch (MCG/HR)           |                 2.4  |
|Hydrocodone                                    |                 1    |
|Hydromorphone                                  |                 4    |
|Methadone                                      |                      |
|  1-20 mg/d                                    |                 4    |
|  21-40 mg/d                                   |                 8    |
|  41-60 mg/d                                   |                10    |
|  61-80+ mg/d                                  |                12    |
| Morphine                                      |                 1    |
| Oxycodone                                     |                 1.5  |
| Oxymorphone                                   |                 3    |

*/
define function GetConversionFactor(ingredientCode System.Code, dailyDose System.Quantity, doseFormCode System.Code, dosesPerDay System.Decimal):
  Coalesce(
    LookupConversionFactor(ingredientCode, dailyDose, doseFormCode, dosesPerDay),
    case ToInteger(ingredientCode.code)
      when 2670 then 0.15 /*	Codeine */
      when 4337 then ( /*	Fentanyl */
        case
          when ToInteger(doseFormCode.code) = 316987 then (0.33333333 / dosesPerDay) * 7200 /* Transdermal system */
          else Message(null, true, 'OMTKLogic.GetConversionFactor.UnknownDoseForm', ErrorLevel, 'Unknown dose form code ' & doseFormCode.code)
        end
      )
      when 5489 then 1 /*	Hydrocodone */
      when 3423 then 4 /*	Hydromorphone */
      when 6813 then ( /*	Methadone */
        case
          when dailyDose.value between 1 and 20 then 4
          when dailyDose.value between 21 and 40 then 8
          when dailyDose.value between 41 and 60 then 10
          when dailyDose.value >= 61 then 12
          when dailyDose is null or dailyDose.value is null then
            Message(null, true, 'OMTKLogic.GetConversionFactor.DailyDoseNull', ErrorLevel, 'Daily dose is required to determine methadone conversion factor')
          else Message(null, dailyDose.value < 1, 'OMTKLogic.GetConversionFactor.DailyDoseLessThanOne', ErrorLevel, 'Daily dose less than 1')
        end
      )
      when 7052 then 1 /*	Morphine */
      when 7804 then 1.5 /*	Oxycodone */
      when 7814 then 3 /*	Oxymorphone */
      else Message(null, true, 'OMTKLogic.GetConversionFactor.UnknownIngredientCode', ErrorLevel, 'Unknown ingredient code: ' & ingredientCode.code)
    end
  )

define ConversionFactorSupplement:
  singleton from (
    [CodeSystem] C
      where C.supplements.value = 'http://www.nlm.nih.gov/research/umls/rxnorm'
      and (
        C.name.value = ConversionFactorSupplementName
          or exists (
            C.useContext UC
              where UC.code ~ "Task Usage Context"
                and UC.value ~ "MME Calculation"
          )
      )
  )

/*
Converts a range value boundary to a Decimal (or null for a wildcard)
*/
define function ToRangeValue(value System.String):
  if value = '*' then null else ToDecimal(value)

/*
Converts the property value of a dose-range-conversion-factor property to the dose range
<low-value>-<high-value>:<conversion-factor>
Note that low-value and/or high-value may be wildcards '*'
*/
define function ToDoseRange(propertyValue FHIR.string):
  ({ : }) X
    let rangeValues: Split(Split(propertyValue.value, ':')[0], '-')
    return Interval[ToRangeValue(rangeValues[0]), ToRangeValue(rangeValues[1])]

/*
Converts the property value of a dose-range-conversion-factor property to the conversion factor
<low-value>-<high-value>:<conversion-factor>
*/
define function ToDoseRangeConversionFactor(propertyValue FHIR.string):
  ToDecimal(Split(propertyValue.value, ':')[1])

/*
Converts the property value of a dose-form-conversion-factor property to the dose form
<dose-form-code>:<conversion-factor>
*/
define function ToDoseForm(propertyValue FHIR.string):
  Split(propertyValue.value, ':')[0]

/*
Converts the property value of a dose-form-conversion-factor property to the conversion factor
<dose-form-code>:<conversion-factor>[@doses-per-day]
*/
define function ToDoseFormConversionFactor(propertyValue FHIR.string, dosesPerDay System.Decimal):
  if PositionOf('@', propertyValue.value) > 0 then
    ToDoseFormDosesPerDayConversionFactor(propertyValue, dosesPerDay)
  else
    ToDecimal(Split(propertyValue.value, ':')[1])

/*
Converts the property value of a dose-form-conversion-factor property to the conversion factor
if the property includes a doses-per-day value
*/
define function ToDoseFormDosesPerDayConversionFactor(propertyValue FHIR.string, dosesPerDay System.Decimal):
  propertyValue P
    let components: Split(P.value, '@')
    return (ToDecimal(components[1]) / dosesPerDay) * ToDecimal(Split(components[0], ':')[1])

/*
Returns the conversion factor for a conversion-factor property
NOTE: These functions are used to avoid use of _is_ and _as_
*/
define function ToConversionFactor(propertyValue FHIR.decimal):
  propertyValue.value

/*
Looks up the conversion factor for the given ingredient, daily dose, and dose form from the
configured conversion factor supplement, if available.

If no conversion factor supplement is configured, returns null
*/
define function LookupConversionFactor(ingredientCode System.Code, dailyDose System.Quantity, doseFormCode System.Code, dosesPerDay System.Decimal):
  ConversionFactorSupplement CFS
    let
      ingredientConcept: singleton from (CFS."concept" C where C.code.value = ingredientCode.code),
      conversionFactor: singleton from (ingredientConcept.property P where P.code.value = 'conversion-factor'),
      doseFormConversionFactors: (ingredientConcept.property P where P.code.value = 'dose-form-conversion-factor'),
      doseRangeConversionFactors: (ingredientConcept.property P where P.code.value = 'dose-range-conversion-factor')
    return
      Coalesce
      (
        case
          when exists (doseRangeConversionFactors) then
            singleton from (
              doseRangeConversionFactors DRCF
                where dailyDose.value in ToDoseRange(DRCF.value)
                return ToDoseRangeConversionFactor(DRCF.value)
            )
          when exists (doseFormConversionFactors) then
            singleton from (
              doseFormConversionFactors DFCF
                where doseFormCode.code = ToDoseForm(DFCF.value)
                return ToDoseFormConversionFactor(DFCF.value, dosesPerDay)
            )
          else null
        end,
        ToConversionFactor(conversionFactor.value)
      )
Content: application/elm+xml
Encoded data (159884 characters)
Content: application/elm+json
Encoded data (778100 characters)