예제 #1
0
    def test_invalid_form(self):
        rc = models.RiskCalculation(
            calculation_mode='scenario',
            owner=helpers.default_user(),
            region_constraint=(
                'POLYGON((-122.0 38.113, -122.114 38.113, -122.57 38.111, '
                '-122.0 38.113))'),
            maximum_distance=100,
            master_seed=666,
            asset_correlation='foo',
            insured_losses=True,
        )

        form = validation.ScenarioRiskForm(
            instance=rc,
            files=dict(occupants_vulnerability_file=object())
        )

        expected_errors = {
            'asset_correlation': [u'Enter a number.',
                                  u'Asset Correlation must be >= 0 and <= 1'],
             'time_event': ['Scenario Risk requires time_event when an '
                            'occupants vulnerability model is given'],
        }
        self.assertFalse(form.is_valid())
        self.assertEqual(expected_errors, dict(form.errors))
예제 #2
0
    def test_hazard_calculation_is_not_valid_missing_geom(self):
        expected_errors = {
            'region': ['Must specify either `region` or `sites`.'],
            'sites': ['Must specify either `region` or `sites`.'],
        }

        hc = models.HazardCalculation(
            owner=helpers.default_user(),
            description='',
            calculation_mode='classical',
            random_seed=37,
            number_of_logic_tree_samples=1,
            rupture_mesh_spacing=0.001,
            width_of_mfd_bin=0.001,
            area_source_discretization=0.001,
            reference_vs30_value=0.001,
            reference_vs30_type='measured',
            reference_depth_to_2pt5km_per_sec=0.001,
            reference_depth_to_1pt0km_per_sec=0.001,
            investigation_time=1.0,
            intensity_measure_types_and_levels=VALID_IML_IMT,
            truncation_level=0.0,
            maximum_distance=100.0,
            mean_hazard_curves=True,
            quantile_hazard_curves=[0.0, 0.5, 1.0],
            poes_hazard_maps=[1.0, 0.5, 0.0],
        )
        form = validation.ClassicalHazardForm(
            instance=hc, files=None
        )
        self.assertFalse(form.is_valid())

        self.assertEqual(expected_errors, dict(form.errors))
예제 #3
0
 def setUp(self):
     self.hc = models.HazardCalculation(
         owner=helpers.default_user(),
         description='',
         region=(
             'POLYGON((-122.0 38.113, -122.114 38.113, -122.57 38.111, '
             '-122.0 38.113))'
         ),
         region_grid_spacing=0.001,
         calculation_mode='classical',
         random_seed=37,
         number_of_logic_tree_samples=1,
         rupture_mesh_spacing=0.001,
         width_of_mfd_bin=0.001,
         area_source_discretization=0.001,
         reference_vs30_value=0.001,
         reference_vs30_type='measured',
         reference_depth_to_2pt5km_per_sec=0.001,
         reference_depth_to_1pt0km_per_sec=0.001,
         investigation_time=1.0,
         intensity_measure_types_and_levels=VALID_IML_IMT,
         truncation_level=0.0,
         maximum_distance=100.0,
         mean_hazard_curves=True,
         quantile_hazard_curves=[0.0, 0.5, 1.0],
         poes=[1.0, 0.5, 0.0],
     )
예제 #4
0
    def setUpClass(cls):
        default_user = helpers.default_user()

        cls.job = models.OqJob(owner=default_user)
        cls.job.save()

        # dmg dist per asset
        cls.ddpa_output = models.Output(
            owner=default_user, oq_job=cls.job,
            display_name='Test dmg dist per asset',
            output_type='dmg_dist_per_asset',
            db_backed=True)
        cls.ddpa_output.save()

        cls.ddpa = models.DmgDistPerAsset(
            output=cls.ddpa_output, dmg_states=cls.DMG_STATES)
        cls.ddpa.save()

        # We also need some sample exposure data records (to satisfy the dmg
        # dist per asset FK).
        test_input = models.Input(
            owner=default_user, input_type='exposure', path='fake', size=0)
        test_input.save()
        i2j = models.Input2job(input=test_input, oq_job=cls.job)
        i2j.save()
        exp_model = models.ExposureModel(
            owner=default_user, input=test_input, name='test-exp-model',
            category='economic loss', stco_type='per_asset', stco_unit='CHF')
        exp_model.save()

        test_site = shapes.Site(3.14, 2.17)
        cls.exp_data = models.ExposureData(  # Asset
            exposure_model=exp_model, asset_ref=helpers.random_string(),
            taxonomy=helpers.random_string(), number_of_units=37,
            site=test_site.point.to_wkt(), stco=1234.56)
        cls.exp_data.save()

        # dmg dist per taxonomy
        cls.ddpt_output = models.Output(
            owner=default_user, oq_job=cls.job,
            display_name='Test dmg dist per taxonomy',
            output_type='dmg_dist_per_taxonomy',
            db_backed=True)
        cls.ddpt_output.save()

        cls.ddpt = models.DmgDistPerTaxonomy(
            output=cls.ddpt_output, dmg_states=cls.DMG_STATES)
        cls.ddpt.save()

        # total dmg dist
        cls.ddt_output = models.Output(
            owner=default_user, oq_job=cls.job,
            display_name='Test dmg dist total',
            output_type='dmg_dist_total',
            db_backed=True)
        cls.ddt_output.save()

        cls.ddt = models.DmgDistTotal(
            output=cls.ddt_output, dmg_states=cls.DMG_STATES)
        cls.ddt.save()
