HCLS/ClinicalObservationsInteroperability/CTCriterialRules.html

From W3C Wiki

Using N3 Rules to Express CT Inclusion/Exclusion Criteria

CT #8 Inclusion Criteria

  1. monotherapy with metformin, insulin secretagogue, or alpha-glucosidase inhibitors,
  2. or a low-dose combination of these at ≤ 50% maximal dose
  3. Dosing is stable for 8 weeks

Mock Patient Data

#test case 1: two prescriptions, but only one candiate medication, one prescription,
#this patient is a candidate, stable dose > 8 weeks
:med0001     a      :Metformin;
             :subject    :P0001;
             :dosePerAdministration   [   :hasValue   "2000";
                                          :hasUnit    "mg"];
             :startDateTime   "2008-01-01T00:00:00"^^xsd:dateTime;
             :endDateTime     "2009-01-01T00:00:00"^^xsd:dateTime.

:med00011     a      :someOtherMedication;
             :subject    :P0001;
             :dosePerAdministration   [   :hasValue   "2000";
                                          :hasUnit    "mg"];
             :startDateTime   "2008-01-01T00:00:00"^^xsd:dateTime;
             :endDateTime     "2009-01-01T00:00:00"^^xsd:dateTime.
                          
#test case 2: one medication, multiple prescriptions
#this patient is not a candidate, due to the change of dose recently (May 2, 2008)

:med0002     a      :Metformin;
             :subject    :P0002;
             :dosePerAdministration   [   :hasValue   "500";
                                          :hasUnit    "mg"];
             :startDateTime   "2007-01-01T00:00:00"^^xsd:dateTime;
             :endDateTime     "2007-05-01T00:00:00"^^xsd:dateTime.
                                                       
                                          
:med0003     a      :Metformin;
             :subject    :P0002;
             :dosePerAdministration   [   :hasValue   "1000";
                                          :hasUnit    "mg"];
             :startDateTime   "2007-05-02T00:00:00"^^xsd:dateTime;
             :endDateTime     "2008-05-01T00:00:00"^^xsd:dateTime.

:med0004     a      :Metformin;
             :subject    :P0002;
             :dosePerAdministration   [   :hasValue   "2000";
                                          :hasUnit    "mg"];
             :startDateTime   "2008-05-02T00:00:00"^^xsd:dateTime;
             :endDateTime     "2009-01-01T00:00:00"^^xsd:dateTime.                                                       
                                                                                    
#test case 3: multiple medication, multiple prescriptions
#this patient is a candidate, stable dose, and dose < 50% max dose
:med0005     a      :Gliclazide;
             :subject    :P0003;
             :dosePerAdministration   [   :hasValue   "60";
                                          :hasUnit    "mg"];
             :startDateTime   "2008-01-01T00:00:00"^^xsd:dateTime;
             :endDateTime     "2009-01-01T00:00:00"^^xsd:dateTime.                                                   
                                          
:med0006     a      :Metformin;
             :subject    :P0003;
             :dosePerAdministration   [   :hasValue   "500";
                                          :hasUnit    "mg"];
             :startDateTime   "2007-01-01T00:00:00"^^xsd:dateTime;
             :endDateTime     "2009-01-01T00:00:00"^^xsd:dateTime.                                                             

#test case 4: multiple medication, multiple prescriptions
#this patient is not a candidate, due to large dose for a combination of medication

:med0007     a      :Gliclazide;
             :subject    :P0004;
             :dosePerAdministration   [   :hasValue   "100";
                                          :hasUnit    "mg"];
             :startDateTime   "2008-01-01T00:00:00"^^xsd:dateTime;
             :endDateTime     "2009-01-01T00:00:00"^^xsd:dateTime;.                                                      
                                          
:med0008     a      :Metformin;
             :subject    :P0004;
             :dosePerAdministration   [   :hasValue   "500";
                                          :hasUnit    "mg"];
             :startDateTime   "2007-01-01T00:00:00"^^xsd:dateTime;
             :endDateTime     "2009-01-01T00:00:00"^^xsd:dateTime.                                                             


