quality-measure-engine 1.1.5 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +12 -0
- data/.travis.yml +16 -0
- data/Gemfile +5 -21
- data/Gemfile.lock +126 -0
- data/LICENSE.txt +13 -0
- data/README.md +23 -44
- data/Rakefile +6 -29
- data/lib/qme/bundle/bundle.rb +34 -0
- data/lib/qme/bundle/importer.rb +69 -0
- data/lib/qme/database_access.rb +7 -11
- data/lib/qme/map/map_reduce_builder.rb +4 -1
- data/lib/qme/map/map_reduce_executor.rb +55 -43
- data/lib/qme/map/measure_calculation_job.rb +24 -23
- data/lib/qme/quality_measure.rb +5 -5
- data/lib/qme/quality_report.rb +37 -19
- data/lib/qme/railtie.rb +7 -0
- data/lib/qme/tasks/bundle.rake +14 -0
- data/lib/qme/version.rb +3 -0
- data/lib/quality-measure-engine.rb +13 -25
- data/quality-measure-engine.gemspec +28 -0
- data/test/fixtures/bundles/just_measure_0002.zip +0 -0
- data/test/fixtures/delayed_backend_mongoid_jobs/queued_job.json +9 -0
- data/test/fixtures/measures/measure_metadata.json +52 -0
- data/test/fixtures/records/barry_berry.json +471 -0
- data/test/fixtures/records/billy_jones_ipp.json +78 -0
- data/test/fixtures/records/jane_jones_numerator.json +120 -0
- data/test/fixtures/records/jill_jones_denominator.json +78 -0
- data/test/simplecov_setup.rb +18 -0
- data/test/test_helper.rb +26 -0
- data/test/unit/qme/map/map_reduce_builder_test.rb +38 -0
- data/test/unit/qme/map/map_reduce_executor_test.rb +56 -0
- data/test/unit/qme/map/measure_calculation_job_test.rb +22 -0
- data/test/unit/qme/quality_measure_test.rb +14 -0
- data/{spec/qme/quality_report_spec.rb → test/unit/qme/quality_report_test.rb} +32 -20
- metadata +91 -115
- data/VERSION +0 -1
- data/js/map_reduce_utils.js +0 -173
- data/js/underscore_min.js +0 -25
- data/lib/qme/ext/record.rb +0 -43
- data/lib/qme/importer/entry.rb +0 -126
- data/lib/qme/importer/generic_importer.rb +0 -117
- data/lib/qme/importer/measure_properties_generator.rb +0 -39
- data/lib/qme/importer/property_matcher.rb +0 -110
- data/lib/qme/measure/database_loader.rb +0 -83
- data/lib/qme/measure/measure_loader.rb +0 -174
- data/lib/qme/measure/properties_builder.rb +0 -184
- data/lib/qme/measure/properties_converter.rb +0 -27
- data/lib/qme/randomizer/patient_randomization_job.rb +0 -47
- data/lib/qme/randomizer/patient_randomizer.rb +0 -250
- data/lib/qme/randomizer/random_patient_creator.rb +0 -47
- data/lib/qme_test.rb +0 -13
- data/lib/tasks/fixtures.rake +0 -91
- data/lib/tasks/measure.rake +0 -110
- data/lib/tasks/mongo.rake +0 -68
- data/lib/tasks/patient_random.rake +0 -45
- data/spec/qme/bundle_spec.rb +0 -37
- data/spec/qme/importer/generic_importer_spec.rb +0 -73
- data/spec/qme/importer/measure_properties_generator_spec.rb +0 -15
- data/spec/qme/importer/property_matcher_spec.rb +0 -174
- data/spec/qme/map/map_reduce_builder_spec.rb +0 -38
- data/spec/qme/map/measures_spec.rb +0 -38
- data/spec/qme/map/patient_mapper_spec.rb +0 -11
- data/spec/qme/measure_loader_spec.rb +0 -12
- data/spec/qme/properties_builder_spec.rb +0 -61
- data/spec/spec_helper.rb +0 -120
- data/spec/validate_measures_spec.rb +0 -21
@@ -1,47 +0,0 @@
|
|
1
|
-
module QME
|
2
|
-
module Randomizer
|
3
|
-
# A Resque job that allows for generation of randomized patients by a Resque worker. Can be created as follows:
|
4
|
-
#
|
5
|
-
# QME::Randomizer::PatientRandomizationJob.create(:template_dir => '/xx/yy', :count => 100, [:test_id => ObjectId])
|
6
|
-
#
|
7
|
-
# This will return a uuid which can be used to check in on the status of a job. More details on this can be found
|
8
|
-
# at the {Resque Stats project page}[https://github.com/quirkey/resque-status].
|
9
|
-
#
|
10
|
-
class PatientRandomizationJob < Resque::JobWithStatus
|
11
|
-
def perform
|
12
|
-
test_id = options['test_id'] ? BSON::ObjectId(options['test_id']) : nil
|
13
|
-
template_dir = options['template_dir']
|
14
|
-
count = options['count']
|
15
|
-
|
16
|
-
tick('Reading templates')
|
17
|
-
templates = []
|
18
|
-
Dir.glob(File.join(template_dir, '*.json.erb')).each do |file|
|
19
|
-
templates << File.read(file)
|
20
|
-
end
|
21
|
-
|
22
|
-
tick('Initializing parser')
|
23
|
-
processed_measures = {}
|
24
|
-
QME::QualityMeasure.all.each_value do |measure_def|
|
25
|
-
measure_id = measure_def['id']
|
26
|
-
if !processed_measures[measure_id]
|
27
|
-
QME::Importer::MeasurePropertiesGenerator.instance.add_measure(measure_id, QME::Importer::GenericImporter.new(measure_def))
|
28
|
-
processed_measures[measure_id] = true
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
tick('Generating patients')
|
33
|
-
count.times do |i|
|
34
|
-
at(i, count, "Generating patient #{i} of #{count}")
|
35
|
-
template = templates[rand(templates.length)]
|
36
|
-
generator = QME::Randomizer::Patient.new(template)
|
37
|
-
json = JSON.parse(generator.get())
|
38
|
-
patient_record = RandomPatientCreator.parse_hash(json)
|
39
|
-
patient_record.test_id = test_id
|
40
|
-
patient_record.save!
|
41
|
-
end
|
42
|
-
|
43
|
-
completed
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
@@ -1,250 +0,0 @@
|
|
1
|
-
require 'erb'
|
2
|
-
|
3
|
-
module QME
|
4
|
-
|
5
|
-
module Randomizer
|
6
|
-
|
7
|
-
# Provides functionality for randomizing patient records based on erb templates
|
8
|
-
class Patient
|
9
|
-
|
10
|
-
# Utility class used to supply a binding to Erb
|
11
|
-
class Context
|
12
|
-
|
13
|
-
# Create a new context
|
14
|
-
def initialize()
|
15
|
-
@genders = ['M', 'F']
|
16
|
-
# 300 most popular forenames according to US census 1990
|
17
|
-
@forenames = {
|
18
|
-
'M' => %w{James John Robert Michael William David Richard Charles Joseph Thomas Christopher Daniel Paul Mark Donald George Kenneth Steven Edward Brian Ronald Anthony Kevin Jason Matthew Gary Timothy Jose Larry Jeffrey Frank Scott Eric Stephen Andrew Raymond Gregory Joshua Jerry Dennis Walter Patrick Peter Harold Douglas Henry Carl Arthur Ryan Roger Joe Juan Jack Albert Jonathan Justin Terry Gerald Keith Samuel Willie Ralph Lawrence Nicholas Roy Benjamin Bruce Brandon Adam Harry Fred Wayne Billy Steve Louis Jeremy Aaron Randy Howard Eugene Carlos Russell Bobby Victor Martin Ernest Phillip Todd Jesse Craig Alan Shawn Clarence Sean Philip Chris Johnny Earl Jimmy Antonio Danny Bryan Tony Luis Mike Stanley Leonard Nathan Dale Manuel Rodney Curtis Norman Allen Marvin Vincent Glenn Jeffery Travis Jeff Chad Jacob Lee Melvin Alfred Kyle Francis Bradley Jesus Herbert Frederick Ray Joel Edwin Don Eddie Ricky Troy Randall Barry Alexander Bernard Mario Leroy Francisco Marcus Micheal Theodore Clifford Miguel Oscar Jay Jim Tom Calvin Alex Jon Ronnie Bill Lloyd Tommy Leon Derek Warren Darrell Jerome Floyd Leo Alvin Tim Wesley Gordon Dean Greg Jorge Dustin Pedro Derrick Dan Lewis Zachary Corey Herman Maurice Vernon Roberto Clyde Glen Hector Shane Ricardo Sam Rick Lester Brent Ramon Charlie Tyler Gilbert Gene Marc Reginald Ruben Brett Angel Nathaniel Rafael Leslie Edgar Milton Raul Ben Chester Cecil Duane Franklin Andre Elmer Brad Gabriel Ron Mitchell Roland Arnold Harvey Jared Adrian Karl Cory Claude Erik Darryl Jamie Neil Jessie Christian Javier Fernando Clinton Ted Mathew Tyrone Darren Lonnie Lance Cody Julio Kelly Kurt Allan Nelson Guy Clayton Hugh Max Dwayne Dwight Armando Felix Jimmie Everett Jordan Ian Wallace Ken Bob Jaime Casey Alfredo Alberto Dave Ivan Johnnie Sidney Byron Julian Isaac Morris Clifton Willard Daryl Ross Virgil Andy Marshall Salvador Perry Kirk Sergio Marion Tracy Seth Kent Terrance Rene Eduardo Terrence Enrique Freddie Wade},
|
19
|
-
'F' => %w{Mary Patricia Linda Barbara Elizabeth Jennifer Maria Susan Margaret Dorothy Lisa Nancy Karen Betty Helen Sandra Donna Carol Ruth Sharon Michelle Laura Sarah Kimberly Deborah Jessica Shirley Cynthia Angela Melissa Brenda Amy Anna Rebecca Virginia Kathleen Pamela Martha Debra Amanda Stephanie Carolyn Christine Marie Janet Catherine Frances Ann Joyce Diane Alice Julie Heather Teresa Doris Gloria Evelyn Jean Cheryl Mildred Katherine Joan Ashley Judith Rose Janice Kelly Nicole Judy Christina Kathy Theresa Beverly Denise Tammy Irene Jane Lori Rachel Marilyn Andrea Kathryn Louise Sara Anne Jacqueline Wanda Bonnie Julia Ruby Lois Tina Phyllis Norma Paula Diana Annie Lillian Emily Robin Peggy Crystal Gladys Rita Dawn Connie Florence Tracy Edna Tiffany Carmen Rosa Cindy Grace Wendy Victoria Edith Kim Sherry Sylvia Josephine Thelma Shannon Sheila Ethel Ellen Elaine Marjorie Carrie Charlotte Monica Esther Pauline Emma Juanita Anita Rhonda Hazel Amber Eva Debbie April Leslie Clara Lucille Jamie Joanne Eleanor Valerie Danielle Megan Alicia Suzanne Michele Gail Bertha Darlene Veronica Jill Erin Geraldine Lauren Cathy Joann Lorraine Lynn Sally Regina Erica Beatrice Dolores Bernice Audrey Yvonne Annette June Samantha Marion Dana Stacy Ana Renee Ida Vivian Roberta Holly Brittany Melanie Loretta Yolanda Jeanette Laurie Katie Kristen Vanessa Alma Sue Elsie Beth Jeanne Vicki Carla Tara Rosemary Eileen Terri Gertrude Lucy Tonya Ella Stacey Wilma Gina Kristin Jessie Natalie Agnes Vera Willie Charlene Bessie Delores Melinda Pearl Arlene Maureen Colleen Allison Tamara Joy Georgia Constance Lillie Claudia Jackie Marcia Tanya Nellie Minnie Marlene Heidi Glenda Lydia Viola Courtney Marian Stella Caroline Dora Jo Vickie Mattie Terry Maxine Irma Mabel Marsha Myrtle Lena Christy Deanna Patsy Hilda Gwendolyn Jennie Nora Margie Nina Cassandra Leah Penny Kay Priscilla Naomi Carole Brandy Olga Billie Dianne Tracey Leona Jenny Felicia Sonia Miriam Velma Becky Bobbie Violet Kristina Toni Misty Mae Shelly Daisy Ramona Sherri Erika Katrina Claire}
|
20
|
-
}
|
21
|
-
# 500 most popular surnames according to US census 1990
|
22
|
-
@surnames = %w{Smith Johnson Williams Jones Brown Davis Miller Wilson Moore Taylor Anderson Thomas Jackson White Harris Martin Thompson Garcia Martinez Robinson Clark Rodriguez Lewis Lee Walker Hall Allen Young Hernandez King Wright Lopez Hill Scott Green Adams Baker Gonzalez Nelson Carter Mitchell Perez Roberts Turner Phillips Campbell Parker Evans Edwards Collins Stewart Sanchez Morris Rogers Reed Cook Morgan Bell Murphy Bailey Rivera Cooper Richardson Cox Howard Ward Torres Peterson Gray Ramirez James Watson Brooks Kelly Sanders Price Bennett Wood Barnes Ross Henderson Coleman Jenkins Perry Powell Long Patterson Hughes Flores Washington Butler Simmons Foster Gonzales Bryant Alexander Russell Griffin Diaz Hayes Myers Ford Hamilton Graham Sullivan Wallace Woods Cole West Jordan Owens Reynolds Fisher Ellis Harrison Gibson Mcdonald Cruz Marshall Ortiz Gomez Murray Freeman Wells Webb Simpson Stevens Tucker Porter Hunter Hicks Crawford Henry Boyd Mason Morales Kennedy Warren Dixon Ramos Reyes Burns Gordon Shaw Holmes Rice Robertson Hunt Black Daniels Palmer Mills Nichols Grant Knight Ferguson Rose Stone Hawkins Dunn Perkins Hudson Spencer Gardner Stephens Payne Pierce Berry Matthews Arnold Wagner Willis Ray Watkins Olson Carroll Duncan Snyder Hart Cunningham Bradley Lane Andrews Ruiz Harper Fox Riley Armstrong Carpenter Weaver Greene Lawrence Elliott Chavez Sims Austin Peters Kelley Franklin Lawson Fields Gutierrez Ryan Schmidt Carr Vasquez Castillo Wheeler Chapman Oliver Montgomery Richards Williamson Johnston Banks Meyer Bishop Mccoy Howell Alvarez Morrison Hansen Fernandez Garza Harvey Little Burton Stanley Nguyen George Jacobs Reid Kim Fuller Lynch Dean Gilbert Garrett Romero Welch Larson Frazier Burke Hanson Day Mendoza Moreno Bowman Medina Fowler Brewer Hoffman Carlson Silva Pearson Holland Douglas Fleming Jensen Vargas Byrd Davidson Hopkins May Terry Herrera Wade Soto Walters Curtis Neal Caldwell Lowe Jennings Barnett Graves Jimenez Horton Shelton Barrett Obrien Castro Sutton Gregory Mckinney Lucas Miles Craig Rodriquez Chambers Holt Lambert Fletcher Watts Bates Hale Rhodes Pena Beck Newman Haynes Mcdaniel Mendez Bush Vaughn Parks Dawson Santiago Norris Hardy Love Steele Curry Powers Schultz Barker Guzman Page Munoz Ball Keller Chandler Weber Leonard Walsh Lyons Ramsey Wolfe Schneider Mullins Benson Sharp Bowen Daniel Barber Cummings Hines Baldwin Griffith Valdez Hubbard Salazar Reeves Warner Stevenson Burgess Santos Tate Cross Garner Mann Mack Moss Thornton Dennis Mcgee Farmer Delgado Aguilar Vega Glover Manning Cohen Harmon Rodgers Robbins Newton Todd Blair Higgins Ingram Reese Cannon Strickland Townsend Potter Goodwin Walton Rowe Hampton Ortega Patton Swanson Joseph Francis Goodman Maldonado Yates Becker Erickson Hodges Rios Conner Adkins Webster Norman Malone Hammond Flowers Cobb Moody Quinn Blake Maxwell Pope Floyd Osborne Paul Mccarthy Guerrero Lindsey Estrada Sandoval Gibbs Tyler Gross Fitzgerald Stokes Doyle Sherman Saunders Wise Colon Gill Alvarado Greer Padilla Simon Waters Nunez Ballard Schwartz Mcbride Houston Christensen Klein Pratt Briggs Parsons Mclaughlin Zimmerman French Buchanan Moran Copeland Roy Pittman Brady Mccormick Holloway Brock Poole Frank Logan Owen Bass Marsh Drake Wong Jefferson Park Morton Abbott Sparks Patrick Norton Huff Clayton Massey Lloyd Figueroa Carson Bowers Roberson Barton Tran Lamb Harrington Casey Boone Cortez Clarke Mathis Singleton Wilkins Cain Bryan Underwood Hogan Mckenzie Collier Luna Phelps Mcguire Allison Bridges Wilkerson Nash Summers Atkins}
|
23
|
-
|
24
|
-
@streetnames = %w{Park Main Oak Pine Maple Cedar Elm Lake Hill Second Washington}
|
25
|
-
@zipcodes = {
|
26
|
-
'01000' => {'city' => 'Springfield', 'state'=> 'MA'},
|
27
|
-
'01200' => {'city' => 'Springfield', 'state'=> 'MA'},
|
28
|
-
'01400' => {'city' => 'Worcester', 'state'=> 'MA'},
|
29
|
-
'02000' => {'city' => 'Brockton', 'state'=> 'MA'},
|
30
|
-
'02100' => {'city' => 'Boston', 'state'=> 'MA'},
|
31
|
-
'02500' => {'city' => 'Cape Cod', 'state'=> 'MA'},
|
32
|
-
'03000' => {'city' => 'Manchester', 'state'=> 'NH'},
|
33
|
-
'03300' => {'city' => 'Concord', 'state'=> 'NH'},
|
34
|
-
'03500' => {'city' => 'White River Junction', 'state'=> 'VT'},
|
35
|
-
'03800' => {'city' => 'Portsmouth', 'state'=> 'NH'},
|
36
|
-
'04000' => {'city' => 'Portland', 'state'=> 'ME'},
|
37
|
-
'04400' => {'city' => 'Bangor', 'state'=> 'ME'},
|
38
|
-
'05400' => {'city' => 'Burlington', 'state'=> 'VT'},
|
39
|
-
'06000' => {'city' => 'Hartford', 'state'=> 'CT'},
|
40
|
-
'06500' => {'city' => 'New Haven', 'state'=> 'CT'}
|
41
|
-
}
|
42
|
-
end
|
43
|
-
|
44
|
-
# Pick a gender at random
|
45
|
-
# @return 'M' or 'F'
|
46
|
-
def gender
|
47
|
-
@genders[rand(@genders.length)]
|
48
|
-
end
|
49
|
-
|
50
|
-
# Picks a race based on 2010 census estimates
|
51
|
-
# Pacific Islander 0.2%
|
52
|
-
# American Indian 0.9%
|
53
|
-
# Asian 4.8%
|
54
|
-
# Black persons 12.6%
|
55
|
-
# Hispanic 16.3%
|
56
|
-
# White 63.7%
|
57
|
-
def race_and_ethnicity
|
58
|
-
race_percent = rand(999)
|
59
|
-
case race_percent
|
60
|
-
when 0..1
|
61
|
-
# pacific islander
|
62
|
-
{race: '2076-8', ethnicity: '2186-5'}
|
63
|
-
when 2..10
|
64
|
-
# american indian
|
65
|
-
{race: '1002-5', ethnicity: '2186-5'}
|
66
|
-
when 11..58
|
67
|
-
# asian
|
68
|
-
{race: '2028-9', ethnicity: '2186-5'}
|
69
|
-
when 59..184
|
70
|
-
# black
|
71
|
-
{race: '2054-5', ethnicity: '2186-5'}
|
72
|
-
when 185..347
|
73
|
-
# hispanic
|
74
|
-
{race: '2106-3', ethnicity: '2135-2'}
|
75
|
-
when 348..984
|
76
|
-
# white (not hispanic)
|
77
|
-
{race: '2106-3', ethnicity: '2186-5'}
|
78
|
-
when 985..999
|
79
|
-
# other
|
80
|
-
{race: '2131-1', ethnicity: '2186-5'}
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
# Picks spoken language based on 2010 census estamates
|
85
|
-
# 80.3% english
|
86
|
-
# 12.3% spanish
|
87
|
-
# 00.9% chinese
|
88
|
-
# 00.7% french
|
89
|
-
# 00.4% german
|
90
|
-
# 00.4% korean
|
91
|
-
# 00.4% vietnamese
|
92
|
-
# 00.3% italian
|
93
|
-
# 00.3% portuguese
|
94
|
-
# 00.3% russian
|
95
|
-
# 00.2% japanese
|
96
|
-
# 00.2% polish
|
97
|
-
# 00.1% greek
|
98
|
-
# 00.1% persian
|
99
|
-
# 00.1% us sign
|
100
|
-
# 03.0% other
|
101
|
-
#
|
102
|
-
def language
|
103
|
-
language_percent = rand(999)
|
104
|
-
case language_percent
|
105
|
-
when 0..802
|
106
|
-
# english
|
107
|
-
'en-US'
|
108
|
-
when 802..925
|
109
|
-
# spanish
|
110
|
-
'es-US'
|
111
|
-
when 926..932
|
112
|
-
# french
|
113
|
-
'fr-US'
|
114
|
-
when 933..935
|
115
|
-
# italian
|
116
|
-
'it-US'
|
117
|
-
when 936..938
|
118
|
-
# portuguese
|
119
|
-
'pt-US'
|
120
|
-
when 939..942
|
121
|
-
# german
|
122
|
-
'de-US'
|
123
|
-
when 943..943
|
124
|
-
# greek
|
125
|
-
'el-US'
|
126
|
-
when 944..946
|
127
|
-
# russian
|
128
|
-
'ru-US'
|
129
|
-
when 947..948
|
130
|
-
# polish
|
131
|
-
'pl-US'
|
132
|
-
when 949..949
|
133
|
-
# persian
|
134
|
-
'fa-US'
|
135
|
-
when 950..958
|
136
|
-
# chinese
|
137
|
-
'zh-US'
|
138
|
-
when 959..960
|
139
|
-
# japanese
|
140
|
-
'ja-US'
|
141
|
-
when 961..964
|
142
|
-
# korean
|
143
|
-
'ko-US'
|
144
|
-
when 965..968
|
145
|
-
# vietnamese
|
146
|
-
'vi-US'
|
147
|
-
when 969..969
|
148
|
-
# us sign
|
149
|
-
'sgn-US'
|
150
|
-
when 970..999
|
151
|
-
# other
|
152
|
-
other = ["aa","ab","ae","af","ak","am","an","ar","as","av","ay","az","ba","be","bg","bh","bi","bm","bn","bo","br","bs","ca","ce","ch","co","cr","cs","cu","cv","cy","da",
|
153
|
-
"dv","dz","ee","eo","et","eu","ff","fi","fj","fo","fy","ga","gd","gl","gn","gu","gv","ha","he","hi","ho","hr","ht","hu","hy","hz","ia","id","ie","ig","ii","ik",
|
154
|
-
"io","is","iu","jv","ka","kg","ki","kj","kk","kl","km","kn","kr","ks","ku","kv","kw","ky","la","lb","lg","li","ln","lo","lt","lu","lv","mg","mh","mi","mk","ml",
|
155
|
-
"mn","mr","ms","mt","my","na","nb","nd","ne","ng","nl","nn","no","nr","nv","ny","oc","oj","om","or","os","pa","pi","ps","qu","rm","rn","ro","rw","sa","sc","sd",
|
156
|
-
"se","sg","si","sk","sl","sm","sn","so","sq","sr","ss","st","su","sv","sw","ta","te","tg","th","ti","tk","tl","tn","to","tr","ts","tt","tw","ty","ug","uk","ur",
|
157
|
-
"uz","ve","vo","wa","wo","xh","yi","yo","za","zu"].sample
|
158
|
-
"#{other}-US"
|
159
|
-
end
|
160
|
-
end
|
161
|
-
|
162
|
-
# Pick a forename at random appropriate for the supplied gender
|
163
|
-
# @param [String] gender the gender 'M' or 'F'
|
164
|
-
# @return a suitable forename
|
165
|
-
def forename(gender)
|
166
|
-
@forenames[gender][rand(@forenames[gender].length)]
|
167
|
-
end
|
168
|
-
|
169
|
-
# Pick a surname at random
|
170
|
-
# @return a surname
|
171
|
-
def surname
|
172
|
-
@surnames[rand(@surnames.length)]
|
173
|
-
end
|
174
|
-
|
175
|
-
# Create an address at random
|
176
|
-
# @return an address hash
|
177
|
-
def address
|
178
|
-
zip = @zipcodes.keys[rand(@zipcodes.length)]
|
179
|
-
{
|
180
|
-
'street' => [
|
181
|
-
"#{rand(100)} #{@streetnames[rand(@streetnames.length)]} Street"
|
182
|
-
],
|
183
|
-
'city' => @zipcodes[zip]['city'],
|
184
|
-
'state' => @zipcodes[zip]['state'],
|
185
|
-
'postalCode' => zip
|
186
|
-
}.to_json
|
187
|
-
end
|
188
|
-
|
189
|
-
# Pick a patient id, which will be a 10 character string, limited to numeric
|
190
|
-
# values for the string
|
191
|
-
def patient_id
|
192
|
-
(0...10).map{ ('0'..'9').to_a[rand(10)] }.join.to_s
|
193
|
-
end
|
194
|
-
|
195
|
-
# Return a set of randomly selected numbers between two bounds
|
196
|
-
# @param [int] min the lower inclusive bound
|
197
|
-
# @param [int] max the upper inclusive bound
|
198
|
-
# @param [int] least the minimum count to return
|
199
|
-
# @param [int] most the maximum count to return
|
200
|
-
# @return [String] a JSON format array of numbers
|
201
|
-
def n_between(min, max, least=1, most=1)
|
202
|
-
count = least+rand(1+most-least).to_i
|
203
|
-
result = []
|
204
|
-
count.times do
|
205
|
-
result << between(min, max)
|
206
|
-
end
|
207
|
-
result.to_json
|
208
|
-
end
|
209
|
-
|
210
|
-
# Return a randomly selected number between two bounds
|
211
|
-
# @param [int] min the lower inclusive bound
|
212
|
-
# @param [int] max the upper inclusive bound
|
213
|
-
# @return [int] a JSON format array of numbers
|
214
|
-
def between(min, max)
|
215
|
-
span = max.to_i - min.to_i + 1
|
216
|
-
min.to_i+rand(span)
|
217
|
-
end
|
218
|
-
|
219
|
-
# Pick true or false according to the supplied probability
|
220
|
-
# @param [int] probability the probability of getting true as a percentage
|
221
|
-
# @return [boolean] true or false
|
222
|
-
def percent(probability)
|
223
|
-
return rand(100)<probability
|
224
|
-
end
|
225
|
-
|
226
|
-
# Get a binding that for the current instance
|
227
|
-
# @return [Binding]
|
228
|
-
def get_binding
|
229
|
-
binding
|
230
|
-
end
|
231
|
-
end
|
232
|
-
|
233
|
-
# Create a new instance with the supplied template
|
234
|
-
# @param [String] patient the patient template
|
235
|
-
def initialize(patient)
|
236
|
-
@template = ERB.new(patient)
|
237
|
-
end
|
238
|
-
|
239
|
-
# Get a randomized record based on the stored template
|
240
|
-
# @return [String] a randomized patient
|
241
|
-
def get
|
242
|
-
context = Context.new()
|
243
|
-
@template.result(context.get_binding)
|
244
|
-
end
|
245
|
-
|
246
|
-
end
|
247
|
-
|
248
|
-
end
|
249
|
-
|
250
|
-
end
|
@@ -1,47 +0,0 @@
|
|
1
|
-
module QME
|
2
|
-
module Randomizer
|
3
|
-
class RandomPatientCreator
|
4
|
-
|
5
|
-
# Parses a patient hash containing demographic and event information
|
6
|
-
#
|
7
|
-
# @param [Hash] patient_hash patient data
|
8
|
-
# @return [Record] a representation of the patient that can be inserted into MongoDB
|
9
|
-
def self.parse_hash(patient_hash)
|
10
|
-
patient_record = Record.new
|
11
|
-
patient_record.first = patient_hash['first']
|
12
|
-
patient_record.last = patient_hash['last']
|
13
|
-
patient_record.gender = patient_hash['gender']
|
14
|
-
patient_record.medical_record_number = patient_hash['medical_record_number']
|
15
|
-
patient_record.birthdate = patient_hash['birthdate']
|
16
|
-
patient_record.race = patient_hash['race']
|
17
|
-
patient_record.ethnicity = patient_hash['ethnicity']
|
18
|
-
# pophealth needs languages... please do not remove
|
19
|
-
patient_record.languages = patient_hash['languages']
|
20
|
-
#patient_record['addresses'] = patient_hash['addresses']
|
21
|
-
patient_hash['events'].each do |key, value|
|
22
|
-
patient_record.send("#{key}=".to_sym, parse_events(value))
|
23
|
-
end
|
24
|
-
patient_record['measures'] = QME::Importer::MeasurePropertiesGenerator.instance.generate_properties(patient_record)
|
25
|
-
|
26
|
-
patient_record
|
27
|
-
end
|
28
|
-
|
29
|
-
# Parses a list of event hashes into an array of Entry objects
|
30
|
-
#
|
31
|
-
# @param [Array] event_list list of event hashes
|
32
|
-
# @return [Array] array of Entry objects
|
33
|
-
def self.parse_events(event_list)
|
34
|
-
event_list.collect do |event|
|
35
|
-
if event.class==String.class
|
36
|
-
# skip String elements in the event list, patient randomization templates
|
37
|
-
# introduce String elements to simplify tailing-comma handling when generating
|
38
|
-
# JSON using ERb
|
39
|
-
nil
|
40
|
-
else
|
41
|
-
Entry.from_event_hash(event)
|
42
|
-
end
|
43
|
-
end.compact
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
data/lib/qme_test.rb
DELETED
@@ -1,13 +0,0 @@
|
|
1
|
-
require 'rspec/core/rake_task'
|
2
|
-
Dir[File.join(File.dirname(__FILE__),'tasks/*.rake')].sort.each do |ext|
|
3
|
-
load ext
|
4
|
-
end
|
5
|
-
|
6
|
-
RSpec::Core::RakeTask.new do |t|
|
7
|
-
t.rspec_opts = ["-c", "-f progress", "-r #{File.join(File.dirname(__FILE__),'../spec/spec_helper.rb')}"]
|
8
|
-
t.pattern = "#{File.join(File.dirname(__FILE__),'../spec/**/*measures_spec.rb')}"
|
9
|
-
end
|
10
|
-
|
11
|
-
RSpec::Core::RakeTask.new do |t|
|
12
|
-
t.rspec_opts = ["-c", "-f progress", "-r #{File.join(File.dirname(__FILE__),'../spec/spec_helper.rb')}"]
|
13
|
-
end
|
data/lib/tasks/fixtures.rake
DELETED
@@ -1,91 +0,0 @@
|
|
1
|
-
require 'json'
|
2
|
-
require 'erb'
|
3
|
-
|
4
|
-
fixtures_dir = ENV['FIXTURE_DIR'] || File.join('fixtures', 'measures')
|
5
|
-
output_dir = ENV['HTML_OUTPUT_DIR'] || File.join('tmp', 'html')
|
6
|
-
|
7
|
-
def epoch_pp(seconds_since_epoch)
|
8
|
-
if seconds_since_epoch.kind_of? Fixnum
|
9
|
-
Time.at(seconds_since_epoch).utc.strftime('%B %d, %Y')
|
10
|
-
else
|
11
|
-
seconds_since_epoch
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
def extract_dates(thingy, dates)
|
16
|
-
if thingy.kind_of? Fixnum
|
17
|
-
dates[thingy] = epoch_pp(thingy)
|
18
|
-
elsif thingy.kind_of? Array
|
19
|
-
thingy.each {|inner_thingy| extract_dates(inner_thingy, dates)}
|
20
|
-
elsif thingy.kind_of? Hash
|
21
|
-
thingy.values.each {|inner_thingy| extract_dates(inner_thingy, dates)}
|
22
|
-
else
|
23
|
-
# Must be a string
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
namespace :fixtures do
|
28
|
-
|
29
|
-
# NOTE: This will create invalid JSON fixture files, since JSON does not have the ability add comments.
|
30
|
-
# However, most JSON parsers handle this just fine.
|
31
|
-
desc 'Place a comment header at the top of each fixture file with a table of seconds since epoch to month, day, year'
|
32
|
-
task :time_comments do
|
33
|
-
Dir.glob(File.join(fixtures_dir,'*','patients','*.json')) do |file|
|
34
|
-
fixture_person = JSON.parse(File.read(file))
|
35
|
-
dates = {}
|
36
|
-
extract_dates(fixture_person, dates)
|
37
|
-
|
38
|
-
fixture = File.open(file, 'w')
|
39
|
-
fixture.write("//\n// Dates used in this fixture\n//\n")
|
40
|
-
dates.each_pair do |key, value|
|
41
|
-
fixture.write("// #{key} - #{value}\n")
|
42
|
-
end
|
43
|
-
fixture.write(JSON.pretty_generate(fixture_person))
|
44
|
-
fixture.close
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
desc 'Generate HTML versions of the patient fixtures'
|
49
|
-
task :html_doc do
|
50
|
-
patient_template = File.read(File.join(File.dirname(__FILE__), 'patient_fixture.erb'))
|
51
|
-
patient_erb = ERB.new(patient_template)
|
52
|
-
|
53
|
-
result_template = File.read(File.join(File.dirname(__FILE__), 'result.erb'))
|
54
|
-
result_erb = ERB.new(result_template)
|
55
|
-
|
56
|
-
fixtures_path = Pathname.new(fixtures_dir)
|
57
|
-
output_path = Pathname.new(output_dir)
|
58
|
-
|
59
|
-
Dir.glob(File.join(fixtures_dir,'*','patients','*.json')) do |file|
|
60
|
-
@patient = JSON.parse(File.read(file))
|
61
|
-
@filename = file
|
62
|
-
html = patient_erb.result(binding)
|
63
|
-
|
64
|
-
fixture_path = Pathname.new(file)
|
65
|
-
relative_fixture_path = fixture_path.relative_path_from(fixtures_path)
|
66
|
-
measure_output_path = output_path + relative_fixture_path
|
67
|
-
FileUtils.mkdir_p(measure_output_path.dirname)
|
68
|
-
File.open(measure_output_path.sub_ext('.html'), 'w') do |html_out|
|
69
|
-
html_out.write(html)
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
Dir.glob(File.join(fixtures_dir,'*','result.json')) do |file|
|
74
|
-
result_json = JSON.parse(File.read(file))
|
75
|
-
if result_json["results"]
|
76
|
-
@results = result_json["results"]
|
77
|
-
else
|
78
|
-
@results = [result_json]
|
79
|
-
end
|
80
|
-
html = result_erb.result(binding)
|
81
|
-
|
82
|
-
result_path = Pathname.new(file)
|
83
|
-
relative_result_path = result_path.relative_path_from(fixtures_path)
|
84
|
-
result_output_path = output_path + relative_result_path
|
85
|
-
|
86
|
-
File.open(result_output_path.sub_ext('.html'), 'w') do |html_out|
|
87
|
-
html_out.write(html)
|
88
|
-
end
|
89
|
-
end
|
90
|
-
end
|
91
|
-
end
|