예제 #5
0
    def test_hazard_calculation_is_valid_with_no_exports(self):
        # When the user does not specify '--exports' on the command line the
        # 'export_dir' parameter needs not be present in the .ini file.
        hc = models.HazardCalculation(
            owner=helpers.default_user(),
            description='',
            region=(
                'POLYGON((-122.0 38.113, -122.114 38.113, -122.57 38.111, '
                '-122.0 38.113))'
            ),
            region_grid_spacing=0.001,
            calculation_mode='classical',
            random_seed=37,
            number_of_logic_tree_samples=1,
            rupture_mesh_spacing=0.001,
            width_of_mfd_bin=0.001,
            area_source_discretization=0.001,
            reference_vs30_value=0.001,
            reference_vs30_type='measured',
            reference_depth_to_2pt5km_per_sec=0.001,
            reference_depth_to_1pt0km_per_sec=0.001,
            investigation_time=1.0,
            intensity_measure_types_and_levels=VALID_IML_IMT,
            truncation_level=0.0,
            maximum_distance=100.0,
            mean_hazard_curves=True,
            quantile_hazard_curves=[0.0, 0.5, 1.0],
            poes_hazard_maps=[1.0, 0.5, 0.0],
        )

        form = validation.ClassicalHazardForm(
            instance=hc, files=None
        )
        self.assertTrue(form.is_valid())
예제 #6
0
 def test_valid_disagg_calc(self):
     hc = models.HazardCalculation(
         owner=helpers.default_user(),
         description='',
         sites='MULTIPOINT((-122.114 38.113))',
         calculation_mode='disaggregation',
         random_seed=37,
         number_of_logic_tree_samples=1,
         rupture_mesh_spacing=0.001,
         width_of_mfd_bin=0.001,
         area_source_discretization=0.001,
         reference_vs30_value=0.001,
         reference_vs30_type='measured',
         reference_depth_to_2pt5km_per_sec=0.001,
         reference_depth_to_1pt0km_per_sec=0.001,
         investigation_time=1.0,
         intensity_measure_types_and_levels=VALID_IML_IMT_STR,
         truncation_level=0.1,
         maximum_distance=100.0,
         mag_bin_width=0.3,
         distance_bin_width=10.0,
         coordinate_bin_width=0.02,  # decimal degrees
         num_epsilon_bins=4,
         poes_disagg=[0.02, 0.1],
     )
     form = validation.DisaggHazardForm(
         instance=hc, files=None
     )
     self.assertTrue(form.is_valid(), dict(form.errors))
예제 #7
0
 def test_hazard_calculation_is_valid_region_only_as_str_list(self):
     hc = models.HazardCalculation(
         owner=helpers.default_user(),
         description='',
         region='-122.0, 38.113, -122.114, 38.113, -122.57, 38.111',
         region_grid_spacing=0.001,
         calculation_mode='classical',
         random_seed=37,
         number_of_logic_tree_samples=1,
         rupture_mesh_spacing=0.001,
         width_of_mfd_bin=0.001,
         area_source_discretization=0.001,
         reference_vs30_value=0.001,
         reference_vs30_type='measured',
         reference_depth_to_2pt5km_per_sec=0.001,
         reference_depth_to_1pt0km_per_sec=0.001,
         investigation_time=1.0,
         intensity_measure_types_and_levels=VALID_IML_IMT,
         truncation_level=0.0,
         maximum_distance=100.0,
         mean_hazard_curves=True,
         quantile_hazard_curves=[0.0, 0.5, 1.0],
         poes_hazard_maps=[1.0, 0.5, 0.0],
     )
     form = validation.ClassicalHazardForm(
         instance=hc, files=None
     )
     self.assertTrue(form.is_valid(), dict(form.errors))
예제 #8
0
    def test_invalid_scenario_calc(self):
        expected_errors = {
            'gsim': ["The gsim u'BooreAtkinson208' is not in in \
openquake.hazardlib.gsim"],
            'number_of_ground_motion_fields': [
                'The number_of_ground_motion_fields must be a positive '
                'integer, got -10']
        }

        hc = models.HazardCalculation(
            owner=helpers.default_user(),
            description='',
            sites='MULTIPOINT((-122.114 38.113))',
            calculation_mode='scenario',
            random_seed=37,
            rupture_mesh_spacing=0.001,
            reference_vs30_value=0.001,
            reference_vs30_type='measured',
            reference_depth_to_2pt5km_per_sec=0.001,
            reference_depth_to_1pt0km_per_sec=0.001,
            intensity_measure_types=VALID_IML_IMT.keys(),
            truncation_level=0.1,
            maximum_distance=100.0,
            gsim='BooreAtkinson208',
            ground_motion_correlation_model='JB2009',
            number_of_ground_motion_fields=-10,
        )
        form = validation.ScenarioHazardForm(
            instance=hc, files=None
        )

        self.assertFalse(form.is_valid())
        equal, err = helpers.deep_eq(expected_errors, dict(form.errors))
        self.assertTrue(equal, err)
예제 #9
0
    def test_invalid_form(self):
        rc = models.RiskCalculation(
            calculation_mode="event_based",
            owner=helpers.default_user(),
            region_constraint=(
                'POLYGON((-122.0 38.113, -122.114 38.113, -122.57 38.111, '
                '-122.0 38.113))'),
            hazard_output=self.job.risk_calculation.hazard_output,
            sites_disagg='-180.1 38.113, -122.114 38.113',
            coordinate_bin_width=0.0,
            loss_curve_resolution=0,
            mag_bin_width=0.0,
        )

        expected_errors = {
            'coordinate_bin_width': ['Coordinate bin width must be > 0.0'],
            'distance_bin_width': ['Distance bin width must be > 0.0'],
            'loss_curve_resolution': ['Loss Curve Resolution must be >= 1'],
            'mag_bin_width': ['Magnitude bin width must be > 0.0'],
            'sites_disagg': ['Longitude values must in the range [-180, 180]',
                             'disaggregation requires mag_bin_width, '
                             'coordinate_bin_width, distance_bin_width'],
        }

        form = validation.EventBasedRiskForm(
            instance=rc, files=None)
        self.assertFalse(form.is_valid())
        self.assertEqual(expected_errors, dict(form.errors))
