def get_risk_job(cfg, username="******", hazard_calculation_id=None, hazard_output_id=None): """ Given a path to a config file and a hazard_calculation_id (or, alternatively, a hazard_output_id, create a :class:`openquake.engine.db.models.OqJob` object for a risk calculation. """ # You can't specify both a hazard output and hazard calculation # Pick one assert not (hazard_calculation_id is not None and hazard_output_id is not None) job = engine.prepare_job(username) params = engine.parse_config(open(cfg, 'r')) params.update( dict(hazard_output_id=hazard_output_id, hazard_calculation_id=hazard_calculation_id) ) risk_calc = engine.create_calculation( models.RiskCalculation, params) risk_calc = models.RiskCalculation.objects.get(id=risk_calc.id) job.risk_calculation = risk_calc job.save() return job
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 = 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_calculation( models.HazardCalculation, params) job.hazard_calculation = calculation job.save() with warnings.catch_warnings(record=True) as w: validation.validate(job, 'hazard', params, ['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(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 = vars(readini.parse_config(open(cfg))) del params["hazard_calculation_id"] del params["hazard_output_id"] 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() calc = get_calculator_class("hazard", job.hazard_calculation.calculation_mode)(job) calc.parse_risk_models() 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()) return job
def get_job(cfg, username="******", hazard_calculation_id=None, hazard_output_id=None, **extras): """ Given a path to a config file and a hazard_calculation_id (or, alternatively, a hazard_output_id, create a :class:`openquake.engine.db.models.OqJob` object for a risk calculation. """ if hazard_calculation_id is None and hazard_output_id is None: return engine.job_from_file(cfg, username, 'error', [], **extras) job = engine.prepare_job(username) oqparam = readini.parse_config( open(cfg), hazard_calculation_id, hazard_output_id) params = vars(oqparam) if hazard_calculation_id is None: params['hazard_calculation_id'] = models.Output.objects.get( pk=hazard_output_id).oq_job.id # we are removing intensity_measure_types_and_levels because it is not # a field of RiskCalculation; this ugliness will disappear when # RiskCalculation will be removed del params['intensity_measure_types_and_levels'] job.save_params(params) risk_calc = engine.create_calculation(models.RiskCalculation, params) risk_calc = models.RiskCalculation.objects.get(id=risk_calc.id) job.risk_calculation = risk_calc job.save() return job
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 = 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_calculation(models.HazardCalculation, params) job.hazard_calculation = calculation job.save() with warnings.catch_warnings(record=True) as w: validation.validate(job, 'hazard', params, ['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_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_calculation( models.HazardCalculation, self.params) actual_warnings = [msg.message.message for msg in w] self.assertEqual(sorted(expected_warnings), sorted(actual_warnings))
def test_create_hazard_calculation(self): hc = engine.create_calculation(models.HazardCalculation, self.params) # 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)
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(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')) init_pr_data_patch = helpers.patch( '%s.%s' % (base_path, 'initialize_pr_data')) patches = (init_src_patch, init_sm_patch, init_rlz_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 get_job(cfg, username="******", hazard_calculation_id=None, hazard_output_id=None): """ Given a path to a config file and a hazard_calculation_id (or, alternatively, a hazard_output_id, create a :class:`openquake.engine.db.models.OqJob` object for a risk calculation. """ if hazard_calculation_id is None and hazard_output_id is None: return engine.job_from_file(cfg, username, 'error', []) job = engine.prepare_job(username) params = vars(readini.parse_config( open(cfg), hazard_calculation_id, hazard_output_id)) risk_calc = engine.create_calculation(models.RiskCalculation, params) risk_calc = models.RiskCalculation.objects.get(id=risk_calc.id) job.risk_calculation = risk_calc job.save() return job
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_job(hazard_cfg, 'openquake') hc = hazard_job.get_oqparam() lt_model = models.LtSourceModel.objects.create( hazard_calculation=hazard_job, ordinal=1, sm_lt_path="test_sm") rlz = models.LtRealization.objects.create( lt_model=lt_model, ordinal=1, weight=None, gsim_lt_path="test_gsim") 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_risk', # 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)], } rc = engine.create_calculation(models.RiskCalculation, params) # 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_risk') 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 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', } rc = engine.create_calculation(models.RiskCalculation, params) # 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 get_fake_risk_job(risk_cfg, hazard_cfg, output_type="curve", username="******"): """ Takes in input the paths to a risk job config file and a hazard job config file. Creates fake hazard outputs suitable to be used by a risk calculation and then creates a :class:`openquake.engine.db.models.OqJob` object for a risk calculation. It also returns the input files referenced by the risk config file. :param output_type: gmf, gmf_scenario, or curve """ hazard_job = get_hazard_job(hazard_cfg, username) 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) if output_type == "curve": models.HazardCurve.objects.create( lt_realization=rlz, output=models.Output.objects.create_output( hazard_job, "Test Hazard output", "hazard_curve_multi"), investigation_time=hc.investigation_time) 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]) for point in ["POINT(-1.01 1.01)", "POINT(0.9 1.01)", "POINT(0.01 0.01)", "POINT(0.9 0.9)"]: models.HazardCurveData.objects.create( hazard_curve=hazard_output, poes=[0.1, 0.2, 0.3], location="%s" % point) elif output_type == "gmf_scenario": hazard_output = models.Gmf.objects.create( output=models.Output.objects.create_output( hazard_job, "Test gmf scenario output", "gmf_scenario")) site_ids = hazard_job.hazard_calculation.save_sites( [(15.48, 38.0900001), (15.565, 38.17), (15.481, 38.25)]) for site_id in site_ids: models.GmfData.objects.create( gmf=hazard_output, imt="PGA", site_id=site_id, gmvs=[0.1, 0.2, 0.3]) else: hazard_output = create_gmf_data_records( hazard_job, rlz)[0].gmf hazard_job.status = "complete" hazard_job.save() job = engine.prepare_job(username) params = engine.parse_config(open(risk_cfg, 'r')) params.update(dict(hazard_output_id=hazard_output.output.id)) risk_calc = engine.create_calculation(models.RiskCalculation, params) job.risk_calculation = risk_calc job.save() error_message = validate(job, 'risk', params, []) # reload risk calculation to have all the types converted properly job.risk_calculation = models.RiskCalculation.objects.get(id=risk_calc.id) if error_message: raise RuntimeError(error_message) return job, set(params['inputs'])
def get_fake_risk_job(risk_cfg, hazard_cfg, output_type="curve", username="******"): """ Takes in input the paths to a risk job config file and a hazard job config file. Creates fake hazard outputs suitable to be used by a risk calculation and then creates a :class:`openquake.engine.db.models.OqJob` object for a risk calculation. It also returns the input files referenced by the risk config file. :param output_type: gmf, gmf_scenario, or curve """ hazard_job = get_job(hazard_cfg, username) hc = hazard_job.hazard_calculation lt_model = models.LtSourceModel.objects.create( hazard_calculation=hazard_job.hazard_calculation, ordinal=1, sm_lt_path="test_sm") rlz = models.LtRealization.objects.create( lt_model=lt_model, ordinal=1, weight=1, gsim_lt_path="test_gsim") if output_type == "curve": models.HazardCurve.objects.create( lt_realization=rlz, output=models.Output.objects.create_output( hazard_job, "Test Hazard output", "hazard_curve_multi"), investigation_time=hc.investigation_time) 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]) for point in ["POINT(-1.01 1.01)", "POINT(0.9 1.01)", "POINT(0.01 0.01)", "POINT(0.9 0.9)"]: models.HazardSite.objects.create( hazard_calculation=hc, location=point) models.HazardCurveData.objects.create( hazard_curve=hazard_output, poes=[0.1, 0.2, 0.3], location="%s" % point) elif output_type == "gmf_scenario": hazard_output = models.Gmf.objects.create( output=models.Output.objects.create_output( hazard_job, "Test gmf scenario output", "gmf_scenario")) models.SESCollection.objects.create( output=models.Output.objects.create_output( hazard_job, "Test SES Collection", "ses"), lt_model=None, ordinal=0) site_ids = hazard_job.hazard_calculation.save_sites( [(15.48, 38.0900001), (15.565, 38.17), (15.481, 38.25)]) for site_id in site_ids: models.GmfData.objects.create( gmf=hazard_output, task_no=0, imt="PGA", site_id=site_id, gmvs=[0.1, 0.2, 0.3], rupture_ids=[0, 1, 2]) elif output_type in ("ses", "gmf"): hazard_output = create_gmf_data_records(hazard_job, rlz)[0].gmf else: raise RuntimeError('Unexpected output_type: %s' % output_type) hazard_job.status = "complete" hazard_job.save() job = engine.prepare_job(username) params = vars(readini.parse_config(open(risk_cfg), hazard_output_id=hazard_output.output.id)) risk_calc = engine.create_calculation(models.RiskCalculation, params) job.risk_calculation = risk_calc job.save() # reload risk calculation to have all the types converted properly job.risk_calculation = models.RiskCalculation.objects.get(id=risk_calc.id) return job, set(params['inputs'])