Skip to content

Commit

Permalink
model enhancements
Browse files Browse the repository at this point in the history
  • Loading branch information
dehall committed Apr 24, 2024
1 parent d0e4371 commit 9ead61d
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 63 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,35 +6,67 @@

public class OphthalmicProgressionModule extends Module {

public OphthalmicProgressionModule() {
this.name = "OphthalmicProgression";
this.submoduleName = "OphthalmicProgression";
this.submodule = true; // make sure this doesn't run except when called
}

public Module clone() {
return this;
}
public OphthalmicProgressionModule() {
this.name = "OphthalmicProgression";
this.submoduleName = "OphthalmicProgression";
this.submodule = true; // make sure this doesn't run except when called
}

public Module clone() {
return this;
}

@Override
public boolean process(Person person, long time) {
public boolean process(Person person, long time) {

int drStage = (Integer) person.attributes.get("diabetic_retinopathy_stage");
boolean edema = (boolean) person.attributes.getOrDefault("macular_edema", false);

// set visual acuity in LogMAR

// some examples (ref: https://en.wikipedia.org/wiki/LogMAR_chart)
// Foot LogMAR
// 20/200 1.00
// 20/160 0.90
// 20/100 0.70
// 20/80 0.60
// 20/40 0.30
// 20/20 0.00
// 20/16 −0.10
person.attributes.put("visual_acuity_logmar", 0.0);


// Foot LogMAR
// 20/200 1.00
// 20/160 0.90
// 20/100 0.70
// 20/80 0.60
// 20/40 0.30
// 20/20 0.00
// 20/16 −0.10
if (edema) {
person.attributes.put("visual_acuity_logmar", 0.30);
} else {
person.attributes.put("visual_acuity_logmar", 0.0);
}

// set intraocular pressure in mmHG
person.attributes.put("intraocular_pressure", 16);


boolean highIop = (boolean) person.attributes.getOrDefault("high_iop", false);

// "Pressures of between 11 and 21 mmHg are considered normal"
// https://www.ncbi.nlm.nih.gov/books/NBK532237/
if (highIop || (drStage == 4 && person.rand() < 0.001)) {
// very small chance of this happening
person.attributes.getOrDefault("high_iop", true);

if (person.record.medicationActive("1923432") || person.record.medicationActive("861204")) {
// dorzolamide 20 MG/ML / timolol 5 MG/ML Ophthalmic Solution
// or
// brimonidine tartrate 1 MG/ML Ophthalmic Solution

// reduce the pressure to a normal range
person.attributes.put("intraocular_pressure", (int) person.rand(new int[] { 15, 18 }));
} else {
// not on pressure drops, give them a high (but not always > clinical threshold)
// iop
person.attributes.put("intraocular_pressure", (int) person.rand(new int[] { 18, 24 }));
}

} else {
// normal
person.attributes.put("intraocular_pressure", (int) person.rand(new int[] { 14, 18 }));
}

// set findings for OCT
Code noAbnormalFindings = new Code("LOINC", "LA28409-8", "No abnormal findings");
person.attributes.put("oct_findings_left", noAbnormalFindings);
Expand All @@ -49,21 +81,31 @@ public boolean process(Person person, long time) {
Schisis cysts 6 LA24889-0
Sub-RPE deposition 7 LA25503-6
*/


person.attributes.put("oct_center_point_thickness", 10);
person.attributes.put("oct_center_subfield_thickness", 10);
person.attributes.put("oct_inner_superior_subfield_thickness", 10);
person.attributes.put("oct_inner_nasal_subfield_thickness", 10);
person.attributes.put("oct_inner_inferior_subfield_thickness", 10);
person.attributes.put("oct_inner_temporal_subfield_thickness", 10);
person.attributes.put("oct_outer_superior_subfield_thickness", 10);
person.attributes.put("oct_outer_nasal_subfield_thickness", 10);
person.attributes.put("oct_outer_inferior_subfield_thickness", 10);
person.attributes.put("oct_outer_temporal_subfield_thickness", 10);
person.attributes.put("oct_total_volume", 10);



// https://iovs.arvojournals.org/article.aspx?articleid=2165526
Integer octOffset = (Integer) person.attributes.get("oct_offset");
if (octOffset == null) {
octOffset = (int) person.rand(-10, 10);
if (person.attributes.get(Person.GENDER).equals("M")) {
// Central subfield thickness was significantly greater in males than that in
// females (P < 0.001, Table 2),
// with a mean of 278 ± 23 μm in males and 263 ± 22 μm in females.
octOffset += 10;
}

person.attributes.put("oct_center_point_thickness", 227 + octOffset);
person.attributes.put("oct_center_subfield_thickness", 270 + octOffset);
person.attributes.put("oct_inner_superior_subfield_thickness", 335 + octOffset);
person.attributes.put("oct_inner_nasal_subfield_thickness", 338 + octOffset);
person.attributes.put("oct_inner_inferior_subfield_thickness", 332 + octOffset);
person.attributes.put("oct_inner_temporal_subfield_thickness", 324 + octOffset);
person.attributes.put("oct_outer_superior_subfield_thickness", 290 + octOffset);
person.attributes.put("oct_outer_nasal_subfield_thickness", 305 + octOffset);
person.attributes.put("oct_outer_inferior_subfield_thickness", 280 + octOffset);
person.attributes.put("oct_outer_temporal_subfield_thickness", 279 + octOffset);
person.attributes.put("oct_total_volume", 8.4);
}

// note return options here, see State$CallSubmodule
// if we return true, the submodule completed and processing continues to the next state
// if we return false, the submodule did not complete (like with a Delay)
Expand Down
18 changes: 0 additions & 18 deletions src/main/resources/modules/eye/intraocular_pressure.json
Original file line number Diff line number Diff line change
Expand Up @@ -74,30 +74,12 @@
}
]
},
{
"condition": {
"condition_type": "Attribute",
"attribute": "eye_pressure_med",
"operator": "is not nil"
},
"distributions": [],
"transition": "End IOP Med"
},
{
"distributions": [],
"transition": "Terminal"
}
]
},
"End IOP Med": {
"type": "MedicationEnd",
"direct_transition": "Clear out med attribute"
},
"Clear out med attribute": {
"type": "SetAttribute",
"attribute": "eye_pressure_med",
"direct_transition": "Terminal"
},
"IOP_Results_Left": {
"type": "Observation",
"category": "vital-signs",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,8 @@
{
"condition_type": "Attribute",
"attribute": "macular_edema",
"operator": "is not nil"
"operator": "==",
"value": true
},
{
"condition_type": "Not",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,18 +160,17 @@
"Chance_of_Macular_Edema": {
"type": "Simple",
"remarks": [
"Incidence of DME is very low. Very rough estimate == ~1% per year.",
"only around 20% of patients will hit this state, so we scale up to about 5% per year among those patients",
"5% / yr = .4% / month",
"Incidence of DME is very low. Very rough estimate == ~1% per year or less.",
"1% / yr = .08% / month ; bumped up slightly per experimentation",
"https://www.ncbi.nlm.nih.gov/pmc/articles/PMC4657234/table/Tab5/"
],
"distributed_transition": [
{
"distribution": 0.004,
"distribution": 0.001,
"transition": "Set_Macular_Edema"
},
{
"distribution": 0.996,
"distribution": 0.999,
"transition": "Chance_of_Blindness"
}
]
Expand Down

0 comments on commit 9ead61d

Please sign in to comment.