예제 #10
0
 def test_hazard_calculation_is_valid_with_site_model(self):
     hc = models.HazardCalculation(
         owner=helpers.default_user(),
         description='',
         region=(
             'POLYGON((-122.0 38.113, -122.114 38.113, -122.57 38.111, '
             '-122.0 38.113))'
         ),
         region_grid_spacing=0.001,
         calculation_mode='classical',
         random_seed=37,
         number_of_logic_tree_samples=1,
         rupture_mesh_spacing=0.001,
         width_of_mfd_bin=0.001,
         area_source_discretization=0.001,
         # The 4 `reference` parameters should be ignored since the site
         # model file is specified.
         # We can define invalid values here; the validator shouldn't care.
         reference_vs30_value=0,
         reference_vs30_type=None,
         reference_depth_to_2pt5km_per_sec=0,
         reference_depth_to_1pt0km_per_sec=0,
         investigation_time=1.0,
         intensity_measure_types_and_levels=VALID_IML_IMT,
         truncation_level=0.0,
         maximum_distance=100.0,
         mean_hazard_curves=True,
         quantile_hazard_curves=[0.0, 0.5, 1.0],
         poes_hazard_maps=[1.0, 0.5, 0.0],
     )
     form = validation.ClassicalHazardForm(
         instance=hc, files=dict(site_model_file=object())
     )
     self.assertTrue(form.is_valid(), dict(form.errors))
예제 #11
0
    def test_serialize(self):
        parser = nrml_parsers.SourceModelParser(MIXED_SRC_MODEL)
        source_model = parser.parse()

        inp = models.Input(
            owner=helpers.default_user(),
            digest='fake',
            path='fake',
            input_type='source',
            size=0
        )
        inp.save()

        db_writer = source_input.SourceDBWriter(
            inp, source_model, MESH_SPACING, BIN_WIDTH, AREA_SRC_DISC
        )
        db_writer.serialize()

        # Check that everything was saved properly.

        # First, check the Input:
        # refresh the record
        [inp] = models.Input.objects.filter(id=inp.id)
        self.assertEquals(source_model.name, inp.name)

        # re-reparse the test file for comparisons:
        nrml_sources = list(
            nrml_parsers.SourceModelParser(MIXED_SRC_MODEL).parse()
        )

        parsed_sources = list(models.ParsedSource.objects.filter(input=inp.id))

        # compare pristine nrml sources to those stored in pickled form in the
        # database (by unpickling them first, of course):
        for i, ns in enumerate(nrml_sources):
            self.assertTrue(*helpers.deep_eq(ns, parsed_sources[i].nrml))

        # now check that the ParsedSource geometry is correct
        # it should be the same as the 'rupture-enclosing' geometry for the
        # nhlib representation of each source
        for i, (ns, ps) in enumerate(zip(nrml_sources, parsed_sources)):
            nhlib_src = source_input.nrml_to_nhlib(
                ns, MESH_SPACING, BIN_WIDTH, AREA_SRC_DISC
            )

            nhlib_poly = nhlib_src.get_rupture_enclosing_polygon()
            # nhlib tests the generation of wkt from a polygon, so we can trust
            # that it is well-formed.

            # Since we save the rupture enclosing polygon as geometry (not wkt)
            # in the database, the WKT we get back from the DB might have
            # slightly different coordinate values (a difference in precision).
            # shapely can help us compare two polygons (generated from wkt)
            # at a specific level of precision (default=6 digits after the
            # decimal point).
            expected_poly = wkt.loads(ps.polygon.wkt)
            actual_poly = wkt.loads(nhlib_poly.wkt)

            self.assertTrue(expected_poly.almost_equals(actual_poly))
예제 #12
0
    def test_a_few_inputs(self):
        cfg = helpers.get_data_path('simple_fault_demo_hazard/job.ini')
        params, files = engine.parse_config(open(cfg, 'r'))
        owner = helpers.default_user()
        hc = engine.create_hazard_calculation(
            owner.user_name, params, files
        )

        inputs = models.inputs4hcalc(hc.id)
        # We expect 3: the two logic trees and one source model
        self.assertEqual(3, inputs.count())
예제 #13
0
    def test_valid_form_with_default_resolution(self):
        rc = models.RiskCalculation(
            calculation_mode="event_based",
            owner=helpers.default_user(),
            region_constraint=(
                'POLYGON((-122.0 38.113, -122.114 38.113, -122.57 38.111, '
                '-122.0 38.113))'),
            hazard_output=self.job.risk_calculation.hazard_output)

        form = validation.EventBasedRiskForm(
            instance=rc, files=None)
        self.assertTrue(form.is_valid(), dict(form.errors))
예제 #14
0
    def test_create_risk_calculation(self):
        # we need an hazard output to create a risk calculation
        hazard_cfg = helpers.get_data_path('simple_fault_demo_hazard/job.ini')
        hazard_job = helpers.get_hazard_job(hazard_cfg, 'openquake')
        hc = hazard_job.hazard_calculation
        rlz = models.LtRealization.objects.create(
            hazard_calculation=hazard_job.hazard_calculation,
            ordinal=1, seed=1, weight=None,
            sm_lt_path="test_sm", gsim_lt_path="test_gsim",
            is_complete=False, total_items=1, completed_items=1)
        hazard_output = models.HazardCurve.objects.create(
            lt_realization=rlz,
            output=models.Output.objects.create_output(
                hazard_job, "Test Hazard output", "hazard_curve"),
            investigation_time=hc.investigation_time,
            imt="PGA", imls=[0.1, 0.2, 0.3])
        params = {
            'hazard_output_id': hazard_output.output.id,
            'base_path': 'path/to/job.ini',
            'export_dir': '/tmp/xxx',
            'calculation_mode': 'classical',
            # just some sample params
            'lrem_steps_per_interval': 5,
            'conditional_loss_poes': '0.01, 0.02, 0.05',
            'region_constraint': '-0.5 0.5, 0.5 0.5, 0.5 -0.5, -0.5, -0.5',
        }

        owner = helpers.default_user()

        vuln_file = models.Input(digest='123', path='/foo/bar', size=0,
                                 input_type='structural_vulnerability',
                                 owner=owner)
        vuln_file.save()
        exposure_file = models.Input(digest='456', path='/foo/baz', size=0,
                                     input_type='exposure', owner=owner)
        exposure_file.save()

        files = [vuln_file, exposure_file]

        rc = engine.create_risk_calculation(owner, params, files)
        # Normalize/clean fields by fetching a fresh copy from the db.
        rc = models.RiskCalculation.objects.get(id=rc.id)

        self.assertEqual(rc.calculation_mode, 'classical')
        self.assertEqual(rc.lrem_steps_per_interval, 5)
        self.assertEqual(rc.conditional_loss_poes, [0.01, 0.02, 0.05])
        self.assertEqual(
            rc.region_constraint.wkt,
            ('POLYGON ((-0.5000000000000000 0.5000000000000000, '
             '0.5000000000000000 0.5000000000000000, '
             '0.5000000000000000 -0.5000000000000000, '
             '-0.5000000000000000 -0.5000000000000000, '
             '-0.5000000000000000 0.5000000000000000))'))
