Example #1
0
    def setUp(self):
        inputs = [("fragility", ""), ("exposure", "")]
        self.job = self.setup_classic_job(inputs=inputs)

        kvs.mark_job_as_current(self.job.id)
        kvs.cache_gc(self.job.id)

        self.site = Site(1.0, 1.0)
        block = Block(self.job.id, BLOCK_ID, [self.site])
        block.to_kvs()

        # this region contains a single site, that is exactly
        # a site with longitude == 1.0 and latitude == 1.0
        params = {"REGION_VERTEX": "1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0",
                "REGION_GRID_SPACING": "0.5", "BASE_PATH": ".",
                "OUTPUT_DIR": "."}

        self.job_ctxt = JobContext(params, self.job.id, oq_job=self.job)

        self.em = self._store_em()
        self._store_gmvs([0.40, 0.30, 0.45, 0.35, 0.40])

        self.calculator = ScenarioDamageRiskCalculator(self.job_ctxt)

        # just stubbing out some preprocessing stuff...
        ScenarioDamageRiskCalculator.store_exposure_assets = lambda self: None
        ScenarioDamageRiskCalculator.store_fragility_model = lambda self: None
        ScenarioDamageRiskCalculator.partition = lambda self: None
Example #2
0
class ScenarioDamageRiskCalculatorTestCase(
    unittest.TestCase, helpers.DbTestCase):

    def setUp(self):
        inputs = [("fragility", ""), ("exposure", "")]
        self.job = self.setup_classic_job(inputs=inputs)

        kvs.mark_job_as_current(self.job.id)
        kvs.cache_gc(self.job.id)

        self.site = Site(1.0, 1.0)
        block = Block(self.job.id, BLOCK_ID, [self.site])
        block.to_kvs()

        # this region contains a single site, that is exactly
        # a site with longitude == 1.0 and latitude == 1.0
        params = {"REGION_VERTEX": "1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0",
                "REGION_GRID_SPACING": "0.5", "BASE_PATH": ".",
                "OUTPUT_DIR": "."}

        self.job_ctxt = JobContext(params, self.job.id, oq_job=self.job)

        self.em = self._store_em()
        self._store_gmvs([0.40, 0.30, 0.45, 0.35, 0.40])

        self.calculator = ScenarioDamageRiskCalculator(self.job_ctxt)

        # just stubbing out some preprocessing stuff...
        ScenarioDamageRiskCalculator.store_exposure_assets = lambda self: None
        ScenarioDamageRiskCalculator.store_fragility_model = lambda self: None
        ScenarioDamageRiskCalculator.partition = lambda self: None

    def test_compute_risk_dda_con(self):
        # test the damage distribution per asset with a continuous
        # fragility model
        fm = self._store_con_fmodel()

        self.calculator.pre_execute()
        self.calculator.compute_risk(BLOCK_ID, fmodel=fm)

        [dda] = DmgDistPerAsset.objects.filter(output__oq_job=self.job.id,
                output__output_type="dmg_dist_per_asset")

        self.assertEquals(["no_damage", "LS1", "LS2"], dda.dmg_states)

        [exposure] = self.em.exposuredata_set.filter(asset_ref="A")
        [data] = DmgDistPerAssetData.objects.filter(dmg_dist_per_asset=dda,
                exposure_data=exposure, dmg_state="no_damage")

        self._close_to(1.00563, data.mean)
        self._close_to(1.61341, data.stddev)

        [data] = DmgDistPerAssetData.objects.filter(dmg_dist_per_asset=dda,
                exposure_data=exposure, dmg_state="LS1")

        self._close_to(34.80851, data.mean)
        self._close_to(18.34906, data.stddev)

        [data] = DmgDistPerAssetData.objects.filter(dmg_dist_per_asset=dda,
                exposure_data=exposure, dmg_state="LS2")

        self._close_to(64.18586, data.mean)
        self._close_to(19.83963, data.stddev)

        [exposure] = self.em.exposuredata_set.filter(asset_ref="B")
        [data] = DmgDistPerAssetData.objects.filter(dmg_dist_per_asset=dda,
                exposure_data=exposure, dmg_state="no_damage")

        self._close_to(3.64527, data.mean)
        self._close_to(3.35330, data.stddev)

        [data] = DmgDistPerAssetData.objects.filter(dmg_dist_per_asset=dda,
                exposure_data=exposure, dmg_state="LS1")

        self._close_to(17.10494, data.mean)
        self._close_to(4.63604, data.stddev)

        [data] = DmgDistPerAssetData.objects.filter(dmg_dist_per_asset=dda,
                exposure_data=exposure, dmg_state="LS2")

        self._close_to(19.24979, data.mean)
        self._close_to(7.78725, data.stddev)

    def test_compute_risk_dda_dsc(self):
        # test the damage distribution per asset with a discrete
        # fragility model
        fm = self._store_dsc_fmodel()

        self.calculator.pre_execute()
        self.calculator.compute_risk(BLOCK_ID, fmodel=fm)

        [dda] = DmgDistPerAsset.objects.filter(output__oq_job=self.job.id,
                output__output_type="dmg_dist_per_asset")

        self.assertEquals(["no_damage", "LS1", "LS2"], dda.dmg_states)

        [exposure] = self.em.exposuredata_set.filter(asset_ref="A")
        [data] = DmgDistPerAssetData.objects.filter(dmg_dist_per_asset=dda,
                exposure_data=exposure, dmg_state="no_damage")

        self._close_to(68.0, data.mean)
        self._close_to(8.5513157, data.stddev)

        [data] = DmgDistPerAssetData.objects.filter(dmg_dist_per_asset=dda,
                exposure_data=exposure, dmg_state="LS1")

        self._close_to(21.0, data.mean)
        self._close_to(4.2756578, data.stddev)

        [data] = DmgDistPerAssetData.objects.filter(dmg_dist_per_asset=dda,
                exposure_data=exposure, dmg_state="LS2")

        self._close_to(11.0, data.mean)
        self._close_to(4.2756578, data.stddev)

        [exposure] = self.em.exposuredata_set.filter(asset_ref="B")
        [data] = DmgDistPerAssetData.objects.filter(dmg_dist_per_asset=dda,
                exposure_data=exposure, dmg_state="no_damage")

        self._close_to(30.4, data.mean)
        self._close_to(3.4, data.stddev)

        [data] = DmgDistPerAssetData.objects.filter(dmg_dist_per_asset=dda,
                exposure_data=exposure, dmg_state="LS1")

        self._close_to(3.9, data.mean)
        self._close_to(1.4, data.stddev)

        [data] = DmgDistPerAssetData.objects.filter(dmg_dist_per_asset=dda,
                exposure_data=exposure, dmg_state="LS2")

        self._close_to(5.7, data.mean)
        self._close_to(2.1, data.stddev)

    def test_dda_iml_above_range(self):
        # corner case where we have a ground motion value
        # (that corresponds to the intensity measure level in the
        # fragility function) that is higher than the highest
        # intensity measure level defined in the model (in this
        # particular case 0.7). Given this condition, to compute
        # the fractions of buildings we use the highest intensity
        # measure level defined in the model (0.7 in this case)

        [ism] = models.inputs4job(self.job.id, input_type="fragility")

        fmodel = models.FragilityModel(
            owner=ism.owner, input=ism, imls=[0.1, 0.3, 0.5, 0.7],
            imt="mmi", lss=["LS1"], format="discrete")

        fmodel.save()

        func = models.Ffd(
            fragility_model=fmodel, taxonomy="RC",
            ls="LS1", poes=[0.05, 0.20, 0.50, 1.00], lsi=1)

        func.save()

        self._close_to(compute_gmv_fractions([func], 0.7),
                compute_gmv_fractions([func], 0.8))

    def test_dda_iml_below_range_damage_limit_undefined(self):
        # corner case where we have a ground motion value
        # (that corresponds to the intensity measure level in the
        # fragility function) that is lower than the lowest
        # intensity measure level defined in the model (in this
        # particular case 0.1). Given this condition, and without
        # having the no_damage_limit attribute defined, the
        # fractions of buildings is 100% no_damage and 0% for the
        # remaining limit states defined in the model
        [ism] = models.inputs4job(self.job.id, input_type="fragility")

        fmodel = models.FragilityModel(
            owner=ism.owner, input=ism, imls=[0.1, 0.3, 0.5, 0.7],
            imt="mmi", lss=["LS1"], format="discrete")

        fmodel.save()

        func = models.Ffd(
            fragility_model=fmodel, taxonomy="RC",
            ls="LS1", poes=[0.05, 0.20, 0.50, 1.00], lsi=1)

        func.save()

        self._close_to([1.0, 0.0],
            compute_gmv_fractions([func], 0.05))

    def test_dda_iml_below_range_damage_limit_defined(self):
        # corner case where we have a ground motion value
        # (that corresponds to the intensity measure level in the
        # fragility function) that is lower than the lowest
        # intensity measure level defined in the model (in this
        # particular case 0.1) and lower than the no_damage_limit
        # attribute defined in the model. Given this condition, the
        # fractions of buildings is 100% no_damage and 0% for the
        # remaining limit states defined in the model.

        [ism] = models.inputs4job(self.job.id, input_type="fragility")

        fmodel = models.FragilityModel(
            owner=ism.owner, input=ism, imls=[0.1, 0.3, 0.5, 0.7],
            imt="mmi", lss=["LS1"], format="discrete", no_damage_limit=0.05)

        fmodel.save()

        func = models.Ffd(
            fragility_model=fmodel, taxonomy="RC",
            ls="LS1", poes=[0.05, 0.20, 0.50, 1.00], lsi=1)

        func.save()

        self._close_to([1.0, 0.0],
            compute_gmv_fractions([func], 0.02))

    def test_gmv_between_no_damage_limit_and_first_iml(self):
        # corner case where we have a ground motion value
        # (that corresponds to the intensity measure level in the
        # fragility function) that is lower than the lowest
        # intensity measure level defined in the model (in this
        # particular case 0.1) but bigger than the no_damage_limit
        # attribute defined in the model. Given this condition, the
        # fractions of buildings is 97.5% no_damage and 2.5% for the
        # remaining limit states defined in the model.

        fm = self._store_dsc_fmodel()
        funcs = fm.ffd_set.filter(
            taxonomy="RC").order_by("lsi")

        self._close_to([0.975, 0.025, 0.],
            compute_gmv_fractions(funcs, 0.075))

    def test_post_execute_serialization(self):
        # when --output-type=xml is specified, we serialize results
        fm = self._store_con_fmodel()

        self.calculator.pre_execute()
        self.calculator.compute_risk(BLOCK_ID, fmodel=fm)

        # since the taxonomy data is computed and aggregated
        # per block in the execute() method and we are not
        # testing it here, just stubbing out some values to
        # produce the taxonomy distribution
        self.calculator.ddt_fractions = {"RC": numpy.array(
                [[1.0, 0.0, 0.0], [1.0, 0.0, 0.0]])}

        # stubbing out also the total distribution
        self.calculator.total_fractions = numpy.array([[1.0, 0.0, 0.0]])

        self.job_ctxt.serialize_results_to = ["xml"]
        self.calculator.post_execute()

        paths = self._results_files()

        for path in paths:
            self.assertTrue(os.path.exists(path))
            os.unlink(path)

    def test_post_execute_no_serialization(self):
        # otherwise, just on database (default)
        fm = self._store_con_fmodel()

        # stubbing out the total distribution
        self.calculator.total_fractions = numpy.array([[1.0, 0.0, 0.0]])

        self.calculator.pre_execute()
        self.calculator.compute_risk(BLOCK_ID, fmodel=fm)
        self.calculator.post_execute()

        paths = self._results_files()

        for path in paths:
            self.assertFalse(os.path.exists(path))

    def _results_files(self):
        target_dir = os.path.join(self.job_ctxt.params.get("BASE_PATH"),
                self.job_ctxt.params.get("OUTPUT_DIR"))

        return [os.path.join(
            target_dir, "dmg-dist-asset-%s.xml" % self.job.id), os.path.join(
            target_dir, "dmg-dist-taxonomy-%s.xml" % self.job.id),
            os.path.join(target_dir, "dmg-dist-total-%s.xml" % self.job.id),
            os.path.join(target_dir, "collapse-map-%s.xml" % self.job.id)]

    def _close_to(self, expected, actual):
        self.assertTrue(numpy.allclose(actual, expected, atol=0.0, rtol=0.05))

    def _store_gmvs(self, gmvs):
        client = kvs.get_client()
        encoder = json.JSONEncoder()

        key = ground_motion_values_key(self.job.id, self.site)

        for gmv in gmvs:
            client.rpush(key, encoder.encode({"mag": gmv}))

    def _store_con_fmodel(self):
        [ism] = models.inputs4job(self.job.id, input_type="fragility")

        fmodel = models.FragilityModel(
            owner=ism.owner, input=ism,
            lss=["LS1", "LS2"], format="continuous")

        fmodel.save()

        models.Ffc(
            fragility_model=fmodel, taxonomy="RC",
            ls="LS2", mean="0.35", stddev="0.10", lsi=2).save()

        models.Ffc(
            fragility_model=fmodel, taxonomy="RC",
            ls="LS1", mean="0.20", stddev="0.05", lsi=1).save()

        models.Ffc(
            fragility_model=fmodel, taxonomy="RM",
            ls="LS2", mean="0.40", stddev="0.12", lsi=2).save()

        models.Ffc(
            fragility_model=fmodel, taxonomy="RM",
            ls="LS1", mean="0.25", stddev="0.08", lsi=1).save()

        return fmodel

    def _store_dsc_fmodel(self):
        [ism] = models.inputs4job(self.job.id, input_type="fragility")

        fmodel = models.FragilityModel(
            owner=ism.owner, input=ism, imls=[0.1, 0.3, 0.5, 0.7],
            imt="mmi", lss=["LS1", "LS2"], format="discrete",
            no_damage_limit=0.05)

        fmodel.save()

        models.Ffd(
            fragility_model=fmodel, taxonomy="RC",
            ls="LS2", poes=[0.00, 0.05, 0.20, 0.50], lsi=2).save()

        models.Ffd(
            fragility_model=fmodel, taxonomy="RC",
            ls="LS1", poes=[0.05, 0.20, 0.50, 1.00], lsi=1).save()

        models.Ffd(
            fragility_model=fmodel, taxonomy="RM",
            ls="LS2", poes=[0.02, 0.07, 0.25, 0.60], lsi=2).save()

        models.Ffd(
            fragility_model=fmodel, taxonomy="RM",
            ls="LS1", poes=[0.03, 0.12, 0.42, 0.90], lsi=1).save()

        return fmodel

    def _store_em(self):
        [ism] = models.inputs4job(self.job.id, input_type="exposure")

        em = models.ExposureModel(
            owner=ism.owner, input=ism,
            name="AAA", category="single_asset",
            reco_type="aggregated", reco_unit="USD",
            stco_type="aggregated", stco_unit="USD")

        em.save()

        models.ExposureData(
            exposure_model=em, taxonomy="RC",
            asset_ref="A", number_of_units=100, stco=1,
            site=geos.GEOSGeometry(self.site.point.to_wkt()), reco=1).save()

        models.ExposureData(
            exposure_model=em, taxonomy="RM",
            asset_ref="B", number_of_units=40, stco=1,
            site=geos.GEOSGeometry(self.site.point.to_wkt()), reco=1).save()

        return em