class TestResetPersonAndRollBackEvents(unittest.TestCase):
    def setUp(self):
        self.baseAge = 55
        self.baseSBP = 120
        self._white_male = Person(
            age=self.baseAge,
            gender=NHANESGender.MALE,
            raceEthnicity=NHANESRaceEthnicity.NON_HISPANIC_WHITE,
            sbp=self.baseSBP,
            dbp=80,
            a1c=6,
            hdl=50,
            totChol=213,
            ldl=90,
            trig=150,
            bmi=22,
            waist=34,
            anyPhysicalActivity=0,
            education=Education.COLLEGEGRADUATE,
            smokingStatus=SmokingStatus.NEVER,
            alcohol=AlcoholCategory.NONE,
            antiHypertensiveCount=0,
            statin=0,
            otherLipidLoweringMedicationCount=0,
            initializeAfib=initializeAfib)

        self._white_male_copy_paste = Person(
            age=self.baseAge,
            gender=NHANESGender.MALE,
            raceEthnicity=NHANESRaceEthnicity.NON_HISPANIC_WHITE,
            sbp=self.baseSBP,
            dbp=80,
            a1c=6,
            hdl=50,
            totChol=213,
            ldl=90,
            trig=150,
            bmi=22,
            waist=34,
            anyPhysicalActivity=0,
            education=Education.COLLEGEGRADUATE,
            smokingStatus=SmokingStatus.NEVER,
            alcohol=AlcoholCategory.NONE,
            antiHypertensiveCount=0,
            statin=0,
            otherLipidLoweringMedicationCount=0,
            initializeAfib=initializeAfib)

        self._white_male_plus_one_year = Person(
            age=self.baseAge + 1,
            gender=NHANESGender.MALE,
            raceEthnicity=NHANESRaceEthnicity.NON_HISPANIC_WHITE,
            sbp=self.baseSBP,
            dbp=80,
            a1c=6,
            hdl=50,
            totChol=213,
            ldl=90,
            trig=150,
            bmi=22,
            waist=34,
            anyPhysicalActivity=0,
            education=Education.COLLEGEGRADUATE,
            smokingStatus=SmokingStatus.NEVER,
            alcohol=AlcoholCategory.NONE,
            antiHypertensiveCount=0,
            statin=0,
            otherLipidLoweringMedicationCount=0,
            initializeAfib=initializeAfib)

        self._white_female = Person(
            age=self.baseAge,
            gender=NHANESGender.FEMALE,
            raceEthnicity=NHANESRaceEthnicity.NON_HISPANIC_WHITE,
            sbp=self.baseSBP,
            dbp=80,
            a1c=6,
            hdl=50,
            totChol=213,
            ldl=90,
            trig=150,
            bmi=22,
            waist=34,
            anyPhysicalActivity=0,
            education=Education.COLLEGEGRADUATE,
            smokingStatus=SmokingStatus.NEVER,
            alcohol=AlcoholCategory.NONE,
            antiHypertensiveCount=0,
            statin=0,
            otherLipidLoweringMedicationCount=0,
            initializeAfib=initializeAfib)

        self._black_female = Person(
            age=self.baseAge,
            gender=NHANESGender.FEMALE,
            raceEthnicity=NHANESRaceEthnicity.NON_HISPANIC_BLACK,
            sbp=self.baseSBP,
            dbp=80,
            a1c=6,
            hdl=50,
            totChol=213,
            ldl=90,
            trig=150,
            bmi=22,
            waist=34,
            anyPhysicalActivity=0,
            education=Education.COLLEGEGRADUATE,
            smokingStatus=SmokingStatus.NEVER,
            alcohol=AlcoholCategory.NONE,
            antiHypertensiveCount=0,
            statin=0,
            otherLipidLoweringMedicationCount=0,
            initializeAfib=initializeAfib)

        self._white_male_plus_sbp = Person(
            age=self.baseAge + 1,
            gender=NHANESGender.MALE,
            raceEthnicity=NHANESRaceEthnicity.NON_HISPANIC_WHITE,
            sbp=self.baseSBP + 10,
            dbp=80,
            a1c=6,
            hdl=50,
            totChol=213,
            ldl=90,
            trig=150,
            bmi=22,
            waist=34,
            anyPhysicalActivity=0,
            education=Education.COLLEGEGRADUATE,
            smokingStatus=SmokingStatus.NEVER,
            alcohol=AlcoholCategory.NONE,
            antiHypertensiveCount=0,
            statin=0,
            otherLipidLoweringMedicationCount=0,
            initializeAfib=initializeAfib)

        self._white_male_plus_dbp = Person(
            age=self.baseAge + 1,
            gender=NHANESGender.MALE,
            raceEthnicity=NHANESRaceEthnicity.NON_HISPANIC_WHITE,
            sbp=self.baseSBP,
            dbp=90,
            a1c=6,
            hdl=50,
            totChol=213,
            ldl=90,
            trig=150,
            bmi=22,
            waist=34,
            anyPhysicalActivity=0,
            education=Education.COLLEGEGRADUATE,
            smokingStatus=SmokingStatus.NEVER,
            alcohol=AlcoholCategory.NONE,
            antiHypertensiveCount=0,
            statin=0,
            otherLipidLoweringMedicationCount=0,
            initializeAfib=initializeAfib)

        self._white_male_plus_a1c = Person(
            age=self.baseAge + 1,
            gender=NHANESGender.MALE,
            raceEthnicity=NHANESRaceEthnicity.NON_HISPANIC_WHITE,
            sbp=self.baseSBP,
            dbp=80,
            a1c=7,
            hdl=50,
            totChol=213,
            ldl=90,
            trig=150,
            bmi=22,
            waist=34,
            anyPhysicalActivity=0,
            education=Education.COLLEGEGRADUATE,
            smokingStatus=SmokingStatus.NEVER,
            alcohol=AlcoholCategory.NONE,
            antiHypertensiveCount=0,
            statin=0,
            otherLipidLoweringMedicationCount=0,
            initializeAfib=initializeAfib)

        self._white_male_plus_hdl = Person(
            age=self.baseAge + 1,
            gender=NHANESGender.MALE,
            raceEthnicity=NHANESRaceEthnicity.NON_HISPANIC_WHITE,
            sbp=self.baseSBP,
            dbp=80,
            a1c=6,
            hdl=60,
            totChol=213,
            ldl=90,
            trig=150,
            bmi=22,
            waist=34,
            anyPhysicalActivity=0,
            education=Education.COLLEGEGRADUATE,
            smokingStatus=SmokingStatus.NEVER,
            alcohol=AlcoholCategory.NONE,
            antiHypertensiveCount=0,
            statin=0,
            otherLipidLoweringMedicationCount=0,
            initializeAfib=initializeAfib)

        self._white_male_plus_totChol = Person(
            age=self.baseAge + 1,
            gender=NHANESGender.MALE,
            raceEthnicity=NHANESRaceEthnicity.NON_HISPANIC_WHITE,
            sbp=self.baseSBP,
            dbp=80,
            a1c=6,
            hdl=50,
            totChol=223,
            ldl=90,
            trig=150,
            bmi=22,
            waist=34,
            anyPhysicalActivity=0,
            education=Education.COLLEGEGRADUATE,
            smokingStatus=SmokingStatus.NEVER,
            alcohol=AlcoholCategory.NONE,
            antiHypertensiveCount=0,
            statin=0,
            otherLipidLoweringMedicationCount=0,
            initializeAfib=initializeAfib)

        self._white_male_plus_ldl = Person(
            age=self.baseAge + 1,
            gender=NHANESGender.MALE,
            raceEthnicity=NHANESRaceEthnicity.NON_HISPANIC_WHITE,
            sbp=self.baseSBP,
            dbp=80,
            a1c=6,
            hdl=50,
            totChol=213,
            ldl=100,
            trig=150,
            bmi=22,
            waist=34,
            anyPhysicalActivity=0,
            education=Education.COLLEGEGRADUATE,
            smokingStatus=SmokingStatus.NEVER,
            alcohol=AlcoholCategory.NONE,
            antiHypertensiveCount=0,
            statin=0,
            otherLipidLoweringMedicationCount=0,
            initializeAfib=initializeAfib)

        self._white_male_plus_trig = Person(
            age=self.baseAge + 1,
            gender=NHANESGender.MALE,
            raceEthnicity=NHANESRaceEthnicity.NON_HISPANIC_WHITE,
            sbp=self.baseSBP,
            dbp=80,
            a1c=6,
            hdl=50,
            totChol=213,
            ldl=90,
            trig=160,
            bmi=22,
            waist=34,
            anyPhysicalActivity=0,
            education=Education.COLLEGEGRADUATE,
            smokingStatus=SmokingStatus.NEVER,
            alcohol=AlcoholCategory.NONE,
            antiHypertensiveCount=0,
            statin=0,
            otherLipidLoweringMedicationCount=0,
            initializeAfib=initializeAfib)

        self._white_male_plus_bmi = Person(
            age=self.baseAge + 1,
            gender=NHANESGender.MALE,
            raceEthnicity=NHANESRaceEthnicity.NON_HISPANIC_WHITE,
            sbp=self.baseSBP,
            dbp=80,
            a1c=6,
            hdl=50,
            totChol=213,
            ldl=90,
            trig=150,
            bmi=25,
            waist=34,
            anyPhysicalActivity=0,
            education=Education.COLLEGEGRADUATE,
            smokingStatus=SmokingStatus.NEVER,
            alcohol=AlcoholCategory.NONE,
            antiHypertensiveCount=0,
            statin=0,
            otherLipidLoweringMedicationCount=0,
            initializeAfib=initializeAfib)

        self._white_male_plus_waist = Person(
            age=self.baseAge + 1,
            gender=NHANESGender.MALE,
            raceEthnicity=NHANESRaceEthnicity.NON_HISPANIC_WHITE,
            sbp=self.baseSBP,
            dbp=80,
            a1c=6,
            hdl=50,
            totChol=213,
            ldl=90,
            trig=150,
            bmi=22,
            waist=36,
            anyPhysicalActivity=0,
            education=Education.COLLEGEGRADUATE,
            smokingStatus=SmokingStatus.NEVER,
            alcohol=AlcoholCategory.NONE,
            antiHypertensiveCount=0,
            statin=0,
            otherLipidLoweringMedicationCount=0,
            initializeAfib=initializeAfib)

        self._white_male_plus_activity = Person(
            age=self.baseAge + 1,
            gender=NHANESGender.MALE,
            raceEthnicity=NHANESRaceEthnicity.NON_HISPANIC_WHITE,
            sbp=self.baseSBP,
            dbp=80,
            a1c=6,
            hdl=50,
            totChol=213,
            ldl=90,
            trig=150,
            bmi=22,
            waist=34,
            anyPhysicalActivity=1,
            education=Education.COLLEGEGRADUATE,
            smokingStatus=SmokingStatus.NEVER,
            alcohol=AlcoholCategory.NONE,
            antiHypertensiveCount=0,
            statin=0,
            otherLipidLoweringMedicationCount=0,
            initializeAfib=initializeAfib)

        self._white_male_minus_edudcation = Person(
            age=self.baseAge + 1,
            gender=NHANESGender.MALE,
            raceEthnicity=NHANESRaceEthnicity.NON_HISPANIC_WHITE,
            sbp=self.baseSBP,
            dbp=80,
            a1c=6,
            hdl=50,
            totChol=213,
            ldl=90,
            trig=150,
            bmi=22,
            waist=34,
            anyPhysicalActivity=1,
            education=Education.HIGHSCHOOLGRADUATE,
            smokingStatus=SmokingStatus.NEVER,
            alcohol=AlcoholCategory.NONE,
            antiHypertensiveCount=0,
            statin=0,
            otherLipidLoweringMedicationCount=0,
            initializeAfib=initializeAfib)

        self._white_male_plus_smoking = Person(
            age=self.baseAge + 1,
            gender=NHANESGender.MALE,
            raceEthnicity=NHANESRaceEthnicity.NON_HISPANIC_WHITE,
            sbp=self.baseSBP,
            dbp=80,
            a1c=6,
            hdl=50,
            totChol=213,
            ldl=90,
            trig=150,
            bmi=22,
            waist=34,
            anyPhysicalActivity=1,
            education=Education.COLLEGEGRADUATE,
            smokingStatus=SmokingStatus.CURRENT,
            alcohol=AlcoholCategory.NONE,
            antiHypertensiveCount=0,
            statin=0,
            otherLipidLoweringMedicationCount=0,
            initializeAfib=initializeAfib)

        self._white_male_plus_bpMed = Person(
            age=self.baseAge + 1,
            gender=NHANESGender.MALE,
            raceEthnicity=NHANESRaceEthnicity.NON_HISPANIC_WHITE,
            sbp=self.baseSBP,
            dbp=80,
            a1c=6,
            hdl=50,
            totChol=213,
            ldl=90,
            trig=150,
            bmi=22,
            waist=34,
            anyPhysicalActivity=0,
            education=Education.COLLEGEGRADUATE,
            smokingStatus=SmokingStatus.NEVER,
            alcohol=AlcoholCategory.NONE,
            antiHypertensiveCount=1,
            statin=0,
            otherLipidLoweringMedicationCount=0,
            initializeAfib=initializeAfib)

        self._white_male_plus_statin = Person(
            age=self.baseAge + 1,
            gender=NHANESGender.MALE,
            raceEthnicity=NHANESRaceEthnicity.NON_HISPANIC_WHITE,
            sbp=self.baseSBP,
            dbp=80,
            a1c=6,
            hdl=50,
            totChol=213,
            ldl=90,
            trig=150,
            bmi=22,
            waist=34,
            anyPhysicalActivity=0,
            education=Education.COLLEGEGRADUATE,
            smokingStatus=SmokingStatus.NEVER,
            alcohol=AlcoholCategory.NONE,
            antiHypertensiveCount=0,
            statin=1,
            otherLipidLoweringMedicationCount=0,
            initializeAfib=initializeAfib)

        self._white_male_plus_lipid = Person(
            age=self.baseAge + 1,
            gender=NHANESGender.MALE,
            raceEthnicity=NHANESRaceEthnicity.NON_HISPANIC_WHITE,
            sbp=self.baseSBP,
            dbp=80,
            a1c=6,
            hdl=50,
            totChol=213,
            ldl=90,
            trig=150,
            bmi=22,
            waist=34,
            anyPhysicalActivity=0,
            education=Education.COLLEGEGRADUATE,
            smokingStatus=SmokingStatus.NEVER,
            alcohol=AlcoholCategory.NONE,
            antiHypertensiveCount=0,
            statin=0,
            otherLipidLoweringMedicationCount=1,
            initializeAfib=initializeAfib)

        self._white_male_plus_afib = Person(
            age=self.baseAge + 1,
            gender=NHANESGender.MALE,
            raceEthnicity=NHANESRaceEthnicity.NON_HISPANIC_WHITE,
            sbp=self.baseSBP,
            dbp=80,
            a1c=6,
            hdl=50,
            totChol=213,
            ldl=90,
            trig=150,
            bmi=22,
            waist=34,
            anyPhysicalActivity=0,
            education=Education.COLLEGEGRADUATE,
            smokingStatus=SmokingStatus.NEVER,
            alcohol=AlcoholCategory.NONE,
            antiHypertensiveCount=0,
            statin=0,
            otherLipidLoweringMedicationCount=0,
            initializeAfib=initializeAfibAlwaysPositive)

        self._baseline_stroke_person = Person(
            age=self.baseAge,
            gender=NHANESGender.MALE,
            raceEthnicity=NHANESRaceEthnicity.NON_HISPANIC_WHITE,
            sbp=self.baseSBP,
            dbp=80,
            a1c=6,
            hdl=50,
            totChol=213,
            ldl=90,
            trig=150,
            bmi=22,
            waist=34,
            anyPhysicalActivity=0,
            education=Education.COLLEGEGRADUATE,
            smokingStatus=SmokingStatus.NEVER,
            alcohol=AlcoholCategory.NONE,
            antiHypertensiveCount=0,
            statin=0,
            otherLipidLoweringMedicationCount=0,
            initializeAfib=initializeAfib,
            selfReportStrokeAge=50)

        self._baseline_stroke_person_copy_paste = Person(
            age=self.baseAge,
            gender=NHANESGender.MALE,
            raceEthnicity=NHANESRaceEthnicity.NON_HISPANIC_WHITE,
            sbp=self.baseSBP,
            dbp=80,
            a1c=6,
            hdl=50,
            totChol=213,
            ldl=90,
            trig=150,
            bmi=22,
            waist=34,
            anyPhysicalActivity=0,
            education=Education.COLLEGEGRADUATE,
            smokingStatus=SmokingStatus.NEVER,
            alcohol=AlcoholCategory.NONE,
            antiHypertensiveCount=0,
            statin=0,
            otherLipidLoweringMedicationCount=0,
            initializeAfib=initializeAfib,
            selfReportStrokeAge=50)

    def testResetBasicAttributes(self):
        self._white_male.advance_year(TestRiskModelRepository(),
                                      AlwaysNonFatalStrokeOutcomeRepository())
        self._baseline_stroke_person.advance_year(
            TestRiskModelRepository(), AlwaysFatalStrokeOutcomeRepository())
        self.assertEqual(2, len(self._white_male._dbp))

        self._white_male.reset_to_baseline()

        self.assertEqual(1, len(self._white_male._dbp))
        self.assertEqual(1, len(self._white_male._totChol))
        self.assertEqual(1, len(self._white_male._trig))
        self.assertEqual(1, len(self._white_male._trig))
        self.assertEqual(1, len(self._white_male._sbp))

        self.assertEqual(self.baseSBP, self._white_male._sbp[-1])
        self.assertEqual(self.baseAge, self._white_male._age[-1])

    def testResetOutcomes(self):
        self._white_male.advance_year(TestRiskModelRepository(),
                                      AlwaysNonFatalStrokeOutcomeRepository())
        self._baseline_stroke_person.advance_year(
            TestRiskModelRepository(), AlwaysFatalStrokeOutcomeRepository())
        self.assertEqual(1,
                         len(self._white_male._outcomes[OutcomeType.STROKE]))
        self._white_male.reset_to_baseline()
        self.assertEqual(0,
                         len(self._white_male._outcomes[OutcomeType.STROKE]))

    def testResetOutcomesPreservesPreSimOutcomes(self):
        self._white_male.advance_year(TestRiskModelRepository(),
                                      AlwaysNonFatalStrokeOutcomeRepository())
        self._baseline_stroke_person.advance_year(
            TestRiskModelRepository(), AlwaysFatalStrokeOutcomeRepository())
        self.assertEqual(
            2, len(self._baseline_stroke_person._outcomes[OutcomeType.STROKE]))
        self._baseline_stroke_person.reset_to_baseline()
        self.assertEqual(
            1, len(self._baseline_stroke_person._outcomes[OutcomeType.STROKE]))

    def testRollbackNonFatalEvent(self):
        self._white_male.advance_year(TestRiskModelRepository(),
                                      AlwaysNonFatalStrokeOutcomeRepository())
        self._baseline_stroke_person.advance_year(
            TestRiskModelRepository(), AlwaysFatalStrokeOutcomeRepository())
        self.assertEqual(False,
                         self._white_male.has_stroke_prior_to_simulation())
        self.assertEqual(True, self._white_male.has_stroke_during_simulation())
        self.assertEqual(True, self._white_male.has_stroke_during_wave(1))

        self._white_male.rollback_most_recent_event(OutcomeType.STROKE)

        self.assertEqual(False,
                         self._white_male.has_stroke_prior_to_simulation())
        self.assertEqual(False, self._white_male.has_stroke_during_wave(1))
        self.assertEqual(False,
                         self._white_male.has_stroke_during_simulation())

    def testRollbackFatalEvent(self):
        self._white_male.advance_year(TestRiskModelRepository(),
                                      AlwaysNonFatalStrokeOutcomeRepository())
        self._baseline_stroke_person.advance_year(
            TestRiskModelRepository(), AlwaysFatalStrokeOutcomeRepository())
        self.assertEqual(
            True, self._baseline_stroke_person.has_stroke_during_simulation())
        self.assertEqual(
            True,
            self._baseline_stroke_person.has_stroke_prior_to_simulation())
        self.assertEqual(
            True, self._baseline_stroke_person.has_stroke_during_wave(1))
        self.assertEqual(True, self._baseline_stroke_person.is_dead())

        self._baseline_stroke_person.rollback_most_recent_event(
            OutcomeType.STROKE)

        self.assertEqual(
            True,
            self._baseline_stroke_person.has_stroke_prior_to_simulation())
        self.assertEqual(
            False, self._baseline_stroke_person.has_stroke_during_wave(1))
        self.assertEqual(
            False, self._baseline_stroke_person.has_stroke_during_simulation())
        self.assertEqual(False, self._baseline_stroke_person.is_dead())
        self.assertEqual(self.baseAge + 1,
                         self._baseline_stroke_person._age[-1])

    def testBasePatientEquals(self):
        self.assertTrue(self._white_male == self._white_male_copy_paste)
        self.assertEqual(self._white_male, self._white_male_copy_paste)
        self.assertNotEqual(self._white_male, self._white_female)
        self.assertNotEqual(self._white_female, self._black_female)
        self.assertNotEqual(self._white_male,
                            self._white_male_minus_edudcation)
        self.assertNotEqual(self._white_male, self._white_male_plus_a1c)
        self.assertNotEqual(self._white_male, self._white_male_plus_activity)
        self.assertNotEqual(self._white_male, self._white_male_plus_afib)
        self.assertNotEqual(self._white_male, self._white_male_plus_bmi)
        self.assertNotEqual(self._white_male, self._white_male_plus_dbp)
        self.assertNotEqual(self._white_male, self._white_male_plus_hdl)
        self.assertNotEqual(self._white_male, self._white_male_plus_ldl)
        self.assertNotEqual(self._white_male, self._white_male_plus_lipid)
        self.assertNotEqual(self._white_male, self._white_male_plus_one_year)
        self.assertNotEqual(self._white_male, self._white_male_plus_sbp)
        self.assertNotEqual(self._white_male, self._white_male_plus_smoking)
        self.assertNotEqual(self._white_male, self._white_male_plus_statin)
        self.assertNotEqual(self._white_male, self._white_male_plus_totChol)
        self.assertNotEqual(self._white_male, self._white_male_plus_trig)
        self.assertNotEqual(self._white_male, self._white_male_plus_waist)

    def testBaselineEqualityAfterAdvancingAYear(self):
        self._white_male.advance_year(TestRiskModelRepository(),
                                      NothingHappensRepository())
        self._white_male_copy_paste.advance_year(TestRiskModelRepository(),
                                                 NothingHappensRepository())
        self.assertEqual(self._white_male, self._white_male_copy_paste)

    def testBasePatientWithBaselineStroke(self):
        self.assertNotEqual(self._white_male, self._baseline_stroke_person)
        self.assertEqual(self._baseline_stroke_person,
                         self._baseline_stroke_person_copy_paste)
        self._baseline_stroke_person.advance_year(TestRiskModelRepository(),
                                                  NothingHappensRepository())
        self._baseline_stroke_person_copy_paste.advance_year(
            TestRiskModelRepository(), NothingHappensRepository())
        self.assertEqual(self._baseline_stroke_person,
                         self._baseline_stroke_person_copy_paste)

    def testBasePatientWithCVEvents(self):
        self.assertEqual(self._white_male_copy_paste, self._white_male)
        self._white_male.advance_year(TestRiskModelRepository(),
                                      AlwaysNonFatalStrokeOutcomeRepository())
        self.assertNotEqual(self._white_male, self._white_male_copy_paste)
        self._white_male_copy_paste.advance_year(
            TestRiskModelRepository(), AlwaysNonFatalStrokeOutcomeRepository())
        self.assertEqual(self._white_male_copy_paste, self._white_male)

    def testBasePatientWithNonCVDeath(self):
        self.assertEqual(self._white_male_copy_paste, self._white_male)
        self._white_male.advance_year(TestRiskModelRepository(),
                                      AlwaysNonCVDeathRepository())
        self.assertNotEqual(self._white_male, self._white_male_copy_paste)
        self._white_male_copy_paste.advance_year(TestRiskModelRepository(),
                                                 NothingHappensRepository())
        self.assertNotEqual(self._white_male_copy_paste, self._white_male)

    def testBasePatientWithNonCVDeathOtherWay(self):
        self.assertEqual(self._white_male_copy_paste, self._white_male)
        self._white_male.advance_year(TestRiskModelRepository(),
                                      AlwaysNonCVDeathRepository())
        self.assertNotEqual(self._white_male, self._white_male_copy_paste)
        self._white_male_copy_paste.advance_year(TestRiskModelRepository(),
                                                 AlwaysNonCVDeathRepository())
        self.assertEqual(self._white_male_copy_paste, self._white_male)

    def testDeepCopy(self):
        self.assertEqual(self._white_male, copy.deepcopy(self._white_male))
        self._white_male.advance_year(TestRiskModelRepository(),
                                      NothingHappensRepository())
        self.assertEqual(self._white_male, copy.deepcopy(self._white_male))
        self._white_male.advance_year(TestRiskModelRepository(),
                                      AlwaysNonFatalStrokeOutcomeRepository())
        self.assertEqual(self._white_male, copy.deepcopy(self._white_male))
        self._white_male.advance_year(TestRiskModelRepository(),
                                      AlwaysNonCVDeathRepository())
        self.assertEqual(self._white_male, copy.deepcopy(self._white_male))