예제 #15
0
 def setUp(self):
     job, _ = helpers.get_risk_job('classical_psha_based_risk/job.ini',
                                   'simple_fault_demo_hazard/job.ini')
     self.compulsory_arguments = dict(
         calculation_mode="classical",
         lrem_steps_per_interval=5)
     self.other_args = dict(
         owner=helpers.default_user(),
         region_constraint=(
             'POLYGON((-122.0 38.113, -122.114 38.113, -122.57 38.111, '
             '-122.0 38.113))'),
         hazard_output=job.risk_calculation.hazard_output)
예제 #16
0
    def test_with_input_type(self):
        cfg = helpers.get_data_path('simple_fault_demo_hazard/job.ini')
        params, files = engine.parse_config(open(cfg, 'r'))
        owner = helpers.default_user()
        hc = engine.create_hazard_calculation(
            owner.user_name, params, files
        )

        inputs = models.inputs4hcalc(
            hc.id, input_type='source_model_logic_tree'
        )
        self.assertEqual(1, inputs.count())
예제 #17
0
    def test_a_few_inputs(self):
        cfg = helpers.demo_file('simple_fault_demo_hazard/job.ini')
        params, files = engine2.parse_config(open(cfg, 'r'), force_inputs=True)
        owner = helpers.default_user()
        hc = engine2.create_hazard_calculation(owner, params, files.values())

        expected_ids = sorted([x.id for x in files.values()])

        inputs = models.inputs4hcalc(hc.id)

        actual_ids = sorted([x.id for x in inputs])

        self.assertEqual(expected_ids, actual_ids)
예제 #18
0
    def test_invalid_form(self):
        rc = models.RiskCalculation(
            calculation_mode="event_based",
            owner=helpers.default_user(),
            loss_curve_resolution=-10,
            region_constraint=(
                'POLYGON((-122.0 38.113, -122.114 38.113, -122.57 38.111, '
                '-122.0 38.113))'),
            hazard_output=self.job.risk_calculation.hazard_output)

        form = validation.EventBasedRiskCalculationForm(
            instance=rc, files=None)
        self.assertFalse(form.is_valid())
예제 #19
0
    def test(self):
        # check that if risk models are provided, then the ``points to
        # compute`` and the imls are got from there

        username = helpers.default_user().user_name

        job = engine.prepare_job(username)

        cfg = helpers.get_data_path('classical_job-sd-imt.ini')
        params, files = engine.parse_config(open(cfg, 'r'))

        haz_calc = engine.create_hazard_calculation(
            job.owner.user_name, params, files)
        haz_calc = models.HazardCalculation.objects.get(id=haz_calc.id)
        job.hazard_calculation = haz_calc
        job.is_running = True
        job.save()

        base_path = ('openquake.engine.calculators.hazard.classical.core'
                     '.ClassicalHazardCalculator')
        init_src_patch = helpers.patch(
            '%s.%s' % (base_path, 'initialize_sources'))
        init_sm_patch = helpers.patch(
            '%s.%s' % (base_path, 'initialize_site_model'))
        init_rlz_patch = helpers.patch(
            '%s.%s' % (base_path, 'initialize_realizations'))
        record_stats_patch = helpers.patch(
            '%s.%s' % (base_path, 'record_init_stats'))
        init_pr_data_patch = helpers.patch(
            '%s.%s' % (base_path, 'initialize_pr_data'))
        patches = (init_src_patch, init_sm_patch, init_rlz_patch,
                   record_stats_patch, init_pr_data_patch)

        mocks = [p.start() for p in patches]

        get_calculator_class(
            'hazard',
            job.hazard_calculation.calculation_mode)(job).pre_execute()

        self.assertEqual([(1.0, -1.0), (0.0, 0.0)],
                         [(point.latitude, point.longitude)
                          for point in haz_calc.points_to_compute()])
        self.assertEqual(['PGA'], haz_calc.get_imts())

        self.assertEqual(3, haz_calc.exposure_model.exposuredata_set.count())

        for i, m in enumerate(mocks):
            m.stop()
            patches[i].stop()

        return job
예제 #20
0
    def test_hazard_curves_from_gmf_invalid_iml_imt(self):
        # Test a configuration where the user has requested to post-process
        # GMFs into hazard curves.
        # In this case, the configuration has the required
        # `intensity_measure_types_and_levels`, but the IMTs are not a subset
        # of `intensity_measure_types`.
        expected_errors = {
            'intensity_measure_types_and_levels': [
                'Unknown IMT(s) [SA(0)] in `intensity_measure_types`'],
        }
        iml_imt = VALID_IML_IMT.keys()
        iml_imt.pop()

        hc = models.HazardCalculation(
            owner=helpers.default_user(),
            description='',
            region=(
                'POLYGON((-122.0 38.113, -122.114 38.113, -122.57 38.111, '
                '-122.0 38.113))'
            ),
            region_grid_spacing=0.001,
            calculation_mode='event_based',
            random_seed=37,
            number_of_logic_tree_samples=1,
            rupture_mesh_spacing=0.001,
            width_of_mfd_bin=0.001,
            area_source_discretization=0.001,
            reference_vs30_value=0.001,
            reference_vs30_type='measured',
            reference_depth_to_2pt5km_per_sec=0.001,
            reference_depth_to_1pt0km_per_sec=0.001,
            investigation_time=1.0,
            intensity_measure_types=iml_imt,
            intensity_measure_types_and_levels=VALID_IML_IMT,
            truncation_level=0.0,
            maximum_distance=100.0,
            ses_per_logic_tree_path=5,
            ground_motion_correlation_model='JB2009',
            ground_motion_correlation_params={"vs30_clustering": True},
            complete_logic_tree_ses=False,
            complete_logic_tree_gmf=True,
            ground_motion_fields=True,
            hazard_curves_from_gmfs=True,
        )
        form = validation.EventBasedHazardForm(
            instance=hc, files=None
        )

        self.assertFalse(form.is_valid())
        equal, err = helpers.deep_eq(expected_errors, dict(form.errors))
        self.assertTrue(equal, err)
