Breast Cancer Screening and Management (BCSM) Clinical Decision Support (CDS) Implementation Guide
1.0.0 - ci-build

Breast Cancer Screening and Management (BCSM) Clinical Decision Support (CDS) Implementation Guide - Local Development build (v1.0.0) built by the FHIR (HL7® FHIR® Standard) Build Tools. See the Directory of published versions

Library: Screening Due Events

Official URL: http://cancerscreeningcds.github.io/bcsm-cds/Library/ScreeningDueEvents Version: 1.0.0
Draft as of 2025-02-28 Computable Name: ScreeningDueEvents
Title: Screening Due Events
Id: ScreeningDueEvents
Version: 1.0.0
Url: Screening Due Events
Status: draft
Type:

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

code: logic-library

Date: 2025-02-28 23:16:14+0000
Publisher: MITRE
Related Artifacts:

Dependencies

Parameters:
NameTypeMinMaxIn/Out
PatientPatient01Out
ActiveBreastCancerScreeningCarePlansCarePlan0*Out
MostRecentActiveScreeningCarePlanCarePlan01Out
MostRecentActiveScreeningCarePlanRequestGroup01Out
ScreeningRequestGroupActionsResource0*Out
MostRecentActiveScreeningCarePlanServiceRequestsServiceRequest0*Out
ScreeningServiceRequestsResource0*Out
ScreeningActivitiesResource0*Out
MammogramPlannedActivityResource01Out
eve-nextdueexistsboolean01Out
LastMammographyDiagnosticReport01Out
eve-noscreening27moboolean01Out
CarePlanActivitiesDueResource0*Out
eve-dueResource0*Out
Data Requirements:
TypeProfileMSCode Filter
Patient http://hl7.org/fhir/StructureDefinition/Patient
CarePlan http://hl7.org/fhir/StructureDefinition/CarePlan ;;;;;;;;;;;;;; code filter:
path: status

code: active

ServiceRequest http://hl7.org/fhir/StructureDefinition/ServiceRequest ;; code filter:
path: intent

code: plan

DiagnosticReport http://hl7.org/fhir/StructureDefinition/DiagnosticReport ;; code filter:
path: code
DiagnosticReport http://hl7.org/fhir/StructureDefinition/DiagnosticReport ;;
Content: text/cql
/*  
  Author: CMS Alliance to Modernize Healthcare, operated by THE MITRE Corporation.

  (C) 2024 The MITRE Corporation. All Rights Reserved. 
  Approved for Public Release: 24-2711. 
  Distribution Unlimited.

  Unless otherwise noted, this work is available under an Apache 2.0 license. 
  It was produced by the MITRE Corporation for the Division of Cancer Prevention 
  and Control, Centers for Disease Control and Prevention in accordance with the 
  Statement of Work, contract number 75FCMC18D0047, task order number 75D30123F17931.
*/

library ScreeningDueEvents version '1.0.0'

using FHIR version '4.0.1'

include FHIRHelpers  version '4.0.1' called FHIRHelpers
include DataElements version '1.0.0' called DataElements
include CSMCommonFunctions version '1.0.0' called CSMCommonFunctions
include BCSMCommonFunctions version '1.0.0' called BCSMCommon

codesystem "LOINC": 'http://loinc.org'
codesystem "SNOMED": 'http://snomed.info/sct'

// Standard codes
code "Breast cancer screening": '268547008' from "SNOMED" display 'Breast cancer screening'
code "MG Breast Screening": '24606-6' from "LOINC" display 'MG Breast Screening' 
code "MR Breast": '30794-2' from "LOINC" display 'MR Breast' 

valueset "Screening Mammogram": 'http://cts.nlm.nih.gov/fhir/ValueSet/2.16.840.1.113762.1.4.1032.393' // TODO clinical validation: keep magnification/localized/spot views?

context Patient

