def test_validate_warns(self): # Test that `validate` raises warnings if unnecessary parameters are # specified for a given calculation. # For example, `ses_per_logic_tree_path` is an event-based hazard # param; if this param is specified for a classical hazard job, a # warning should be raised. cfg_file = helpers.get_data_path('simple_fault_demo_hazard/job.ini') job = engine.prepare_job() params, files = engine.parse_config(open(cfg_file, 'r')) # Add a few superfluous parameters: params['ses_per_logic_tree_path'] = 5 params['ground_motion_correlation_model'] = 'JB2009' calculation = engine.create_hazard_calculation( job.owner.user_name, params, files ) job.hazard_calculation = calculation job.save() with warnings.catch_warnings(record=True) as w: validation.validate(job, 'hazard', params, files, ['xml']) expected_warnings = [ "Unknown parameter '%s' for calculation mode 'classical'." " Ignoring." % x for x in ('ses_per_logic_tree_path', 'ground_motion_correlation_model') ] actual_warnings = [m.message.message for m in w] self.assertEqual(sorted(expected_warnings), sorted(actual_warnings))
def test_pre_execute_check_imts_raises(self): haz_job = engine.prepare_job() cfg = helpers.get_data_path('classical_job.ini') params, files = engine.parse_config(open(cfg, 'r')) haz_job.hazard_calculation = engine.create_hazard_calculation( haz_job.owner, params, files.values()) haz_job.save() hazard_curve_output = models.Output.objects.create_output( haz_job, 'test_hazard_curve', 'hazard_curve' ) models.HazardCurve.objects.create( output=hazard_curve_output, investigation_time=50.0, imt='PGV', # the vulnerability model only defines SA(0.1) statistics='mean' ) cfg = helpers.get_data_path( 'end-to-end-hazard-risk/job_risk_classical.ini') risk_job = helpers.get_risk_job( cfg, hazard_output_id=hazard_curve_output.id ) models.JobStats.objects.create(oq_job=risk_job) calc = classical.ClassicalRiskCalculator(risk_job) # Check for compatibility between the IMTs defined in the vulnerability # model and the chosen hazard output (--hazard-output-id) with self.assertRaises(ValueError) as ar: calc.pre_execute() self.assertEqual( "There is no hazard output for: SA(0.1). " "The available IMTs are: PGA.", ar.exception.message)
def test_pre_execute_check_imts_no_errors(self): haz_job = engine.prepare_job() cfg = helpers.get_data_path( 'end-to-end-hazard-risk/job_haz_classical.ini') params, files = engine.parse_config(open(cfg, 'r')) haz_job.hazard_calculation = engine.create_hazard_calculation( haz_job.owner, params, files.values()) haz_job.save() hazard_curve_output = models.Output.objects.create_output( haz_job, 'test_hazard_curve', 'hazard_curve' ) models.HazardCurve.objects.create( output=hazard_curve_output, investigation_time=50.0, # this imt is compatible with the vuln model imt='SA', sa_period=0.025, sa_damping=5.0, statistics='mean' ) cfg = helpers.get_data_path( 'end-to-end-hazard-risk/job_risk_classical.ini') risk_job = helpers.get_risk_job( cfg, hazard_output_id=hazard_curve_output.id ) models.JobStats.objects.create(oq_job=risk_job) calc = classical.ClassicalRiskCalculator(risk_job) # In contrast to the test above (`test_pre_execute_check_imts_raises`), # we expect no errors to be raised. calc.pre_execute()
def test_create_hazard_calculation_warns(self): # If unknown parameters are specified in the config file, we expect # `create_hazard_calculation` to raise warnings and ignore those # parameters. # Add some random unknown params: self.params['blargle'] = 'spork' self.params['do_science'] = 'true' expected_warnings = [ "Unknown parameter 'blargle'. Ignoring.", "Unknown parameter 'do_science'. Ignoring.", ] with warnings.catch_warnings(record=True) as w: engine.create_hazard_calculation(self.owner, self.params, self.files) actual_warnings = [msg.message.message for msg in w] self.assertEqual(sorted(expected_warnings), sorted(actual_warnings))
def test_read_and_validate_hazard_config(self): cfg = helpers.get_data_path('simple_fault_demo_hazard/job.ini') job = engine.prepare_job(getpass.getuser()) params, files = engine.parse_config(open(cfg, 'r')) calculation = engine.create_hazard_calculation( job.owner, params, files.values()) form = validation.ClassicalHazardForm( instance=calculation, files=files ) self.assertTrue(form.is_valid())
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_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.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()) 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(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 get_hazard_job(cfg, username=None): """ Given a path to a config file, create a :class:`openquake.engine.db.models.OqJob` object for a hazard calculation. """ username = username if username is not None else default_user().user_name job = engine.prepare_job(username) params, files = engine.parse_config(open(cfg, 'r')) haz_calc = engine.create_hazard_calculation( job.owner, params, files.values()) haz_calc = models.HazardCalculation.objects.get(id=haz_calc.id) job.hazard_calculation = haz_calc job.save() return job
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 _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 = engine.create_hazard_calculation(owner.user_name, params, {}) return hc
def test_create_hazard_calculation(self): hc = engine.create_hazard_calculation(self.owner, self.params, self.files) # Normalize/clean fields by fetching a fresh copy from the db. hc = models.HazardCalculation.objects.get(id=hc.id) self.assertEqual(hc.calculation_mode, 'classical') self.assertEqual(hc.width_of_mfd_bin, 1.0) self.assertEqual(hc.rupture_mesh_spacing, 1.0) self.assertEqual(hc.area_source_discretization, 2.0) self.assertEqual(hc.investigation_time, 50.0) self.assertEqual(hc.truncation_level, 0.0) self.assertEqual(hc.maximum_distance, 200.0) # Test the input2haz_calc link: [inp2hcs] = models.Input2hcalc.objects.filter( hazard_calculation=hc.id) self.assertEqual(self.site_model.id, inp2hcs.input.id)