hqmf2js 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. data/.gitignore +10 -0
  2. data/.travis.yml +17 -0
  3. data/Gemfile +41 -0
  4. data/Gemfile.lock +202 -0
  5. data/README.md +7 -0
  6. data/Rakefile +22 -0
  7. data/VERSION +1 -0
  8. data/app/assets/javascripts/hqmf_util.js.coffee +776 -0
  9. data/app/assets/javascripts/logging_utils.js.coffee +150 -0
  10. data/app/assets/javascripts/patient_api_extension.js.coffee +36 -0
  11. data/app/assets/javascripts/specifics.js.coffee +462 -0
  12. data/bin/hqmf2js.rb +25 -0
  13. data/config/warble.rb +144 -0
  14. data/hqmf2js.gemspec +20 -0
  15. data/lib/config/codes.xml +1935 -0
  16. data/lib/generator/characteristic.js.erb +19 -0
  17. data/lib/generator/codes_to_json.rb +81 -0
  18. data/lib/generator/converter.rb +60 -0
  19. data/lib/generator/data_criteria.js.erb +47 -0
  20. data/lib/generator/derived_data.js.erb +5 -0
  21. data/lib/generator/js.rb +263 -0
  22. data/lib/generator/measure_period.js.erb +18 -0
  23. data/lib/generator/patient_data.js.erb +22 -0
  24. data/lib/generator/population_criteria.js.erb +4 -0
  25. data/lib/generator/precondition.js.erb +14 -0
  26. data/lib/hqmf2js.rb +20 -0
  27. data/lib/hquery/engine.rb +4 -0
  28. data/lib/tasks/codes.rake +12 -0
  29. data/lib/tasks/coffee.rake +15 -0
  30. data/lib/tasks/convert.rake +47 -0
  31. data/lib/tasks/cover_me.rake +8 -0
  32. data/test/fixtures/NQF59New.xml +1047 -0
  33. data/test/fixtures/codes/codes.xls +0 -0
  34. data/test/fixtures/codes/codes.xml +1941 -0
  35. data/test/fixtures/i2b2.xml +305 -0
  36. data/test/fixtures/invalid/missing_id.xml +18 -0
  37. data/test/fixtures/invalid/unknown_criteria_type.xml +16 -0
  38. data/test/fixtures/invalid/unknown_demographic_entry.xml +16 -0
  39. data/test/fixtures/invalid/unknown_population_type.xml +9 -0
  40. data/test/fixtures/invalid/unknown_value_type.xml +18 -0
  41. data/test/fixtures/js/59New.js +366 -0
  42. data/test/fixtures/js/test1.js +356 -0
  43. data/test/fixtures/js/test2.js +366 -0
  44. data/test/fixtures/json/0043.json +6 -0
  45. data/test/fixtures/json/0043_hqmf1.json +1 -0
  46. data/test/fixtures/json/0043_hqmf2.json +172 -0
  47. data/test/fixtures/json/59New.json +1352 -0
  48. data/test/fixtures/patient_api.js +2823 -0
  49. data/test/fixtures/patients/francis_drake.json +1180 -0
  50. data/test/fixtures/patients/larry_vanderman.json +645 -0
  51. data/test/test_helper.rb +58 -0
  52. data/test/unit/codes_to_json_test.rb +38 -0
  53. data/test/unit/effective_date_test.rb +48 -0
  54. data/test/unit/hqmf_from_json_javascript_test.rb +108 -0
  55. data/test/unit/hqmf_javascript_test.rb +175 -0
  56. data/test/unit/library_function_test.rb +553 -0
  57. data/test/unit/specifics_test.rb +757 -0
  58. metadata +183 -0