예제 #21
0
    def test(self):
        # check that if risk models are provided, then the ``points to
        # compute`` and the imls are got from there

        username = helpers.default_user()

        job = engine.prepare_job(username)

        cfg = helpers.get_data_path('classical_job-sd-imt.ini')
        params = engine.parse_config(open(cfg, 'r'))

        haz_calc = engine.create_calculation(models.HazardCalculation, params)
        haz_calc = models.HazardCalculation.objects.get(id=haz_calc.id)
        job.hazard_calculation = haz_calc
        job.is_running = True
        job.save()

        base_path = ('openquake.engine.calculators.hazard.classical.core'
                     '.ClassicalHazardCalculator')
        init_src_patch = helpers.patch('%s.%s' %
                                       (base_path, 'initialize_sources'))
        init_sm_patch = helpers.patch('%s.%s' %
                                      (base_path, 'initialize_site_model'))
        init_rlz_patch = helpers.patch('%s.%s' %
                                       (base_path, 'initialize_realizations'))
        record_stats_patch = helpers.patch('%s.%s' %
                                           (base_path, 'record_init_stats'))
        init_pr_data_patch = helpers.patch('%s.%s' %
                                           (base_path, 'initialize_pr_data'))
        patches = (init_src_patch, init_sm_patch, init_rlz_patch,
                   record_stats_patch, init_pr_data_patch)

        mocks = [p.start() for p in patches]

        get_calculator_class(
            'hazard',
            job.hazard_calculation.calculation_mode)(job).pre_execute()

        self.assertEqual([(1.0, -1.0), (0.0, 0.0)],
                         [(point.latitude, point.longitude)
                          for point in haz_calc.points_to_compute()])
        self.assertEqual(['PGA'], haz_calc.get_imts())

        self.assertEqual(3,
                         haz_calc.oqjob.exposuremodel.exposuredata_set.count())

        for i, m in enumerate(mocks):
            m.stop()
            patches[i].stop()

        return job
예제 #22
0
    def test_with_input_type(self):
        cfg = helpers.demo_file("simple_fault_demo_hazard/job.ini")
        params, files = engine2.parse_config(open(cfg, "r"), force_inputs=True)
        owner = helpers.default_user()
        hc = engine2.create_hazard_calculation(owner, params, files.values())

        # It should only be 1 id, actually.
        expected_ids = [x.id for x in files.values() if x.input_type == "lt_source"]

        inputs = models.inputs4hcalc(hc.id, input_type="lt_source")

        actual_ids = sorted([x.id for x in inputs])

        self.assertEqual(expected_ids, actual_ids)
예제 #23
0
    def test_invalid_disagg_calc(self):
        expected_errors = {
            'mag_bin_width': ['Magnitude bin width must be > 0.0'],
            'distance_bin_width': ['Distance bin width must be > 0.0'],
            'coordinate_bin_width': ['Coordinate bin width must be > 0.0'],
            'num_epsilon_bins': ['Number of epsilon bins must be > 0'],
            'truncation_level': ['Truncation level must be > 0 for'
                                 ' disaggregation calculations'],
            'poes_disagg': ['PoEs for disaggregation must be in the range'
                            ' [0, 1]'],
        }

        hc = models.HazardCalculation(
            owner=helpers.default_user(),
            description='',
            sites='MULTIPOINT((-122.114 38.113))',
            calculation_mode='disaggregation',
            random_seed=37,
            number_of_logic_tree_samples=1,
            rupture_mesh_spacing=0.001,
            width_of_mfd_bin=0.001,
            area_source_discretization=0.001,
            reference_vs30_value=0.001,
            reference_vs30_type='measured',
            reference_depth_to_2pt5km_per_sec=0.001,
            reference_depth_to_1pt0km_per_sec=0.001,
            investigation_time=1.0,
            intensity_measure_types_and_levels=VALID_IML_IMT_STR,
            truncation_level=0.0,
            maximum_distance=100.0,
            mag_bin_width=0.0,
            distance_bin_width=0.0,
            coordinate_bin_width=0.0,  # decimal degrees
            num_epsilon_bins=0,
            poes_disagg=[1.00001, -0.5, 0.0],
        )
        form = validation.DisaggHazardForm(instance=hc, files=None)

        self.assertFalse(form.is_valid())
        equal, err = helpers.deep_eq(expected_errors, dict(form.errors))
        self.assertTrue(equal, err)

        # test with an empty `poes_disagg` list
        hc.poes_disagg = []
        form = validation.DisaggHazardForm(instance=hc, files=None)
        expected_errors['poes_disagg'] = [(
            '`poes_disagg` must contain at least 1 value')]
        self.assertFalse(form.is_valid())
        equal, err = helpers.deep_eq(expected_errors, dict(form.errors))
        self.assertTrue(equal, err)