//calculated nextdue logic:
//  +duedate, -interval, -lastreport or +lastreport < duedate = use duedate
//  +duedate, +interval, -lastreport or +lastreport < duedate = use duedate
//  +duedate, -interval, +lastreport > duedate = no prediction
//  +duedate, +interval, +lastreport > duedate = use lastreport + interval
//  -duedate = use CalculateNextDueByCodeAndInterval
// mammogram only and in age range:
//  +duedate, -interval, +lastreport > duedate = use lastreport + 24mos
//  -duedate, -interval, +lastreport = use lastreport + 24mos
//  no activity = use today
//return{
//  code: action.code
//  nextdue: calculated date
//  planneddue: action.timingTiming.event
//  plannedstart: action.timingTiming.repeat.boundsPeriod.start
//  plannedrepeat: action.timingTiming.repeat
//  lastReportDate: DiagnosticReport date
//  flag: "NOT DUE", "DUE", "OVERDUE", none
//}

define "eve-nextdueexists":
  ActivityPlannedDate(MammogramPlannedActivity.timing) is not null

define "eve-noscreening27mo":
  AgeInYears() >= 40 and AgeInYears() <=74 and 
  (LastMammography is null or Today() > (FHIRHelpers.ToDateTime(LastMammography.effective) as DateTime) + 27 months)

define "eve-due":
  CarePlanActivitiesDue A where A.flag in {BCSMCommon."DUE", BCSMCommon."OVERDUE"}

define CarePlanActivitiesDue:
  ScreeningActivities A
  let lastReport: BCSMCommon.MostRecentDiagnosticReportByCode(A.code),
  lastReportDate: CSMCommonFunctions.DiagnosticReportDate(lastReport),
  nextdue: CalculateActivityNextDue(A)
  return {
    code: A.code,
    intent: 'plan',
    nextDue: nextdue,
    plannedDue: A.plannedDue,
    plannedStart: A.plannedStart,
    plannedRepeat: BCSMCommon.EvaluateInterval((A.timing as FHIR.Timing).repeat),
    lastReportDate: lastReportDate,
    flag: BCSMCommon.EvaluateFlag((A.timing as FHIR.Timing).repeat, nextdue)
  }   

define ScreeningActivities:
  ScreeningRequestGroupActions union ScreeningServiceRequests

define LastMammography:
  BCSMCommon.MostRecentDiagnosticReportByVS("Screening Mammogram")


//------------------------------------------------------------------------------
// calculated next due
//------------------------------------------------------------------------------

define function CalculateActivityNextDue(
  activity Tuple{code FHIR.CodeableConcept,plannedDue System.DateTime,plannedStart System.DateTime,timing FHIR.Timing}
):
  activity A
  let lastReport: BCSMCommon.MostRecentDiagnosticReportByCode(A.code),
  lastReportDate: FHIRHelpers.ToDateTime(lastReport.effective) as DateTime,
  duedate: A.plannedDue,
  repeat: Tuple{frequency: FHIRHelpers.ToInteger((A.timing as Timing).repeat.frequency),
        period: FHIRHelpers.ToDecimal((A.timing as Timing).repeat.period),
        periodUnit: FHIRHelpers.ToString((A.timing as Timing).repeat.periodUnit)}
  return
    case
      // -duedate = use CalculateNextDueByCodeAndInterval
      when duedate is null then 
        BCSMCommon.CalculateNextDueByCodeAndInterval(
          A.code, 
          FHIRHelpers.ToDateTime(((A.timing as Timing).repeat.bounds as Period).start),
          repeat)
      // +duedate, -repeat, -lastreport or +lastreport < duedate = use duedate
      when BCSMCommon.RepeatIsValid(repeat) is false and (lastReport is null or lastReportDate < duedate) then duedate
      // +duedate, +repeat, -lastreport or +lastreport < duedate = use duedate
      when BCSMCommon.RepeatIsValid(repeat) and (lastReport is null or lastReportDate < duedate) then duedate
      // +duedate, -repeat, +lastreport > duedate = no prediction
      when BCSMCommon.RepeatIsValid(repeat) is false and lastReport is not null and lastReportDate > duedate then null
      // +duedate, +repeat, +lastreport > duedate = use lastreport + repeat
      when BCSMCommon.RepeatIsValid(repeat) and lastReport is not null and lastReportDate > duedate then
        date from BCSMCommon.AddIntervalToDateTime(lastReportDate, repeat)
      // Default case if none of the above conditions are met      
      else null
    end         