@@ -0,0 +1,356 @@
1
+ var OidDictionary = {'2.16.840.1.113883.3.464.1.14':{'HL7':['00110']},'2.16.840.1.113883.3.464.1.37':{'ICD-10-CM':['E10.36','E11.36','E11.9','E13.31','E13.32','E13.33','E13.34','E13.35','E13.43','O24.42'],'ICD-9-CM':['250','250','250','250.1','250.2','250.3','250.10','250.11','250.12','250.13','250.20','250.21','250.22','250.23','250.30','250.31','250.32','250.33','250.4','250.40','250.41','250.42','250.43','250.50','250.51','250.52','250.53','250.60','250.61','250.62','250.63','250.7','250.70','250.71','250.72','250.73','250.8','250.80','250.81','250.82','250.83','250.9','250.90','250.91','250.92','250.93','357.2','362','362.1','362.2','362.3','362.4','362.5','362.6','362.7','366.41','648','648','648.1','648.2','648.3','648.4'],'SNOMED-CT':['111552007','111558006','11530004','123763000','127013003','127014009','190321005','190328004','190330002','190331003','190336008','190353001','190361006','190368000','190369008','190371008','190372001','190383005','190389009','190390000','190392008','190406000','190407009','190410002','190411003','190412005','190416001','190417004','190418009','190419001','190422004','193184006','197605007','198609003','199223000','199227004','199229001','199230006','199231005','199234002','201250006','201251005','201252003','23045005','230572002','230577008','237599002','237600004','237601000','237604008','237613005','237618001','237619009','237627000','25907005','26298008','267379000','267380002','2751001','275918005','28032008','28453007','290002008','309426007','310387003','311366001','312912001','313435000','313436004','314537004','314771006','314772004','314893005','314902007','314903002','33559001','34140002','359611005','359638003','359642000','360546002','371087003','38542009','39058009','39181008','408539000','408540003','413183008','414890007','414906009','420414003','420422005','421750000','421847006','421895002','422183001','422228004','422275004','423263001','424736006','424989000','425159004','425442003','426705001','426875007','427089005','428896009','42954008','44054006','4627003','46635009','50620007','51002006','5368009','54181000','57886004','59079001','5969009','70694009','73211009','74263009','75524006','75682002','76751001','81531005','81830002','8801005','91352004','9859006']},'2.16.840.1.113883.3.464.1.38':{'ICD-10-CM':['E10.36','E11.36','E11.9','E13.31','E13.32','E13.33','E13.34','E13.35','E13.43','O24.42']},'2.16.840.1.113883.3.464.1.39':{'ICD-9-CM':['250','250','250','250.1','250.2','250.3','250.10','250.11','250.12','250.13','250.20','250.21','250.22','250.23','250.30','250.31','250.32','250.33','250.4','250.40','250.41','250.42','250.43','250.50','250.51','250.52','250.53','250.60','250.61','250.62','250.63','250.7','250.70','250.71','250.72','250.73','250.8','250.80','250.81','250.82','250.83','250.9','250.90','250.91','250.92','250.93','357.2','362','362.1','362.2','362.3','362.4','362.5','362.6','362.7','366.41','648','648','648.1','648.2','648.3','648.4']},'2.16.840.1.113883.3.464.1.40':{'SNOMED-CT':['111552007','111558006','11530004','123763000','127013003','127014009','190321005','190328004','190330002','190331003','190336008','190353001','190361006','190368000','190369008','190371008','190372001','190383005','190389009','190390000','190392008','190406000','190407009','190410002','190411003','190412005','190416001','190417004','190418009','190419001','190422004','193184006','197605007','198609003','199223000','199227004','199229001','199230006','199231005','199234002','201250006','201251005','201252003','23045005','230572002','230577008','237599002','237600004','237601000','237604008','237613005','237618001','237619009','237627000','25907005','26298008','267379000','267380002','2751001','275918005','28032008','28453007','290002008','309426007','310387003','311366001','312912001','313435000','313436004','314537004','314771006','314772004','314893005','314902007','314903002','33559001','34140002','359611005','359638003','359642000','360546002','371087003','38542009','39058009','39181008','408539000','408540003','413183008','414890007','414906009','420414003','420422005','421750000','421847006','421895002','422183001','422228004','422275004','423263001','424736006','424989000','425159004','425442003','426705001','426875007','427089005','428896009','42954008','44054006','4627003','46635009','50620007','51002006','5368009','54181000','57886004','59079001','5969009','70694009','73211009','74263009','75524006','75682002','76751001','81531005','81830002','8801005','91352004','9859006']},'2.16.840.1.113883.3.464.1.42':{'CPT':['99221','99222','99223','99231','99232','99233','99238','99239','99251','99252','99253','99254','99255','99291','99281','99282','99283','99284','99285']},'2.16.840.1.113883.3.464.1.43':{'CPT':['99221','99222','99223','99231','99232','99233','99238','99239','99251','99252','99253','99254','99255','99291']},'2.16.840.1.113883.3.464.1.45':{'CPT':['99281','99282','99283','99284','99285']},'2.16.840.1.113883.3.464.1.46':{'CPT':['99304','99305','99306','99307','99308','99309','99310','99315','99316','99318','99324','99325','99326','99327','99328','99334','99335','99336','99337']},'2.16.840.1.113883.3.464.3.1142':{'CPT':['99201','99202','99203','99204','99205','99211','99212','99213','99214','99215','99217','99218','99219','99220','99241','99242','99243','99244','99245','99341','99342','99343','99344','99345','99347','99348','99349','99350','99384','99385','99386','99387','99394','99395','99396','99397','99401','99402','99403','99404','99411','99412','99420','99429','99455','99456'],'ICD-9-CM':['V70.','V70.3','V70.5','V70.6','V70.8','V70.9']},'2.16.840.1.113883.3.464.1.48':{'CPT':['99201','99202','99203','99204','99205','99211','99212','99213','99214','99215','99217','99218','99219','99220','99241','99242','99243','99244','99245','99341','99342','99343','99344','99345','99347-99350','99384','99385','99386','99387','99394','99395','99396','99397','99401','99402','99403','99404','99411','99412','99420','99429','99455','99456']},'2.16.840.1.113883.3.464.1.50':{'ICD-9-CM':['V70.','V70.3','V70.5','V70.6','V70.8','V70.9']},'2.16.840.1.113883.3.464.1.67':{'ICD-10-CM':['R73.2','R73.9'],'ICD-9-CM':['648.8','648.80','648.81','648.82','648.83','648.84'],'SNOMED-CT':['11687002','420491007','420738003','420989005','421223006','421389009','421443003','422155003','46894009','71546005','75022004']},'2.16.840.1.113883.3.464.1.72':{'CPT':['83036','83037'],'LOINC':['17856-6','4548-4','4549-2'],'SNOMED-CT':['117346004','165680008','259689004','259690008','313835008','33601001','40402000','408254005','43396009']},'2.16.840.1.113883.3.464.1.94':{'RxNorm':['199149','199150','200132','205329','205330','205331','401938','200256','200257','200258','311919','314142','389139','861035','861039','861042','861044','861787','861790','665033','665038','665042','744863','847910','847915','861769','861819','602544','602549','602550','647237','647239','706895','706896','861731','861736','861740','861743','861748','861753','861760','861763','861769','861783','861787','861790','861795','861806','861816','861819','861822','665033','665038','665042','860975','860978','860981','860984','860996','860999','861004','861007','861010','861021','861025','861731','861736','861740','861743','861748','861753','861760','861763','861769','861783','861787','861790','861795','861806','861816','861819','861822','105374','153842','197306','197307','197495','197496','197737','198291','198292','198293','198294','199245','199246','199247','199825','199984','199985','200065','252960','310488','310489','310490','310534','310536','310537','310539','312440','312441','312859','312860','312861','313418','313419','314000','314006','315107','315239','317573','379804','389137','602544','602549','602550','647237','647239','706895','706896','757710','757712','844809','844824','844827','861731','861736','861740','861743','861748','861753','861760','861763','861783','861795','861806','861816','861822','312440','312441','312859','312860','312861','317573','205314','237527','242120','242916','242917','259111','260265','283394','311040','311041','311053','311054','311055','311056','311057','311058','311059','311060','311061','314038','317800','351297','358349','484322','485210','544614','763002','763007','763013','763014','833159','847191','847207','847211','847230','847239','847252','847259','847263','847416','200256','200257','200258','311919','314142','389139']},'2.16.840.1.113883.3.464.1.98':{'ICD-10-CM':['E28.2'],'ICD-9-CM':['256.4'],'SNOMED-CT':['69878008']},'2.16.840.1.113883.3.464.1.113':{'ICD-10-CM':['E08','E10','T38'],'ICD-9-CM':['249','249','249','249.1','249.1','249.10','249.11','249.2','249.20','249.21','249.3','249.30','249.31','249.4','249.40','249.41','249.5','249.50','249.51','249.6','249.60','249.61','249.7','249.70','249.71','249.8','249.80','249.81','249.9','249.90','249.91','251.8','962'],'SNOMED-CT':['190416008','190447002','53126001']}};var CD, IVL, PQ, PREVSUM, RECENT, TS, allTrue, atLeastOneTrue, filterEventsByValue, getCodes, matchingValue,
2
+ __slice = Array.prototype.slice;
3
+
4
+ TS = (function() {
5
+
6
+ function TS(hl7ts) {
7
+ var day, month, year;
8
+ year = parseInt(hl7ts.substring(0, 4));
9
+ month = parseInt(hl7ts.substring(4, 6), 10) - 1;
10
+ day = parseInt(hl7ts.substring(6, 8), 10);
11
+ this.date = new Date(year, month, day);
12
+ }
13
+
14
+ TS.prototype.add = function(pq) {
15
+ if (pq.unit === "a") {
16
+ this.date.setFullYear(this.date.getFullYear() + pq.value);
17
+ } else if (pq.unit === "mo") {
18
+ this.date.setMonth(this.date.getMonth() + pq.value);
19
+ } else if (pq.unit === "d") {
20
+ this.date.setDate(this.date.getDate() + pq.value);
21
+ } else if (pq.unit === "h") {
22
+ this.date.setHours(this.date.getHours() + pq.value);
23
+ } else if (pq.unit === "min") {
24
+ this.date.setMinutes(this.date.getMinutes() + pq.value);
25
+ } else {
26
+ throw "Unknown time unit: " + pq.unit;
27
+ }
28
+ return this;
29
+ };
30
+
31
+ TS.prototype.asDate = function() {
32
+ return this.date;
33
+ };
34
+
35
+ return TS;
36
+
37
+ })();
38
+
39
+ CD = (function() {
40
+
41
+ function CD(code) {
42
+ this.code = code;
43
+ }
44
+
45
+ CD.prototype.code = function() {
46
+ return this.code;
47
+ };
48
+
49
+ CD.prototype.match = function(val) {
50
+ return this.code === val;
51
+ };
52
+
53
+ return CD;
54
+
55
+ })();
56
+
57
+ PQ = (function() {
58
+
59
+ function PQ(value, unit) {
60
+ this.value = value;
61
+ this.unit = unit;
62
+ }
63
+
64
+ PQ.prototype.unit = function() {
65
+ return this.unit;
66
+ };
67
+
68
+ PQ.prototype.value = function() {
69
+ return this.value;
70
+ };
71
+
72
+ PQ.prototype.lessThan = function(val) {
73
+ return this.value < val;
74
+ };
75
+
76
+ PQ.prototype.greaterThan = function(val) {
77
+ return this.value > val;
78
+ };
79
+
80
+ PQ.prototype.match = function(val) {
81
+ return this.value === val;
82
+ };
83
+
84
+ return PQ;
85
+
86
+ })();
87
+
88
+ IVL = (function() {
89
+
90
+ function IVL(low_pq, high_pq) {
91
+ this.low_pq = low_pq;
92
+ this.high_pq = high_pq;
93
+ }
94
+
95
+ IVL.prototype.match = function(val) {
96
+ return (!(this.low_pq != null) || ((this.low_pq != null) && this.low_pq.lessThan(val))) && (!(this.high_pq != null) || ((this.high_pq != null) && this.high_pq.greaterThan(val)));
97
+ };
98
+
99
+ return IVL;
100
+
101
+ })();
102
+
103
+ atLeastOneTrue = function() {
104
+ var trueValues, value, values;
105
+ values = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
106
+ trueValues = (function() {
107
+ var _i, _len, _results;
108
+ _results = [];
109
+ for (_i = 0, _len = values.length; _i < _len; _i++) {
110
+ value = values[_i];
111
+ if (value && (value === true || value.length !== 0)) _results.push(value);
112
+ }
113
+ return _results;
114
+ })();
115
+ return trueValues.length > 0;
116
+ };
117
+
118
+ allTrue = function() {
119
+ var trueValues, value, values;
120
+ values = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
121
+ trueValues = (function() {
122
+ var _i, _len, _results;
123
+ _results = [];
124
+ for (_i = 0, _len = values.length; _i < _len; _i++) {
125
+ value = values[_i];
126
+ if (value && (value === true || value.length !== 0)) _results.push(value);
127
+ }
128
+ return _results;
129
+ })();
130
+ return trueValues.length > 0 && trueValues.length === values.length;
131
+ };
132
+
133
+ matchingValue = function(value, compareTo) {
134
+ return compareTo.match(value);
135
+ };
136
+
137
+ filterEventsByValue = function(events, value) {
138
+ var event, matchingValues;
139
+ matchingValues = (function() {
140
+ var _i, _len, _results;
141
+ _results = [];
142
+ for (_i = 0, _len = events.length; _i < _len; _i++) {
143
+ event = events[_i];
144
+ if (event.value && value.match(event.value().scalar)) _results.push(event);
145
+ }
146
+ return _results;
147
+ })();
148
+ return matchingValues;
149
+ };
150
+
151
+ getCodes = function(oid) {
152
+ return OidDictionary[oid];
153
+ };
154
+
155
+ PREVSUM = function(eventList) {
156
+ return eventList;
157
+ };
158
+
159
+ RECENT = function(events) {
160
+ var dateSortDescending;
161
+ dateSortDescending = function(a, b) {
162
+ return b.json.time - a.json.time;
163
+ };
164
+ return events.sort(dateSortDescending)[0];
165
+ };
166
+ // Measure variables
167
+ var MeasurePeriod = {
168
+ "low": new TS("20110101"),
169
+ "high": new TS("20111231"),
170
+ "width": new PQ(1, "a")
171
+ };
172
+ var StartDate = new TS("20100101");
173
+ var EndDate = new TS("20101231");
174
+
175
+ // Data critera
176
+ var ageBetween17and64 = function(patient) {
177
+ var value = patient.age(EndDate.asDate());
178
+ return matchingValue(value, new IVL(new PQ(17, "a"), new PQ(64, "a")));
179
+ }
180
+
181
+ var ageBetween17and21 = function(patient) {
182
+ var value = patient.age(EndDate.asDate());
183
+ return matchingValue(value, new IVL(new PQ(17, "a"), new PQ(21, "a")));
184
+ }
185
+
186
+ var ageBetween22and29 = function(patient) {
187
+ var value = patient.age(EndDate.asDate());
188
+ return matchingValue(value, new IVL(new PQ(22, "a"), new PQ(29, "a")));
189
+ }
190
+
191
+ var ageBetween30and39 = function(patient) {
192
+ var value = patient.age(EndDate.asDate());
193
+ return matchingValue(value, new IVL(new PQ(30, "a"), new PQ(39, "a")));
194
+ }
195
+
196
+ var ageBetween40and49 = function(patient) {
197
+ var value = patient.age(EndDate.asDate());
198
+ return matchingValue(value, new IVL(new PQ(40, "a"), new PQ(49, "a")));
199
+ }
200
+
201
+ var ageBetween50and59 = function(patient) {
202
+ var value = patient.age(EndDate.asDate());
203
+ return matchingValue(value, new IVL(new PQ(50, "a"), new PQ(59, "a")));
204
+ }
205
+
206
+ var ageBetween60and64 = function(patient) {
207
+ var value = patient.age(new TS("20100101").asDate());
208
+ return matchingValue(value, new IVL(new PQ(60, "a"), new PQ(64, "a")));
209
+ }
210
+
211
+ var genderMale = function(patient) {
212
+ var value = patient.gender();
213
+ return matchingValue(value, new CD("M"));
214
+ }
215
+
216
+ var genderFemale = function(patient) {
217
+ var value = patient.gender();
218
+ return matchingValue(value, new CD("F"));
219
+ }
220
+
221
+ var EDorInpatientEncounter = function(patient) {
222
+ var codes = getCodes("2.16.840.1.113883.3.464.1.42");
223
+ var start = null;
224
+ var end = EndDate.add(new PQ(-2,"a")).asDate();
225
+ var events = patient.encounters().match(codes, start, end);
226
+ return events;
227
+ }
228
+
229
+ var AmbulatoryEncounter = function(patient) {
230
+ var codes = getCodes("2.16.840.1.113883.3.464.1.1142");
231
+ var start = null;
232
+ var end = EndDate.add(new PQ(-2,"a")).asDate();
233
+ var events = patient.encounters().match(codes, start, end);
234
+ events = PREVSUM(events);
235
+ return events;
236
+ }
237
+
238
+ var DummyProcedure = function(patient) {
239
+ var codes = {"SNOMED-CT":["127355002"]};
240
+ var start = new TS("20100101").asDate();
241
+ var end = new TS("20111231").asDate();
242
+ var events = patient.procedures().match(codes, start, end);
243
+ return events;
244
+ }
245
+
246
+ var HasDiabetes = function(patient) {
247
+ var codes = getCodes("2.16.840.1.113883.3.464.1.37");
248
+ var events = patient.conditions().match(codes);
249
+ return events;
250
+ }
251
+
252
+ var HasGestationalDiabetes = function(patient) {
253
+ var codes = getCodes("2.16.840.1.113883.3.464.1.67");
254
+ var start = StartDate.asDate();
255
+ var end = EndDate.asDate();
256
+ var events = patient.conditions().match(codes, start, end);
257
+ return events;
258
+ }
259
+
260
+ var HasPolycysticOvaries = function(patient) {
261
+ var codes = getCodes("2.16.840.1.113883.3.464.1.98");
262
+ var start = StartDate.add(new PQ(-1,"a")).asDate();
263
+ var end = EndDate.asDate();
264
+ var events = patient.conditions().match(codes, start, end);
265
+ return events;
266
+ }
267
+
268
+ var HasSteroidInducedDiabetes = function(patient) {
269
+ var codes = getCodes("2.16.840.1.113883.3.464.1.113");
270
+ var start = StartDate.asDate();
271
+ var end = EndDate.asDate();
272
+ var events = patient.conditions().match(codes, start, end);
273
+ return events;
274
+ }
275
+
276
+ var HbA1C = function(patient) {
277
+ var codes = getCodes("2.16.840.1.113883.3.464.1.72");
278
+ var events = patient.results().match(codes);
279
+ events = filterEventsByValue(events, new IVL(new PQ(9, "%"), null));
280
+ events = RECENT(events);
281
+ return events;
282
+ }
283
+
284
+ var DiabetesMedAdministered = function(patient) {
285
+ var codes = getCodes("2.16.840.1.113883.3.464.1.94");
286
+ var start = StartDate.add(new PQ(-2,"a")).asDate();
287
+ var end = null;
288
+ var events = patient.medications().match(codes, start, end);
289
+ return events;
290
+ }
291
+
292
+ var DiabetesMedIntended = function(patient) {
293
+ var codes = getCodes("2.16.840.1.113883.3.464.1.94");
294
+ var start = null;
295
+ var end = EndDate.add(new PQ(-2,"a")).asDate();
296
+ var events = patient.medications().match(codes, start, end);
297
+ return events;
298
+ }
299
+
300
+ var DiabetesMedSupplied = function(patient) {
301
+ var codes = getCodes("2.16.840.1.113883.3.464.1.94");
302
+ var start = null;
303
+ var end = EndDate.add(new PQ(-2,"a")).asDate();
304
+ var events = patient.medications().match(codes, start, end);
305
+ return events;
306
+ }
307
+
308
+ var DiabetesMedOrdered = function(patient) {
309
+ var codes = getCodes("2.16.840.1.113883.3.464.1.94");
310
+ var start = null;
311
+ var end = EndDate.add(new PQ(-2,"a")).asDate();
312
+ var events = patient.medications().match(codes, start, end);
313
+ return events;
314
+ }
315
+
316
+ var IPP = function(patient) {
317
+ return allTrue(
318
+ ageBetween17and64(patient)
319
+ );
320
+ };
321
+
322
+ var DENOM = function(patient) {
323
+ return allTrue(
324
+ atLeastOneTrue(
325
+ allTrue(
326
+ HasDiabetes(patient),
327
+ atLeastOneTrue(
328
+ EDorInpatientEncounter(patient),
329
+ AmbulatoryEncounter(patient)
330
+ )
331
+ ),
332
+ DiabetesMedAdministered(patient),
333
+ DiabetesMedIntended(patient),
334
+ DiabetesMedSupplied(patient),
335
+ DiabetesMedOrdered(patient)
336
+ )
337
+ );
338
+ };
339
+
340
+ var NUMER = function(patient) {
341
+ return allTrue(
342
+ HbA1C(patient)
343
+ );
344
+ };
345
+
346
+ var DENEXCEP = function(patient) {
347
+ return atLeastOneTrue(
348
+ allTrue(
349
+ HasPolycysticOvaries(patient),
350
+ HasDiabetes(patient)
351
+ ),
352
+ HasSteroidInducedDiabetes(patient),
353
+ HasGestationalDiabetes(patient)
354
+ );
355
+ };
356
+