SanteSuite Help Portal
  • SanteSuite Help Portal
    • Disclaimer
  • Product Overview
    • SanteSuite Products
      • Introducing SanteDB CDR
        • SanteDB Solutions
      • Master Patient Index - SanteMPI
      • Immunization Management System - SanteIMS
      • Privacy & Security - SanteGuard
    • SanteDB Versions
  • Architecture
    • SanteDB Architecture
      • SanteDB History
    • Solution Architecture
    • Software Architecture
      • Publish / Subscribe Architecture
      • New ADO (nuado)
      • Roadmap
    • Data & Information Architecture
      • Conceptual Information Model
        • Concept Dictionary
          • Data Dictionary
        • Acts
          • State Machine
          • Act Relationships
          • Mood Concepts
          • Class Concepts
          • Data Dictionary
        • Entities
          • State Machine
          • Entity Relationships
          • Determiner Codes
          • Class Codes
          • Data Dictionary
        • Null Reasons
        • Extended Data
      • Physical Model
        • Act Data Dictionary
        • Entity Data Dictionary
        • Concept Dictionary Data Dictionary
      • Data Storage Patterns
        • Master Data Storage
      • SanteDB Object Identifiers (OIDs)
    • Security Architecture
    • Privacy Architecture
    • Matching Engine
    • HIE & Interoperability
  • Installation
    • Installation
    • Releases
      • 3.0 Releases
      • Queenston Release
    • Quick Start Guide
      • Seeding ONC Patient Matching Data
    • Operationalizing SanteDB
      • Information Gathering & Analysis
      • Planning & Preparation Work
        • Pre-flight Checklist
        • Develop a Business Architecture
        • Develop an Information Architecture
          • Establishing Minimum Datasets
          • Identity Environment
        • Develop Operational Technology Architecture
        • Developing Privacy Impact Assessments
        • Develop Threat / Risk Assessments
      • Deployment
        • Pre-Flight Checklist
        • Installing Software
          • SanteDB iCDR Server
            • Installation on Virtual or Physical Environments
              • Installation on Microsoft Windows
              • Installation on Linux and Unix
            • Installation using Appliances
              • Using Docker Containers
                • Adding Sample Data
                • Feature Configuration
                • SanteDB within Instant OpenHIE
              • Using Virtual Appliances
            • Installation Qualification
              • Master Patient Index / Client Registry Qualification
                • MPI/CR Test Cases for HL7v2
                  • TEST: OHIE-CR-02-HL7v2
                  • TEST: OHIE-CR-03-HL7v2
                  • TEST: OHIE-CR-04-HL7v2
                  • TEST: OHIE-CR-05-HL7v2
                  • TEST: OHIE-CR-06-HL7v2
                  • TEST: OHIE-CR-07-HL7v2
                  • TEST: OHIE-CR-08-HL7v2
                  • TEST: OHIE-CR-09-HL7v2
                  • TEST: OHIE-CR-10-HL7v2
                  • TEST: OHIE-CR-11-HL7v2
                  • TEST: OHIE-CR-12-HL7v2
                  • TEST: OHIE-CR-13-HL7v2
                  • TEST: OHIE-CR-14-HL7v2
                  • TEST: OHIE-CR-15-HL7v2
                  • TEST: OHIE-CR-16-HL7v2
                  • TEST: OHIE-CR-17-HL7v2
                  • TEST: OHIE-CR-18-HL7v2
                  • TEST: OHIE-CR-01-HL7v2
                  • HL7v2 Test Cases Instructions
                • MPI/CR Test Cases for FHIR
                  • TEST: OHIE-CR-01-FHIR
                  • TEST: OHIE-CR-02-FHIR
                  • TEST: OHIE-CR-03-FHIR
                  • TEST: OHIE-CR-04-FHIR
                  • TEST: OHIE-CR-05-FHIR
                  • TEST: OHIE-CR-06-FHIR
                  • TEST: OHIE-CR-07-FHIR
                  • TEST: OHIE-CR-08-FHIR
                  • TEST: OHIE-CR-09-FHIR
                  • FHIR Test Cases Instructions
              • Security Administration Testing
                • Administrative Panel Validation
                  • User Management Tests
                    • TEST: SECURITY-UM-01
                    • TEST: SECURITY-UM-02
                    • TEST: SECURITY-UM-03
                    • TEST: SECURITY-UM-04
                    • TEST: SECURITY-UM-05
                    • TEST: SECURITY-UM-06
                    • TEST: SECURITY-UM-07
                    • TEST: SECURITY-UM-08
                    • TEST: SECURITY-UM-09
                    • TEST: SECURITY-UM-10
                    • TEST: SECURITY-UM-11
                    • TEST: SECURITY-UM-12
                    • TEST: SECURITY-UM-13
                    • TEST: SECURITY-UM-14
                    • TEST: SECURITY-UM-15
                    • TEST: SECURITY-UM-16
                    • TEST: SECURITY-UM-17
                    • TEST: SECURITY-UM-18
                    • TEST: SECURITY-UM-19
                    • TEST: SECURITY-UM-20
                    • TEST: SECURITY-UM-21
                    • TEST: SECURITY-UM-22
                    • TEST: SECURITY-UM-23
                    • TEST: SECURITY-UM-24
                    • TEST: SECURITY-UM-25
                    • TEST: SECURITY-UM-26
                    • TEST: SECURITY-UM-27
                    • TEST: SECURITY-UM-28
                    • TEST: SECURITY-UM-29
                    • TEST: SECURITY-UM-30
                    • TEST: SECURITY-UM-31
                    • TEST: SECURITY-UM-32
                    • TEST: SECURITY-UM-33
                    • TEST: SECURITY-UM-34
                    • TEST: SECURITY-UM-35
                    • TEST: SECURITY-UM-36
                    • TEST: SECURITY-UM-37
                  • Group/Role Management Tests
                    • TEST: SECURITY-GRM-01
                    • TEST: SECURITY-GRM-02
                    • TEST: SECURITY-GRM-03
                    • TEST: SECURITY-GRM-04
                    • TEST: SECURITY-GRM-05
                    • TEST: SECURITY-GRM-06
                    • TEST: SECURITY-GRM-07
                    • TEST: SECURITY-GRM-08
                    • TEST: SECURITY-GRM-09
                    • TEST: SECURITY-GRM-10
                    • TEST: SECURITY-GRM-11
                    • TEST: SECURITY-GRM-12
                    • TEST: SECURITY-GRM-13
                    • TEST: SECURITY-GRM-14
                    • TEST: SECURITY-GRM-15
                  • Security Policy Management Tests
                    • TEST: SECURITY-PM-01
                    • TEST: SECURITY-PM-02
                    • TEST: SECURITY-PM-03
                    • TEST: SECURITY-PM-04
                  • Device Management Tests
                    • TEST: SECURITY-DM-01
                    • TEST: SECURITY-DM-02
                    • TEST: SECURITY-DM-03
                    • TEST: SECURITY-DM-04
                    • TEST: SECURITY-DM-05
                    • TEST: SECURITY-DM-06
                    • TEST: SECURITY-DM-07
                    • TEST: SECURITY-DM-08
                    • TEST: SECURITY-DM-09
                  • Application Management Tests
                    • TEST: SECURITY-AM-01
                    • TEST: SECURITY-AM-02
                    • TEST: SECURITY-AM-03
                    • TEST: SECURITY-AM-04
                    • TEST: SECURITY-AM-05
                    • TEST: SECURITY-AM-06
                    • TEST: SECURITY-AM-07
                    • TEST: SECURITY-AM-08
          • SanteDB dCDR Instances
            • Installing Web Access Gateway
            • Installing Disconnected Gateway
            • Installing Disconnected Windows Application
            • Installing the dCDR SDK
            • User Interface App Settings
        • Configuring Privacy Controls
        • Post Deployment Tuning
        • Securing SanteDB Configuration
        • Securing SanteDB Databases
        • Securing SanteDB APIs
      • Rollout
    • Demonstration Environments
  • Operations
    • SanteDB Operations
    • Server Administration
      • Configuration Tool
        • Messaging Settings
          • HL7 Version 2 Service
          • FHIR R4 Service
          • GS1 BMS XML Service
          • Health Data Services Interface
          • Administrative Management Interface
        • Diagnostics Settings
        • Persistence Settings
          • Retention Policies
          • Resource Manager Settings
          • Database Connections
        • System Settings
        • Performance Settings
        • Security Settings
          • Data Privacy Filtering
          • Auditing Configuration
        • Operating System Settings
      • Server Configuration File
        • Service API Configuration
          • REST Service Configuration
        • Connection Strings
        • Application Service Context Configuration
        • Applet Configuration
        • Diagnostics Configuration
        • Data Quality Services
      • SanteDB iCDR Host Command
      • Backup Procedures
      • Log File Management
    • CDR Administration
      • SanteDB Administration Portal
        • Logging In
        • Managing Your Profile
        • System Administration
          • Jobs
          • Logs
          • Pub/Sub Manager
          • Server Status
          • Dispatcher Queue
          • Probes
        • Reference Data Administration
          • Place Administration
          • Facility Administration
          • Materials
          • Identity Domain Management
        • Concept Dictionary Administration
          • Concept Sets
          • Concepts
          • Code Systems
        • CDR Administration
          • Importing Data
          • Data Quality Rules
          • Extensions
          • Decision Support Library
            • View CDSS Library
            • Edit CDSS Library
          • Matching Configuration
            • Creating / Viewing Configurations
            • General Configuration
            • Blocking Configuration
            • Scoring Configuration
            • Classification Configuration
            • Testing Match Configuration
            • Match Configuration XML Definition
        • Data Warehouse
        • Reports Centre
        • Security Administration
          • Managing User Accounts
          • Managing Groups
          • Managing Policies
          • Managing Devices
          • Managing Applications
          • Reviewing Audits
      • SanteDB Administration Console
        • User Administration
        • Group / Role Administration
        • Policy Administration
        • Device Administration
        • Application Administration
    • Standard Operating Procedures
      • User Management SOPs
        • SOP: Onboarding Users
        • SOP: User Lockout
        • SOP: Deactivating Users
      • Role Management SOPs
        • SOP: Role Policy Assignment
        • SOP: Assigning Users to Roles
        • SOP: Creating New Roles
      • Device Management SOPs
        • SOP: Onboarding new HL7v2 Device
        • SOP: Onboarding new dCDR Device
      • Application Management SOPs
      • Standard Operating Procedure Template
  • User Guides & Training
    • SanteDB User Guides
    • Common User Interface Elements
    • SanteMPI
      • Getting Started with the MPI
      • SanteMPI Matches
      • SanteMPI Searching
      • SanteMPI Power Search
      • SanteMPI Patient Detail
        • Demographics Tab
          • Demographic Information Panel
          • Identifiers Panel
          • Related Persons Panel
          • Entity Relationships Panel
        • Master Data Management Tab
          • Records of Truth
        • Data Quality Tab
      • SanteMPI Dashboard
    • SanteEMR
      • EMR Administration
        • Care Pathways
        • Visit Types & Flows
        • Clinical Templates
    • SanteGuard
  • Developers
    • Extending & Customizing SanteDB
    • Getting Started
    • SanteDB XML Schemas
    • Applets
      • Applet Use and Lifecycle
      • Applet SDK Components
        • Applet Development Environment
        • SanteDB Brain Bug
        • Package Manager
        • BRE Debugger
      • Applet Structure
      • JavaScript API
      • Business Intelligence Assets
        • BI Asset Definitions
          • Data Sources
          • Parameters
          • Queries
          • Reference Data
          • Views
          • Data Marts
          • Reports
          • Indicators
        • BI Render Controls
      • Localization
      • Customization & Branding
      • Assets
        • HTML Assets
        • HTML Widgets
        • Virtual Assets
      • AngularJS
      • Clinical Decision-Support
        • CDSS Definitions
        • Legacy CDSS
      • Business Rules
      • Dataset Files
      • External Data Maps
      • Applet Solution Packages
      • JavaScript API Reference
      • Recipes
        • Adding Security Policy based on Occupation
        • Assigning a Home Facility
        • Codified Address
        • Generating ID on Registration
    • .NET Plugins
      • Plugin Libraries
      • Host Context & Lifecycle
      • Business Model Objects
      • Services & Configuration
        • Configuration
          • Configuration Panels
          • Custom Docker Feature Configuration
        • Passive Services
        • Daemon Services
        • Service Definitions
          • Ad-Hoc Cache Provider
          • Application Identity Provider
          • Audit Dispatch Service
          • Barcode Generator Provider
          • Business Rules Service
          • Care Plan Generation Service
          • CDSS Clinical Protocol Repository
          • Concept/Terminology Provider
          • Configuration Manager Service
          • Daemon Service
          • Data Archiving Service
          • Data Privacy Enforcement Provider
          • Data Signing Service
          • dCDR Subscription Definition Provider
          • dCDR Subscription Execution Provider
          • Device Identity Provider
          • Exec-Once Message Persistence
          • Freetext Search Provider
          • IDataPersistenceService{TData}
          • IDataPersistenceServiceEx{TModel}
          • IDataQualityConfigurationProviderService
          • Identity Domain Provider
          • IDispatcherQueueManagerService
          • IElevatableIdentityProviderService
          • IExtensionTypeRepository
          • IFastQueryDataPersistenceService{TEntity}
          • IFastQueryRepositoryService{TEntity}
          • IPersistableQueryRepositoryService{TEntity}
          • IPubSubManagerService
          • IRecordMergingService{T}
          • IRepositoryService
          • ISecurityRepositoryService
          • ISqlDataPersistenceService
          • IStoredQueryDataPersistenceService{TEntity}
          • ITagPersistenceService
          • ITemplateDefinitionRepositoryService
          • IThreadPoolService
          • IUnionQueryDataPersistenceService{TEntity}
          • IValidatingRepositoryService{TModel}
          • Job Management Service
          • Localization Provider
          • Mail Repository Provider
          • Name Alias Provider
          • Network Metadata Provider
          • Password Hashing Service
          • Password Validation Service
          • Policy Decision Provider (PDP)
          • Policy Enforcement Provider (PEP)
          • Policy Information Provider (PIP)
          • Primary Data Caching Provider
          • Query Result Scoring Provider
          • Record Matching Configuration Provider
          • Record Matching Provider
          • Record Merging Provider
          • Repository Service
          • Repository Service with Cancellation Support
          • Repository Service with Extended Functions
          • Repository Service with Notification Support
          • Resource Checkout/Locking Provider
          • Resource Patching Provider
          • Resource Pointer Service
          • Role Provider
          • Security Challenge Authentication Provider
          • Security Challenge Storage Provider
          • Session Authentication Provider
          • Session Storage Provider
          • Stateful Query Provider
          • Stock Management Provider
          • Symmetric Encryption Provider
          • TFA/MFA Secret Generator
          • User Identity Provider
          • User Notification Relay Provider
          • User Notification Template Filler
          • User Notification Template Repository
      • Plugin Metadata
      • Database Patching
      • Custom Match Algorithms
      • Unit Testing Framework
      • Digital Signing Requirements
      • .NET API Reference
    • Service APIs
      • OpenID Connect
        • Consent & Privacy
      • Business Intelligence Service (BIS)
      • Administration Management Interface (AMI)
      • Health Data Service Interface (HDSI)
        • HTTP Request Verbs
        • HDSI Query Syntax
          • Filter Functions
        • API Responses
        • Patching
        • MDM Extensions for HDSI
        • Synchronization API
        • Visual Resource Pointer API
      • HL7v2
        • Enabling HL7v2 Interfaces
        • HL7 Authentication
        • SanteDB HL7v2 Implementation
      • HL7 FHIR
        • Enabling FHIR Interfaces
        • SanteDB FHIR Implementation
          • FHIR Subscriptions
          • Related Persons
        • Extending FHIR Functionality
      • GS1 BMS XML
      • Examples
        • Connecting to the FHIR API
        • Obtaining A Session
    • SanteDB Software Publishers
  • Knowledgebase
    • Knowledgebase
      • SanteDB 2.1.161+ on PostgreSQL 10 returns "websearch_to_tsquery" error
      • Upgrading SanteDB iCDR with large databases
      • Upgrading Gateway to SanteDB Langley (v2.0.30+) from SanteDB Kelowna and earlier
      • When sending a National Scoped ID in PID-19 (SSN) you receive "AuthorityUuid" missing error
      • After Installing dCDR you receive an error on SecurityUser
      • When logging into the dCDR you are immediately logged back out
      • PostgreSQL connections fail with block message
      • Backing up HDSI server database
      • You receive an "out of disk space" error on the IMS server
      • Setting up the "sherlock" service
      • Diagnosing service port issues
      • You receive a certificate expired or certificate not found error on startup
      • After updating a database field the values are not reflected in the application layer
      • Diagnosing Submission Errors From Mobile Device
      • Migrating A SanteDB Server
      • Pruning and Cleaning the Database
      • Improving Download Speeds on Slow Connections
      • You receive a client already running error message
      • Resetting the configuration of the Windows & Linux Applications
      • After setting up the application data appears to be missing
      • Disconnected Client Window is Scaled Improperly
      • Fatal Error on Startup
      • Synchronization Issues on Mobile
      • Installation on Mono 4.x does not permit joining of realm
      • Creating A Public Backup
      • Installing the SanteDB Disconnected Server
    • Fixes & Patches
      • 20170721-01
      • 20170725-01
      • 20170803-01
      • 20170804-01
      • 20170913-01
      • 20171003-01
      • 20171011-01
      • 20171016-01
      • 20171023-01
      • 20171030-01
      • 20171108-01
      • 20171124-01
      • 20180126-01
      • 20180131-01
      • 20180211-01
      • 20181112-01
      • 20181113-01
      • 20190322-01
      • 20190522-01
      • 20190625-01
      • 20200105-01
  • OpenIZ
    • About OpenIZ
      • Upgrading from OpenIZ to SanteDB
    • FAQ
    • OpenIZ Demonstration Servers
