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 job_from_file(cfg_file_path, username, log_level, exports, hazard_output_id=None, hazard_calculation_id=None): """ Create a full job profile from a job config file. :param str cfg_file_path: Path to the job.ini. :param str username: The user who will own this job profile and all results. :param str log_level: Desired log level. :param exports: List of desired export types. :param int hazard_output_id: ID of a hazard output to use as input to this calculation. Specify this xor ``hazard_calculation_id``. :param int hazard_calculation_id: ID of a complete hazard calculation to use as input to this calculation. Specify this xor ``hazard_output_id``. :returns: :class:`openquake.engine.db.models.OqJob` object :raises: `RuntimeError` if the input job configuration is not valid """ # create the job job = prepare_job(user_name=username, log_level=log_level) # read calculation params and create the calculation profile params = readini.parse_config(open(cfg_file_path, 'r')) missing = set(params['inputs']) - INPUT_TYPES if missing: raise ValueError( 'The parameters %s in the .ini file does ' 'not correspond to a valid input type' % ', '.join(missing)) if hazard_output_id is None and hazard_calculation_id is None: # this is a hazard calculation, not a risk one job.hazard_calculation = create_calculation( models.HazardCalculation, params) job.save() # validate and raise an error if there are any problems error_message = validate(job, 'hazard', params, exports) if error_message: raise RuntimeError(error_message) return job # otherwise run a risk calculation params.update(dict(hazard_output_id=hazard_output_id, hazard_calculation_id=hazard_calculation_id)) calculation = create_calculation(models.RiskCalculation, params) job.risk_calculation = calculation job.save() # validate and raise an error if there are any problems error_message = validate(job, 'risk', params, exports) if error_message: raise RuntimeError(error_message) 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 haz_job_from_file(cfg_file_path, username, log_level, exports): """ Create a full hazard job profile from a job config file. :param str cfg_file_path: Path to the job.ini. :param str username: The user who will own this job profile and all results. :param str log_level: Desired log level. :param exports: List of desired export types. :returns: :class:`openquake.engine.db.models.OqJob` object :raises: `RuntimeError` if the input job configuration is not valid """ # create the job job = prepare_job(user_name=username, log_level=log_level) # read calculation params and create the calculation profile params = parse_config(open(cfg_file_path, 'r')) job.hazard_calculation = create_calculation( models.HazardCalculation, params) job.save() # validate and raise if there are any problems error_message = validate(job, 'hazard', params, exports) if error_message: raise RuntimeError(error_message) return job
def haz_job_from_file(cfg_file_path, username, log_level, exports): """ Create a full hazard job profile from a job config file. :param str cfg_file_path: Path to the job.ini. :param str username: The user who will own this job profile and all results. :param str log_level: Desired log level. :param exports: List of desired export types. :returns: :class:`openquake.engine.db.models.OqJob` object :raises: `RuntimeError` if the input job configuration is not valid """ # create the job job = prepare_job(user_name=username, log_level=log_level) # read calculation params and create the calculation profile params = parse_config(open(cfg_file_path, 'r')) job.hazard_calculation = create_calculation(models.HazardCalculation, params) job.save() # validate and raise if there are any problems error_message = validate(job, 'hazard', params, exports) if error_message: raise RuntimeError(error_message) return job
def risk_job_from_file(cfg_file_path, username, log_level, exports, hazard_output_id=None, hazard_calculation_id=None): """ Create a full risk job profile from a job config file. :param str cfg_file_path: Path to the job.ini. :param str username: The user who will own this job profile and all results. :param str log_level: Desired log level. :param exports: List of desired export types. :param int hazard_output_id: ID of a hazard output to use as input to this calculation. Specify this xor ``hazard_calculation_id``. :param int hazard_calculation_id: ID of a complete hazard calculation to use as input to this calculation. Specify this xor ``hazard_output_id``. :returns: :class:`openquake.engine.db.models.OqJob` object :raises: `RuntimeError` if the input job configuration is not valid """ assert not (hazard_output_id is None and hazard_calculation_id is None), ( "Must specify either `hazard_output_id` or `hazard_calculation_id`, " "and not both") # create the job job = prepare_job(user_name=username, log_level=log_level) # read calculation params and create the calculation profile params = parse_config(open(cfg_file_path, 'r')) # Add the hazard output id to the risk calculation constructor args params.update( dict(hazard_output_id=hazard_output_id, hazard_calculation_id=hazard_calculation_id)) calculation = create_calculation(models.RiskCalculation, params) job.risk_calculation = calculation job.save() error_message = validate(job, 'risk', params, exports) if error_message: raise RuntimeError(error_message) return job
def risk_job_from_file(cfg_file_path, username, log_level, exports, hazard_output_id=None, hazard_calculation_id=None): """ Create a full risk job profile from a job config file. :param str cfg_file_path: Path to the job.ini. :param str username: The user who will own this job profile and all results. :param str log_level: Desired log level. :param exports: List of desired export types. :param int hazard_output_id: ID of a hazard output to use as input to this calculation. Specify this xor ``hazard_calculation_id``. :param int hazard_calculation_id: ID of a complete hazard calculation to use as input to this calculation. Specify this xor ``hazard_output_id``. :returns: :class:`openquake.engine.db.models.OqJob` object :raises: `RuntimeError` if the input job configuration is not valid """ assert not(hazard_output_id is None and hazard_calculation_id is None), ( "Must specify either `hazard_output_id` or `hazard_calculation_id`, " "and not both" ) # create the job job = prepare_job(user_name=username, log_level=log_level) # read calculation params and create the calculation profile params, files = parse_config(open(cfg_file_path, 'r')) # Add the hazard output id to the risk calculation constructor args params.update(dict(hazard_output_id=hazard_output_id, hazard_calculation_id=hazard_calculation_id)) calculation = create_risk_calculation( job.owner, params, files ) job.risk_calculation = calculation job.save() error_message = validate(job, 'risk', params, files, exports) if error_message: raise RuntimeError(error_message) return job
def get_fake_risk_job(risk_cfg, hazard_cfg, output_type="curve", username=None): """ 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 """ username = username if username is not None else default_user().user_name 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, files = engine.parse_config(open(risk_cfg, 'r')) params.update(dict(hazard_output_id=hazard_output.output.id)) risk_calc = engine.create_risk_calculation(job.owner, params, files) job.risk_calculation = risk_calc job.save() error_message = validate(job, 'risk', params, files, []) # 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, files