def test_invalid_disagg_calc_truncation_not_set(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 set for' ' disaggregation calculations' ], 'poes_disagg': ['PoEs for disaggregation must be in the range' ' [0, 1]'], } self.hc.truncation_level = None self.hc.mag_bin_width = 0.0 self.hc.distance_bin_width = 0.0 self.hc.coordinate_bin_width = 0.0 # decimal degrees self.hc.num_epsilon_bins = 0 self.hc.poes_disagg = [1.00001, -0.5, 0.0] form = validation.DisaggHazardForm(instance=self.hc, files=None) self.assertFalse(form.is_valid()) helpers.deep_eq(expected_errors, dict(form.errors))
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]'], } self.hc.mag_bin_width = 0.0 self.hc.distance_bin_width = 0.0 self.hc.coordinate_bin_width = 0.0 # decimal degrees self.hc.num_epsilon_bins = 0 self.hc.poes_disagg = [1.00001, -0.5, 0.0] self.hc.truncation_level = 0.0 form = validation.DisaggHazardForm(instance=self.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 self.hc.poes_disagg = [] form = validation.DisaggHazardForm(instance=self.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_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_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_complete_logic_tree_gmf_iter(self): job = models.OqJob.objects.latest('id') # Test data: td = gmf_set_iter_test_data exp_gmfs = itertools.chain( td.GMFS_GMF_SET_0, td.GMFS_GMF_SET_1, td.GMFS_GMF_SET_2, td.GMFS_GMF_SET_3, td.GMFS_GMF_SET_4, td.GMFS_GMF_SET_5) exp_gmf_set = FakeGmfSet(complete_logic_tree_gmf=True, ses_ordinal=None, investigation_time=60.0, gmfs=exp_gmfs) [act_gmf_set] = models.GmfSet.objects\ .filter(gmf_collection__output__oq_job=job.id, gmf_collection__lt_realization__isnull=True)\ .order_by('id') self.assertEqual(len(list(exp_gmf_set)), len(list(act_gmf_set))) self.assertEqual(exp_gmf_set.complete_logic_tree_gmf, act_gmf_set.complete_logic_tree_gmf) self.assertEqual(exp_gmf_set.ses_ordinal, act_gmf_set.ses_ordinal) self.assertEqual(exp_gmf_set.investigation_time, act_gmf_set.investigation_time) for i, exp_gmf in enumerate(exp_gmf_set): act_gmf = list(act_gmf_set)[i] equal, error = helpers.deep_eq(exp_gmf, act_gmf) self.assertTrue(equal, error)
def test_iter(self): # Test data td = gmf_set_iter_test_data exp_gmf_sets = [ FakeGmfSet(complete_logic_tree_gmf=False, ses_ordinal=1, investigation_time=10.0, gmfs=td.GMFS_GMF_SET_0), FakeGmfSet(complete_logic_tree_gmf=False, ses_ordinal=2, investigation_time=10.0, gmfs=td.GMFS_GMF_SET_1), FakeGmfSet(complete_logic_tree_gmf=False, ses_ordinal=3, investigation_time=10.0, gmfs=td.GMFS_GMF_SET_2), FakeGmfSet(complete_logic_tree_gmf=False, ses_ordinal=1, investigation_time=10.0, gmfs=td.GMFS_GMF_SET_3), FakeGmfSet(complete_logic_tree_gmf=False, ses_ordinal=2, investigation_time=10.0, gmfs=td.GMFS_GMF_SET_4), FakeGmfSet(complete_logic_tree_gmf=False, ses_ordinal=3, investigation_time=10.0, gmfs=td.GMFS_GMF_SET_5), ] job = models.OqJob.objects.latest("id") gmf_sets = models.GmfSet.objects.filter( gmf_collection__output__oq_job=job.id, gmf_collection__lt_realization__isnull=False ).order_by("gmf_collection", "ses_ordinal") for i, exp_gmf_set in enumerate(exp_gmf_sets): act_gmf_set = gmf_sets[i] self.assertEqual(exp_gmf_set.complete_logic_tree_gmf, act_gmf_set.complete_logic_tree_gmf) self.assertEqual(exp_gmf_set.ses_ordinal, act_gmf_set.ses_ordinal) self.assertEqual(exp_gmf_set.investigation_time, act_gmf_set.investigation_time) for j, exp_gmf in enumerate(exp_gmf_set): act_gmf = list(act_gmf_set)[j] equal, error = helpers.deep_eq(exp_gmf, act_gmf) self.assertTrue(equal, error)
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_characteristic_complex(self): exp = self._expected_char_complex actual = source_input.nrml_to_hazardlib(self.char_complex, 10, BIN_WIDTH, AREA_SRC_DISC) eq, msg = helpers.deep_eq(exp, actual) self.assertTrue(eq, msg)
def test_characteristic_multi(self): exp = self._expected_char_multi actual = source_input.nrml_to_hazardlib(self.char_multi, MESH_SPACING, BIN_WIDTH, AREA_SRC_DISC) eq, msg = helpers.deep_eq(exp, actual) self.assertTrue(eq, msg)
def test_complex_to_hazardlib(self): exp = self._expected_complex actual = source_input.nrml_to_hazardlib(self.cmplx, MESH_SPACING, BIN_WIDTH, AREA_SRC_DISC) eq, msg = helpers.deep_eq(exp, actual) self.assertTrue(eq, msg)
def test_simple_to_hazardlib(self): exp = self._expected_simple actual = source_input.nrml_to_hazardlib( self.simple, MESH_SPACING, BIN_WIDTH, AREA_SRC_DISC ) eq, msg = helpers.deep_eq(exp, actual) self.assertTrue(eq, msg)
def test_characteristic_complex(self): exp = self._expected_char_complex actual = source_input.nrml_to_hazardlib( self.char_complex, 10, BIN_WIDTH, AREA_SRC_DISC ) eq, msg = helpers.deep_eq(exp, actual) self.assertTrue(eq, msg)
def test_characteristic_multi(self): exp = self._expected_char_multi actual = source_input.nrml_to_hazardlib( self.char_multi, MESH_SPACING, BIN_WIDTH, AREA_SRC_DISC ) eq, msg = helpers.deep_eq(exp, actual) self.assertTrue(eq, msg)
def test_complex_to_nhlib(self): exp = self._expected_complex actual = source_input.nrml_to_nhlib( self.cmplx, MESH_SPACING, BIN_WIDTH, AREA_SRC_DISC ) eq, msg = helpers.deep_eq(exp, actual) self.assertTrue(eq, msg)
def test_hazard_calculation_is_not_valid_missing_grid_spacing(self): expected_errors = { 'region': ['`region` requires `region_grid_spacing`'], } self.hc.region_grid_spacing = None form = validation.ClassicalHazardForm(instance=self.hc, files=None) self.assertFalse(form.is_valid()) equal, err = helpers.deep_eq(expected_errors, dict(form.errors)) self.assertTrue(equal, err)
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_hazard_calculation_is_not_valid_missing_grid_spacing(self): expected_errors = { 'region': ['`region` requires `region_grid_spacing`'], } self.hc.region_grid_spacing = None form = validation.ClassicalHazardForm( instance=self.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_disagg_calc_truncation_not_set(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 set for' ' disaggregation calculations'], 'poes_disagg': ['PoEs for disaggregation must be in the range' ' [0, 1]'], } self.hc.truncation_level = None self.hc.mag_bin_width = 0.0 self.hc.distance_bin_width = 0.0 self.hc.coordinate_bin_width = 0.0 # decimal degrees self.hc.num_epsilon_bins = 0 self.hc.poes_disagg = [1.00001, -0.5, 0.0] form = validation.DisaggHazardForm(instance=self.hc, files=None) self.assertFalse(form.is_valid()) helpers.deep_eq(expected_errors, dict(form.errors))
def test_ses_per_logic_tree_path_is_not_valid(self): expected_errors = { 'ses_per_logic_tree_path': [ '`Stochastic Event Sets Per Sample` (ses_per_logic_tree_path) ' 'must be > 0' ], } self.hc.ses_per_logic_tree_path = -1 form = validation.EventBasedHazardForm(instance=self.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_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]'], } self.hc.mag_bin_width = 0.0 self.hc.distance_bin_width = 0.0 self.hc.coordinate_bin_width = 0.0 # decimal degrees self.hc.num_epsilon_bins = 0 self.hc.poes_disagg = [1.00001, -0.5, 0.0] self.hc.truncation_level = 0.0 form = validation.DisaggHazardForm(instance=self.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 self.hc.poes_disagg = [] form = validation.DisaggHazardForm(instance=self.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_hazard_calculation_is_not_valid_missing_export_dir(self): # When the user specifies '--exports' on the command line the # 'export_dir' parameter must be present in the .ini file. err = ('--exports specified on the command line but the ' '"export_dir" parameter is missing in the .ini file') expected_errors = { 'export_dir': [err], } form = validation.ClassicalHazardForm( instance=self.hc, files=None, exports=['xml'] ) 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_missing_export_dir(self): # When the user specifies '--exports' on the command line the # 'export_dir' parameter must be present in the .ini file. err = ('--exports specified on the command line but the ' '"export_dir" parameter is missing in the .ini file') expected_errors = { 'export_dir': [err], } form = validation.ClassicalHazardForm(instance=self.hc, files=None, exports=['xml']) self.assertFalse(form.is_valid()) equal, err = helpers.deep_eq(expected_errors, dict(form.errors)) self.assertTrue(equal, err)
def test_ses_per_logic_tree_path_is_not_valid(self): expected_errors = { 'ses_per_logic_tree_path': [ '`Stochastic Event Sets Per Sample` (ses_per_logic_tree_path) ' 'must be > 0'], } self.hc.ses_per_logic_tree_path = -1 form = validation.EventBasedHazardForm( instance=self.hc, files=None ) self.assertFalse(form.is_valid()) equal, err = helpers.deep_eq(expected_errors, dict(form.errors)) self.assertTrue(equal, err)
def test_gmfs_false_hazard_curves_true(self): # An error should be raised if `hazard_curves_from_gmfs` is `True`, but # `ground_motion_fields` is `False`. # GMFs are needed to compute hazard curves. expected_errors = { 'hazard_curves_from_gmfs': ['`hazard_curves_from_gmfs` requires ' '`ground_motion_fields` to be `true`'], } self.hc.ground_motion_fields = False self.hc.hazard_curves_from_gmfs = True form = validation.EventBasedHazardForm(instance=self.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_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 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'] } self.hc.number_of_ground_motion_fields = -10 self.hc.gsim = 'BooreAtkinson208' form = validation.ScenarioHazardForm( instance=self.hc, files=None ) self.assertFalse(form.is_valid()) equal, err = helpers.deep_eq(expected_errors, dict(form.errors)) self.assertTrue(equal, err)
def test_classical_hc_hazard_maps_uhs_no_poes(self): # Test that errors are reported if `hazard_maps` and # `uniform_hazard_spectra` are `true` but no `poes` are # specified. expected_errors = { 'hazard_maps': ['`poes` are required to compute hazard maps'], 'uniform_hazard_spectra': ['`poes` are required to compute UHS'], } self.hc.hazard_maps = True self.hc.uniform_hazard_spectra = True self.hc.poes = None form = validation.ClassicalHazardForm(instance=self.hc, files=None) 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_sites_only(self): expected_errors = { 'sites': [ 'Longitude values must in the range [-180, 180]', 'Latitude values must be in the range [-90, 90]', ], } self.hc.region = None self.hc.region_grid_spacing = None self.hc.sites = 'MULTIPOINT((-180.001 90.001), (180.001 -90.001))' form = validation.ClassicalHazardForm(instance=self.hc, files=None) self.assertFalse(form.is_valid()) equal, err = helpers.deep_eq(expected_errors, dict(form.errors)) self.assertTrue(equal, err)
def test_area_with_tgr_mfd(self): area_mfd = nrml_models.TGRMFD(a_val=-3.5, b_val=1.0, min_mag=5.0, max_mag=6.5) self.area_source_attrib['mfd'] = area_mfd area_source = nrml_models.AreaSource(**self.area_source_attrib) # Re-scaled MFD for the points point_mfd = nrml_models.TGRMFD(a_val=-4.1020599913279625, b_val=1.0, min_mag=5.0, max_mag=6.5) for exp in self.expected: exp.mfd = point_mfd actual = list(source_input.area_source_to_point_sources(area_source, 100)) equal, err = helpers.deep_eq(self.expected, actual) self.assertTrue(equal, err)
def test_gmfs_false_hazard_curves_true(self): # An error should be raised if `hazard_curves_from_gmfs` is `True`, but # `ground_motion_fields` is `False`. # GMFs are needed to compute hazard curves. expected_errors = { 'hazard_curves_from_gmfs': [ '`hazard_curves_from_gmfs` requires ' '`ground_motion_fields` to be `true`' ], } self.hc.ground_motion_fields = False self.hc.hazard_curves_from_gmfs = True form = validation.EventBasedHazardForm(instance=self.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_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' ] } self.hc.number_of_ground_motion_fields = -10 self.hc.gsim = 'BooreAtkinson208' form = validation.ScenarioHazardForm(instance=self.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_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' ], } self.hc.number_of_logic_tree_samples = 0 self.hc.complete_logic_tree_gmf = True form = validation.EventBasedHazardForm(instance=self.hc, files=None) self.assertFalse(form.is_valid()) equal, err = helpers.deep_eq(expected_errors, dict(form.errors)) self.assertTrue(equal, err)
def test_area_with_incr_mfd(self): area_mfd = nrml_models.IncrementalMFD(min_mag=6.55, bin_width=0.1, occur_rates=[0.1, 0.2, 0.3, 0.4]) self.area_source_attrib['mfd'] = area_mfd area_source = nrml_models.AreaSource(**self.area_source_attrib) # Re-scaled MFD for the points point_mfd = nrml_models.IncrementalMFD( min_mag=6.55, bin_width=0.1, occur_rates=[0.025, 0.05, 0.075, 0.1]) for exp in self.expected: exp.mfd = point_mfd actual = list( source_input.area_source_to_point_sources(area_source, 100)) equal, err = helpers.deep_eq(self.expected, actual) self.assertTrue(equal, err)
def test_classical_hc_hazard_maps_uhs_no_poes(self): # Test that errors are reported if `hazard_maps` and # `uniform_hazard_spectra` are `true` but no `poes` are # specified. expected_errors = { 'hazard_maps': ['`poes` are required to compute hazard maps'], 'uniform_hazard_spectra': ['`poes` are required to compute UHS'], } self.hc.hazard_maps = True self.hc.uniform_hazard_spectra = True self.hc.poes = None form = validation.ClassicalHazardForm( instance=self.hc, files=None ) self.assertFalse(form.is_valid()) equal, err = helpers.deep_eq(expected_errors, dict(form.errors)) self.assertTrue(equal, err)
def test_hazard_curves_from_gmf_no_iml_imt(self): # Test a configuration where the user has requested to post-process # GMFs into hazard curves. # In this case, the configuration is missing the required # `intensity_measure_types_and_levels`. expected_errors = { 'intensity_measure_types_and_levels': [ '`hazard_curves_from_gmfs` requires ' '`intensity_measure_types_and_levels`' ], } self.hc.intensity_measure_types_and_levels = None form = validation.EventBasedHazardForm(instance=self.hc, files=None) 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_sites_only(self): expected_errors = { 'sites': [ 'Longitude values must in the range [-180, 180]', 'Latitude values must be in the range [-90, 90]', ], } self.hc.region = None self.hc.region_grid_spacing = None self.hc.sites = 'MULTIPOINT((-180.001 90.001), (180.001 -90.001))' form = validation.ClassicalHazardForm( instance=self.hc, files=None ) 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_missing_export_dir(self): # When the user specifies '--exports' on the command line the # 'export_dir' parameter must be present in the .ini file. err = ('--exports specified on the command line but the ' '"export_dir" parameter is missing in the .ini file') expected_errors = { 'export_dir': [err], } 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, exports=['xml'] ) self.assertFalse(form.is_valid()) equal, err = helpers.deep_eq(expected_errors, dict(form.errors)) self.assertTrue(equal, err)
def test_hazard_curves_from_gmf_no_iml_imt(self): # Test a configuration where the user has requested to post-process # GMFs into hazard curves. # In this case, the configuration is missing the required # `intensity_measure_types_and_levels`. expected_errors = { 'intensity_measure_types_and_levels': [ '`hazard_curves_from_gmfs` requires ' '`intensity_measure_types_and_levels`'], } self.hc.intensity_measure_types_and_levels = None form = validation.EventBasedHazardForm( instance=self.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_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'], } self.hc.number_of_logic_tree_samples = 0 self.hc.complete_logic_tree_gmf = True form = validation.EventBasedHazardForm( instance=self.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', ], } self.hc.intensity_measure_types = INVALID_IML_IMT.keys() self.hc.intensity_measure_types_and_levels = None self.hc.hazard_curves_from_gmfs = False form = validation.EventBasedHazardForm(instance=self.hc, files=None) self.assertFalse(form.is_valid()) equal, err = helpers.deep_eq(expected_errors, dict(form.errors)) self.assertTrue(equal, err)
def test_area_with_incr_mfd(self): area_mfd = nrml_models.IncrementalMFD( min_mag=6.55, bin_width=0.1, occur_rates=[0.1, 0.2, 0.3, 0.4] ) self.area_source_attrib['mfd'] = area_mfd area_source = nrml_models.AreaSource(**self.area_source_attrib) # Re-scaled MFD for the points point_mfd = nrml_models.IncrementalMFD( min_mag=6.55, bin_width=0.1, occur_rates=[0.025, 0.05, 0.075, 0.1] ) for exp in self.expected: exp.mfd = point_mfd actual = list(source_input.area_source_to_point_sources(area_source, 100)) equal, err = helpers.deep_eq(self.expected, actual) 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]' ], } self.hc.region_grid_spacing = 0 self.hc.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))') form = validation.ClassicalHazardForm(instance=self.hc, files=None) self.assertFalse(form.is_valid()) equal, err = helpers.deep_eq(expected_errors, dict(form.errors)) self.assertTrue(equal, err)
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() self.hc.intensity_measure_types = iml_imt self.hc.intensity_measure_types_and_levels = VALID_IML_IMT form = validation.EventBasedHazardForm(instance=self.hc, files=None) self.assertFalse(form.is_valid()) equal, err = helpers.deep_eq(expected_errors, dict(form.errors)) self.assertTrue(equal, err)
def test_area_with_tgr_mfd(self): area_mfd = nrml_models.TGRMFD(a_val=-3.5, b_val=1.0, min_mag=5.0, max_mag=6.5) self.area_source_attrib['mfd'] = area_mfd area_source = nrml_models.AreaSource(**self.area_source_attrib) # Re-scaled MFD for the points point_mfd = nrml_models.TGRMFD(a_val=-4.1020599913279625, b_val=1.0, min_mag=5.0, max_mag=6.5) for exp in self.expected: exp.mfd = point_mfd actual = list( source_input.area_source_to_point_sources(area_source, 100)) equal, err = helpers.deep_eq(self.expected, actual) 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', ], } self.hc.intensity_measure_types = INVALID_IML_IMT.keys() self.hc.intensity_measure_types_and_levels = None self.hc.hazard_curves_from_gmfs = False form = validation.EventBasedHazardForm( instance=self.hc, files=None ) self.assertFalse(form.is_valid()) equal, err = helpers.deep_eq(expected_errors, dict(form.errors)) self.assertTrue(equal, err)
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).order_by('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))
def test_hazard_calculation_is_not_valid_missing_grid_spacing(self): expected_errors = { 'region': ['`region` requires `region_grid_spacing`'], } 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))' ), 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()) equal, err = helpers.deep_eq(expected_errors, dict(form.errors)) self.assertTrue(equal, err)
def test_hazard_calculation_is_not_valid(self): # test with an invalid job profile # several parameters are given invalid values expected_errors = { 'area_source_discretization': [ 'Area source discretization must be > 0', ], 'calculation_mode': [ 'Calculation mode must be "classical"', ], 'investigation_time': ['Investigation time must be > 0'], 'maximum_distance': ['Maximum distance must be > 0'], 'number_of_logic_tree_samples': [ 'Number of logic tree samples must be >= 0', ], 'poes': [ '`poes` values must be in the range [0, 1]', ], 'quantile_hazard_curves': ['Quantile hazard curve values must in the range [0, 1]'], 'random_seed': [ 'Random seed must be a value from -2147483648 to 2147483647 ' '(inclusive)', ], 'rupture_mesh_spacing': ['Rupture mesh spacing must be > 0'], 'truncation_level': ['Truncation level must be >= 0'], 'width_of_mfd_bin': ['Width of MFD bin must be > 0'], 'intensity_measure_types_and_levels': [ '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'), 'IA: IMLs must be > 0', 'PGD: IML lists must have at least 1 value', 'SA(2x): SA period value should be a float >= 0', 'PGA: IMLs must be > 0', 'PGZ: Invalid intensity measure type', 'SA(0.025): IML lists must have at least 1 value', 'MMI: IMLs must be specified as a list of floats', ], 'region': ['Cannot specify `region` and `sites`. Choose one.'], '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( description='', region=('POLYGON((-122.0 38.113, -122.114 38.113, -122.57 38.111, ' '-122.0 38.113))'), region_grid_spacing=0, sites='-122.0 38.113 , -122.114,38.113', calculation_mode='Classical', random_seed=2147483648, number_of_logic_tree_samples=-1, rupture_mesh_spacing=0, width_of_mfd_bin=0, area_source_discretization=0, reference_vs30_type=None, reference_vs30_value=0, reference_depth_to_2pt5km_per_sec=0, reference_depth_to_1pt0km_per_sec=0, investigation_time=0, intensity_measure_types_and_levels=INVALID_IML_IMT, truncation_level=-0.1, maximum_distance=0, quantile_hazard_curves=[0.0, -0.1, 1.1], poes=[1.00001, -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)