예제 #2
0
class TestPersonAdvanceOutcomes(unittest.TestCase):
    def setUp(self):
        self.joe = Person(
            42,
            NHANESGender.MALE,
            NHANESRaceEthnicity.NON_HISPANIC_BLACK,
            140,
            90,
            5.5,
            50,
            200,
            25,
            90,
            150,
            45,
            0,
            Education.COLLEGEGRADUATE,
            SmokingStatus.NEVER,
            AlcoholCategory.NONE,
            0,
            0,
            0,
            0,
            initializeAFib,
        )

        self.joe_with_mi = copy.deepcopy(self.joe)
        self.joe_with_mi.add_outcome_event(Outcome(OutcomeType.MI, False))

        self.joe_with_stroke = copy.deepcopy(self.joe)
        self.joe_with_stroke.add_outcome_event(Outcome(OutcomeType.STROKE, False))

        self._population_dataframe = init_vectorized_population_dataframe(
            [self.joe, self.joe_with_mi, self.joe_with_stroke],
            with_base_gcp=True,
        )

        self._always_positive_repository = AlwaysPositiveOutcomeRepository()
        self._always_negative_repository = AlwaysNegativeOutcomeRepository()
        self.cvDeterminer = CVOutcomeDetermination(self._always_positive_repository)

    def test_dead_is_dead_advance_year(self):
        self.joe._alive[-1] = False
        with self.assertRaises(RuntimeError, msg="Person is dead. Can not advance year"):
            self.joe.advance_year(None, None)

    def test_dead_is_dead_advance_risk_factors(self):
        self.joe._alive[-1] = False
        with self.assertRaises(RuntimeError, msg="Person is dead. Can not advance risk factors"):
            self.joe.advance_risk_factors(None)

    def test_dead_is_dead_advance_outcomes(self):
        self.joe._alive[-1] = False
        with self.assertRaises(RuntimeError, msg="Person is dead. Can not advance outcomes"):
            self.joe.advance_outcomes(None)

    def test_will_have_fatal_mi(self):
        joe_data = self._population_dataframe.iloc[0]

        is_max_prob_mi_fatal = self.cvDeterminer._will_have_fatal_mi(
            joe_data,
            vectorized=True,
            overrideMIProb=1.0,
        )
        is_min_prob_mi_fatal = self.cvDeterminer._will_have_fatal_mi(
            joe_data,
            vectorized=True,
            overrideMIProb=0.0,
        )

        self.assertTrue(is_max_prob_mi_fatal)
        self.assertFalse(is_min_prob_mi_fatal)

    def test_fatal_mi_secondary_prob(self):
        self.cvDeterminer.mi_secondary_case_fatality = 1.0
        self.cvDeterminer.mi_case_fatality = 0.0
        joe_data = self._population_dataframe.iloc[0]
        joe_with_mi_data = self._population_dataframe.iloc[1]  # same as joe_data plus 1 MI

        will_have_fatal_first_mi = self.cvDeterminer._will_have_fatal_mi(
            joe_data,
            vectorized=True,
            overrideMIProb=0.0,
        )
        will_have_fatal_second_mi = self.cvDeterminer._will_have_fatal_mi(
            joe_with_mi_data,
            vectorized=True,
            overrideMIProb=0.0,
        )

        self.assertFalse(will_have_fatal_first_mi)
        # even though the passed fatality rate is zero, it should be overriden by the
        # secondary rate given that joe had a prior MI
        self.assertTrue(will_have_fatal_second_mi)

    def test_fatal_stroke_secondary_prob(self):
        self.cvDeterminer.stroke_secondary_case_fatality = 1.0
        self.cvDeterminer.stroke_case_fatality = 0.0
        joe_data = self._population_dataframe.iloc[0]
        joe_with_stroke_data = self._population_dataframe.iloc[2]  # same as joe_data plus 1 stroke

        will_have_fatal_first_stroke = self.cvDeterminer._will_have_fatal_stroke(
            joe_data,
            vectorized=True,
            overrideStrokeProb=0.0,
        )
        will_have_fatal_second_stroke = self.cvDeterminer._will_have_fatal_stroke(
            joe_with_stroke_data,
            vectorized=True,
            overrideStrokeProb=0.0,
        )

        self.assertFalse(will_have_fatal_first_stroke)
        # even though the passed fatality rate is zero, it shoudl be overriden by the
        # secondary rate given that joeclone had a prior stroke
        self.assertTrue(will_have_fatal_second_stroke)

    def test_will_have_fatal_stroke(self):
        joe_data = self._population_dataframe.iloc[0]

        is_max_prob_stroke_fatal = self.cvDeterminer._will_have_fatal_stroke(
            joe_data,
            vectorized=True,
            overrideStrokeProb=1.0,
        )
        is_min_prob_stroke_fatal = self.cvDeterminer._will_have_fatal_stroke(
            joe_data,
            vectorized=True,
            overrideStrokeProb=0.0,
        )

        self.assertTrue(is_max_prob_stroke_fatal)
        self.assertFalse(is_min_prob_stroke_fatal)

    def test_has_mi_vs_stroke(self):
        joe_data = self._population_dataframe.iloc[0]

        has_mi_max_manual_prob = self.cvDeterminer._will_have_mi(
            joe_data,
            outcome_model_repository=None,
            vectorized=False,
            manualMIProb=1.0,
        )
        has_mi_min_manual_prob = self.cvDeterminer._will_have_mi(
            joe_data,
            outcome_model_repository=None,
            vectorized=False,
            manualMIProb=0.0,
        )

        self.assertTrue(has_mi_max_manual_prob)
        self.assertFalse(has_mi_min_manual_prob)

    def test_advance_outcomes_fatal_mi(self):
        self._always_positive_repository.stroke_case_fatality = 1.0
        self._always_positive_repository.mi_case_fatality = 1.0
        self._always_positive_repository.manualStrokeMIProbability = 1.0

        self.joe.advance_outcomes(self._always_positive_repository)
        self.assertTrue(self.joe.has_mi_during_simulation())
        self.assertFalse(self.joe.has_stroke_during_simulation())
        self.assertTrue(self.joe.is_dead())

    def test_advance_outcomes_fatal_stroke(self):
        self._always_positive_repository.stroke_case_fatality = 1.0
        self._always_positive_repository.mi_case_fatality = 1.0
        self._always_positive_repository.manualStrokeMIProbability = 0.0

        self.joe.advance_outcomes(self._always_positive_repository)
        self.assertFalse(self.joe.has_mi_during_simulation())
        self.assertTrue(self.joe.has_stroke_during_simulation())
        self.assertTrue(self.joe.is_dead())

    def test_advance_outcomes_nonfatal_mi(self):
        self.assertEqual(0, self.joe.is_dead())
        self._always_positive_repository.stroke_case_fatality = 0.0
        self._always_positive_repository.mi_case_fatality = 0.0
        self._always_positive_repository.manualStrokeMIProbability = 1.0

        self.joe.advance_outcomes(self._always_positive_repository)
        self.assertTrue(self.joe.has_mi_during_simulation())
        self.assertFalse(self.joe.has_stroke_during_simulation())

    def test_advance_outcomes_nonfatal_stroke(self):
        self._always_positive_repository.stroke_case_fatality = 0.0
        self._always_positive_repository.mi_case_fatality = 0.0
        self._always_positive_repository.manualStrokeMIProbability = 0.0

        self.joe.advance_outcomes(self._always_positive_repository)
        self.assertFalse(self.joe.has_mi_during_simulation())
        self.assertTrue(self.joe.has_stroke_during_simulation())
예제 #3
0
class TestGCPModel(unittest.TestCase):
    def initializeAfib(person):
        return None

    def setUp(self):
        self._test_case_one = Person(
            age=65 - 0.828576318 * 10,
            gender=NHANESGender.FEMALE,
            raceEthnicity=NHANESRaceEthnicity.NON_HISPANIC_WHITE,
            sbp=120 + 0.45 * 10,
            dbp=80,
            # guessingon the centering standard for glucose...may have to check
            a1c=Person.convert_fasting_glucose_to_a1c(100 - 1.1 * 10),
            hdl=50,
            totChol=127 - 3.64 * 10,
            ldl=90,
            trig=150,
            bmi=26.6 + 15.30517532,
            waist=94 + 19.3,
            anyPhysicalActivity=1,
            education=Education.COLLEGEGRADUATE,
            smokingStatus=SmokingStatus.NEVER,
            alcohol=AlcoholCategory.ONETOSIX,
            antiHypertensiveCount=1,
            statin=0,
            otherLipidLoweringMedicationCount=0,
            initializeAfib=TestGCPModel.initializeAfib)

        self._test_case_two = Person(
            age=65 - 0.458555784 * 10,
            gender=NHANESGender.MALE,
            raceEthnicity=NHANESRaceEthnicity.NON_HISPANIC_WHITE,
            sbp=120 + 0.3 * 10,
            dbp=80,
            # guessingon the centering standard for glucose...may have to check
            a1c=Person.convert_fasting_glucose_to_a1c(100 + 0.732746529 * 10),
            hdl=50,
            totChol=127 + 1.18 * 10,
            ldl=90,
            trig=150,
            bmi=26.6 + 0.419305619,
            waist=94 - 2.5,
            anyPhysicalActivity=1,
            education=Education.SOMEHIGHSCHOOL,
            smokingStatus=SmokingStatus.NEVER,
            alcohol=AlcoholCategory.ONETOSIX,
            antiHypertensiveCount=0,
            statin=0,
            otherLipidLoweringMedicationCount=0,
            initializeAfib=TestGCPModel.initializeAfib)

        self._test_case_three = Person(
            age=65 - 0.358692676 * 10,
            gender=NHANESGender.FEMALE,
            raceEthnicity=NHANESRaceEthnicity.NON_HISPANIC_BLACK,
            sbp=120 + 2.3 * 10,
            dbp=80,
            # guessingon the centering standard for glucose...may have to check
            a1c=Person.convert_fasting_glucose_to_a1c(100 + 0.8893 * 10),
            hdl=50,
            totChol=127 + 4.7769 * 10,
            ldl=90,
            trig=150,
            bmi=26.6 + 2.717159247,
            waist=94 + 9,
            anyPhysicalActivity=1,
            education=Education.LESSTHANHIGHSCHOOL,
            smokingStatus=SmokingStatus.NEVER,
            alcohol=AlcoholCategory.NONE,
            antiHypertensiveCount=1,
            statin=0,
            otherLipidLoweringMedicationCount=0,
            initializeAfib=TestGCPModel.initializeAfib)

    def test_baseline_gcp(self):
        # check that all of the random elements have been removed for testing...
        self.assertEqual(
            GCPModel().calc_linear_predictor(person=self._test_case_one,
                                             test=True),
            GCPModel().calc_linear_predictor(person=self._test_case_one,
                                             test=True))

        # this is for the first person in teh spreadsheet (1569nomas)...comparator is GCP + backing out the cohort effect (NOMAS)
        self.assertAlmostEqual(64.45419405 - 2.7905,
                               GCPModel().calc_linear_predictor(
                                   person=self._test_case_one, test=True),
                               places=1)

        # this is for the 2nd person in the spreadhsheet (204180409594cardia)...comparabor is GCP margin + backing out the cohort effect (cardia)
        self.assertAlmostEqual(50.01645213 + 1.3320,
                               GCPModel().calc_linear_predictor(
                                   person=self._test_case_two, test=True),
                               places=1)

        # this is for the the first black person in the spreadsheet (J150483aric)...comparator is GCP + no cohort effect (ARIC)
        self.assertAlmostEqual(42.99471241,
                               GCPModel().calc_linear_predictor(
                                   person=self._test_case_three, test=True),
                               places=1)

    def test_gcp_after_one_year(self):
        # this is for the first person in teh spreadsheet (1569nomas)...comparator is GCP + backing out the cohort effect (NOMAS)
        self._test_case_one.advance_year(
            DoNotChangeRiskFactorsModelRepository(),
            AlwaysNegativeOutcomeRepository())
        # account for the difference between the actual mean systolic change
        self.assertAlmostEqual(64.28862964 - 2.7905,
                               GCPModel().calc_linear_predictor(
                                   person=self._test_case_one, test=True),
                               places=1)

    def test_gcp_random_effect(self):
        self._test_case_one._randomEffects['gcp'] = 5
        self.assertAlmostEqual(64.45419405 - 2.7905 + 5,
                               GCPModel().get_risk_for_person(
                                   person=self._test_case_one,
                                   years=1,
                                   test=True),
                               places=1)
예제 #4
0
class TestPersonAdvanceOutcomes(unittest.TestCase):
    def setUp(self):
        self.joe = Person(42, NHANESGender.MALE,
                          NHANESRaceEthnicity.NON_HISPANIC_BLACK, 140, 90, 5.5,
                          50, 200, 25, 90, 150, 45, 0,
                          Education.COLLEGEGRADUATE, SmokingStatus.NEVER,
                          AlcoholCategory.NONE, 0, 0, 0, initializeAFib)
        self._always_positive_repository = AlwaysPositiveOutcomeRepository()
        self._always_negative_repository = AlwaysNegativeOutcomeRepository()
        self.cvDeterminer = CVOutcomeDetermination(
            self._always_positive_repository)

    def test_dead_is_dead_advance_year(self):
        self.joe._alive[-1] = False
        with self.assertRaises(RuntimeError,
                               msg="Person is dead. Can not advance year"):
            self.joe.advance_year(None, None)

    def test_dead_is_dead_advance_risk_factors(self):
        self.joe._alive[-1] = False
        with self.assertRaises(
                RuntimeError,
                msg="Person is dead. Can not advance risk factors"):
            self.joe.advance_risk_factors(None)

    def test_dead_is_dead_advance_outcomes(self):
        self.joe._alive[-1] = False
        with self.assertRaises(RuntimeError,
                               msg="Person is dead. Can not advance outcomes"):
            self.joe.advance_outcomes(None)

    def test_will_have_fatal_mi(self):
        self.assertEqual(self.cvDeterminer._will_have_fatal_mi(self.joe, 1.0),
                         1)
        self.assertEqual(self.cvDeterminer._will_have_fatal_mi(self.joe, 0.0),
                         0)

    def test_fatal_mi_secondary_prob(self):
        self.cvDeterminer.mi_secondary_case_fatality = 1.0
        self.cvDeterminer.mi_case_fatality = 0.0

        joeClone = copy.deepcopy(self.joe)

        self.assertEqual(self.cvDeterminer._will_have_fatal_mi(joeClone, 0.0),
                         0)

        joeClone._outcomes[OutcomeType.MI] = (joeClone._age,
                                              Outcome(OutcomeType.MI, False))
        # even though the passed fatality rate is zero, it shoudl be overriden by the
        # secondary rate given that joeclone had a prior MI
        self.assertEqual(self.cvDeterminer._will_have_fatal_mi(joeClone, 0.0),
                         1)

    def test_fatal_stroke_secondary_prob(self):
        self.cvDeterminer.stroke_secondary_case_fatality = 1.0
        self.cvDeterminer.stroke_case_fatality = 0.0

        joeClone = copy.deepcopy(self.joe)

        self.assertEqual(
            self.cvDeterminer._will_have_fatal_stroke(joeClone, 0.0), 0)

        joeClone._outcomes[OutcomeType.STROKE] = (joeClone._age,
                                                  Outcome(
                                                      OutcomeType.STROKE,
                                                      False))
        # even though the passed fatality rate is zero, it shoudl be overriden by the
        # secondary rate given that joeclone had a prior stroke
        self.assertEqual(
            self.cvDeterminer._will_have_fatal_stroke(joeClone, 0.0), 1)

    def test_will_have_fatal_stroke(self):
        self.assertEqual(
            self.cvDeterminer._will_have_fatal_stroke(self.joe, 1.0), 1)
        self.assertEqual(
            self.cvDeterminer._will_have_fatal_stroke(self.joe, 0.0), 0)

    def test_has_mi_vs_stroke(self):
        self.assertEqual(self.cvDeterminer._will_have_mi(self.joe, None, 1.0),
                         1)
        self.assertEqual(self.cvDeterminer._will_have_mi(self.joe, None, 0.0),
                         0)

    def test_advance_outcomes_fatal_mi(self):
        self._always_positive_repository.stroke_case_fatality = 1.0
        self._always_positive_repository.mi_case_fatality = 1.0
        self._always_positive_repository.manualStrokeMIProbability = 1.0

        self.joe.advance_outcomes(self._always_positive_repository)
        self.assertTrue(self.joe.has_mi_during_simulation())
        self.assertFalse(self.joe.has_stroke_during_simulation())
        self.assertTrue(self.joe.is_dead())

    def test_advance_outcomes_fatal_stroke(self):
        self._always_positive_repository.stroke_case_fatality = 1.0
        self._always_positive_repository.mi_case_fatality = 1.0
        self._always_positive_repository.manualStrokeMIProbability = 0.0

        self.joe.advance_outcomes(self._always_positive_repository)
        self.assertFalse(self.joe.has_mi_during_simulation())
        self.assertTrue(self.joe.has_stroke_during_simulation())
        self.assertTrue(self.joe.is_dead())

    def test_advance_outcomes_nonfatal_mi(self):
        self.assertEqual(0, self.joe.is_dead())
        self._always_positive_repository.stroke_case_fatality = 0.0
        self._always_positive_repository.mi_case_fatality = 0.0
        self._always_positive_repository.manualStrokeMIProbability = 1.0

        self.joe.advance_outcomes(self._always_positive_repository)
        self.assertTrue(self.joe.has_mi_during_simulation())
        self.assertFalse(self.joe.has_stroke_during_simulation())

    def test_advance_outcomes_nonfatal_stroke(self):
        self._always_positive_repository.stroke_case_fatality = 0.0
        self._always_positive_repository.mi_case_fatality = 0.0
        self._always_positive_repository.manualStrokeMIProbability = 0.0

        self.joe.advance_outcomes(self._always_positive_repository)
        self.assertFalse(self.joe.has_mi_during_simulation())
        self.assertTrue(self.joe.has_stroke_during_simulation())
예제 #5
0
class TestPersonWaveStatus(unittest.TestCase):
    def setUp(self):
        self.oldJoe = Person(
            age=60,
            gender=NHANESGender.MALE,
            raceEthnicity=NHANESRaceEthnicity.NON_HISPANIC_BLACK,
            sbp=140,
            dbp=90,
            a1c=5.5,
            hdl=50,
            totChol=200,
            bmi=25,
            ldl=90,
            trig=150,
            waist=45,
            anyPhysicalActivity=0,
            education=Education.COLLEGEGRADUATE,
            smokingStatus=SmokingStatus.NEVER,
            alcohol=AlcoholCategory.NONE,
            antiHypertensiveCount=0,
            statin=0,
            otherLipidLoweringMedicationCount=0,
            initializeAfib=initializeAFib)

        self.youngJoe = Person(
            age=40,
            gender=NHANESGender.MALE,
            raceEthnicity=NHANESRaceEthnicity.NON_HISPANIC_BLACK,
            sbp=140,
            dbp=90,
            a1c=5.5,
            hdl=50,
            totChol=200,
            bmi=25,
            ldl=90,
            trig=150,
            waist=45,
            anyPhysicalActivity=0,
            education=Education.COLLEGEGRADUATE,
            smokingStatus=SmokingStatus.NEVER,
            alcohol=AlcoholCategory.NONE,
            antiHypertensiveCount=0,
            statin=0,
            otherLipidLoweringMedicationCount=0,
            initializeAfib=initializeAFib)

    def testStatusAfterFatalStroke(self):
        self.youngJoe.advance_year(TestRiskModelRepository(),
                                   AgeOver50CausesFatalStroke())
        self.assertEqual(41, self.youngJoe._age[-1])
        self.assertEqual(False, self.youngJoe.is_dead())
        self.assertEqual(False, self.youngJoe._stroke)

        self.assertEqual(True, self.youngJoe.alive_at_start_of_wave(1))
        self.assertEqual(True, self.youngJoe.alive_at_start_of_wave(2))
        with self.assertRaises(Exception):
            self.youngJoe.alive_at_start_of_wave(3)

        self.youngJoe.advance_year(TestRiskModelRepository(),
                                   AgeOver50CausesFatalStroke())
        self.assertEqual(True, self.youngJoe.alive_at_start_of_wave(3))

        self.oldJoe.advance_year(TestRiskModelRepository(),
                                 AgeOver50CausesFatalStroke())
        self.assertEqual(60, self.oldJoe._age[-1])
        self.assertEqual(True, self.oldJoe.is_dead())
        self.assertEqual(True, self.oldJoe._stroke)

        self.assertEqual(True, self.oldJoe.alive_at_start_of_wave(1))
        self.assertEqual(False, self.oldJoe.alive_at_start_of_wave(2))

        # this is called to verify that it DOES NOT throw an excepiotn
        self.oldJoe.alive_at_start_of_wave(3)

    def testNonCVMortalityLeadsToCorrectStatus(self):
        self.youngJoe.advance_year(TestRiskModelRepository(),
                                   AgeOver50CausesNonCVMortality())
        self.assertEqual(41, self.youngJoe._age[-1])
        self.assertEqual(False, self.youngJoe.is_dead())
        self.assertEqual(False, self.youngJoe._stroke)

        self.assertEqual(True, self.youngJoe.alive_at_start_of_wave(1))
        self.assertEqual(True, self.youngJoe.alive_at_start_of_wave(2))
        with self.assertRaises(Exception):
            self.youngJoe.alive_at_start_of_wave(3)

        self.youngJoe.advance_year(TestRiskModelRepository(),
                                   AgeOver50CausesNonCVMortality())
        self.assertEqual(True, self.youngJoe.alive_at_start_of_wave(3))

        self.oldJoe.advance_year(TestRiskModelRepository(),
                                 AgeOver50CausesNonCVMortality())
        self.assertEqual(60, self.oldJoe._age[-1])
        self.assertEqual(True, self.oldJoe.is_dead())
        self.assertEqual(False, self.oldJoe._stroke)

        self.assertEqual(True, self.oldJoe.alive_at_start_of_wave(1))
        self.assertEqual(False, self.oldJoe.alive_at_start_of_wave(2))

        # this is called to verify that it DOES NOT throw an excepiotn
        self.oldJoe.alive_at_start_of_wave(3)

    def testHasFatalStrokeInWaveIsCaptured(self):
        self.oldJoe.advance_year(TestRiskModelRepository(),
                                 AgeOver50CausesFatalStroke())
        self.assertEqual(True, self.oldJoe.has_stroke_during_simulation())
        self.assertEqual(True, self.oldJoe.has_stroke_during_wave(1))
        with self.assertRaises(Exception):
            self.oldJoe.has_stroke_during_wave(0)
        # calling to make sure it does NOT raise an exception...you should
        # be able to ask whether somebody has a stroke in a wave after they are dead, the answer is
        # "No"
        self.assertEqual(False, self.oldJoe.has_stroke_during_wave(2))

    def testNonFatalStrokeInWaveWithNonCVDeathIsCaptured(self):
        self.oldJoe.advance_year(TestRiskModelRepository(),
                                 NonFatalStrokeAndNonCVMortality())
        self.assertEqual(True, self.oldJoe.has_stroke_during_simulation())
        self.assertEqual(True, self.oldJoe.has_stroke_during_wave(1))
        self.assertEqual(True, self.oldJoe.is_dead())