Repository: synthetichealth/synthea
Issue: Encounter.diagnosePastConditions

The `Encounter.diagnosePastConditions` method has a couple issues:
https://github.com/synthetichealth/synthea/blob/master/src/main/java/org/mitre/synthea/engine/State.java#L527

1. It is inconsistent with the description of how conditions being diagnosed is supposed to work. Per 
https://github.com/synthetichealth/synthea/wiki/Generic-Module-Framework%3A-States#conditiononset  a condition should only be diagnosed at the target_encounter, not any encounter

2. It loops over every state in the module's history, which can be slow as module histories grow over the years. It should break early if possible, ex if it finds another instance of the same state in the history.

Changed files:
src/main/java/org/mitre/synthea/engine/State.java, src/test/java/org/mitre/synthea/engine/StateTest.java

diff --git a/src/main/java/org/mitre/synthea/engine/State.java b/src/main/java/org/mitre/synthea/engine/State.java
index a0ffd9fe8..33495d246 100644
--- a/src/main/java/org/mitre/synthea/engine/State.java
+++ b/src/main/java/org/mitre/synthea/engine/State.java
@@ -525,9 +525,17 @@ public abstract class State implements Cloneable {
     }
 
     private void diagnosePastConditions(Person person, long time) {
+      // reminder: history[0] is current state, history[size-1] is Initial
       for (State state : person.history) {
-        if (state instanceof OnsetState && !((OnsetState) state).diagnosed) {
-          ((OnsetState) state).diagnose(person, time);
+        if (state instanceof OnsetState) {
+          OnsetState onset = (OnsetState) state;
+          
+          if (!onset.diagnosed && this.name.equals(onset.targetEncounter)) {
+            onset.diagnose(person, time);
+          }
+        } else if (state instanceof Encounter && state.name.equals(this.name)) {
+          // a prior instance of hitting this same state. no need to go back any further
+          break;
         }
       }
     }
diff --git a/src/test/java/org/mitre/synthea/engine/StateTest.java b/src/test/java/org/mitre/synthea/engine/StateTest.java
index a8e63d0fb..4c42dad72 100644
--- a/src/test/java/org/mitre/synthea/engine/StateTest.java
+++ b/src/test/java/org/mitre/synthea/engine/StateTest.java
@@ -151,6 +151,32 @@ public class StateTest {
     verifyZeroInteractions(person.record);
   }
 
+  @Test
+  public void condition_onset_diagnosed_by_target_encounter() { 
+    Module module = getModule("condition_onset.json");
+    
+    State condition = module.getState("Diabetes");
+    // Should pass through this state immediately without calling the record
+    assertTrue(condition.process(person, time));
+    person.history.add(0, condition);
+    
+    // The encounter comes next (and add it to history);
+    State encounter = module.getState("ED_Visit");
+
+    assertTrue(encounter.process(person, time));
+    person.history.add(0, encounter);
+
+    assertEquals(1, person.record.encounters.size());
+    Encounter enc = person.record.encounters.get(0);
+    Code code = enc.codes.get(0);
+    assertEquals("50849002", code.code);
+    assertEquals("Emergency Room Admission", code.display);
+    assertEquals(1, enc.conditions.size());
+    code = enc.conditions.get(0).codes.get(0);
+    assertEquals("73211009", code.code);
+    assertEquals("Diabetes mellitus", code.display);
+  }
+
   @Test
   public void condition_onset_during_encounter() {
     Module module = getModule("condition_onset.json");