Powered by GitBook
On this page
  • CDSS Library Syntax
  • Strings
  • Dotted Identifiers
  • Block Definitions
  • Comments
  • Object Status
  • Metadata
  • Logic Blocks
  • Facts
  • Models
  • Rules
  • Protocols
  • Computable Expressions
  • Health Data Service Interface Query
  • C# Expressions
  • Aggregate Logic Expression
  • Fact References
  • Output Actions
  • Propose
  • Assign a Value to Property
  • Raise an Alert
  • Apply Another Rule
  • Repeat Actions
  • Data Blocks
  • Querying Data Blocks

Was this helpful?

  1. Developers
  2. Applets
  3. Clinical Decision-Support

CDSS Definitions

PreviousClinical Decision-SupportNextLegacy CDSS

Last updated 1 year ago

Was this helpful?

Starting with SanteDB 3.0, a new, more robust CDSS XML format has been introduced which greatly improves the re-use of decision logic blocks in CDSS rules. CDSS definitions are contained in an XML or text file structure known as a CDSS Library. The CDSS library contains different definition sections as illustrated below.

  • Metadata: Descriptive information about the CDSS library including the version, its current status, and authors, etc.

  • Includes: Allow a CDSS library to import definitions from other CSS libraries (including the system library)

  • Logic Blocks: Blocks of definition assets which apply to a particular context.

    • Context: Allows for the limiting of rules, protocols, and facts to a particular resource type, and even a subset of resource types.

    • Facts: Defines a discrete piece of information which is extracted from the context in the CDSS

    • Rules: Structures which trigger a series of actions when a series of facts are true

    • Protocols: A more structured version of a rule which includes metadata for the CDSS engine, including the steps in a care plan package.

  • Data Blocks: Allow a CDSS author to include reference data which rules may use. For example, an author may include pre-computed z-scores for a particular type of observation which is then used to set the interpretation of an observation.

