Files
St.Clair/MLMStripper/bin/Debug/SYS/SYS_ROUND_DOSAGE.mlm

266 lines
11 KiB
Plaintext

maintenance:
title: Round Medication Dosage;;
mlmname: SYS_ROUND_DOSAGE;;
arden: version 2.5;;
version: 18.4;;
institution: Allscripts, System MLM;;
author: Allscripts Healthcare Solutions, Inc.;;
specialist: ;;
date: 2018-10-26;;
validation: testing;;
/* P r o p r i e t a r y N o t i c e */
/* Unpublished (c) 2013 - 2018 Allscripts Healthcare, LLC. and/or its affiliates. All Rights Reserved.
P r o p r i e t a r y N o t i c e: This software has been provided pursuant to a License Agreement, with
Allscripts Healthcare, LLC. and/or its affiliates, containing restrictions on its use. This software contains
valuable trade secrets and proprietary information of Allscripts Healthcare, LLC. and/or its affiliates and is
protected by trade secret and copyright law. This software may not be copied or distributed in any form or medium,
disclosed to any third parties, or used in any manner not provided for in said License Agreement except with prior
written authorization from Allscripts Healthcare, LLC. and/or its affiliates. Notice to U.S. Government Users:
This software is {{{SINGLE-QUOTE}}}Commercial Computer Software{{{SINGLE-QUOTE}}}.
All product names are the trademarks or registered trademarks of Allscripts Healthcare, LLC. and/or its affiliates.
*/
/* P r o p r i e t a r y N o t i c e */
library:
purpose: Rounds a medication dose to the appropriate value using the medication route; or
within the limit of a maximum of 10% variation, regardless of route.
;;
explanation: Implements rounding rules in one of three ways. The first two were developed
by Eclipsys, and the third was developed at Johns Hopkins Hospital using an algorithm
that limits the rounding so that it never exceeds 10% of the original dose amount. The
Eclipsys rounding rules are designated as "Standard" and are the default function of
this MLM. The third rule is designated as "10pctLimit" and can be selected by changing
the RoundingRule flag in the Spelling and Flags section.
The "Standard" rounding rules can be used when the route is supplied. An error message
is returned if the Dose is NOT a string, or if the Route is NULL, or if the dose amount
is smaller than 0.005:
(1) The Parenteral Rounding Rules are used whenever the route matches the routes
listed in the Parenteral_Route_List variable.
(2) The Other Rounding Rules are used whenever a route exists and does NOT match
the routes listed in the Parenteral_Route_List variable.
PARENTERAL ROUNDING RULES
For values < 0.005, return Error_Message
For values <= 1, round to the nearest 0.01
For values > 1 and <= 5, round to the nearest 0.1
For values > 5 and <= 50, round to the nearest 1 (integer)
For values > 50 and <= 100, round to the nearest 2 (even number)
For values > 100 and <= 500, round to the nearest 10 (integer)
For values > 500 and <= 2000, round to the nearest 50 (integer)
For values > 2000, round to the nearest 100 (integer)
OTHER ROUNDING RULES
For values < 0.005, return Error_Message
For values <= 1, round to the nearest 0.01
For values >= 1 and <= 10, round to the nearest 0.1
For values >= 10 and <= 50, round to the nearest integer
For values > 50, round to the nearest 5
The "10pctLimit" rule implements the requirement that rounding shall not exceed 10% of the original
amount. It rounds to values that are always within 1 log value of the dose, as in the chart below.
It will not evaluate a Route nor return a route error message. To conform with the functional limits
of the Sunrise application, it will return: 1) an error message and NULL for the rounded dose if
the dose amount is less than 0.00005; 2) a warning message and a rounded dose that may exceed the
10% limit if 0.00005 <= dose < 0.0005; or 3) a NULL message and a rounded dose within the 10% limit
for all other dose values.
. .
. .
(error) any smaller <= Dose < 0.00005 -> return Error_Message
0.00005 <= Dose < 0.0005 -> Round to the nearest 0.0001, return warning_message
0.0005 <= Dose < 0.005 -> Round to the nearest 0.0001
0.005 <= Dose < 0.05 -> Round to the nearest 0.001
0.05 <= Dose < 0.5 -> Round to the nearest 0.01
(A) 0.5 <= Dose < 5 -> Round to the nearest 0.1
(B) 5 <= Dose < 50 -> Round to the nearest 1
50 <= Dose < 500 -> Round to the nearest 10
500 <= Dose < 5000 -> Round to the nearest 100
5000 <= Dose < 50000 -> Round to the nearest 1000
50000 <= Dose < 500000 -> Round to the nearest 10000
500000 <= Dose < 5000000 -> Round to the nearest 100000
5000000 <= Dose < 50000000 -> Round to the nearest 1000000
.
.
.
METHOD:
1) The Dose is normalized by moving the decimal point so that
1 <= (normalized value) < 10. This is done by taking the log of the Dose.
2) Because the normalized Dose satisfies 1 <= (normalized Dose) < 10, we apply
rule (A) above if the normalized Dose is < 5 and rule (B) above otherwise.
3) The decimal point is moved back to its former location (denormalized).
A facility can modify this MLM if a different rounding is preferred.
;;
keywords:
;;
knowledge:
type: data-driven;;
data:
/***************** Make Changes To Spelling And Flags In This Section ******************/
// The rounding rule type to be applied by the MLM. Current valid values are
// "Standard" (the default) and "10pctLimit"
RoundingRule := "Standard";
// The list of PARENTERAL ROUTES that will be used to round the
// dose using the "Dose Rounding Rules for Parenteral Routes."
// The strings must match entries in your Route Dictionary.
// If there any entries that are NOT in your Route Dictionary, remove them.
Parenteral_Route_List := ("IM", "IM or IV", "IV", "IV push",
"IVPB", "SC", "Subcutaneous");
/* Set to true if logging is needed.*/
log_execution_info := false;
/***************************************************************************************/
/*-----------*/
/* ARGUMENTS */
/*-----------*/
(dose, // A number that is the amount of the dose.
route) // A string that is from the Route Dictionary.
:= Argument;
/* Set Return Variables to NULL */
rounded_dose := NULL;
error_message := NULL;
/* Set Round, Dose and Route errors to blank */
round_error := "";
dose_error := "";
route_error := "";
/* Assume no errors to start */
fatal_error := false;
minor_error := false;
if dose is not number then
/*------------------------------------------------------*/
/* Create Error Message for non-numerical dose argument */
/*------------------------------------------------------*/
fatal_error := true;
dose_error := " the Dose is NOT a number.";
else
/*----------------------------------------------*/
/* proceed if we have numeric argument for dose */
/*----------------------------------------------*/
if (RoundingRule is null or RoundingRule = "Standard") then
if not exist Route then
fatal_error := true;
route_error := " the Route is missing or invalid.";
elseif dose < 0.005 then
fatal_error := true;
dose_error := " the Dose amount is less than the {{{SINGLE-QUOTE}}}Standard{{{SINGLE-QUOTE}}} rounding lower limit (0.005).";
else // process only if we have a route
if route is in Parenteral_Route_List then
/*---------------------------*/
/* PARENTERAL Rounding Rules */
/*---------------------------*/
if dose <=1 then
/* For values <= 1, round to the nearest 0.01 */
rounded_dose:= (int((dose + 0.0051)*100))/100;
elseif dose <= 5 then
/* For values > 1 and <= 5, round to the nearest 0.1 */
rounded_dose:= (int((dose + 0.051)*10))/10;
elseif dose <= 50 then
/* For values > 5 and <= 50, round to the nearest 1 (integer) */
rounded_dose:= int(dose + 0.51);
elseif dose <= 100 then
/* For values > 50 and <= 100, round to the nearest 2 (even number) */
rounded_dose:= int((dose/2)+ 0.5)* 2;
elseif dose <= 500 then
/* For values > 100 and <= 500, round to the nearest 10 (integer) */
rounded_dose:= int((dose/10)+ 0.5)* 10;
elseif dose <= 2000 then
/* For values > 500 and <= 2000, round to the nearest 50 (integer) */
rounded_dose:= int((dose/50)+ 0.5)* 50;
elseif dose > 2000 then
/* For values > 2000, round to the nearest 100 (integer) */
rounded_dose:= int((dose/100)+ 0.5)* 100;
endif; // dose ranges (Parenteral route)
else
/*---------------------------------------------*/
/* OTHER (non-parenteral Route) Rounding Rules */
/*---------------------------------------------*/
if dose <= 1 then
/*For values <= 1, round to the nearest 0.01*/
rounded_dose:= (int((dose + 0.0051)*100))/100;
elseif dose < 10 then
/* For values >= 1 and <= 10, round to the nearest 0.1 */
rounded_dose:= (int((dose + 0.051)*10))/10;
elseif dose <= 50 then
/* For values >= 10 and <= 50, round to the nearest integer */
rounded_dose:= int(dose + 0.51);
else
/* For values > 50, round to the nearest 5 */
rounded_dose:= int((dose/5)+ 0.51)* 5;
endif; // dose ranges (non-Parenteral route)
endif; // Route is in parenteral list
endif; // not exist Route (for Standard rounding)
elseif RoundingRule = "10pctLimit" then
/* the number of decimal places is found by the log base 10 */
decimal_offset := int(log10(dose));
/* shift decimal point to "normalize" dose */
dose_normalized := dose / (10**decimal_offset);
/*-----------------------------------*/
/* now 1 <= dose_normalized < 10 */
/*-----------------------------------*/
if (dose < 0.00005) then
fatal_error := true;
dose_error := " the Dose amount is less than the {{{SINGLE-QUOTE}}}10pctLimit{{{SINGLE-QUOTE}}} "
|| "rounding lower limit (0.00005).";
elseif (0.00005 <= dose) and (dose < 0.0005) then
rounded_dose := dose formatted with "%.4f";
rounded_dose := rounded_dose as number;
if (abs(rounded_dose - dose) / dose) > 0.1 then
minor_error := true;
round_error := " rounded dose is outside the 10% limit "
|| "due to number of decimal places.";
endif; // rounded dose is outside 10%
else
/* round value below 5 to nearest 10th */
if dose_normalized < 5 then
rounded_dose_normalized := int((dose_normalized + 0.051)*10)/10;
else
/* or round to next higher integer */
rounded_dose_normalized := int(dose_normalized + 0.51);
endif;
/* restore decimal point */
rounded_dose := rounded_dose_normalized * (10**decimal_offset);
endif; // (dose < 0.00005) (10pctLimit)
/*----------------------------------*/
/* Insert other Rounding Rules here */
/*----------------------------------*/
endif; // Rounding Rule is Standard or 10pctLimit (or other)
endif; /* dose is number */
;;
evoke:
;;
logic:
if fatal_error then
error_message := "Unable to round dose because" || dose_error || route_error;
elseif minor_error then
error_message := "Warning: " || round_error;
endif;
/* Always conclude true to return a value */
conclude true;
;;
action:
return error_message, rounded_dose;
;;
end: