health_seven 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/health_seven.gemspec +23 -0
- data/lib/health_seven.rb +3 -0
- data/lib/health_seven/message.rb +215 -0
- data/lib/health_seven/nodes.rb +20 -0
- data/spec/admit_message_spec.rb +41 -0
- data/spec/diagnoses_message_spec.rb +21 -0
- data/spec/messages/admit.hl7 +12 -0
- data/spec/messages/corrupt_admit.hl7 +13 -0
- data/spec/messages/diagnoses.hl7 +6 -0
- data/spec/messages/oru_r01.hl7 +46 -0
- data/spec/oru_message_spec.rb +38 -0
- data/spec/spec_helper.rb +15 -0
- metadata +93 -0
@@ -0,0 +1,23 @@
|
|
1
|
+
# Version numbering: http://wiki.github.com/sandal/prawn/development-roadmap
|
2
|
+
HEALTH_SEVEN_VERSION = "0.0.1"
|
3
|
+
|
4
|
+
Gem::Specification.new do |spec|
|
5
|
+
spec.name = "health_seven"
|
6
|
+
spec.version = HEALTH_SEVEN_VERSION
|
7
|
+
spec.platform = Gem::Platform::RUBY
|
8
|
+
spec.summary = "Ruby library for hl7 2.x"
|
9
|
+
spec.files = Dir.glob("{lib,spec}/**/**/*") +
|
10
|
+
['health_seven.gemspec']
|
11
|
+
spec.require_path = "lib"
|
12
|
+
spec.required_ruby_version = '>= 1.9.1'
|
13
|
+
spec.required_rubygems_version = ">= 1.3.6"
|
14
|
+
|
15
|
+
spec.test_files = Dir[ "spec/*_spec.rb" ]
|
16
|
+
spec.authors = ["Nikolay Ryzhikov", "Dmitry Rybakov"]
|
17
|
+
spec.email = ["niquola@gmail.com"]
|
18
|
+
spec.add_dependency('treetop')
|
19
|
+
spec.add_dependency('ttfunk', '~>1.0.0')
|
20
|
+
spec.description = 'Ruby library for HL7 2.x'
|
21
|
+
spec.post_install_message = ''
|
22
|
+
spec.homepage = 'https://github.com/hospital-systems/health_seven'
|
23
|
+
end
|
data/lib/health_seven.rb
ADDED
@@ -0,0 +1,215 @@
|
|
1
|
+
require 'treetop'
|
2
|
+
require "#{File.dirname(__FILE__)}/nodes.rb"
|
3
|
+
|
4
|
+
module HealthSeven
|
5
|
+
class BadGrammarException < Exception; end
|
6
|
+
|
7
|
+
class Message
|
8
|
+
##
|
9
|
+
## GRAMMAR PART
|
10
|
+
##
|
11
|
+
class SegmentDef
|
12
|
+
def initialize(name, &block)
|
13
|
+
@name = name
|
14
|
+
@segments = []
|
15
|
+
self.instance_eval(&block) if block_given?
|
16
|
+
end
|
17
|
+
|
18
|
+
def dsl_off!
|
19
|
+
@dsl_off = true
|
20
|
+
end
|
21
|
+
|
22
|
+
def seg_name
|
23
|
+
return '' if @name == :message
|
24
|
+
"'#{@name.to_s[0..2].upcase}'"
|
25
|
+
end
|
26
|
+
|
27
|
+
def rule_name
|
28
|
+
@name[0..2]
|
29
|
+
end
|
30
|
+
|
31
|
+
def optional?
|
32
|
+
@name[-1] == '?'
|
33
|
+
end
|
34
|
+
|
35
|
+
def multiple?
|
36
|
+
@name[3] == 's'
|
37
|
+
end
|
38
|
+
|
39
|
+
def method_missing(name, &block)
|
40
|
+
unless @dsl_off
|
41
|
+
@segments<< SegmentDef.new(name, &block)
|
42
|
+
else
|
43
|
+
super
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def to_gramar(gramar)
|
48
|
+
gramar.push <<-RULE
|
49
|
+
|
50
|
+
rule #{self.rule_name}
|
51
|
+
#{seg_name} payload delim #{_children_enum.join(" ")} <HealthSeven::SegmentLiteral>
|
52
|
+
end
|
53
|
+
RULE
|
54
|
+
|
55
|
+
@segments.each do |s|
|
56
|
+
s.to_gramar(gramar)
|
57
|
+
end
|
58
|
+
gramar
|
59
|
+
end
|
60
|
+
|
61
|
+
def _children_enum
|
62
|
+
children = @segments.map do |s|
|
63
|
+
s.dsl_off!
|
64
|
+
res = s.rule_name
|
65
|
+
if s.optional?
|
66
|
+
if s.multiple?
|
67
|
+
res<< "*"
|
68
|
+
else
|
69
|
+
res<< "?"
|
70
|
+
end
|
71
|
+
else
|
72
|
+
res<< "+" if s.multiple?
|
73
|
+
end
|
74
|
+
res
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
class MessageDef < SegmentDef
|
79
|
+
def to_gramar(gramar)
|
80
|
+
gramar.push <<-RULE
|
81
|
+
|
82
|
+
rule message
|
83
|
+
#{_children_enum.join(" ")} "\\n" <HealthSeven::SegmentLiteral>
|
84
|
+
end
|
85
|
+
|
86
|
+
rule delim
|
87
|
+
"\\r"
|
88
|
+
end
|
89
|
+
|
90
|
+
rule not_delim
|
91
|
+
[^"\\r"]
|
92
|
+
end
|
93
|
+
|
94
|
+
rule payload
|
95
|
+
not_delim+ <HealthSeven::FieldsLiteral>
|
96
|
+
end
|
97
|
+
RULE
|
98
|
+
|
99
|
+
@segments.each do |s|
|
100
|
+
s.to_gramar(gramar)
|
101
|
+
end
|
102
|
+
gramar
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
def self.define_message(&block)
|
107
|
+
@message_def = MessageDef.new(:message, &block)
|
108
|
+
self.load_grammar
|
109
|
+
end
|
110
|
+
|
111
|
+
def self.message_def
|
112
|
+
@message_def
|
113
|
+
end
|
114
|
+
|
115
|
+
def self.treetop_grammar
|
116
|
+
<<-RULE
|
117
|
+
grammar #{self.name}Grammar
|
118
|
+
#{@message_def.to_gramar([]).join("\n")}
|
119
|
+
end
|
120
|
+
RULE
|
121
|
+
end
|
122
|
+
|
123
|
+
def self.load_grammar
|
124
|
+
Object.const_set("#{self.name}Grammar", Module.new)
|
125
|
+
Treetop.load_from_string(treetop_grammar)
|
126
|
+
end
|
127
|
+
##
|
128
|
+
## END OF GRAMMAR PART
|
129
|
+
##
|
130
|
+
|
131
|
+
|
132
|
+
class Segment
|
133
|
+
attr_accessor :name
|
134
|
+
attr_accessor :fields
|
135
|
+
attr_accessor :children
|
136
|
+
|
137
|
+
def initialize
|
138
|
+
@children = []
|
139
|
+
end
|
140
|
+
|
141
|
+
def method_missing(method_name, *args)
|
142
|
+
res = nil
|
143
|
+
if method_name.length == 3
|
144
|
+
res = @children.find { |segment| segment.name == method_name.to_s.upcase }
|
145
|
+
else
|
146
|
+
res = @children.select { |segment| segment.name == method_name.to_s[0..2].upcase }
|
147
|
+
end
|
148
|
+
|
149
|
+
return res
|
150
|
+
end
|
151
|
+
|
152
|
+
def [](field, subfield = nil)
|
153
|
+
f = fields.split('|')[field - 1]
|
154
|
+
if subfield
|
155
|
+
f.split('^')[subfield - 1]
|
156
|
+
else
|
157
|
+
f
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
class Message < Segment
|
163
|
+
def[](*args)
|
164
|
+
nil
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
def self.parse(data)
|
169
|
+
parser = Object.const_get("#{self.name}GrammarParser").new
|
170
|
+
# Pass the data over to the parser instance
|
171
|
+
ast_tree = parser.parse(data)
|
172
|
+
|
173
|
+
# If the AST is nil then there was an error during parsing
|
174
|
+
# we need to report a simple error message to help the user
|
175
|
+
if(ast_tree.nil?)
|
176
|
+
message = ""
|
177
|
+
parser.failure_reason =~ /^(Expected .+) after/m
|
178
|
+
message << "#{$1.gsub("\n", '$NEWLINE')}:"
|
179
|
+
message << data.lines.to_a[parser.failure_line - 1]
|
180
|
+
message << "#{'~' * (parser.failure_column - 1)}^"
|
181
|
+
raise HealthSeven::BadGrammarException, message
|
182
|
+
end
|
183
|
+
msg = Message.new
|
184
|
+
self.clean_tree(ast_tree, msg)
|
185
|
+
|
186
|
+
msg
|
187
|
+
end
|
188
|
+
|
189
|
+
def self.clean_tree(node, segment)
|
190
|
+
if node.is_a?(Treetop::Runtime::SyntaxNode) && !node.elements
|
191
|
+
return false
|
192
|
+
end
|
193
|
+
|
194
|
+
segment.name = node.name
|
195
|
+
segment.fields = node.fields
|
196
|
+
|
197
|
+
return true unless node.elements
|
198
|
+
node.elements.each do |e|
|
199
|
+
if e.is_a?(HealthSeven::SegmentLiteral)
|
200
|
+
child_segment = Segment.new
|
201
|
+
if self.clean_tree(e, child_segment)
|
202
|
+
segment.children << child_segment
|
203
|
+
end
|
204
|
+
elsif e.elements
|
205
|
+
e.elements.each do |ee|
|
206
|
+
child_segment = Segment.new
|
207
|
+
if self.clean_tree(ee, child_segment)
|
208
|
+
segment.children << child_segment
|
209
|
+
end
|
210
|
+
end
|
211
|
+
end
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
215
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module HealthSeven
|
2
|
+
class Treetop::Runtime::SyntaxNode
|
3
|
+
end
|
4
|
+
|
5
|
+
class MessageLiteral < Treetop::Runtime::SyntaxNode
|
6
|
+
end
|
7
|
+
|
8
|
+
class SegmentLiteral < Treetop::Runtime::SyntaxNode
|
9
|
+
def name
|
10
|
+
@name ||= self.text_value.split('|')[0]
|
11
|
+
end
|
12
|
+
|
13
|
+
def fields
|
14
|
+
@fields ||= self.text_value.gsub(name + '|', '')
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
class FieldsLiteral < Treetop::Runtime::SyntaxNode
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe HealthSeven::Message do
|
4
|
+
class AdmitMessage < HealthSeven::Message
|
5
|
+
define_message do
|
6
|
+
msh
|
7
|
+
evn
|
8
|
+
pid
|
9
|
+
nk1
|
10
|
+
pv1
|
11
|
+
al1
|
12
|
+
gt1
|
13
|
+
in1s {
|
14
|
+
in2
|
15
|
+
}
|
16
|
+
zbc
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should pasre admit message" do
|
21
|
+
msg = AdmitMessage.parse(load_message('admit'))
|
22
|
+
|
23
|
+
msg.evn[1].should == 'A04'
|
24
|
+
|
25
|
+
msg.pid[5,1].should == 'SMITH'
|
26
|
+
msg.pid[5,2].should == 'LIDA'
|
27
|
+
|
28
|
+
msg.in1s.count.should == 2
|
29
|
+
msg.in1s[0][4,1].should == 'MEDICARE I/P'
|
30
|
+
msg.in1s[0].in2[2].should == '000000008'
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'should not parse a corrupted message' do
|
34
|
+
-> {
|
35
|
+
msg = AdmitMessage.parse(load_message('corrupt_admit'))
|
36
|
+
}.should raise_error do |error|
|
37
|
+
error.should be_a(HealthSeven::BadGrammarException)
|
38
|
+
error.message.should =~ 'IN2'
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe HealthSeven::Message do
|
4
|
+
class DiagnosesMessage < HealthSeven::Message
|
5
|
+
define_message do
|
6
|
+
msh
|
7
|
+
evn
|
8
|
+
pid
|
9
|
+
pv1?
|
10
|
+
dg1s
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should pasre diagnoses message" do
|
15
|
+
msg = DiagnosesMessage.parse(load_message('diagnoses'))
|
16
|
+
|
17
|
+
msg.dg1s.count.should == 2
|
18
|
+
msg.dg1s[0][4].should == 'DX HAIR LOSS 427.0 785.1'
|
19
|
+
msg.dg1s[1][2].should == 'I9'
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
MSH|^~\&|MS4ADT|001|UST|001|20090123204848||ADT^A04|00000000008186657|P|2.3
|
2
|
+
EVN|A04|20090123204846|||NURSE
|
3
|
+
PID|1|111111122^^^MS4^PN^|11-22-33^^^MS4^MR^001|11-22-33^^^MS4^MR^001|SMITH^LIDA^^^||19670101|F||P|9166 NEW-YORK CANYON^(OAKVIEW CONV)^NEW-YORK^CA^91042^^^||(111)111-2222|| 31|W|OTH|00016604787^^^MS4001^AN^001|000-00-0000
|
4
|
+
NK1|1|IVANOV^JOHN^^^|J|7903 HELLSTREET^^NEW-YORK^CA^91040^^|(222)222-3333||S||||||UNKNOWN|S|F||||||||||NON||||||||202244189^^^MS4^PN^||C|| 1
|
5
|
+
PV1||I|ICU5^T589^ A^001^OCCPD|1|||20131^PARTAMIAN^LEON^N^^^MD^^^^^^^|||MED||||7||||I||0401|3||||||||||||||||||001|OCCPD||||200901192300||46141.20|46141.20
|
6
|
+
AL1|1|FA|NONE^NONE^^^^|||
|
7
|
+
GT1|1|111111122^^^MS4^PN^|SMITH^LIDA^^^|IVANOV^JOHN^^^|9166 NEW-YORK CANYON^(OAKVIEW CONV)^NEW-YORK^CA^91042^^|(111)111-2222||19670101|F||A|000-00-0000||||RETIRED|^^^^00000||||||||||||07496|W||||||||Y|||OTH||||||||RETIRED||||||P
|
8
|
+
IN1|1||0401|MEDICARE I/P|^^^^ |||||||19990201|||MCR|SMITH^LIDA^^^|A|19670101|9166 NEW-YORK CANYON^(OAKVIEW CONV)^NEW-YORK^CA^91042^^^^|||1||||||||||||||000000008M|||||||F|^^^^00000|Y||||111111122
|
9
|
+
IN2||000000008|07496^RETIRED|||000000008M||||||||||||||||||||||||||||||Y|||OTH||||W|||RETIRED|||||||||||||||||(111)111-2222||||||||P
|
10
|
+
IN1|2||0304|MEDI-CAL SECONDARY|P.O. BOX 15600^^NEW-YORK^CA^95891-1600|||||||19940501|||MCD|SMITH^LIDA^^^|A|19670101|9166 NEW-YORK CANYON^(OAKVIEW CONV)^NEW-YORK^CA^91042^^^^|||2||||||||||||||00000000000000|||||||F|^^^^00000|N||||111111122
|
11
|
+
IN2||000000000|07496^RETIRED|||||00000000000000||||||||||||||||||||||||||||Y|||OTH||||W|||RETIRED|||||||||||||||||(111)111-2222||||||||P
|
12
|
+
ZBC|16000087|TELPC01 |TELLABEL
|
@@ -0,0 +1,13 @@
|
|
1
|
+
MSH|^~\&|MS4ADT|001|UST|001|20090123204848||ADT^A04|00000000008186657|P|2.3
|
2
|
+
EVN|A04|20090123204846|||NURSE
|
3
|
+
PID|1|111111122^^^MS4^PN^|11-22-33^^^MS4^MR^001|11-22-33^^^MS4^MR^001|SMITH^LIDA^^^||19670101|F||P|9166 NEW-YORK CANYON^(OAKVIEW CONV)^NEW-YORK^CA^91042^^^||(111)111-2222|| 31|W|OTH|00016604787^^^MS4001^AN^001|000-00-0000
|
4
|
+
NK1|1|IVANOV^JOHN^^^|J|7903 HELLSTREET^^NEW-YORK^CA^91040^^|(222)222-3333||S||||||UNKNOWN|S|F||||||||||NON||||||||202244189^^^MS4^PN^||C|| 1
|
5
|
+
PV1||I|ICU5^T589^ A^001^OCCPD|1|||20131^PARTAMIAN^LEON^N^^^MD^^^^^^^|||MED||||7||||I||0401|3||||||||||||||||||001|OCCPD||||200901192300||46141.20|46141.20
|
6
|
+
AL1|1|FA|NONE^NONE^^^^|||
|
7
|
+
GT1|1|111111122^^^MS4^PN^|SMITH^LIDA^^^|IVANOV^JOHN^^^|9166 NEW-YORK CANYON^(OAKVIEW CONV)^NEW-YORK^CA^91042^^|(111)111-2222||19670101|F||A|000-00-0000||||RETIRED|^^^^00000||||||||||||07496|W||||||||Y|||OTH||||||||RETIRED||||||P
|
8
|
+
IN2||000000008|07496^RETIRED|||000000008M||||||||||||||||||||||||||||||Y|||OTH||||W|||RETIRED|||||||||||||||||(111)111-2222||||||||P
|
9
|
+
IN1|1||0401|MEDICARE I/P|^^^^ |||||||19990201|||MCR|SMITH^LIDA^^^|A|19670101|9166 NEW-YORK CANYON^(OAKVIEW CONV)^NEW-YORK^CA^91042^^^^|||1||||||||||||||000000008M|||||||F|^^^^00000|Y||||111111122
|
10
|
+
IN2||000000008|07496^RETIRED|||000000008M||||||||||||||||||||||||||||||Y|||OTH||||W|||RETIRED|||||||||||||||||(111)111-2222||||||||P
|
11
|
+
IN1|2||0304|MEDI-CAL SECONDARY|P.O. BOX 15600^^NEW-YORK^CA^95891-1600|||||||19940501|||MCD|SMITH^LIDA^^^|A|19670101|9166 NEW-YORK CANYON^(OAKVIEW CONV)^NEW-YORK^CA^91042^^^^|||2||||||||||||||00000000000000|||||||F|^^^^00000|N||||111111122
|
12
|
+
IN2||000000000|07496^RETIRED|||||00000000000000||||||||||||||||||||||||||||Y|||OTH||||W|||RETIRED|||||||||||||||||(111)111-2222||||||||P
|
13
|
+
ZBC|16000087|TELPC01 |TELLABEL
|
@@ -0,0 +1,6 @@
|
|
1
|
+
MSH|^~\&|MS4ADT|001|WEBMEDAPP|001|20100330145611||ADT^A04|00000000009568610|P|2.3|
|
2
|
+
EVN|A04|20100330145608|||LABTCARLIN|
|
3
|
+
PID|1|000055550^^^MS4^PN|11-22-99^^^MS4^MR^001|11-22-99^^^MS4^MR^001|IVANOVA^JOHN^M||19330527|F||C|1917 PARIS LANE^^LA CANADA^CA^91011||(444)444-0000||ENG|M|PRO|00099999999^^^MS4001^AN^001|000-00-0000||||NEW YORK CITY, NY|
|
4
|
+
PV1||O||3|||80911^IVANOVA^SYLVIA^P|||VL1||||1||||V||0407|1||||||||||||||||||001|OCCPD||||201003301455|
|
5
|
+
DG1|1|I9||DX HAIR LOSS 427.0 785.1||A|||||||||0|
|
6
|
+
DG1|2|I9||LAB WORK||A|||||||||0|
|
@@ -0,0 +1,46 @@
|
|
1
|
+
MSH|^~\&|LAB|05D0557149|LA WEBvCMR|LA COUNTY|201212131138||ORU^R01|RES-OUT.1.1055001|P|2.1
|
2
|
+
PID|1|69962^^^^^Main Lab&0520317149&CLIA|11-11-11^^^^^Main Lab&0520317149&CLIA|^^^^^Main Lab&0520317149&CLIA|SMITH^JOHN^Junior||99251104|M|||4444 CILEDON WAY^^LOS ANGELES^CA^9999||(323)111-8888|||||111111|556128209
|
3
|
+
ORC|RE|1213:L00106S|1213:L00106S|||||||||BERK^BERKENBILE^LEO^E.^^^M.D.|Verdugo Hills Hospital|111-222-3333|||||||Verdugo Hills Hospital^^05D0557149^^^CLIA|1812 Verdugo Boulevard^Glendale, CA 91209^||1812 VERDUGO BLVD., ER^^GLENDALE, CA 91208^^
|
4
|
+
OBR|1|1213:L00106S|1213:L00106SCBC|^^^CBC^COMPLETE BLOOD COUNT|||201212131035|||AS/EMR||||201212131035|^|BERK^BERKENBILE^LEO^E.^^^M.D.|111-222-3333|||||201212131111|||A||^^^^^S
|
5
|
+
OBX|1|NM|6690-2^Leukocytes^^WBC^WHITE BLOOD COUNT||8.7|10\S\3/uL|4.8-10.8||||F|||201212131035|ML^Main Lab
|
6
|
+
OBX|2|NM|789-8^Erythrocytes^^RBC^RED BLOOD COUNT||4.23|10\S\6/uL|4.30-5.90| L|||F|||201212131035|ML^Main Lab
|
7
|
+
OBX|3|NM|718-7^Hemoglobin^^HGB^HEMOGLOBIN||13.5|g/dL|13.9-16.3| L|||F|||201212131035|ML^Main Lab
|
8
|
+
OBX|4|NM|20570-8^Hematocrit^^HCT^HEMATOCRIT||40.4|%|39.0-55.0||||F|||201212131035|ML^Main Lab
|
9
|
+
OBX|5|NM|787-2^Erythrocyte mean corpuscular volume^^MCV^MEAN CORPUSCULAR VOLUME||95.5|fl|80.0-94.0| H|||F|||201212131035|ML^Main Lab
|
10
|
+
OBX|6|NM|785-6^Erythrocyte mean corpuscular hemoglobin^^MCH^MEAN CORPUSCULAR HEMGLOB||31.9|pg|29.0-33.0||||F|||201212131035|ML^Main Lab
|
11
|
+
OBX|7|NM|786-4^Erythrocyte mean corpuscular hemoglobin concentrat^^MCHC^MEAN CORPUSCULAR HGB CONC||33.5|g/dL|32.0-36.0||||F|||201212131035|ML^Main Lab
|
12
|
+
OBX|8|NM|788-0^Erythrocyte distribution width^^RDW^RED CELL DISTRIB WIDTH||14.3|%|11.5-14.5||||F|||201212131035|ML^Main Lab
|
13
|
+
OBX|9|NM|777-3^Platelets^^PLT^PLATELET COUNT||200|10\S\3/uL|130-450||||F|||201212131035|ML^Main Lab
|
14
|
+
OBX|10|NM|32623-1^Platelet mean volume^^MPV^MEAN PLATELET VOLUME||8.9|fl|7.4-10.4||||F|||201212131035|ML^Main Lab
|
15
|
+
OBX|11|NM|770-8^Neutrophils/100 leukocytes^^NEC^NEUTROPHIL PERCENT||84.4|%|50.0-70.0| H|||F|||201212131035|ML^Main Lab
|
16
|
+
OBX|12|NM|751-8^Neutrophils^^NEN^NEUTROPHILS,ABSOLUTE||7.3|10\S\3/uL|2.4-7.5||||F|||201212131035|ML^Main Lab
|
17
|
+
OBX|13|NM|736-9^Lymphocytes/100 leukocytes^^LC^LYMPHOCYTE PERCENT||9.4|%|20.0-40.0| L|||F|||201212131035|ML^Main Lab
|
18
|
+
OBX|14|NM|5905-5^Monocytes/100 leukocytes^^MOC^MONOCYTE PERCENT||6.1|%|0.0-14.0||||F|||201212131035|ML^Main Lab
|
19
|
+
OBX|15|NM|713-8^Eosinophils/100 leukocytes^^EOC^EOSINOPHIL PERCENT||0.0|%|0.0-3.0||||F|||201212131035|ML^Main Lab
|
20
|
+
OBX|16|NM|706-2^Basophils/100 leukocytes^^BAC^BASOPHIL PERCENT||0.1|%|0.0-1.5||||F|||201212131035|^
|
21
|
+
OBR|2|1213:L00106S|1213:L00106SPT|^^^PT^PROTHROMBIN TIME|||201212131035|||AS/EMR||||201212131035|^|BERK^BERKENBILE^LEO^E.^^^M.D.|111-222-3333|||||201212131111|||A||^^^^^S
|
22
|
+
OBX|1|NM|5902-2^Coagulation tissue factor induced^^*PTP^PRO TIME PATIENT||10.6|SEC|9.8-12.4||||F|||201212131035|ML^Main Lab
|
23
|
+
NTE|1||Note: New Reference Range effective 12/7/12
|
24
|
+
OBX|2|NM|5902-2^Coagulation tissue factor induced^^*PTI^PRO TIME INR||1.0||0.9-1.2||||F|||201212131035|ML^Main Lab
|
25
|
+
NTE|1||LEVEL OF
|
26
|
+
NTE|2||THERAPY INR VALUES
|
27
|
+
NTE|3||-------------------------------------------------------
|
28
|
+
NTE|4||STD. DOSE: RX OF VENOUS THROMBOSIS. 2-3
|
29
|
+
NTE|5||RX OF PULMONARY EMBOLISM.
|
30
|
+
NTE|6||PROPHYLAXIS AGAINST VENOUS
|
31
|
+
NTE|7||THROMBOSIS OR SYSTEMIC
|
32
|
+
NTE|8||EMBOLIZATION.
|
33
|
+
NTE|9||
|
34
|
+
NTE|10||HIGH DOSE: HIGH RISK PATIENTS WITH 2.5-3.5
|
35
|
+
NTE|11||MECHANICAL HEART VALVES.
|
36
|
+
NTE|12||
|
37
|
+
NTE|13||USE OF INR IS NOT STANDARDIZED FOR THE INDUCTION PHASE
|
38
|
+
NTE|14||OF ANTICOAGULATION THERAPY. VARIOUS REAGENTS REACT TO
|
39
|
+
NTE|15||FALLING FACTORS VARIABLY DURING THE ONSET OF COUMADIN
|
40
|
+
NTE|16||THERAPY.
|
41
|
+
OBR|3|1213:L00106S|1213:L00106SPTT|^^^PTT^PARTIAL THROMBOPLASTIN|||201212131035|||AS/EMR||||201212131035|^|BERK^BERKENBILE^LEO^E.^^^M.D.|111-222-3333|||||201212131111|||A||^^^^^S
|
42
|
+
OBX|1|NM|14979-9^Coagulation surface induced^^*PTTP^PTT-PATIENT||32.1|SEC|25.6-36.7||||F|||201212131035|ML^Main Lab
|
43
|
+
NTE|1||Note:
|
44
|
+
NTE|2||New reference range effective 12/4/12
|
45
|
+
NTE|3||Heparin Therapeutic Ranges: PTT = 1.5 to 2.5 times the
|
46
|
+
NTE|4||normal range.
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe HealthSeven::Message do
|
4
|
+
class OruMessage < HealthSeven::Message
|
5
|
+
define_message do
|
6
|
+
msh
|
7
|
+
pid
|
8
|
+
pv1?
|
9
|
+
orc {
|
10
|
+
obrs {
|
11
|
+
ntes?
|
12
|
+
obxs {
|
13
|
+
ntes?
|
14
|
+
}
|
15
|
+
}
|
16
|
+
}
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should pasre ORU message" do
|
21
|
+
mrn = '111'
|
22
|
+
account_number = '111'
|
23
|
+
msg = OruMessage.parse(load_message('oru_r01'))
|
24
|
+
msg.pid[5,1].should == 'SMITH'
|
25
|
+
msg.pid[5,2].should == 'JOHN'
|
26
|
+
|
27
|
+
msg.pv1.should be_nil
|
28
|
+
|
29
|
+
msg.orc.obrs.length.should == 3
|
30
|
+
msg.orc.obrs[0].obxs.length.should == 16
|
31
|
+
msg.orc.obrs[1].obxs.length.should == 2
|
32
|
+
msg.orc.obrs[2].obxs.length.should == 1
|
33
|
+
|
34
|
+
msg.orc.obrs[0].ntes.should be_empty
|
35
|
+
|
36
|
+
msg.orc.obrs[2].obxs[0].ntes[0][3].should =~ /Note:/
|
37
|
+
end
|
38
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
puts "HealthSeven specs: Running on Ruby Version: #{RUBY_VERSION}"
|
4
|
+
|
5
|
+
require "rubygems"
|
6
|
+
require "bundler"
|
7
|
+
Bundler.setup
|
8
|
+
|
9
|
+
$LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', 'lib')
|
10
|
+
require "health_seven"
|
11
|
+
def load_message(name)
|
12
|
+
msg = File.read(File.join(File.dirname(__FILE__), 'messages', "#{name}.hl7"))
|
13
|
+
msg.gsub!("\n", "\r")
|
14
|
+
"#{msg}\n"
|
15
|
+
end
|
metadata
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: health_seven
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: 0.0.1
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Nikolay Ryzhikov
|
9
|
+
- Dmitry Rybakov
|
10
|
+
autorequire:
|
11
|
+
bindir: bin
|
12
|
+
cert_chain: []
|
13
|
+
date: 2012-12-18 00:00:00.000000000 Z
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
type: :runtime
|
17
|
+
requirement: !ruby/object:Gem::Requirement
|
18
|
+
none: false
|
19
|
+
requirements:
|
20
|
+
- - ! '>='
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '0'
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
name: treetop
|
31
|
+
- !ruby/object:Gem::Dependency
|
32
|
+
type: :runtime
|
33
|
+
requirement: !ruby/object:Gem::Requirement
|
34
|
+
none: false
|
35
|
+
requirements:
|
36
|
+
- - ~>
|
37
|
+
- !ruby/object:Gem::Version
|
38
|
+
version: 1.0.0
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 1.0.0
|
46
|
+
name: ttfunk
|
47
|
+
description: Ruby library for HL7 2.x
|
48
|
+
email:
|
49
|
+
- niquola@gmail.com
|
50
|
+
executables: []
|
51
|
+
extensions: []
|
52
|
+
extra_rdoc_files: []
|
53
|
+
files:
|
54
|
+
- lib/health_seven.rb
|
55
|
+
- lib/health_seven/nodes.rb
|
56
|
+
- lib/health_seven/message.rb
|
57
|
+
- spec/messages/admit.hl7
|
58
|
+
- spec/messages/diagnoses.hl7
|
59
|
+
- spec/messages/corrupt_admit.hl7
|
60
|
+
- spec/messages/oru_r01.hl7
|
61
|
+
- spec/diagnoses_message_spec.rb
|
62
|
+
- spec/admit_message_spec.rb
|
63
|
+
- spec/oru_message_spec.rb
|
64
|
+
- spec/spec_helper.rb
|
65
|
+
- health_seven.gemspec
|
66
|
+
homepage: https://github.com/hospital-systems/health_seven
|
67
|
+
licenses: []
|
68
|
+
post_install_message: ''
|
69
|
+
rdoc_options: []
|
70
|
+
require_paths:
|
71
|
+
- lib
|
72
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: 1.9.1
|
78
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
79
|
+
none: false
|
80
|
+
requirements:
|
81
|
+
- - ! '>='
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: 1.3.6
|
84
|
+
requirements: []
|
85
|
+
rubyforge_project:
|
86
|
+
rubygems_version: 1.8.24
|
87
|
+
signing_key:
|
88
|
+
specification_version: 3
|
89
|
+
summary: Ruby library for hl7 2.x
|
90
|
+
test_files:
|
91
|
+
- spec/diagnoses_message_spec.rb
|
92
|
+
- spec/admit_message_spec.rb
|
93
|
+
- spec/oru_message_spec.rb
|