예제 #24
0
    def test_hazard_calculation_is_not_valid_region_only(self):
        expected_errors = {
            'region_grid_spacing': ['Region grid spacing must be > 0'],
            'region': [
                'Invalid region geomerty: Self-intersection[0 0]',
                'Region geometry can only be a single linear ring',
                'Longitude values must in the range [-180, 180]',
                'Latitude values must be in the range [-90, 90]'],
            'reference_vs30_value': ['Reference VS30 value must be > 0'],
            'reference_vs30_type': [
                'Reference VS30 type must be either "measured" or "inferred"',
            ],
            'reference_depth_to_1pt0km_per_sec': [
                'Reference depth to 1.0 km/sec must be > 0',
            ],
            'reference_depth_to_2pt5km_per_sec': [
                'Reference depth to 2.5 km/sec must be > 0',
            ],
        }

        hc = models.HazardCalculation(
            owner=helpers.default_user(),
            description='',
            region=(
                'POLYGON((-180.001 90.001, 180.001 -90.001, -179.001 -89.001, '
                '179.001 89.001, -180.001 90.001), (1 1, 2 2, 3 3, 4 4, 1 1))'
            ),
            region_grid_spacing=0,
            calculation_mode='classical',
            random_seed=2147483647,
            number_of_logic_tree_samples=1,
            rupture_mesh_spacing=1,
            width_of_mfd_bin=1,
            area_source_discretization=1,
            investigation_time=1,
            intensity_measure_types_and_levels=VALID_IML_IMT,
            truncation_level=0,
            maximum_distance=1,
            quantile_hazard_curves=[0.0, 0.1, 1.0],
            poes_hazard_maps=[1.0, 0.5, 0.0],
        )

        form = validation.ClassicalHazardForm(
            instance=hc, files=None
        )

        self.assertFalse(form.is_valid())
        equal, err = helpers.deep_eq(expected_errors, dict(form.errors))
        self.assertTrue(equal, err)
예제 #25
0
    def test_invalid_imts(self):
        expected_errors = {
            'intensity_measure_types': [
                'SA(-0.1): SA period values must be >= 0',
                ('SA<2.5>: SA must be specified with a period value, in the '
                 'form `SA(N)`, where N is a value >= 0'),
                'SA(2x): SA period value should be a float >= 0',
                'PGZ: Invalid intensity measure type',
            ],
        }

        hc = models.HazardCalculation(
            owner=helpers.default_user(),
            description='',
            region=(
                'POLYGON((-122.0 38.113, -122.114 38.113, -122.57 38.111, '
                '-122.0 38.113))'
            ),
            region_grid_spacing=0.001,
            calculation_mode='event_based',
            random_seed=37,
            number_of_logic_tree_samples=1,
            rupture_mesh_spacing=0.001,
            width_of_mfd_bin=0.001,
            area_source_discretization=0.001,
            reference_vs30_value=0.001,
            reference_vs30_type='measured',
            reference_depth_to_2pt5km_per_sec=0.001,
            reference_depth_to_1pt0km_per_sec=0.001,
            investigation_time=1.0,
            intensity_measure_types=INVALID_IML_IMT.keys(),
            truncation_level=0.0,
            maximum_distance=100.0,
            ses_per_logic_tree_path=5,
            ground_motion_correlation_model='JB2009',
            ground_motion_correlation_params={"vs30_clustering": True},
            complete_logic_tree_ses=False,
            complete_logic_tree_gmf=True,
            ground_motion_fields=True,
        )
        form = validation.EventBasedHazardForm(
            instance=hc, files=None
        )

        self.assertFalse(form.is_valid())
        equal, err = helpers.deep_eq(expected_errors, dict(form.errors))
        self.assertTrue(equal, err)
예제 #26
0
    def test_with_input_type(self):
        cfg = helpers.get_data_path('simple_fault_demo_hazard/job.ini')
        params, files = engine.parse_config(open(cfg, 'r'))
        owner = helpers.default_user()
        hc = engine.create_hazard_calculation(owner, params, files.values())

        # It should only be 1 id, actually.
        expected_ids = [x.id for x in files.values()
                        if x.input_type == 'source_model_logic_tree']

        inputs = models.inputs4hcalc(
            hc.id, input_type='source_model_logic_tree'
        )

        actual_ids = sorted([x.id for x in inputs])

        self.assertEqual(expected_ids, actual_ids)
예제 #27
0
    def test_invalid_form(self):
        region_constraint = (
            'POLYGON((-122.0 38.113, -122.114 38.113, '
            '-122.57 38.111, -122.0 38.113))'
        )

        rc = models.RiskCalculation(
            calculation_mode="event_based_bcr",
            owner=helpers.default_user(),
            region_constraint=region_constraint,
            hazard_output=self.job.risk_calculation.hazard_output,
        )

        form = validation.EventBasedBCRRiskForm(
            instance=rc, files=None)

        self.assertFalse(form.is_valid())
예제 #28
0
    def test_invalid_params_complet_lt_gmf_with_eb_enum(self):
        # When the `complete_logic_tree_gmf` is requested with end-branch
        # enumeration, this is not allowed. (The complete LT GMF is not a
        # useful artifact in this case.)
        expected_errors = {
            'complete_logic_tree_gmf': [
                '`complete_logic_tree_gmf` is not available with end branch '
                'enumeration'],
        }

        hc = models.HazardCalculation(
            owner=helpers.default_user(),
            description='',
            region=(
                'POLYGON((-122.0 38.113, -122.114 38.113, -122.57 38.111, '
                '-122.0 38.113))'
            ),
            region_grid_spacing=0.001,
            calculation_mode='event_based',
            random_seed=37,
            number_of_logic_tree_samples=0,
            rupture_mesh_spacing=0.001,
            width_of_mfd_bin=0.001,
            area_source_discretization=0.001,
            reference_vs30_value=0.001,
            reference_vs30_type='measured',
            reference_depth_to_2pt5km_per_sec=0.001,
            reference_depth_to_1pt0km_per_sec=0.001,
            investigation_time=1.0,
            intensity_measure_types=VALID_IML_IMT.keys(),
            truncation_level=0.0,
            maximum_distance=100.0,
            ses_per_logic_tree_path=5,
            ground_motion_correlation_model='JB2009',
            ground_motion_correlation_params={"vs30_clustering": True},
            complete_logic_tree_ses=False,
            complete_logic_tree_gmf=True,
            ground_motion_fields=True,
        )
        form = validation.EventBasedHazardForm(
            instance=hc, files=None
        )

        self.assertFalse(form.is_valid())
        equal, err = helpers.deep_eq(expected_errors, dict(form.errors))
        self.assertTrue(equal, err)