CDSS definitions are transpiled into an XML format from the CDSS source files. The CDSS source files are text files which can be created with any text editor. CDSS library definitions are uploaded to the SanteDB server or loaded into the SanteDB business rules debugger.

The structure of the CDSS and its equivalent XML structure are provided below.

include <id.of.lib.to.include>

define library "name of library file"
   having id <id.of.library>
   having uuid "uuid-of-library"
   having status active|trial-use|retired|dont-use
   with metadata
   ...
   end metadata
as 
   define logic "name of logic block"
      // logic definitions
   end logic
   
   define data "name of data block"
      // CSV data
   end data 
end library

CDSS files are always placed in the protocols/ folder of your applet. This folder can contain XML or text-based definitions for your libraries.

CDSS Library Syntax

Strings

There are two types of strings which are supported in the CDSS definition file, a single line string is enclosed in double quotes such as "This is a string", a string can be escaped with a double quote such as "This is a ""string"" that is escaped".

Strings which cross multiple lines or strings which need to use lots of quotes (which would require a lot of escaping) are represented as multi-line strings. These strings are enclosed in $$ indicators such as $$ This is a "string" too $$ , these are useful for representing C#, HDSI or even large JSON objects such as:

$$
{
   "$type": "Patient",
   "dateOfBirth": "2023-01-01"
}
$$