//------------------------------------------------------------------------------
// Care plan
//------------------------------------------------------------------------------

define MostRecentActiveScreeningCarePlan:
  Last(ActiveBreastCancerScreeningCarePlans C 
    sort by Coalesce(start of period, created)
  )      

define ActiveBreastCancerScreeningCarePlans:
  [CarePlan] C
    where C.status in {'active'}
      and exists C.category cat where cat ~ "Breast cancer screening"   

//------------------------------------------------------------------------------
// Care plan/Request group
//------------------------------------------------------------------------------

define ScreeningRequestGroupActions:
  MostRecentActiveScreeningCarePlanRequestGroup.action A
  return {
    code: First(A.code),
    plannedDue: ActivityPlannedDate(A.timing),
    plannedStart: FHIRHelpers.ToDateTime(((A.timing as Timing).repeat.bounds as Period).start),
    timing: A.timing as FHIR.Timing
  } 

define MostRecentActiveScreeningCarePlanRequestGroup:
  if MostRecentActiveScreeningCarePlan.activity[0].reference.reference is not null
    and StartsWith(MostRecentActiveScreeningCarePlan.activity[0].reference.reference,'RequestGroup/')
  then
    First(
      [RequestGroup] R where 
        R.id = Last(Split(MostRecentActiveScreeningCarePlan.activity[0].reference.reference,'/'))
    )
  else null       

//------------------------------------------------------------------------------
// Care plan/Service requests
//------------------------------------------------------------------------------

define ScreeningServiceRequests:
  MostRecentActiveScreeningCarePlanServiceRequests R
  return {
    code: R.code,
    plannedDue: Coalesce(
      ActivityPlannedDate(R.occurrence as Timing),
      (R.occurrence as FHIR.dateTime).value,
      (R.occurrence as FHIR.Period)."end".value,
      (R.occurrence as FHIR.Period)."start".value
    ),
    plannedStart: FHIRHelpers.ToDateTime(((R.occurrence as FHIR.Timing).repeat.bounds as Period).start),
    timing: R.occurrence as FHIR.Timing
  }

define MostRecentActiveScreeningCarePlanServiceRequests:
  MostRecentActiveScreeningCarePlan.activity A
  where
    A.reference.reference is not null and StartsWith(A.reference.reference,'ServiceRequest/')
  return singleton from (
    [ServiceRequest] R 
    where R.id = Last(Split(A.reference.reference,'/'))
      and R.intent = 'plan' //from CPG workflow        
  )

//------------------------------------------------------------------------------
// Activity
//------------------------------------------------------------------------------

define MammogramPlannedActivity:
  NextPlannedActivityByCode(ScreeningActivities, "MG Breast Screening")    

define function NextPlannedActivityByCode(
  activities List<Tuple{code FHIR.CodeableConcept,plannedDue System.DateTime,plannedStart System.DateTime,timing FHIR.Timing}>,
  code Code
):
  NextPlannedActivity(activities A where A.code ~ ToConcept(code))

define function NextPlannedActivity(
  activities List<Tuple{code FHIR.CodeableConcept,plannedDue System.DateTime,plannedStart System.DateTime,timing FHIR.Timing}>
):
  Last(activities A sort by ActivityPlannedDate(timing))

//------------------------------------------------------------------------------
// planned due date
//------------------------------------------------------------------------------

define function ActivityPlannedDate(timing Choice<FHIR.Timing,FHIR.Period>):
  Coalesce(
    MostRecentTimingEvent(timing as FHIR.Timing),
    (timing as FHIR.Period)."start".value,
    (timing as FHIR.Period)."end".value
  )

define function MostRecentTimingEvent(timing FHIR.Timing):
  Last(timing.event E sort asc).value 

Content: application/elm+xml
Encoded data (222068 characters)
Content: application/elm+json
Encoded data (422536 characters)