예제 #29
0
    def setUp(self):
        job, _ = helpers.get_fake_risk_job(
            get_data_path('classical_psha_based_risk/job.ini'),
            get_data_path('simple_fault_demo_hazard/job.ini')
        )
        self.compulsory_arguments = dict(
            calculation_mode="classical_bcr",
            lrem_steps_per_interval=5,
            interest_rate=0.05,
            asset_life_expectancy=40)

        self.other_args = dict(
            owner=helpers.default_user(),
            region_constraint=(
                'POLYGON((-122.0 38.113, -122.114 38.113, -122.57 38.111, '
                '-122.0 38.113))'),
            hazard_output=job.risk_calculation.hazard_output)
예제 #30
0
    def test_valid_event_based_params(self):
        subset_iml_imt = VALID_IML_IMT.copy()
        subset_iml_imt.pop('PGA')

        hc = models.HazardCalculation(
            owner=helpers.default_user(),
            description='',
            region=(
                'POLYGON((-122.0 38.113, -122.114 38.113, -122.57 38.111, '
                '-122.0 38.113))'
            ),
            region_grid_spacing=0.001,
            calculation_mode='event_based',
            random_seed=37,
            number_of_logic_tree_samples=1,
            rupture_mesh_spacing=0.001,
            width_of_mfd_bin=0.001,
            area_source_discretization=0.001,
            reference_vs30_value=0.001,
            reference_vs30_type='measured',
            reference_depth_to_2pt5km_per_sec=0.001,
            reference_depth_to_1pt0km_per_sec=0.001,
            investigation_time=1.0,
            intensity_measure_types=VALID_IML_IMT.keys(),
            # intensity_measure_types_and_levels just needs to be a subset of
            # intensity_measure_types
            intensity_measure_types_and_levels=subset_iml_imt,
            truncation_level=0.0,
            maximum_distance=100.0,
            ses_per_logic_tree_path=5,
            ground_motion_correlation_model='JB2009',
            ground_motion_correlation_params={"vs30_clustering": True},
            complete_logic_tree_ses=False,
            complete_logic_tree_gmf=True,
            ground_motion_fields=True,
            hazard_curves_from_gmfs=True,
            mean_hazard_curves=True,
            quantile_hazard_curves=[0.5, 0.95],
            poes_hazard_maps=[0.1, 0.2],
        )
        form = validation.EventBasedHazardForm(
            instance=hc, files=None
        )

        self.assertTrue(form.is_valid(), dict(form.errors))
예제 #31
0
 def _create_haz_calc(cls):
     params = {
         'base_path': 'a/fake/path',
         'calculation_mode': 'classical',
         'region': '1 1 2 2 3 3',
         'width_of_mfd_bin': '1',
         'rupture_mesh_spacing': '1',
         'area_source_discretization': '2',
         'investigation_time': 50,
         'truncation_level': 0,
         'maximum_distance': 200,
         'number_of_logic_tree_samples': 1,
         'intensity_measure_types_and_levels': dict(PGA=[1, 2, 3, 4]),
         'random_seed': 37,
     }
     owner = helpers.default_user()
     hc = engine2.create_hazard_calculation(owner, params, [])
     return hc