Dotted Identifiers

Dotted identifiers allow for direct, unambiguous references to objects in the CDSS subsystem. Dotted identifiers are enclosed in < marks. The use of these are illustrated in references such as include <org.santedb.example> where org.santedb.example is the dotted identifier.

Block Definitions

Block definitions include all of: libraries, logic, data, facts, protocols, rules, models, proposals, etc. Blocks are multiple lines which encapsulate the modifiers and instructions for the blocks. Block definitions always have the pattern:

define (library|logic|data|fact|model|...) "NAME"
   having statements
   with metadata
       // contents of metadata
   end metadata
   as
      // contents of the block
end (library|logic|data|fact|model...)

Comments

Comments can be added to any of part of your CDSS file. Comments differ from metadata documentation in that comments are stripped from the transpiled source, and are only visible to developers. Any line or part of line following a double-slash // is a comment.

Object Status

The status of an object will be used to determine whether the object is to be referenced or used in the evaluation of rules in the library. The status is indicated on an element with <status> element on the object.

Status
Description
Impact

trial-use

The object is for trial use only.

The library, logic block, rule, etc. is only used in debugging and testing contexts.

active

The object is active and available for system use.

The library, logic block, rule, etc. is used for all clinical encounters and when the CDSS engine is called.

retired

The object was active, and can continue to be used, however should not be used for new care plans.

Patients which have care plans which were generated using the CDSS logic will continue to have the logic applied. However, new care plans will not be generated with this library asset.

dont-use

The object should not be used.

Effective immediately (when the state is indicated) no furher proposals will be generated with the assets in the library.

Metadata

All library objects carry a metadata section which is used to provide information about the logic block, library, etc. Metadata is placed onto an object using the with metadata indicator or in the <meta> element.

with metadata
    author The Name of an Author
    author The Name of another Author
    version semantic-version
    doc A line of documentation
    doc another line of documentation
end metadata
<meta>
  <authors>
    <add>Name of a maintainer for the object</add>
  </authors>
  <version>Informative version identifier</version>
  <documentation>Long form documentation for the object which is shown for 
                 administrators and users.</documentation>
</meta>
define logic "Example Logic Block"
   having id <org.example.logic>
   having status active
   with metadata
      author An Example Author
      version 1.0-alpha
      doc This is just an example logic block
   end metadata
   ...
end logic

Logic Blocks

Logic blocks are sections of the CDSS rule file which define one or more facts, rules, protocols, or other computable decision support assets. Logic blocks contain metadata which specify the context to which the contents of the block apply.

Logic blocks have the following contents:

  • Context: The object/resource to which the contents of the logic block applies

  • When Block: Which is used to further restrict the type of objects to which the logic block applies (for example, only apply to Female patients)

  • Definitions: Which are the facts, models, rules, and protocols of the logic block.

Logic blocks are defined with define logic ... end logic or the <logic> element, and have a format as illustrated below:

define logic "Name of Logic Block"
   having id <dotted.id.of.the.logic.block>
   having uuid "uuid-of-the-block"
   having oid "oid.of.logic.block"
   having status active|trial|dont-use|retired
   having context (Patient|Act|QuantityObservation...)
        when computable_expression
   with metadata
      ...
   end metadata
   as 
      define (fact|model|rule|protocol)
      ..
      end
