Class: Inferno::Terminology::ValueSet
- Inherits:
-
Object
- Object
- Inferno::Terminology::ValueSet
- Defined in:
- lib/inferno/terminology/value_set.rb
Constant Summary collapse
- SAB =
UMLS Vocabulary: www.nlm.nih.gov/research/umls/sourcereleasedocs/index.html
{ 'http://unitsofmeasure.org' => { abbreviation: 'NCI_UCUM', name: 'Unified Code for Units of Measure (UCUM)' }.freeze, 'http://loinc.org' => { abbreviation: 'LNC', name: 'Logical Observation Identifiers Names and Codes terminology (LOINC)' }.freeze, 'http://snomed.info/sct' => { abbreviation: 'SNOMEDCT_US', name: 'Systematized Nomenclature of Medicine-Clinical Terms (SNOMED CT), US Edition' }.freeze # The systems below are needed if building all terminology rather than # only the required bindings. # 'http://www.nlm.nih.gov/research/umls/rxnorm' => { # abbreviation: 'RXNORM', # name: 'RxNorm Vocabulary' # }.freeze, # 'http://www.cms.gov/Medicare/Coding/ICD10' => { # abbreviation: 'ICD10PCS', # name: 'ICD-10 Procedure Coding System (ICD-10-PCS)' # }.freeze, # 'http://hl7.org/fhir/sid/cvx' => { # abbreviation: 'CVX', # name: 'Vaccines Administered (CVX)' # }.freeze, # 'http://hl7.org/fhir/sid/icd-10-cm' => { # abbreviation: 'ICD10CM', # name: 'International Classification of Diseases, Tenth Revision, Clinical Modification (ICD-10-CM)' # }.freeze, # 'http://hl7.org/fhir/sid/icd-9-cm' => { # abbreviation: 'ICD9CM', # name: 'International Classification of Diseases, Ninth Revision, Clinical Modification (ICD-9-CM)' # }.freeze, # 'urn:oid:2.16.840.1.113883.6.101' => { # abbreviation: 'NUCCHCPT', # name: 'National Uniform Claim Committee - Health Care Provider Taxonomy (NUCCHCPT)' # }, # 'http://nucc.org/provider-taxonomy' => { # abbreviation: 'NUCCHCPT', # name: 'National Uniform Claim Committee - Health Care Provider Taxonomy (NUCCHCPT)' # }.freeze, # 'http://www.ama-assn.org/go/cpt' => { # abbreviation: 'CPT', # name: 'Current Procedural Terminology (CPT)' # }.freeze, # 'http://www.cms.gov/Medicare/Coding/HCPCSReleaseCodeSets' => { # abbreviation: 'HCPCS', # name: 'Healthcare Common Procedure Coding System (HCPCS)' # }.freeze, # 'urn:oid:2.16.840.1.113883.6.285' => { # abbreviation: 'HCPCS', # name: 'Healthcare Common Procedure Coding System (HCPCS)' # }.freeze, # 'urn:oid:2.16.840.1.113883.6.13' => { # abbreviation: 'CDT', # name: 'Code on Dental Procedures and Nomenclature (CDT)' # }.freeze, # 'http://ada.org/cdt' => { # abbreviation: 'CDT', # name: 'Code on Dental Procedures and Nomenclature (CDT)' # }, # 'http://www.ada.org/cdt' => { # abbreviation: 'CDT', # name: 'Code on Dental Procedures and Nomenclature (CDT)' # } }.freeze
- CODE_SYS =
{ 'urn:ietf:bcp:13' => -> { BCP13.code_set }, 'urn:ietf:bcp:47' => ->(filter = nil) { BCP47.code_set(filter) }, 'http://ihe.net/fhir/ValueSet/IHE.FormatCode.codesystem' => -> { value_sets_repo.find('http://hl7.org/fhir/ValueSet/formatcodes').value_set }, 'https://www.usps.com/' => lambda do codes = [ 'AL', 'AK', 'AS', 'AZ', 'AR', 'CA', 'CO', 'CT', 'DE', 'DC', 'FM', 'FL', 'GA', 'GU', 'HI', 'ID', 'IL', 'IN', 'IA', 'KS', 'KY', 'LA', 'ME', 'MH', 'MD', 'MA', 'MI', 'MN', 'MS', 'MO', 'MT', 'NE', 'NV', 'NH', 'NJ', 'NM', 'NY', 'NC', 'ND', 'MP', 'OH', 'OK', 'OR', 'PW', 'PA', 'PR', 'RI', 'SC', 'SD', 'TN', 'TX', 'UT', 'VT', 'VI', 'VA', 'WA', 'WV', 'WI', 'WY', 'AE', 'AP', 'AA' ] codes.each_with_object(Set.new) do |code, set| set.add(system: 'https://www.usps.com/', code:) end end }.freeze
- FILTER_PROP =
{ 'CLASSTYPE' => 'LCN', 'DOC' => 'Doc', 'SCALE_TYP' => 'LOINC_SCALE_TYP' }.freeze
- TOO_COSTLY_URL =
'http://hl7.org/fhir/StructureDefinition/valueset-toocostly'.freeze
- UNCLOSED_URL =
'http://hl7.org/fhir/StructureDefinition/valueset-unclosed'.freeze
Class Attribute Summary collapse
-
.value_sets_repo ⇒ Object
readonly
Returns the value of attribute value_sets_repo.
Instance Attribute Summary collapse
-
#db ⇒ Object
The UMLS Database.
-
#use_expansions ⇒ Object
Flag to say “use the provided expansion” when processing the valueset.
-
#value_set_model ⇒ Object
The FHIR::Model Representation of the ValueSet.
Class Method Summary collapse
-
.load_system(filename) ⇒ Object
Load a code system from a file.
Instance Method Summary collapse
- #all_included_code_systems ⇒ Object
- #code_system_metadata(system) ⇒ Object
- #code_system_set(code_system) ⇒ Object
- #code_systems_in_codings ⇒ Object
-
#contains_code?(code) ⇒ Boolean
Checks if the provided code is in the valueset.
-
#count ⇒ Object
Return the number of codes in the valueset.
- #expansion_as_fhir_value_set ⇒ Object
- #expansion_present? ⇒ Boolean
- #generate_bloom ⇒ Object
- #included_code_systems ⇒ Object
-
#initialize(database, use_expansions = true) ⇒ ValueSet
constructor
rubocop:disable Style/OptionalBooleanParameter.
- #process_expanded_value_set ⇒ Object
-
#process_value_set ⇒ Object
Creates the whole valueset.
-
#process_with_expansions ⇒ Object
Delegates to process_expanded_valueset if there’s already an expansion Otherwise it delegates to process_valueset to do the expansion.
-
#read_value_set(filename) ⇒ Object
Read the desired valueset from a JSON file.
-
#save_bloom_to_file(filename = "resources/validators/bloom/#{(URI(url).host + URI(url).path).gsub(%r{[./]}, '_')}.msgpack") ⇒ Object
Saves the valueset bloomfilter to a msgpack file.
-
#save_csv_to_file(filename = "resources/validators/csv/#{(URI(url).host + URI(url).path).gsub(%r{[./]}, '_')}.csv") ⇒ Object
Saves the valueset to a csv.
- #too_costly? ⇒ Boolean
- #umls_abbreviation(system) ⇒ Object
- #unclosed? ⇒ Boolean
-
#url ⇒ Object
(also: #id)
Return the url of the valueset.
-
#value_set ⇒ Object
The ValueSet [Set].
- #value_sets_repo ⇒ Object
Constructor Details
#initialize(database, use_expansions = true) ⇒ ValueSet
rubocop:disable Style/OptionalBooleanParameter
131 132 133 134 |
# File 'lib/inferno/terminology/value_set.rb', line 131 def initialize(database, use_expansions = true) # rubocop:disable Style/OptionalBooleanParameter @db = database @use_expansions = use_expansions end |
Class Attribute Details
.value_sets_repo ⇒ Object (readonly)
Returns the value of attribute value_sets_repo.
30 31 32 |
# File 'lib/inferno/terminology/value_set.rb', line 30 def value_sets_repo @value_sets_repo end |
Instance Attribute Details
#db ⇒ Object
The UMLS Database
20 21 22 |
# File 'lib/inferno/terminology/value_set.rb', line 20 def db @db end |
#use_expansions ⇒ Object
Flag to say “use the provided expansion” when processing the valueset
25 26 27 |
# File 'lib/inferno/terminology/value_set.rb', line 25 def use_expansions @use_expansions end |
#value_set_model ⇒ Object
The FHIR::Model Representation of the ValueSet
22 23 24 |
# File 'lib/inferno/terminology/value_set.rb', line 22 def value_set_model @value_set_model end |
Class Method Details
.load_system(filename) ⇒ Object
Load a code system from a file
325 326 327 328 329 330 331 332 333 334 335 336 337 |
# File 'lib/inferno/terminology/value_set.rb', line 325 def self.load_system(filename) # TODO: Generalize this cs = FHIR::Json.from_json(File.read(filename)) cs_set = Set.new load_codes = lambda do |concept| concept.each do |concept_code| cs_set.add(system: cs.url, code: concept_code.code) load_codes.call(concept_code.concept) unless concept_code.concept.empty? end end load_codes.call(cs.concept) cs_set end |
Instance Method Details
#all_included_code_systems ⇒ Object
203 204 205 |
# File 'lib/inferno/terminology/value_set.rb', line 203 def all_included_code_systems (included_code_systems + code_systems_in_codings).uniq end |
#code_system_metadata(system) ⇒ Object
149 150 151 |
# File 'lib/inferno/terminology/value_set.rb', line 149 def (system) SAB[system] end |
#code_system_set(code_system) ⇒ Object
175 176 177 |
# File 'lib/inferno/terminology/value_set.rb', line 175 def code_system_set(code_system) filter_code_set(code_system) end |
#code_systems_in_codings ⇒ Object
211 212 213 214 215 216 217 218 |
# File 'lib/inferno/terminology/value_set.rb', line 211 def code_systems_in_codings return [] if value_set.blank? value_set .map { |coding| coding[:system] } .compact .uniq end |
#contains_code?(code) ⇒ Boolean
Checks if the provided code is in the valueset
Codes should be provided as a [Hash] type object
e.g. ‘loinc.org’, code: ‘1234’
285 286 287 |
# File 'lib/inferno/terminology/value_set.rb', line 285 def contains_code?(code) @value_set.include? code end |
#count ⇒ Object
Return the number of codes in the valueset
199 200 201 |
# File 'lib/inferno/terminology/value_set.rb', line 199 def count @value_set.length end |
#expansion_as_fhir_value_set ⇒ Object
179 180 181 182 183 184 185 186 187 188 189 |
# File 'lib/inferno/terminology/value_set.rb', line 179 def expansion_as_fhir_value_set expansion_backbone = FHIR::ValueSet::Expansion.new expansion_backbone. = DateTime.now.strftime('%Y-%m-%dT%H:%M:%S%:z') expansion_backbone.contains = value_set.map do |code| FHIR::ValueSet::Expansion::Contains.new({ system: code[:system], code: code[:code] }) end expansion_backbone.total = expansion_backbone.contains.length expansion_value_set = @value_set_model.deep_dup # Make a copy so that the original definition is left intact expansion_value_set.expansion = expansion_backbone expansion_value_set end |
#expansion_present? ⇒ Boolean
230 231 232 |
# File 'lib/inferno/terminology/value_set.rb', line 230 def expansion_present? !!@value_set_model&.expansion&.contains end |
#generate_bloom ⇒ Object
289 290 291 292 293 294 295 296 297 |
# File 'lib/inferno/terminology/value_set.rb', line 289 def generate_bloom require 'bloomer' @bf = Bloomer::Scalable.create_with_sufficient_size(value_set.length) value_set.each do |cc| @bf.add_without_duplication("#{cc[:system]}|#{cc[:code]}") end @bf end |
#included_code_systems ⇒ Object
207 208 209 |
# File 'lib/inferno/terminology/value_set.rb', line 207 def included_code_systems @value_set_model.compose.include.map(&:system).compact.uniq end |
#process_expanded_value_set ⇒ Object
269 270 271 272 273 274 275 |
# File 'lib/inferno/terminology/value_set.rb', line 269 def include_set = Set.new @value_set_model.expansion.contains.each do |contain| include_set.add(system: contain.system, code: contain.code) end @value_set = include_set end |
#process_value_set ⇒ Object
Creates the whole valueset
Creates a [Set] representing the valueset
255 256 257 258 259 260 261 262 263 264 265 266 267 |
# File 'lib/inferno/terminology/value_set.rb', line 255 def process_value_set Inferno.logger.debug "Processing #{@value_set_model.url}" include_set = Set.new @value_set_model.compose.include.each do |include| # Cumulative of each include include_set.merge(get_code_sets(include)) end @value_set_model.compose.exclude.each do |exclude| # Remove excluded codes include_set.subtract(get_code_sets(exclude)) end @value_set = include_set end |
#process_with_expansions ⇒ Object
Delegates to process_expanded_valueset if there’s already an expansion Otherwise it delegates to process_valueset to do the expansion
236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 |
# File 'lib/inferno/terminology/value_set.rb', line 236 def process_with_expansions if expansion_present? # This is moved into a nested clause so we can tell in the debug statements which path we're taking if too_costly? || unclosed? Inferno.logger.debug("ValueSet too costly or unclosed: #{url}") process_value_set else Inferno.logger.debug("Processing expanded valueset: #{url}") end else Inferno.logger.debug("Processing composed valueset: #{url}") process_value_set end end |
#read_value_set(filename) ⇒ Object
Read the desired valueset from a JSON file
171 172 173 |
# File 'lib/inferno/terminology/value_set.rb', line 171 def read_value_set(filename) @value_set_model = FHIR::Json.from_json(File.read(filename)) end |
#save_bloom_to_file(filename = "resources/validators/bloom/#{(URI(url).host + URI(url).path).gsub(%r{[./]}, '_')}.msgpack") ⇒ Object
Saves the valueset bloomfilter to a msgpack file
302 303 304 305 306 307 308 309 |
# File 'lib/inferno/terminology/value_set.rb', line 302 def save_bloom_to_file( filename = "resources/validators/bloom/#{(URI(url).host + URI(url).path).gsub(%r{[./]}, '_')}.msgpack" ) generate_bloom unless @bf bloom_file = File.new(filename, 'wb') bloom_file.write(@bf.to_msgpack) unless @bf.nil? filename end |
#save_csv_to_file(filename = "resources/validators/csv/#{(URI(url).host + URI(url).path).gsub(%r{[./]}, '_')}.csv") ⇒ Object
Saves the valueset to a csv
313 314 315 316 317 318 319 320 |
# File 'lib/inferno/terminology/value_set.rb', line 313 def save_csv_to_file(filename = "resources/validators/csv/#{(URI(url).host + URI(url).path).gsub(%r{[./]}, '_')}.csv") CSV.open(filename, 'wb') do |csv| value_set.each do |code| csv << [code[:system], code[:code]] end end end |
#too_costly? ⇒ Boolean
221 222 223 |
# File 'lib/inferno/terminology/value_set.rb', line 221 def too_costly? @value_set_model&.expansion&.extension&.find { |vs| vs.url == TOO_COSTLY_URL }&.value end |
#umls_abbreviation(system) ⇒ Object
136 137 138 139 140 141 142 143 144 145 146 147 |
# File 'lib/inferno/terminology/value_set.rb', line 136 def umls_abbreviation(system) if system != 'http://nucc.org/provider-taxonomy' && system != 'urn:oid:2.16.840.1.113883.6.101' return SAB.dig(system, :abbreviation) end @nucc_system ||= # rubocop:disable Naming/MemoizedInstanceVariableName if @db.execute("SELECT COUNT(*) FROM mrconso WHERE SAB = 'NUCCPT'").flatten.first.positive? 'NUCCPT' else 'NUCCHCPT' end end |
#unclosed? ⇒ Boolean
226 227 228 |
# File 'lib/inferno/terminology/value_set.rb', line 226 def unclosed? @value_set_model&.expansion&.extension&.find { |vs| vs.url == UNCLOSED_URL }&.value end |
#url ⇒ Object Also known as: id
Return the url of the valueset
192 193 194 |
# File 'lib/inferno/terminology/value_set.rb', line 192 def url @value_set_model.url end |
#value_set ⇒ Object
The ValueSet [Set]
158 159 160 161 162 163 164 165 166 |
# File 'lib/inferno/terminology/value_set.rb', line 158 def value_set return @value_set if @value_set if @use_expansions process_with_expansions else process_value_set end end |
#value_sets_repo ⇒ Object
153 154 155 |
# File 'lib/inferno/terminology/value_set.rb', line 153 def value_sets_repo self.class.value_sets_repo end |