Library Name |
Name |
AppropriateDXAScansForWomenUnder65FHIR |
DXA Scan Order During Measurement Period |
|
define "DXA Scan Order During Measurement Period":
( ( [ServiceRequest: "DXA (Dual energy Xray Absorptiometry) Scan"] ).isDiagnosticStudyOrder ( ) ) DXA
where DXA.authoredOn.toInterval ( ) during "Measurement Period"
// and DXA.doNotPerform is not true
// https://oncprojectracking.healthit.gov/support/browse/CQLIT-447
sort by authoredOn asc
|
Library Name |
Name |
AppropriateDXAScansForWomenUnder65FHIR |
Numerator |
|
define "Numerator":
exists "DXA Scan Order During Measurement Period"
|
Library Name |
Name |
AppropriateDXAScansForWomenUnder65FHIR |
Qualifying Encounter |
|
define "Qualifying Encounter":
( ( [Encounter: "Office Visit"]
union [Encounter: "Preventive Care Services Established Office Visit, 18 and Up"]
union ( [Encounter] E
where exists ( ( E.type ) T
where T ~ "Unlisted preventive medicine service"
)
)
union [Encounter: "Preventive Care Services Initial Office Visit, 18 and Up"]
union [Encounter: "Outpatient Consultation"]
union [Encounter: "Virtual Encounter"]
union [Encounter: "Telephone Visits"]
).isEncounterPerformed ( ) ) ValidEncounters
where ValidEncounters.period.toInterval ( ) during day of "Measurement Period"
|
Library Name |
Name |
AppropriateDXAScansForWomenUnder65FHIR |
Initial Population |
|
define "Initial Population":
AgeInYearsAt(date from start of "Measurement Period") in Interval[50, 63]
and Patient.gender = 'female'
and exists "Qualifying Encounter"
|
Library Name |
Name |
AppropriateDXAScansForWomenUnder65FHIR |
Denominator |
|
define "Denominator":
"Initial Population"
|
Library Name |
Name |
AppropriateDXAScansForWomenUnder65FHIR |
First BMI in Measurement Period |
|
define "First BMI in Measurement Period":
First(((["observation-bmi"]).isObservationBMI()) BMIRatio
where BMIRatio.effective.toInterval() during "Measurement Period"
and BMIRatio.value as Quantity is not null
sort by start of effective.toInterval()
)
|
Library Name |
Name |
AppropriateDXAScansForWomenUnder65FHIR |
First BMI in Measurement Period Less Than or Equal to 20 kg m2 |
|
define "First BMI in Measurement Period Less Than or Equal to 20 kg m2":
"First BMI in Measurement Period" FirstBMI
where FirstBMI.value as Quantity <= 20 'kg/m2'
|
Library Name |
Name |
AppropriateDXAScansForWomenUnder65FHIR |
First Average Number of Drinks Assessments Indicating More Than Two Per Day |
|
define "First Average Number of Drinks Assessments Indicating More Than Two Per Day":
First((([Observation: "Alcoholic drinks per day"]).isAssessmentPerformed()) AverageDrinks
where start of AverageDrinks.effective.toInterval() during "Measurement Period"
and AverageDrinks.value as Quantity > 2 '{drinks}/d'
sort by start of effective.toInterval()
)
|
Library Name |
Name |
AppropriateDXAScansForWomenUnder65FHIR |
Has Risk Factor Active During the Measurement Period |
|
define "Has Risk Factor Active During the Measurement Period":
"First BMI in Measurement Period Less Than or Equal to 20 kg m2" is not null
or "First Average Number of Drinks Assessments Indicating More Than Two Per Day" is not null
|
Library Name |
Name |
AppropriateDXAScansForWomenUnder65FHIR |
Has Risk Factor Any Time in History Prior to Measurement Period |
|
define "Has Risk Factor Any Time in History Prior to Measurement Period":
exists ( ( [Condition: "Osteoporosis Without Current Fracture"] OsteoporosisDiagnosis
where OsteoporosisDiagnosis.prevalenceInterval ( ) starts before start of "Measurement Period"
)
union ( [Condition: "Osteopenia"] OsteopeniaDiagnosis
where OsteopeniaDiagnosis.prevalenceInterval ( ) starts before start of "Measurement Period"
)
union ( ( ( ( [Procedure: "Gastric Bypass Surgery"] ).isProcedurePerformed ( ) ) GastricBypass
where GastricBypass.performed.toInterval ( ) ends before start of "Measurement Period"
)
union ( ( ( [MedicationRequest: "Aromatase Inhibitors"] ).isMedicationActive ( ) ) AromataseInhibitorActive
where CMD."MedicationRequestPeriod" ( AromataseInhibitorActive ) starts before start of "Measurement Period"
)
union ( ( ( [MedicationRequest: "Aromatase Inhibitors"] ).isMedicationOrder ( ) ) AromataseInhibitorOrder
where AromataseInhibitorOrder.authoredOn.toInterval ( ) before start of "Measurement Period"
)
union ( ( [Observation: "History of hip fracture in parent"] ).isAssessmentPerformed ( ) ) ParentFractureHistory
where start of ParentFractureHistory.effective.toInterval ( ) before start of "Measurement Period"
)
)
|
Library Name |
Name |
AppropriateDXAScansForWomenUnder65FHIR |
Glucocorticoid Active Medication Days |
|
define "Glucocorticoid Active Medication Days":
( ( ( ( [MedicationRequest: "Glucocorticoids (oral only)"] ).isMedicationActive ( ) ) OralGlucocorticoid
where ( OralGlucocorticoid ).medicationRequestPeriod ( ) starts before end of "Measurement Period" ) Glucocorticoid
return ( Glucocorticoid ).medicationRequestPeriod ( )
intersect Interval[Patient.birthDate, date from end of "Measurement Period"]
).cumulativeDuration ( )
|
Library Name |
Name |
AppropriateDXAScansForWomenUnder65FHIR |
Has 90 or More Active Glucocorticoid Medication Days |
|
define "Has 90 or More Active Glucocorticoid Medication Days":
"Glucocorticoid Active Medication Days" >= 90
|
Library Name |
Name |
AppropriateDXAScansForWomenUnder65FHIR |
Has Double or Bilateral Oophorectomy |
|
define "Has Double or Bilateral Oophorectomy":
exists ( ( [Procedure: "Bilateral Oophorectomy"] ).procedureInPatientHistory ( ) )
or exists ( ( [Procedure: "Evidence of Bilateral Oophorectomy"] ).procedureInPatientHistory ( ) )
or ( exists ( ( ( [Procedure: "Unilateral Oophorectomy, Unspecified Laterality"] UnilateralOophorectomy
where exists ( UnilateralOophorectomy.bodySite C
where C ~ "Right (qualifier value)"
)
)
union [Procedure: "Unilateral Oophorectomy Right"]
).procedureInPatientHistory ( )
)
and exists ( ( ( [Procedure: "Unilateral Oophorectomy, Unspecified Laterality"] UnilateralOophorectomy
where exists ( UnilateralOophorectomy.bodySite D
where D ~ "Left (qualifier value)"
)
)
union [Procedure: "Unilateral Oophorectomy Left"]
).procedureInPatientHistory ( )
)
)
|
Library Name |
Name |
AppropriateDXAScansForWomenUnder65FHIR |
Has Organ Transplants |
|
define "Has Organ Transplants":
exists ( [Procedure: "Major Transplant"]
union [Procedure: "Kidney Transplant"]
union [Procedure: "Bone Marrow Transplant"]
).procedureInPatientHistory ( )
|
Library Name |
Name |
AppropriateDXAScansForWomenUnder65FHIR |
Has Risk Factor Any Time in History or During Measurement Period |
|
define "Has Risk Factor Any Time in History or During Measurement Period":
"Has 90 or More Active Glucocorticoid Medication Days"
or exists ( [Condition: "Osteoporosis With Current Fracture"]
union [Condition: "Malabsorption Syndromes"]
union [Condition: "Chronic Malnutrition"]
union [Condition: "Chronic Liver Disease"]
union [Condition: "Rheumatoid Arthritis"]
union [Condition: "Hyperthyroidism"]
union [Condition: "Type 1 Diabetes"]
union [Condition: "End Stage Renal Disease"]
union [Condition: "Osteogenesis Imperfecta"]
union [Condition: "Ankylosing Spondylitis"]
union [Condition: "Psoriatic Arthritis"]
union [Condition: "Ehlers Danlos Syndrome"]
union [Condition: "Cushings Syndrome"]
union [Condition: "Hyperparathyroidism"]
union [Condition: "Marfan's Syndrome"]
union [Condition: "Lupus"]
union [Condition: "Multiple Myeloma"]
union [Condition: "Premature Menopause"]
union [Condition: "Eating Disorders"]
union [Condition: "Amenorrhea"]
).diagnosisInPatientHistory ( )
or exists ( [Procedure: "Chemotherapy"] ).procedureInPatientHistory ( )
or "Has Double or Bilateral Oophorectomy"
or "Has Organ Transplants"
|
Library Name |
Name |
AppropriateDXAScansForWomenUnder65FHIR |
Denominator Exclusions |
|
define "Denominator Exclusions":
"Has Risk Factor Active During the Measurement Period"
or "Has Risk Factor Any Time in History Prior to Measurement Period"
or "Has Risk Factor Any Time in History or During Measurement Period"
|
Library Name |
Name |
AppropriateDXAScansForWomenUnder65FHIR |
Osteoporosis Fracture Risk Assessment Prior to First DXA Scan |
|
define "Osteoporosis Fracture Risk Assessment Prior to First DXA Scan":
( ( ( ( [Observation: "Major osteoporotic fracture 10-year probability [Likelihood] Fracture Risk Assessment"] ).isAssessmentPerformed ( ) ) FRAX
where FRAX.value >= 8.4 '%'
)
union ( ( ( [Observation: "Osteoporosis Risk Assessment Instrument"] ).isAssessmentPerformed ( ) ) ORAI
where ORAI.value as Integer >= 9
)
union ( ( ( [Observation: "Osteoporosis Index of Risk panel"] ).isAssessmentPerformed ( ) ) OSIRIS
where OSIRIS.value as Quantity < 1.0
)
union ( ( ( [Observation: "Osteoporosis Self-Assessment Tool"] ).isAssessmentPerformed ( ) ) OST
where OST.value as Quantity < 2.0
) ) RiskAssessment
where start of RiskAssessment.effective.toInterval ( ) before First("DXA Scan Order During Measurement Period").authoredOn
|
Library Name |
Name |
AppropriateDXAScansForWomenUnder65FHIR |
Numerator Exclusion |
|
define "Numerator Exclusion":
exists "Osteoporosis Fracture Risk Assessment Prior to First DXA Scan"
|
Library Name |
Name |
Status |
isDiagnosticStudyOrder |
|
//Diagnostic Study, Order: active and completed only
define fluent function isDiagnosticStudyOrder(ServiceRequest List<ServiceRequest>):
ServiceRequest S
where S.status in { 'active', 'completed' }
and S.intent = 'order'
|
Library Name |
Name |
QICoreCommon |
toInterval |
|
/*
@description: Normalizes a value that is a choice of timing-valued types to an equivalent interval
@comment: Normalizes a choice type of DateTime, Quanitty, Interval<DateTime>, or Interval<Quantity> types
to an equivalent interval. This selection of choice types is a superset of the majority of choice types that are used as possible
representations for timing-valued elements in QICore, allowing this function to be used across any resource.
The input can be provided as a DateTime, Quantity, Interval<DateTime> or Interval<Quantity>.
The intent of this function is to provide a clear and concise mechanism to treat single
elements that have multiple possible representations as intervals so that logic doesn't have to account
for the variability. More complex calculations (such as medication request period or dispense period
calculation) need specific guidance and consideration. That guidance may make use of this function, but
the focus of this function is on single element calculations where the semantics are unambiguous.
If the input is a DateTime, the result a DateTime Interval beginning and ending on that DateTime.
If the input is a Quantity, the quantity is expected to be a calendar-duration interpreted as an Age,
and the result is a DateTime Interval beginning on the Date the patient turned that age and ending immediately before one year later.
If the input is a DateTime Interval, the result is the input.
If the input is a Quantity Interval, the quantities are expected to be calendar-durations interpreted as an Age, and the result
is a DateTime Interval beginning on the date the patient turned the age given as the start of the quantity interval, and ending
immediately before one year later than the date the patient turned the age given as the end of the quantity interval.
If the input is a Timing, an error will be thrown indicating that Timing calculations are not implemented. Any other input will reslt in a null DateTime Interval
*/
define fluent function toInterval(choice Choice<DateTime, Quantity, Interval<DateTime>, Interval<Quantity>, Timing>):
case
when choice is DateTime then
Interval[choice as DateTime, choice as DateTime]
when choice is Interval<DateTime> then
choice as Interval<DateTime>
when choice is Quantity then
Interval[Patient.birthDate + (choice as Quantity),
Patient.birthDate + (choice as Quantity) + 1 year)
when choice is Interval<Quantity> then
Interval[Patient.birthDate + (choice.low as Quantity),
Patient.birthDate + (choice.high as Quantity) + 1 year)
when choice is Timing then
Message(null, true, 'NOT_IMPLEMENTED', 'Error', 'Calculation of an interval from a Timing value is not supported') as Interval<DateTime>
else
null as Interval<DateTime>
end
|
Library Name |
Name |
Status |
isEncounterPerformed |
|
//Encounter, Performed
//General usage unless required otherwise by measure intent (e.g., follow-up encounters)
define fluent function isEncounterPerformed(Enc List<Encounter>):
Enc E
where E.status in {'finished', 'arrived', 'triaged', 'in-progress', 'onleave'}
|
Library Name |
Name |
FHIRHelpers |
ToConcept |
|
/*
@description: Converts the given FHIR [CodeableConcept](https://hl7.org/fhir/datatypes.html#CodeableConcept) value to a CQL Concept.
*/
define function ToConcept(concept FHIR.CodeableConcept):
if concept is null then
null
else
System.Concept {
codes: concept.coding C return ToCode(C),
display: concept.text.value
}
|
Library Name |
Name |
Status |
isObservationBMI |
|
define fluent function isObservationBMI(Obs List<"QICore.observation-bmi">):
Obs O
where O.status in { 'final', 'amended', 'corrected' }
|
Library Name |
Name |
Status |
isAssessmentPerformed |
|
//This library contains functions that are based on QDM 5.6 to QICore 4.1.1 March 2023 (https://github.com/cqframework/CQL-Formatting-and-Usage-Wiki/wiki/Authoring-Patterns---QICore-v4.1.1). The functions may appear similar to some QICoreCommon functions but different in that they have constraints that are relevant for measures authored by NCQA.
//Assessment, Performed
define fluent function isAssessmentPerformed(Obs List<Observation>):
Obs O
where O.status in { 'final', 'amended', 'corrected' }
and exists ( O.category ObservationCategory
where ( ObservationCategory ) ~ "survey"
)
|
Library Name |
Name |
QICoreCommon |
prevalenceInterval |
|
/*
@description: Returns an interval representing the normalized prevalence period of a given Condition.
@comment: Uses the ToInterval and ToAbatementInterval functions to determine the widest potential interval from
onset to abatement as specified in the given Condition. If the condition is active, or has an abatement date the resulting
interval will have a closed ending boundary. Otherwise, the resulting interval will have an open ending boundary.
*/
define fluent function prevalenceInterval(condition Condition):
if condition.clinicalStatus ~ "active"
or condition.clinicalStatus ~ "recurrence"
or condition.clinicalStatus ~ "relapse" then
Interval[start of condition.onset.toInterval(), end of condition.abatementInterval()]
else
(end of condition.abatementInterval()) abatementDate
return if abatementDate is null then
Interval[start of condition.onset.toInterval(), abatementDate)
else
Interval[start of condition.onset.toInterval(), abatementDate]
|
Library Name |
Name |
Status |
isProcedurePerformed |
|
//Procedure, Performed
define fluent function isProcedurePerformed(Proc List<Procedure>):
Proc P
where P.status ~ 'completed'
|
Library Name |
Name |
Status |
isMedicationActive |
|
//Medication, Active
define fluent function isMedicationActive(MedicationRequest List<MedicationRequest>):
MedicationRequest M
where M.status = 'active'
and M.intent = 'order'
|
Library Name |
Name |
CumulativeMedicationDuration |
MedicationRequestPeriod |
|
/*
Now that we have a ToDaily function, we can approach calculation of the
duration of medication for an order. First, consider the definitions
for each element:
* 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
* authoredOn: The date the prescription was written
* dispenseRequest.validityPeriod: Time period supply is authorized for
* dispenseRequest.quantity: amount of medication supplied per dispense
* dispenseRequest.numberOfRepeatsAllowed: number of refills authorized
* dispenseRequest.expectedSupplyDuration: number of days supply per dispense
* dosageInstruction.timing.repeat.boundsDuration: total duration of the repeat
* dosageInstruction.timing.repeat.boundsRange: range of durations of the repeat
* dosageInstruction.timing.repeat.boundsPeriod: period bounds of the repeat
* dosageInstruction.timing.repeat.count: number of times to repeat
* dosageInstruction.timing.repeat.countMax: maximum number of times to repeat
* dosageInstruction.timing.repeat.frequency: event occurs frequency times per period
* dosageInstruction.timing.repeat.frequencyMax: event occurs up to frequencyMax times per period
* dosageInstruction.timing.repeat.period: event occurs frequency times per period
* dosageInstruction.timing.repeat.periodMax: upper limit of period
* dosageInstruction.timing.repeat.periodUnit: period duration (s | min | h | d | wk | mo | a)
* dosageInstruction.timing.repeat.timeOfDay: time of day for the event (0..*)
* dosageInstruction.timing.repeat.when: event timing (HS | WAKE | C | CM | CD | CV | AC | ACM...)
* dosageInstruction.timing.code: BID | TID | QID | AM | PM | QD | QOD...
* dosageInstruction.asNeeded
* dosageInstruction.doseAndRate.doseQuantity
* dosageInstruction.doseAndRate.doseRange
If expectedSupplyDuration is present, then the duration is
expectedSupplyDuration * (1 + numberOfRepeatsAllowed)
If expectedSupplyDuration is not present, then it must be calculated based on the quantity, dosage, and frequency:
(quantity / (dosage * frequency)) * (1 + numberOfRepeatsAllowed)
dosage: Coalesce(end of doseAndRate.doseRange, doseAndRate.doseQuantity)
frequency: Coalesce(frequencyMax, frequency)
period: Quantity(period, periodUnit)
If expectedSupplyDuration is not present and cannot be calculated, and the boundsPeriod is present (and completely specified), we can use that directly
dosage.timing.repeat.boundsPeriod
This calculation results in a number of days, which can then be turned into a period by anchoring that to the
start of the validityPeriod or the authoredOn:
Interval[earliestDispensable, earliestDispensable + expectedSupplyDuration - 1]
earliestDispensable: Coalesce(start of validityPeriod, authoredOn)
The following function illustrates this completely:
*/
/*
Calculates the Medication Period for a single MedicationRequest.
MedicationRequest instances provided to this function are expected
to conform to the [MMEMedicationRequest](http://build.fhir.org/ig/cqframework/opioid-mme-r4/StructureDefinition-mmemedicationrequest.html)
profile, which expects:
* 1 and only 1 dosageInstruction, multiple dosageInstruction elements will result in an error
* 1 and only 1 doseAndRate, multiple doseAndRate elements will result in an error
* 1 timing with 1 repeat, missing timing or repeat elements will result in a null
* frequency, frequencyMax, defaulting to 1
* period, periodUnit, defaulting to 1 'd'
* timeOfDay
* doseQuantity or doseRange, missing doseQuantity and doseRange will result in a null
Note that MedicationRequest status is not considered by this calculation, as the
list of MedicationRequest instances provided to this function should already have
considered appropriate statuses, depending on the use case, typically `completed`.
*/
define function MedicationRequestPeriod(Request "MedicationRequest"):
Request R
let
dosage: singleton from R.dosageInstruction,
doseAndRate: singleton from dosage.doseAndRate,
timing: dosage.timing,
frequency: Coalesce(timing.repeat.frequencyMax, timing.repeat.frequency),
period: Quantity(timing.repeat.period, timing.repeat.periodUnit),
doseRange: doseAndRate.dose,
doseQuantity: doseAndRate.dose,
dose: Coalesce(end of doseRange, doseQuantity),
dosesPerDay: Coalesce(ToDaily(frequency, period), Count(timing.repeat.timeOfDay), 1.0),
boundsPeriod: timing.repeat.bounds as Interval<DateTime>,
daysSupply: (convert R.dispenseRequest.expectedSupplyDuration to days).value,
quantity: R.dispenseRequest.quantity,
refills: Coalesce(R.dispenseRequest.numberOfRepeatsAllowed, 0),
startDate:
Coalesce(
date from start of boundsPeriod,
date from R.authoredOn,
date from start of R.dispenseRequest.validityPeriod
),
totalDaysSupplied: Coalesce(daysSupply, quantity.value / (dose.value * dosesPerDay)) * (1 + refills)
return
if startDate is not null and totalDaysSupplied is not null then
Interval[startDate, startDate + Quantity(totalDaysSupplied - 1, 'day') ]
else if startDate is not null and boundsPeriod."high" is not null then
Interval[startDate, date from end of boundsPeriod]
else
null
|
Library Name |
Name |
CumulativeMedicationDuration |
Quantity |
|
/**********************************************************************/
/* Functions in this region are copied from opioid-mme-r4 */
/**********************************************************************/
define function Quantity(value Decimal, unit String):
if value is not null then
System.Quantity { value: value, unit: unit }
else
null
|
Library Name |
Name |
CumulativeMedicationDuration |
ToDaily |
|
/*
Goal is to get to number of days
Two broad approaches to the calculation:
1) Based on supply and frequency, calculate the number of expected days the medication will cover/has covered
2) Based on relevant period, determine a covered interval and calculate the length of that interval in days
This topic covers several use cases and illustrates how to calculate Cumulative
Medication Duration for each type of medication resource using the supply and
frequency approach.
*/
/*
For the first approach, we need to get from frequency to a frequency/day
So we define ToDaily
*/
/*
Calculates daily frequency given frequency within a period
*/
define function ToDaily(frequency System.Integer, period System.Quantity):
case period.unit
when 'h' then frequency * (24.0 / period.value)
when 'min' then frequency * (24.0 / period.value) * 60
when 's' then frequency * (24.0 / period.value) * 60 * 60
when 'd' then frequency * (24.0 / period.value) / 24
when 'wk' then frequency * (24.0 / period.value) / (24 * 7)
when 'mo' then frequency * (24.0 / period.value) / (24 * 30) /* assuming 30 days in month */
when 'a' then frequency * (24.0 / period.value) / (24 * 365) /* assuming 365 days in year */
when 'hour' then frequency * (24.0 / period.value)
when 'minute' then frequency * (24.0 / period.value) * 60
when 'second' then frequency * (24.0 / period.value) * 60 * 60
when 'day' then frequency * (24.0 / period.value) / 24
when 'week' then frequency * (24.0 / period.value) / (24 * 7)
when 'month' then frequency * (24.0 / period.value) / (24 * 30) /* assuming 30 days in month */
when 'year' then frequency * (24.0 / period.value) / (24 * 365) /* assuming 365 days in year */
when 'hours' then frequency * (24.0 / period.value)
when 'minutes' then frequency * (24.0 / period.value) * 60
when 'seconds' then frequency * (24.0 / period.value) * 60 * 60
when 'days' then frequency * (24.0 / period.value) / 24
when 'weeks' then frequency * (24.0 / period.value) / (24 * 7)
when 'months' then frequency * (24.0 / period.value) / (24 * 30) /* assuming 30 days in month */
when 'years' then frequency * (24.0 / period.value) / (24 * 365) /* assuming 365 days in year */
else Message(null, true, 'CMDLogic.ToDaily.UnknownUnit', ErrorLevel, 'Unknown unit ' & period.unit)
end
|
Library Name |
Name |
Status |
isMedicationOrder |
|
//Medication, Order: active and completed only
define fluent function isMedicationOrder(MedicationRequest List<MedicationRequest>):
MedicationRequest M
where M.status in { 'active', 'completed' }
and M.intent = 'order'
|
Library Name |
Name |
CumulativeMedicationDuration |
cumulativeDuration |
|
/*
Now that we have functions for determining the medication period for individual
prescriptions, administrations, and dispenses, we can combine those using
an overall cumulative medication duration calculation.
There are two broad approaches to calculating cumulative duration, one that _collapses_
overlapping intervals so that calculations are not duplicated, and one that _rolls out_
overlapping intervals so that the durations are laid end-to-end.
First, we define a function that simply calculates CumulativeDuration of a set of
intervals:
*/
define fluent function cumulativeDuration(Intervals List<Interval<Date>>):
if Intervals is not null then ( Sum((collapse Intervals per day)X
return all(difference in days between start of X and
end of X
)+ 1
)
)
else null
|
Library Name |
Name |
CumulativeMedicationDuration |
medicationRequestPeriod |
|
define fluent function medicationRequestPeriod(Request "MedicationRequest"):
Request R
let
dosage: singleton from R.dosageInstruction,
doseAndRate: singleton from dosage.doseAndRate,
timing: dosage.timing,
frequency: Coalesce(timing.repeat.frequencyMax, timing.repeat.frequency),
period: Quantity(timing.repeat.period, timing.repeat.periodUnit),
doseRange: doseAndRate.dose,
doseQuantity: doseAndRate.dose,
dose: Coalesce(end of doseRange, doseQuantity),
dosesPerDay: Coalesce(ToDaily(frequency, period), Count(timing.repeat.timeOfDay), 1.0),
boundsPeriod: timing.repeat.bounds as Interval<DateTime>,
daysSupply: (convert R.dispenseRequest.expectedSupplyDuration to days).value,
quantity: R.dispenseRequest.quantity,
refills: Coalesce(R.dispenseRequest.numberOfRepeatsAllowed, 0),
startDate:
Coalesce(
date from start of boundsPeriod,
date from R.authoredOn,
date from start of R.dispenseRequest.validityPeriod
),
totalDaysSupplied: Coalesce(daysSupply, quantity.value / (dose.value * dosesPerDay)) * (1 + refills)
return
if startDate is not null and totalDaysSupplied is not null then
Interval[startDate, startDate + Quantity(totalDaysSupplied - 1, 'day') ]
else if startDate is not null and boundsPeriod."high" is not null then
Interval[startDate, date from end of boundsPeriod]
else
null
|
Library Name |
Name |
AppropriateDXAScansForWomenUnder65FHIR |
diagnosisInPatientHistory |
|
define fluent function "diagnosisInPatientHistory"(Condition List<"Condition">):
( Condition ) Dx
where Dx.prevalenceInterval ( ) starts on or before day of end of "Measurement Period"
|
Library Name |
Name |
AppropriateDXAScansForWomenUnder65FHIR |
procedureInPatientHistory |
|
define fluent function "procedureInPatientHistory"(Procedure List<"Procedure">):
( ( Procedure ).isProcedurePerformed ( ) ) Proc
where Proc.performed.toInterval ( ) ends on or before day of end of "Measurement Period"
|