end logic
<logic id="dotted.id.for.logic.block" 
    name="Human Friendly Name For Logic Block"
    uuid="uuid-for-logic-block">
    <status>active|trial-use|dont-use|retired</status>
    <!-- Specify the resource to which all logic in this block applies -->
    <context type="Resource"/>
    <!-- Selectively include the block when the conditions specified are true -->
    <when>
        <!-- Computable Expression Here -->
        <all|any|none|csharp|hdsi/>
    </when>
    <define>
        <!-- One or more definitions -->
    </define>
</logic>
include <org.santedb.core>

library "Example Library"
    having id <org.example.library>
    as 
    
   define logic "Example Logic Block for Female Patients"
       having id <org.example.library.logic.female>
       having context Patient when hdsi("genderConcept.mnemonic=Female")
   as 
       ...
   end logic
end library

Facts

A fact represents a single piece of information which is known to be true based on data passed to it. A fact represents an instruction which can be used to extract information or make a determination about the state of data. Examples of facts can be:

  • The patient's gender

  • If the patient is under 5 years old

  • If an observation was not made within a time period

define fact "name of fact"
   having id <id.of.fact>
   having type (int|real|bool|string|date)
   having negation (true|false)
   as 
      computable expression
end fact
<fact name="Name of a Fact"
    id="dotted.id.of.fact"
    type="string|integer|long|date|boolean|real">
    <!-- One of -->
    <csharp../>
    <hdsi.../>
    <all.../>
    <none../>
    <!-- Zero or many transforms -->
    <normalize>
        <when>
          <!-- Computable Expression -->
        </when>
        <csharp|hdsi.../>
    </normalize>
</fact>
library "Example Library"
  as
    ...
    
   define logic "Example Logic Block for Female Patients"
    ...
   as 
     define fact "Patient Is Too Young for HPV Programme"
       having type bool
       with metadata
         doc Patients under 9 years old are too young to receive HPV dose
       end metadata
       as
         hdsi($$ 
           dateOfBirth=:(age)<P9Y
         $$)
     end fact
   end logic
end library

Facts can also be used to extract data in a consistent form, for example, a fact defining the age of the patient in years may be defined as:

define fact "Patient Age In Years" having type real as
  csharp($$
     DateTime.Now.Subtract(context.Target.DateOfBirth.Value.Date).TotalDays / 365.25f
  $$)
end

Normalization

Facts can be normalized according to one or more normalization rules. Normalization is useful when you need a fact to be translated from one format to another using a computation. Take, for example, a rule which may need to determine if an observation made was out of range, however needs to change units (for example weight). Such a fact should be normalized, for example:

define logic "Interpret Weight"
    having context QuantityObservation 
        when hdsi("typeConcept=a261f8cd-69b0-49aa-91f4-e6d3e5c612ed")
    as 
    
        // Determine whether the observation was recorded in LBS
	define fact "Weight is Expressed in Lbs" having type bool
        as 
            hdsi("unitOfMeasure=49974584-7c48-457e-a79c-031cdd62714a")
        end fact
        
        // Create a fact which normalizes the wieght into KGs so we can do a lookup
        define fact "Observed Weight Expressed in Kgs" having type real
	as 
	    hdsi("value")
	    normalize when "Weight is Expressed in Lbs" 
	        computed as csharp($$ value * 0.45359237d $$)
	end fact
end logic

Models

Models are used when you wish to define a template of data which is reused. These are usually referenced from proposals, and they represent a fact which has a static, complex structure. Models are defined in the logic block with define model ... end model or the <model> element in XML.

define model "Name of Model"
    having id <id.of.model>
    having uuid "uuid-of-model"
    having format json|xml
    with metadata
        ...
    end metadata
    as 
    $$
        // contents of the model 
    $$
end model
<model name="Name of Model" id="id.of.model">
    <json><![CDATA[.....]]></json>
    <Act|QuantityObservation|CodedObservation.... xmlns="http://santedb.org/model">
        ...
    </Act|QuantityObservation|CodedObservation...>
</model>
define model "Propose HPV Dose Administration"
    having format json 
    as 
    $$
    {
      "$type": "SubstanceAdministration",
      "typeConcept": "F3BE6B88-BC8F-4263-A779-86F21EA10A47",
      "statusConcept" : "c8064cbd-fa06-4530-b430-1a52f1530c27", 
      "doseQuantity" : 1.0,
      "doseUnit" : "a4fc5c93-31c2-4f87-990e-c5a4e5ea2e76",
      "route" : "d594f99f-0151-41a0-a359-282ab54683a1",
      "site" : "dd5db8ed-0d97-4728-bd94-27aacd79ea02",
      "participation": {
	   "Product": [{
              "player" : "15b42b90-17fa-48cd-8121-f909c9d00ccc",
              "quantity": 1
            }]
      }
    }
    $$
end model

Rules

The structure of the rules is illustrated below.