예제 #32
0
    def test_import_job_profile(self):
        # Given a path to a demo config file, ensure that the appropriate
        # database record for OqJobProfile is created.

        # At the moment, the api function used to import the job profile also
        # returns a dict of the config params and a list of config file
        # sections.

        cfg_path = helpers.demo_file('HazardMapTest/config.gem')

        # Default 'openquake' user:
        owner = helpers.default_user()

        smlt_input = models.Input(
            owner=helpers.default_user(),
            path=os.path.abspath(helpers.demo_file(
                'HazardMapTest/source_model_logic_tree.xml')),
            input_type='lt_source', size=671,
            digest="4372d13cec89f2a1072a2c7c694656d0")

        gmpelt_input = models.Input(
            owner=helpers.default_user(),
            path=os.path.abspath(helpers.demo_file(
                'HazardMapTest/gmpe_logic_tree.xml')),
            input_type='lt_gmpe', size=709,
            digest="d9ece248a1e73ee25bd5964670282012")

        src_model_input = models.Input(
            owner=helpers.default_user(),
            path=os.path.abspath(helpers.demo_file(
                'HazardMapTest/source_model.xml')),
            input_type='source', size=1644,
            digest="3118538b30b69289e6ea47967e9f51aa")

        expected_inputs_map = dict(
            lt_source=smlt_input, lt_gmpe=gmpelt_input, source=src_model_input)

        expected_jp = models.OqJobProfile(
            owner=owner,
            calc_mode='classical',
            job_type=['hazard'],
            region=GEOSGeometry(
                    'POLYGON((-122.2 37.6, -122.2 38.2, '
                    '-121.5 38.2, -121.5 37.6, -122.2 37.6))'),
            region_grid_spacing=0.01,
            min_magnitude=5.0,
            investigation_time=50.0,
            maximum_distance=200.0,
            component='gmroti50',
            imt='pga',
            period=None,
            damping=None,
            truncation_type='twosided',
            truncation_level=3.0,
            imls=[
                0.005, 0.007, 0.0098, 0.0137, 0.0192, 0.0269, 0.0376, 0.0527,
                0.0738, 0.103, 0.145, 0.203, 0.284, 0.397, 0.556, 0.778, 1.09],
            poes=[0.1],
            realizations=1,
            depth_to_1pt_0km_per_sec=100.0,
            vs30_type='measured',
            source_model_lt_random_seed=23,
            gmpe_lt_random_seed=5,
            width_of_mfd_bin=0.1,
            standard_deviation_type='total',
            reference_vs30_value=760.0,
            reference_depth_to_2pt5km_per_sec_param=5.0,
            sadigh_site_type='rock',
            # area sources:
            include_area_sources=True,
            treat_area_source_as='pointsources',
            area_source_discretization=0.1,
            area_source_magnitude_scaling_relationship=(
                'W&C 1994 Mag-Length Rel.'),
            # point sources:
            include_grid_sources=False,
            treat_grid_source_as='pointsources',
            grid_source_magnitude_scaling_relationship=(
                'W&C 1994 Mag-Length Rel.'),
            # simple faults:
            include_fault_source=True,
            fault_rupture_offset=1.0,
            fault_surface_discretization=1.0,
            fault_magnitude_scaling_relationship='Wells & Coppersmith (1994)',
            fault_magnitude_scaling_sigma=0.0,
            rupture_aspect_ratio=2.0,
            rupture_floating_type='downdip',
            # complex faults:
            include_subduction_fault_source=False,
            subduction_fault_rupture_offset=10.0,
            subduction_fault_surface_discretization=10.0,
            subduction_fault_magnitude_scaling_relationship=(
                'W&C 1994 Mag-Length Rel.'),
            subduction_fault_magnitude_scaling_sigma=0.0,
            subduction_rupture_aspect_ratio=1.5,
            subduction_rupture_floating_type='downdip',
            quantile_levels=[],
            compute_mean_hazard_curve=True)

        expected_sections = ['HAZARD', 'general']
        expected_params = {
            'AREA_SOURCE_DISCRETIZATION': '0.1',
            'AREA_SOURCE_MAGNITUDE_SCALING_RELATIONSHIP':
                'W&C 1994 Mag-Length Rel.',
            'BASE_PATH': os.path.abspath(helpers.demo_file('HazardMapTest')),
            'CALCULATION_MODE': 'Classical',
            'COMPONENT': 'Average Horizontal (GMRotI50)',
            'COMPUTE_MEAN_HAZARD_CURVE': 'true',
            'DAMPING': '5.0',
            'DEPTHTO1PT0KMPERSEC': '100.0',
            'FAULT_MAGNITUDE_SCALING_RELATIONSHIP':
                'Wells & Coppersmith (1994)',
            'FAULT_MAGNITUDE_SCALING_SIGMA': '0.0',
            'FAULT_RUPTURE_OFFSET': '1.0',
            'FAULT_SURFACE_DISCRETIZATION': '1.0',
            'GMPE_LOGIC_TREE_FILE': os.path.abspath(
                helpers.demo_file('HazardMapTest/gmpe_logic_tree.xml')),
            'GMPE_LT_RANDOM_SEED': '5',
            'GMPE_TRUNCATION_TYPE': '2 Sided',
            'GRID_SOURCE_MAGNITUDE_SCALING_RELATIONSHIP':
                'W&C 1994 Mag-Length Rel.',
            'INCLUDE_AREA_SOURCES': 'true',
            'INCLUDE_FAULT_SOURCE': 'true',
            'INCLUDE_GRID_SOURCES': 'false',
            'INCLUDE_SUBDUCTION_FAULT_SOURCE': 'false',
            'INTENSITY_MEASURE_LEVELS': (
                '0.005, 0.007, 0.0098, 0.0137, 0.0192, 0.0269, 0.0376, 0.0527,'
                ' 0.0738, 0.103, 0.145, 0.203, 0.284, 0.397, 0.556, 0.778,'
                ' 1.09'),
            'INTENSITY_MEASURE_TYPE': 'PGA',
            'INVESTIGATION_TIME': '50.0',
            'MAXIMUM_DISTANCE': '200.0',
            'MINIMUM_MAGNITUDE': '5.0',
            'NUMBER_OF_LOGIC_TREE_SAMPLES': '1',
            'OUTPUT_DIR': 'computed_output',
            'PERIOD': '0.0',
            'POES': '0.1',
            'QUANTILE_LEVELS': '',
            'REFERENCE_DEPTH_TO_2PT5KM_PER_SEC_PARAM': '5.0',
            'REFERENCE_VS30_VALUE': '760.0',
            'REGION_GRID_SPACING': '0.01',
            'REGION_VERTEX':
                '37.6, -122.2, 38.2, -122.2, 38.2, -121.5, 37.6, -121.5',
            'RUPTURE_ASPECT_RATIO': '2.0',
            'RUPTURE_FLOATING_TYPE': 'Along strike and down dip',
            'SADIGH_SITE_TYPE': 'Rock',
            'SOURCE_MODEL_LOGIC_TREE_FILE': os.path.abspath(
                helpers.demo_file(
                    'HazardMapTest/source_model_logic_tree.xml')),
            'SOURCE_MODEL_LT_RANDOM_SEED': '23',
            'STANDARD_DEVIATION_TYPE': 'Total',
            'SUBDUCTION_FAULT_MAGNITUDE_SCALING_RELATIONSHIP':
                'W&C 1994 Mag-Length Rel.',
            'SUBDUCTION_FAULT_MAGNITUDE_SCALING_SIGMA': '0.0',
            'SUBDUCTION_FAULT_RUPTURE_OFFSET': '10.0',
            'SUBDUCTION_FAULT_SURFACE_DISCRETIZATION': '10.0',
            'SUBDUCTION_RUPTURE_ASPECT_RATIO': '1.5',
            'SUBDUCTION_RUPTURE_FLOATING_TYPE': 'Along strike and down dip',
            'TREAT_AREA_SOURCE_AS': 'Point Sources',
            'TREAT_GRID_SOURCE_AS': 'Point Sources',
            'TRUNCATION_LEVEL': '3',
            'VS30_TYPE': 'measured',
            'WIDTH_OF_MFD_BIN': '0.1'}

        actual_jp, params, sections = engine.import_job_profile(
            cfg_path, self.job)
        self.assertEqual(expected_params, params)
        self.assertEqual(expected_sections, sections)

        # Test the OqJobProfile:
        self.assertTrue(
            models.model_equals(expected_jp, actual_jp, ignore=(
                'id', 'last_update', '_owner_cache')))

        # Test the Inputs:
        actual_inputs = models.inputs4job(self.job.id)
        self.assertEqual(3, len(actual_inputs))

        for act_inp in actual_inputs:
            exp_inp = expected_inputs_map[act_inp.input_type]
            self.assertTrue(
                models.model_equals(
                    exp_inp, act_inp, ignore=(
                        "id", "last_update", "path", "model", "_owner_cache",
                        "owner_id", "model_content_id")))