#test case 5: one medication, multiple prescriptions
#this patient is not a candidate, his is no longer taking one of the candidate medication

:med0009     a      :Metformin;
             :subject    :P0005;
             :dosePerAdministration   [   :hasValue   "500";
                                          :hasUnit    "mg"];
             :startDateTime   "2007-01-01T00:00:00"^^xsd:dateTime;
             :endDateTime     "2007-05-01T00:00:00"^^xsd:dateTime.
                                                       
                                          
:med0010     a      :Metformin;
             :subject    :P0005;
             :dosePerAdministration   [   :hasValue   "1000";
                                          :hasUnit    "mg"];
             :startDateTime   "2007-05-02T00:00:00"^^xsd:dateTime;
             :endDateTime     "2008-05-01T00:00:00"^^xsd:dateTime.

'''#test case 6: one medication, multiple prescriptions, stable dose in the past '''
#this patient is a candidate

:med0011     a      :Metformin;
             :subject    :P0006;
             :dosePerAdministration   [   :hasValue   "500";
                                          :hasUnit    "mg"];
             :startDateTime   "2007-01-01T00:00:00"^^xsd:dateTime;
             :endDateTime     "2008-01-01T00:00:00"^^xsd:dateTime.
                                                       
                                          
:med0012     a      :Metformin;
             :subject    :P0006;
             :dosePerAdministration   [   :hasValue   "500";
                                          :hasUnit    "mg"];
             :startDateTime   "2008-01-02T00:00:00"^^xsd:dateTime;
             :endDateTime     "2008-06-01T00:00:00"^^xsd:dateTime.


Drug Information

###################################################################
# monotherapy with metformin, insulin secretagogue, 
# or alpha-glucosidase inhibitors,
# or a low-dose combination of these at <= 50% maximal dose
#
# since each medicine has its own maximum dose and it is a general knowledge,
# we state the max dose of each medicine seperately from the selection (query rules)
# The following statement can be moved to STDM ontology
###################################################################

                                          
:Metformin  a  owl:Class;
           :maxDose    [  :hasValue    "2000";
                           :hasUnit     "mg"].
:Repaglinide    a  owl:Class;
                owl:subClassOf    :InsulinSecertagogue;
				:maxDose    
                        [  :hasValue    "4";
                           :hasUnit     "mg"].
:Gliclazide		a  owl:Class;
                owl:subClassOf     :InsulinSecertagogue;
				:maxDose    
                        [  :hasValue    "120";
                           :hasUnit     "mg"].

:Glipizide		a  owl:Class;
                owl:subClassOf     :InsulinSecertagogue;
				:maxDose    
                        [  :hasValue    "10";
                           :hasUnit     "mg"].
:Acarbose		a  owl:Class;
                owl:subClassOf   :AlphaGlucosidaseInhibitor;
           		:maxDose    
                        [  :hasValue    "100";
                           :hasUnit     "mg"].                                               

:Miglitol		a  owl:Class;
                owl:subClassOf   :AlphaGlucosidaseInhibitor;
           		:maxDose    
                        [  :hasValue    "100";
                           :hasUnit     "mg"].                               


CT Criteria Rules

Here we have to use "close" our world when searching for all prescriptions of a patient. We use a built-in called "e:findall".


#assume now is "2008-05-22T00:00:00"
:CTcheckTime  :hasDate   "2008-05-22T00:00:00"^^xsd:dateTime.


:CandidateMedicine   owl:unionOf  (:AlphaGlucosidaseInhibitor :InsulinSecertagogue :Metformin).

{:CandidateMedicine   owl:unionOf ?L.  ?B :inSomeOf  ?L} => {?B a :CandidatePrescription}.


# assume all knowledge about the patient are contained in this one knowledgebase - scoped closure

