Skip to content

Commit

Permalink
Bump to hermes v1.2.1026
Browse files Browse the repository at this point in the history
  • Loading branch information
wardle committed Mar 29, 2023
1 parent 2d04e8e commit e8c279a
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 58 deletions.
2 changes: 1 addition & 1 deletion deps.edn
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
org.clojure/tools.logging {:mvn/version "1.2.4"}

com.eldrix/dmd {:mvn/version "0.6.146"}
com.eldrix/hermes {:mvn/version "1.1.1000"}}
com.eldrix/hermes {:mvn/version "1.2.1026"}}

:aliases {:dev
{:extra-paths ["cmd" "test/src" "test/resources"]}
Expand Down
90 changes: 35 additions & 55 deletions src/com/eldrix/codelists/core.clj
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,6 @@
is good when a codelist is very large, and fewer checks are needed. Set-up
time is small.
The key abstraction here is simply a codelist and a test for membership using
'member?' as defined by protocol 'CodeList'.
For a set of concepts, whether manually listed or derived from an input
specification, it simply checks set membership.
For (3), the source concepts are mapped to the appropriate code system(s)
and the check done based on the rules of each code system.
In many situations all approaches might be necessary, depending on trade-offs.
You might generate a codelist for documentation purposes but use a different
approach to check each row of source data. All approaches should give the
Expand All @@ -40,8 +31,6 @@
(defn parse-json [s]
(json/read-str s :key-fn keyword))

(declare realize-concepts)

(defn apply-union
"Applies function f to x, but if x is a sequence, returns the logical union
of applying f to each member. 'f' should be a function returning a set."
Expand All @@ -51,7 +40,7 @@
(f x)))

