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))
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))
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], )
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()
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())
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))
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))
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)
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))
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))
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))
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())
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))
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))'))
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)
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())
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)
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())
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
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)
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
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)
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)
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)
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)
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)
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())
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)
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)
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))
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
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")))