#step 1: check if patient is taking the candidate medicine and one of his prescription has a end date later than CTcheckTime (?NOW)
{
    :CTcheckTime :hasDate  ?NOW.
    
    ?X :subject ?P;
       a    :CandidatePrescription;      
             :startDateTime   ?sDate;
             :endDateTime     ?eDate.      
    (?eDate ?NOW)  math:difference  ?E.
    ?E math:greaterThan "P1D"^^xsd:duration.
}
=>
{?P a :possibleCandidate}.    

#step 2:If a patient has multiple prescription of a medicine, check if the dose is stable for at least 8 weeks 

#step 2.1 find all prescriptions of each kind of candidate medication and dose is stable for at least 8 weeks
{
 :CandidateMedicine   owl:unionOf ?L.
 ?P  a  :possibleCandidate.
 ?X_m  :subject ?P;
    a   ?B.
 ?B list:in   ?L.   
 (?SCOPE 1) e:findall (?X 
      {?X  :subject ?P;
        a   ?B;
        :dosePerAdministration   ?ADose;
        :startDateTime   ?sDate;
        :endDateTime     ?eDate.  
       ?ADose  :hasValue ?DoseValue.      
     }  ?MedicationList).
#find the stable dose
}
=>
{(?P ?B)  :hasPrescriptionList ?MedicationList.
 ?MedicationList  a  rdf:List}.       

#step 2.2 if a patient has only one type of candidate medication, check if the dose is stable for at least 8 weeks
#case 1: one prescription
{ :CTcheckTime :hasDate  ?NOW.
  (?P ?B)  :hasPrescriptionList ?MedicationList. 
  ?MedicationList math:memberCount  ?Count.
  ?MedicationList rdf:first ?I.
  ?I    :startDateTime   ?S;
        :endDateTime     ?E.  
  (?NOW ?S)  math:difference  ?T.
   ?T math:greaterThan "P2M"^^xsd:duration.
  (?E ?NOW)  math:difference  ?T1.
    ?T1 math:greaterThan "P1D"^^xsd:duration. 
   
}
=>
{?P  a :CTCandidate}.


Supporting Rules (generic rdf and owl semantics)

{?A owl:subClassOf  ?B. ?x  a  ?A} => {?x  a ?B}.

rdf:first a rdf:Property; rdfs:domain rdf:List.
rdf:rest a rdf:Property; rdfs:domain rdf:List; rdfs:range rdf:List.
rdfs:subClassOf a rdf:Property; rdfs:domain rdfs:Class; rdfs:range rdfs:Class; a owl:TransitiveProperty.
rdfs:subPropertyOf a rdf:Property; rdfs:domain rdf:Property; rdfs:range rdf:Property; a owl:TransitiveProperty.
owl:equivalentClass a rdf:Property; rdfs:domain rdfs:Class; rdfs:range rdfs:Class; rdfs:subPropertyOf rdfs:subClassOf; a owl:SymmetricProperty.
owl:equivalentProperty a rdf:Property; rdfs:domain rdf:Property; rdfs:range rdf:Property; rdfs:subPropertyOf rdfs:subPropertyOf; a owl:SymmetricProperty.
owl:sameAs a rdf:Property; a owl:SymmetricProperty, owl:TransitiveProperty.
owl:inverseOf a rdf:Property; rdfs:domain owl:ObjectProperty; rdfs:range owl:ObjectProperty; a owl:SymmetricProperty.
owl:differentFrom a rdf:Property; a owl:SymmetricProperty.
owl:distinctMembers a rdf:Property; rdfs:domain owl:AllDifferent; rdfs:range rdf:List.
owl:oneOf a rdf:Property; rdfs:domain rdfs:Class; rdfs:range rdf:List.
owl:intersectionOf a rdf:Property; rdfs:domain rdfs:Class; rdfs:range rdf:List.
owl:unionOf a rdf:Property; rdfs:domain rdfs:Class; rdfs:range rdf:List.
owl:complementOf a rdf:Property; rdfs:domain rdfs:Class; rdfs:range rdfs:Class.