rule "Name of Rule"
   having id <dotted.id.of.rule>
   having uuid "uuid-of-rule"
   having oid "dotted.oid.of.rule"
   having status (active|trial-use|dont-use|retired)
   having priority NNN
   with metadata
      ...
   end metadata
   as 
      when 
         any( ...
         all( ...
         none( ...
         csharp( ...
         hdsi( ...
      then 
         raise ...
         repeat ...
         apply ...
         propose ...
         assign ...
end rule
<rule name="Name of Rule"
      id="dotted.id.of.rule"
      priority="n">
      <meta>
          ...
      </meta>
      <when>
            <!-- Computable Expression Here -->
            <csharp.../>
            <any.../>
            <hdsi.../>
            <all.../>
            <none.../>
            <fact ref="Name of fact to reference" />
      </when>
      <then>
            <!-- One or More Output Actions Here -->
            <propose.../>
            <raise.../>
            <assign.../>
            <apply ref="Name of another rule to apply"/>
      </then>
</rule>
define rule "Raise Alert When Patient Has AEFI to COVID Vaccine"
   metadata
     doc Will raise a warning when a COVID vaccination has been proposed and 
     doc an unresolved adverse event or allergy has been recorded
   end metadata
   when 
     all(
       "Patient Has Unresolved COVID Vaccine AEFI",
       "Patient Was Proposed COVID Vaccine"
     )
   then 
     raise $$
       Patient has previous suspected or confirmed adverse reaction or allergy
       to COVID vaccination in their history. Please review allergen and event
       history with patient prior to administration
     $$ having priority danger
end rule

When the CDSS engine's Execute() or Analyze() methods are invoked, all rules which are contained in the relevant logic blocks (which apply to the object being executed or analyzed). Rules are selectively applied when a ComputeProposal() call or GenerateCarePlan() methods are called based on the protocols which apply.

Protocols

A protocol is a specialized form of a rule. A protocol has identical metadata to a rule, with the exception that a protocol can define one or more encounter scopes to which the protocol applies, and a protocol explicitly marks a rule as an "entry point" for a more complex series of care which result in the creation of a care plan.

Protocols can be used to represent:

  • Regular nutritional counseling for patients based on their weight/history

  • Regular vaccination recommendations for patients based on their age/history

A protocol always applies to PATIENT , protocols cannot be applied to contexts other than PATIENT.

Protocols are defined with the define protocol ... end protocol or <protocol> element.

define protocol "Name of Protocol"
   having id <dotted.id.of.protocol>
   having uuid "uuid-of-rule"
   having oid "dotted.oid.of.rule"
   having status (active|trial-use|dont-use|retired)
   having priority NNN
   having scope <dotted.id.of.scope>
   having scope "name of scope"
   with metadata
      ...
   end metadata
   as
     when 
       any( ...
       all( ...
       none( ...
       csharp( ...
       hdsi( ...
     then
       raise ...
       repeat ...
       apply ...
       propose ...
       assign ...
end protocol    
<protocol name="Name of Rule"
   oid="dotted.oid.of.rule"
   id="dotted.id.of.rule"
   uuid="uuid-of-rule"
   priority="N">
   <scopes>
      <add id="dotted.id.of.scope" oid="oid.of.scope" />
   </scopes>
   <when>
      <csharp ... />
      <hdsi ... />
      <all ... />
      <any ... />
      <none ... />
      <fact ref="name of fact" />
   </when>
   <then>
      <propose ... />
      <assign ... />
      <repeat ... />
      <apply ... />
      <raise ... />
   </then>
</rule>
define protocol "COVID Vaccination Base Immunization Schedule"
    having id <org.example.covid.vaccine.protocol>
    having oid "2.25.30239238239232"
    having scope <org.santedb.emr.enc.adult.consult>
as
    when 
        none(
            "Patient Has Previous Adverse Event to COVID Vaccine",
            "Patient Has No Previous Doses of COVID Vaccine"
        )
    then
        apply "Propose COVID Vaccine Dose #1 Standard Schedule"
        apply "Propose COVID Vaccine Dose #2 Standard Schedule"
end protocol

Computable Expressions

Computable expressions are those expressions which are used to:

  • Extract data from a resource as the basis for a fact

  • Determine a boolean logic output for a when condition in a rule or protocol or as a block on a logic block.

Computable expressions are made against either the context (which is the input data) or the scopedObject which is the current action object. The scopedObject represents:

  • The input context object for facts

  • The output object of a proposal

Health Data Service Interface Query

The HDSI expression is either scoped to context meaning the input object to the analysis or the proposal which is the currently scoped object. HDSI expressions which are negated are those which have a NOT() operation applied to them.

Multiline expression:

hdsi($$
   expression
$$ 
   scoped-to (context|proposal) 
   negated
)

Singleline expression:

hdsi("expression here" scoped-to (context|proposal) negated)
<hdsi scope="context|scopedObject">expression</hdsi>
define fact "Patient Is Over 10 Years Old" type bool as
    csharp(
    $$
        dateOfBirth=:(age)>P10Y
    $$ 
        scoped-to context
    )
end fact

C# Expressions

There arise some instances in your decision logic where you must execute more advanced operations such as calculations, date subtraction, and string formatting. The CDSS engine allow the execution of a limited subset of expressions using the C# language. The subset allows for CDSS rule developers to:

  • Cast objects from the context as base types or resources

  • Perform mathematical operations

  • Perform Date calculations

  • Array functions (like Find, FirstOrDefault, etc.)

The C# expression handler has access to reflection disabled, and late object binding disabled. While this increases the security of the C# expressions, it does mean that all variables must be cast prior to use.

csharp($$
   // C# Code Here
$$)
<csharp><![CDATA[ // csharp goes here ]]></csharp>
...
then 
    repeat for 100 iterations track-by index
        csharp($$
            Trace.WriteLine("Iteration {0}", context["index"])
        $$)
    end repeat
end rule

Context Object

The current CDSS context object can be accessed with the context variable. context can be used to lookup facts and the output of rules which have been (or will be) executed. Context is used in the following manners

Description
Example

Lookup a fact from the current execution context.

context["name of fact"]

Get the value of a fact with a specified type

context.Int("name of fact") context.String("name of fact") context.Real("name of fact") context.Date("name of fact") context.Bool("name of fact")

context.DataSets["name of dataset"]

Cast a fact as a RIM based object

(Patient)context["name of fact"]

Access the input object (context's current execution target)

context.Target.DateOfBirth

Set a value of a fact on the context

context["name of fact"] = value of fact

Special Variables

There are other special variables which can be accessed in the C# interpreter including:

  • scopedObject which is of type IdentifiedData and always points to the current "in scope" object. If the C# appears in a fact definition this is the same as context.Target , if it appears in a propose statement it is the value of the proposal (the object that is being proposed)

  • value which is used when a normalize computation is written in C#.

Aggregate Logic Expression

There are three aggregate logic expressions which can be used to combine the result of multiple computable expressions. These are identiifed in the table below:

Expression
Logic
Description

any(...)

OR

Returns TRUE when any of the contained facts or statements return TRUE or a non-null value.

all(...)

AND

Returns TRUE when all of the contained facts or statements return TRUE or a non-null value.

none(...)

NAND

Returns TRUE only when all of the contained statements are not TRUE or are a null value.

These logic statements can be combined to represent decision logic structures, for example, if we want to define a fact that is true when:

  • The Patient is Under 18 Months AND received the first dose of an antigen in their 17 months, OR

  • The Patient is Over 18 Months AND has NOT received any dose of the antigen

define fact "Child is Eligible for Accelerated MR Schedule" type bool as
    any(
        all(
            hdsi($$ dateOfBirth=:(age)<P18M $$),
            csharp($$ (int)context["Age of Patient for Dose 1"] > 16 $$)
        ),
        all(
            hdsi($$ dateOfBirth=:(age)>P18M &&),
            none("Patient's Administration of Dose 1")
        )
    )
end fact

Fact References

Facts can be referenced and combined using fact references. In the CDSS text file syntax, this is done by referencing the name of the fact in quotes. In XML this is done using the <fact ref="Name of Fact"/> element or <fact ref="#id.of.fact"/>.

Output Actions

Actions are used in rules and protocols as a series of steps which should be taken. These actions can:

  • Propose that some action or course of treatment be performed

  • Assign a value (such as an interpretation, or flag) on the existing object in scope

  • Raise an end-user alert which must be cleared prior to completing the encounter

  • Apply another rule or decision tree

  • Repeat certain actions for a specified number of iterations or until a condition is true.

Propose

// Using a shared model reference
propose "Descriprive Name for Proposal"
   having model "Name of Model Definition To Use"
   with metadata
      ...
   end metadata
   as
      assign ...
end propose

// Using an inline model 
propose "Descriptive Name for Proposal"
   having model with format (json|xml) as
   $$
      model here
   $$
   with metadata 
       ...
    end metadata
    as
       assign ...
end propose
<propose name="Name for Proposal">
    <model ref="Name of Referenced Model">
        <json>
           // JSON for inline model
        </json>
     </model>
     <assign ... />
</propose>
define rule "Propose Supplement for Underweight Patients"  as
   when 
      "Patient Is Underweight"
   then 
      propose "Propose Nutrition Supplement Administration"
         having model "Nutrition Supplement Administration Model"
         as
         assign csharp("DateTime.Now") to actTime
         assign const 1 to doseSequence
      end propose
end rule

Assign a Value to Property

Actions can also assign computed, fixed values, or facts to a property on the scopedObject. When an assignment exists outside of a propose this means the assignment occurs on context.Target however within a propose the assignment is against the scoped (proposed) object.

Assignments are made using the assign ... to path syntax or the <assign> element in XML.

// Assign C# expression 
assign csharp(...) to property
// Assign HDSI expression
assign hdsi(...) to property
// Assign a fact to property
assign "name of fact" to property
// Assign a fixed value to a property
assign const value to property
<assign path="propertyName">
    <csharp ... />
    <hdsi ... />
    <fixed>value</fixed>
    <fact ref="name of fact" />
</assign>
rule "Assign Interpretation Code With Observed Value is Low" as
    when 
        all(
            "Observed Value Is Below Normal Reference Range",
            "Author Has Not Manually Assigned an Interpretation"
        )
    then 
        assign const "6188F821-261F-420C-9520-0DE240A05661" to interpretationConcept
        assign const "true" to tag[cdssInterpretation]
        assign const "CDSS Has Set Interpretation Concept on this observation"
            to note
end rule

Raise an Alert

There are often times where a CDSS rule may wish to raise an alert to an end-user in the context of an encounter based on some clinical status of the patient or a previously observed value. This is done with the raise statement in CDSS or the <raise> element in XML.

The raise alert function will do three things:

  1. When the CDSS engine is being called as part of analysis for a captured value (via Analyze()) it will be displayed to the user in their encounter capture screen.

  2. When the CDSS engine is being called prior to discharge of the patient, the end user must clear (or acknowledge) the alert before discharging the patient.

raise 
   having priority (danger|warn|info)
   having type "UUID-OF-CONCEPT-FOR-CLASSIFICATION"
   having id <dotted.id.for.issue>
   with metadata
      ...
   end
$$
   This is the text that is to be displayed in the alert. You can also use a 
   single line string with "quotes around a single line of text"
$$ 
<raise>
    <issue xmlns="http://santedb.org/issue"
        priority="Error|Warning|Information"
        id="dotted.id.of.issue"
        type="uuid-of-issue-type"
    >
    This is the text of your issue
    </issue>
</raise>
define rule "Alert Clinician the Nutritional Counseling Should be Performed" as
    when 
        any(
            "Child Is Under Healthy Weight For Age",
            "Child Is Over Healthy Weight for Age"
        )
    then 
        raise having priority warn
            $$
                The observed weight indicates that the child is not a normal 
                healthy weight. Please review pamphlet PM5049 with the guardian 
                prior to discharge.
            $$
end rule

Apply Another Rule

One rule may be chained to another via an explicit call. This is useful for protocols where a series of rules needs to be executed in a specific order to create an appropriate care plan. Applying rules is performed via the apply statement or <apply> in XML.

// Apply by rule name
apply "name of the rule to be applied"
// Apply by rule unique id
apply <dotted.id.of.rule>
<!-- Apply via name -->
<apply ref="Name of Rule to be Applied" />
<!-- Apply via ID -->
<apply ref="#dotted.id.of.rule.to.be.applied" />
define protocol "A simple vaccination protocol" as 
    when 
        "Patient is Eligible for Enrolment to Simple Vaccination Programme"
    then 
        assign "true" to tag[IsEnrolledInSpecialProgramme]
        apply "Simple Vaccination Programme Step 1"
        apply "Simple Vaccination Programme Step 2"
end protocol

Repeat Actions

Any action (proposals, assignment, raising, etc.) can be repeated a specific number of iterations (like a for loop) or until a certain fact becomes true or not null (like a while loop). Repeat actions are defined with the repeat ... end repeat statements or the <repeat> element in XML.

// Repeat specified actiosn N times 
repeat for N iterations track-by fact_name
    apply ...
    propose ...
    raise ...
    assign ...
end repeat

// Repeat specified actions until the specified fact becomes true
repeat until 
    // one of 
    hdsi( ... )
    csharp( ... )
    "fact name"
    all( ... )
    any( ... )
    none( ... )
    // actions
    apply ...
    propose ...
    raise ...
    assign ...
end repeat
<!-- Repeat N times -->
<repeat iterations="N" trackBy="name_of_track_fact">
    <apply ... />
    <raise ... />
    <propose ... />
    <assign ... />
</repeat>

<!-- Repeat until fact is true -->
<repeat>
    <until>
        <csharp ... />
        <hdsi ... />
        <all ... />
        <any ... />
        <none ... />
        <fact ref="name of fact" />
    </until>
    <apply ... />
    <raise ... />
    <propose ... />
    <assign ... />
</repeat>    
define protocol "Measure Weight for 6 months post-operation" 
    when 
        "Patient Has Had Procedure XYZ Performed and Requires Weight Observation"
    then 
        repeat for 6 iterations track-by index
            propose "Weight Observation"
                having model "Weight Observation"
                as 
                assign csharp($$ 
                    ((DateTime)context["Date Of Procedure"]).AddMonths((int)context["index"])
                $$)
            end propose
        end repeat
end protocol            

Data Blocks

There arise occasions where a CDSS rules will need to reference pre-computed tables. Examples may include:

  • Standardized Z-Scores for "acceptable" observation values

  • Standardized age ranges for dosing and/or procedure schedules

  • Computation of offsets or unit conversion tables

In the SanteDB CDSS rule format, you can specify these reference sets in your library using a data block. Data blocks are defined with the define data ... end data or <data> element in XML.

library "Name of Library"
   ...
   define data "Name of Reference Data"
      having id <dotted.id.of.data>
      having uuid {uuid-of-data}
      having oid "dotted.oid.of.data"
      with metadata 
         ...
      end metadata
      as
      $$
      csv,formatted,data,here
      with,the,first,row,as,column,names
      ##
   end data
end library
<library ...>
    <data name="name of data block"
        id="dotted.id.of.data.block"
        uuid="uuid-of-data-block"
        oid="dotted.oid.of.data.block"
        compression="zip|gz|bz">
        <meta>
            ...
        </meta>
        <![CDATA[data]]>
    </data>
</library>

All data blocks in the text CDSS rule format are uncompressed comma-separated-values. Data blocks in XML may either be a raw format CSV data block, or a base-64 blob representing the compressed CSV data using algorithm @compression.

Querying Data Blocks

  • Name of the data block such as context.DataSets["name of the data block"]

  • Id of the data block prefixed with a hash such as context.DataSets["#dotted.id.of.the.data.block"]

The data block reference will load the CSV data into the data context where the data can be filtered. Filtering is performed via a streaming reader on the CSV data so it is important that your data is sorted in the manner you're filtering. The operations which are available on the data set object are enumerated below.

Lookup Row

Lookup up a row is performed with the Lookup(columnName, value), where columnName is the name of the column as it appears in the first row of the CSV data. For example, to look-up a gender based on a fact of Patient Gender the filter: context["Reference Ranges"].Lookup("gender", context["Patient Gender"]) .

The result of a lookup row is a filtered streaming reader. This can be chained with another lookup, for example, to filter on gender for those records matching Patient Gender and then filter on ageInWeeks on fact Patient Age in Weeks the C# expression: context.DataSets["Reference Ranges"].Lookup("gender", context["Patient Gender"]).Lookup("ageInWeeks", context["Patient Age in Weeks"])

Lookup Range

The Between(columnName, lowerValue, upperValue) function can be used to filter the input reader for any rows where columnName is between the lowerValue and upperValue.

Select a Column

To select a column, the Select(columnName) function is used. This returns a numerator which can be used with any of the System.Linq operators (such as Average(), Sum(), Min(), Max(), etc.).

The expression evaluator used in SanteDB currently does not support generics. Use the functions SelectInt(columnName), SelectReal(columnName), or SelectLong(columnName) as an alternate to Select(columnName).OfType<>().

For example, to compute a fact for Patient Weight Below Average one may write:

define fact "Patient Weight Below Average" type bool as 
    csharp($$
        context.Real("Observed Patient Weight in Kgs") <
        context["Reference Ranges"]
            .Lookup("gender", context["Patient Gender"])
            .Between("ageInWeeks", context.Int("Patient Age In Weeks") - 5, context.Int("Patient Age In Weeks") + 5)
            .SelectReal("nominal")
            .Average()
    $$)
end fact

LINQ aggregation functions which are useful for CDSS rules are enumerated in the table below.

Expression
Behavior
Example

Last()

Return the last non-null object in the reader, throw an error if no matching records exist.

LastOrDefault()

Return the last non-null object in the reader, return the default null if none found.

First()

Return the first non-null object in the reader, throw an error if no matching records exist.

FirstOrDefault()

Return the first non-null object in the reader, return null if none found.

.Select("column").FirstOrDefault()

Average()

Compute the average of all the matching column values.

.SelectReal("nominal").Average()

Sum()

Compute the sum of all matching column values.

.SelectInt("column").Sum()

Min()

Select the minimum value of matching columns.

.SelectLong("column").Min()

Max()

Select the maximum value of matching columns.

.Select("column").Max()

Single()

Select a single matching value from the result set, throw an error if more than one matching row exists, or if no row exists.

SingleOrDefault()

Select a sinle matching value from the result set, thow an error if more than one matching row exists, if no row exists return null.

A fact is defined with the define fact ... end fact or XML element <fact> , and must carry either an ID or NAME. A fact can be computed using any of the documented.

Rules are defined within a logic blocks and represent a simple logic construct using when/then semantics. Rules are defined using the define rule ... end rule or the <rule> element in XML. The when block represents the trigger and is comprised of any . The then block is a collection of which should be undertaken when the condition is true.

The Health Data Service Interface Query computable expression uses the grammar to extract data or make decisions. HDSI queries are encapsulated in the hdsi() qualifier in CDSS text file or the <hdsi> element in XML.

Lookup a dataset from the context (see )

The propose action is used to emit a proposal onto the current context. A proposal represents an Act which should occur (with a of Propose).

Proposals are represented in CDSS text files with the propose ... end propose statement or in XML with <propose>. Proposals must carry a model (see ) and optionally a series of assign (see ) statements to modify the model.

When the CDSS engine is being called as part of a care plan generation, the issue is added to the care plan in the extension.

Data blocks in a CDSS library are referenced in by calling the DataSets property on the context object passing the dotted identifier or name of the dataset into the parameter as a reference. This can be done via:

Health Data Service Query
mood code
http://santedb.org/extensions/core/safetyConcernIssue
Computable Expressions
computable expression
output actions
models
assign
C# Computable Expressions
Querying Data Blocks