(defn tf-for-product [hermes concept-id]
(filter #(seq (hermes/get-component-refset-items hermes % 999000631000001100)) (hermes/get-all-parents hermes concept-id)))
(filter #(seq (hermes/component-refset-items hermes % 999000631000001100)) (hermes/all-parents hermes concept-id)))

(defn atc->snomed-ecl
"Map an ATC regexp into a SNOMED expression that can include all UK product
Expand All @@ -66,6 +55,8 @@
vmps (map #(str "<<" %) (:VMP products))]
(str/join " OR " (concat tfs vtms vmps))))

(declare realize-concepts)

(defn realize-concepts*
[{:com.eldrix/keys [hermes dmd] :as env} {and' :and or' :or not' :not :keys [ecl icd10 atc]}]
(let [incl (set/union
Expand Down Expand Up @@ -95,7 +86,7 @@
"Map a collection of concept identifiers to a set of ICD-10 codes."
[{:com.eldrix/keys [hermes]} concept-ids]
(->> concept-ids
(mapcat #(hermes/get-component-refset-items hermes % 447562003))
(mapcat #(hermes/component-refset-items hermes % 447562003))
(map :mapTarget)
(filter identity)
(into #{})))
Expand All @@ -104,7 +95,7 @@
"Is the product a type of trade family product?
We simply use the TF reference set as a check for membership."
[{:com.eldrix/keys [hermes]} concept-id]
(seq (hermes/get-component-refset-items hermes concept-id 999000631000001100)))
(seq (hermes/component-refset-items hermes concept-id 999000631000001100)))

(defn to-atc
"Map a collection of concept identifiers to a set of ATC codes.
Expand All @@ -115,56 +106,45 @@
(->> concept-ids
(mapcat (fn [concept-id]
(if (is-trade-family? system concept-id)
(distinct (map #(dmd/atc-for-product dmd %) (hermes/get-child-relationships-of-type hermes concept-id snomed/IsA)))
(distinct (map #(dmd/atc-for-product dmd %) (hermes/child-relationships-of-type hermes concept-id snomed/IsA)))
(vector (dmd/atc-for-product dmd concept-id)))))
(filter identity)
set))

(comment

(def hermes (hermes/open "/Users/mark/Dev/hermes/snomed.db"))
(def dmd (dmd/open-store "/Users/mark/Dev/dmd/dmd-2021-09-13.db"))
(def dmd (dmd/open-store "/Users/mark/Dev/dmd/dmd-2022-05-09.db"))
(def system {:com.eldrix/hermes hermes :com.eldrix/dmd dmd})
(defn ps [id] (vector id (:term (hermes/get-preferred-synonym (:com.eldrix/hermes system) id "en-GB"))))
(defn ps [id] (vector id (:term (hermes/preferred-synonym (:com.eldrix/hermes system) id "en-GB"))))
(ps 24700007)

(def multiple-sclerosis (expand-codelist system {:inclusions {:icd10 "G35"}}))
(member? multiple-sclerosis [24700007])
(map ps (expand-codelist system {:inclusions {:icd10 "G35"}}))
(map ps (expand-codelist system {:inclusions {:atc "N07AA02"}}))
(map ps (expand-codelist system {:inclusions {:atc "N07AA0"}
:exclusions {:atc "N07AA02"}}))
(def codelist (make-codelist system {:ecl "<<24700007"}))
(def codelist2 (make-codelist system {:icd10 "G70"}))
(member? codelist [155092009])
(member? codelist2 [155092009])
(any-member? system {:inclusions {:ecl "<<24700007"}} [155023009])
(def codelist {:inclusions {:icd10 "G35"}})
(def inclusions (or (:inclusions codelist) codelist))
(def exclusions (set (when-let [excl (:exclusions codelist)] (expand-codes system excl))))
exclusions
(def concept-ids' (set/difference (set [24700007]) exclusions))
(to-icd10 system concept-ids')
(match-codes ["G35"] #{"G35"})

(def ace-inhibitors (make-codelist system {:atc "C09A"}))
(def calcium-channel-blockers (make-codelist system {:atc "C08"}))
(expand calcium-channel-blockers)
(member? ace-inhibitors [21912111000001107])
(member? ace-inhibitors [7304611000001104])
(member? calcium-channel-blockers [7304611000001104])
(def multiple-sclerosis (make-codelist system {:icd10 "G35"}))
(expand multiple-sclerosis)
(require '[clojure.data.csv])
(def os-calchan (set (map #(Long/parseLong (get % 1)) (rest (clojure.data.csv/read-csv (clojure.java.io/reader "https://www.opencodelists.org/codelist/opensafely/calcium-channel-blockers/2020-05-19/download.csv"))))))
os-calchan
(def calchan (expand calcium-channel-blockers))
(map ps (set/difference os-calchan calchan))
(map ps (set/difference calchan os-calchan))

(hermes/expand-ecl-historic hermes (dmd/atc->snomed-ecl dmd #"C09A.*"))
(dmd/atc->products-for-ecl dmd #"C09A.*")
(hermes/subsumed-by? hermes 10441211000001106 9191801000001103))
(dmd/fetch-release-date dmd)
(dmd/fetch-product dmd 108537001)
(hermes/concept hermes 108537001)
(ps 108537001)
(def calcium-channel (realize-concepts system {:atc #"C08CA.*"})) ;; see https://www.whocc.no/atc_ddd_index/?code=C08CA01
(count calcium-channel)
(contains? calcium-channel 108537001)

(def multiple-sclerosis (realize-concepts system {:icd10 "G35"}))
(contains? multiple-sclerosis 24700007)

(def basal-ganglion (-> (hermes/search hermes {:s "Basal ganglion" :max-hits 1}) first :conceptId))
(def peripheral-nerve (-> (hermes/search hermes {:s "Peripheral nerve structure" :max-hits 1}) first :conceptId))
basal-ganglion
peripheral-nerve
(defn finding-site?
[concept-id site-concept-id]
(let [concept-ids (get (hermes/parent-relationships-expanded hermes concept-id snomed/FindingSite) snomed/FindingSite)]
(contains? concept-ids site-concept-id)))
(def parkinsons (realize-concepts system {:icd10 "G20"}))
parkinsons
;; is G20 a disease of the basal ganglia? -> yes
(some #(finding-site? % basal-ganglion) (realize-concepts system {:icd10 "G20"}))
;; is G20 a disease of the peripheral nerve? -> no
(some #(finding-site? % peripheral-nerve) (realize-concepts system {:icd10 "G20"}))
;; are G61.* diseases of the peripheral nerve -> yes
(some #(finding-site? % peripheral-nerve) (realize-concepts system {:icd10 "G61.*"}))) ; G61.* = peripheral neuropathy



Expand Down
7 changes: 5 additions & 2 deletions test/com/eldrix/codelists/core_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
(use-fixtures :once live-test-fixture)

(deftest ^:live basic-gets
(is (= 24700007 (.id (hermes/get-concept *hermes* 24700007)))))
(is (= 24700007 (.id (hermes/concept *hermes* 24700007)))))

(deftest simple-ecl)

Expand All @@ -27,5 +27,8 @@
(def hermes (hermes/open "../hermes/snomed.db"))
(def dmd (dmd/open-store "../dmd/dmd-2022-05-09.db"))
(def env {:com.eldrix/hermes hermes :com.eldrix/dmd dmd})
(count (cl/realize-concepts env {:icd10 [ "G35" "G46"]})))
(defn ps [id] (vector id (:term (hermes/preferred-synonym hermes id "en-GB"))))

(map ps (cl/realize-concepts env {:icd10 ["B20.*", "B21.*", "B22.*", "B24.*", "F02.4" "O98.7" "Z21.*", "R75"]}))
(cl/to-icd10 env (cl/realize-concepts env {:ecl "<24700007"})))
(cl/parse-json "[{\"ecl\": \"<<24700007\"}] ")

0 comments on commit e8c279a

Please sign in to comment.