{?S ?P ?O} => {?P a rdf:Property}.
{?P rdfs:domain ?C. ?S ?P ?O} => {?S a ?C}.
{?P rdfs:range ?C. ?S ?P ?O} => {?O a ?C}.
{?A rdfs:subClassOf ?B. ?S a ?A} => {?S a ?B}.
{?P rdfs:subPropertyOf ?R. ?S ?P ?O} => {?S ?R ?O}.
#{?X owl:sameAs ?Y. ?P a rdf:Property. ?X ?P ?O} => {?Y ?P ?O}.
#{?X owl:sameAs ?Y. ?S ?X ?O} => {?S ?Y ?O}.
#{?X owl:sameAs ?Y. ?P a rdf:Property. ?S ?P ?X} => {?S ?P ?Y}.
{?P owl:inverseOf ?Q. ?S ?P ?O} => {?O ?Q ?S}.
{?P a owl:SymmetricProperty. ?S ?P ?O} => {?O ?P ?S}.
{?P a owl:TransitiveProperty. ?X ?P ?O. ?S ?P ?X} => {?S ?P ?O}.
#{?P a owl:FunctionalProperty. ?S ?P ?X. ?S ?P ?Y} => {?X owl:sameAs ?Y}.
{?P a owl:InverseFunctionalProperty. ?X ?P ?O. ?Y ?P ?O} => {?X owl:sameAs ?Y}.
{?A owl:distinctMembers ?D. ?D rdf:rest ?R} => {?A owl:distinctMembers ?R}.
{?A owl:distinctMembers ?D. ?L :subListOf ?D. ?L rdf:first ?X; rdf:rest ?R. ?Y list:in ?R} => {?X owl:differentFrom ?Y}.
{?C owl:oneOf ?L. ?X list:in ?L} => {?X a ?C}.
{?C owl:intersectionOf ?L. ?X :inAllOf ?L} => {?X a ?C}.
{?A   owl:unionOf  ?L} => {?L  a  rdf:List}.
{?C owl:unionOf ?L. ?X :inSomeOf ?L} => {?X a ?C}.

{?L rdf:rest ?R} => {?R a rdf:List}.
{?L rdf:first ?I; a rdf:List} => {?I list:in ?L}.
{?L rdf:rest ?R; a rdf:List. ?I list:in ?R} => {?I list:in ?L}.
{?L a rdf:List} => {?L :subListOf ?L}.
{?L rdf:rest ?R; a rdf:List. ?X :subListOf ?R} => {?X :subListOf ?L}.
{?L rdf:first ?A; a rdf:List. ?X a ?A. ?L rdf:rest rdf:nil} => {?X :inAllOf ?L}.
{?L rdf:first ?A; a rdf:List. ?X a ?A. ?L rdf:rest ?R. ?X :inAllOf ?R} => {?X :inAllOf ?L}.
{?L rdf:first ?A; a rdf:List. ?X a ?A} => {?X :inSomeOf ?L}.
{?L rdf:rest ?R; a rdf:List. ?X :inSomeOf ?R} => {?X :inSomeOf ?L}.


Query

{?B  :hasPrescriptionList ?MedicationList} => {?B  :hasPrescriptionList ?MedicationList}. 
{?P  a  :CTCandidate} => {?P  a  :CTCandidate}.


Results

The following is the preliminary results. We have not checked dose < 50% max dose when using a combination of drugs.

(:P0003 :InsulinSecertagogue) :hasPrescriptionList (:med0005).
(:P0003 :Metformin) :hasPrescriptionList (:med0006).
(:P0004 :InsulinSecertagogue) :hasPrescriptionList (:med0007).
(:P0004 :Metformin) :hasPrescriptionList (:med0008).
(:P0001 :Metformin) :hasPrescriptionList (:med0001).
(:P0002 :Metformin) :hasPrescriptionList (:med0002 :med0003 :med0004).
(:P0006 :Metformin) :hasPrescriptionList (:med0011 :med0012).
:P0003 a :CTCandidate.
:P0004 a :CTCandidate.
:P0001 a :CTCandidate.