def test_raises_useful_error(self): # Test that the source id and name are included with conversion errors, # to help the users deal with problems in their source models. area_geom = nrml_models.AreaGeometry( wkt='POLYGON((0.0 0.0, 1.0 0.0, 0.0 0.0 ))', upper_seismo_depth=0.0, lower_seismo_depth=10.0, ) area_mfd = nrml_models.IncrementalMFD( min_mag=6.55, bin_width=0.1, occur_rates=[ 0.0010614989, 8.8291627E-4, 7.3437777E-4, 6.108288E-4, 5.080653E-4 ], ) area_npd = [ nrml_models.NodalPlane(probability=decimal.Decimal("0.3"), strike=0.0, dip=90.0, rake=0.0), nrml_models.NodalPlane(probability=decimal.Decimal("0.7"), strike=90.0, dip=45.0, rake=90.0), ] area_hdd = [ nrml_models.HypocentralDepth(probability=decimal.Decimal("0.5"), depth=4.0), nrml_models.HypocentralDepth(probability=decimal.Decimal("0.5"), depth=8.0), ] area_src = nrml_models.AreaSource( id='1', name='Quito', trt='Active Shallow Crust', geometry=area_geom, mag_scale_rel='PeerMSR', rupt_aspect_ratio=1.5, mfd=area_mfd, nodal_plane_dist=area_npd, hypo_depth_dist=area_hdd, ) with self.assertRaises(Exception) as ar: source_input.nrml_to_hazardlib(area_src, MESH_SPACING, BIN_WIDTH, AREA_SRC_DISC) expected_error = ( "The following error has occurred with source id='1', " "name='Quito': Could not create geometry because of errors while " "reading input.") self.assertEqual(expected_error, ar.exception.message)
def compute_gmfs(job_id, sites, rupture_id, gmfcoll_id, realizations): """ Compute ground motion fields and store them in the db. :param job_id: ID of the currently running job. :param sites: The subset of the full SiteCollection scanned by this task :param rupture_id: The parsed rupture model from which we will generate ground motion fields. :param gmfcoll_id: the id of a :class:`openquake.engine.db.models.Gmf` record :param realizations: Number of realizations to create. """ hc = models.HazardCalculation.objects.get(oqjob=job_id) rupture_mdl = source.nrml_to_hazardlib( models.ParsedRupture.objects.get(id=rupture_id).nrml, hc.rupture_mesh_spacing, None, None) imts = [haz_general.imt_to_hazardlib(x) for x in hc.intensity_measure_types] gsim = AVAILABLE_GSIMS[hc.gsim]() # instantiate the GSIM class correlation_model = haz_general.get_correl_model(hc) with EnginePerformanceMonitor('computing gmfs', job_id, gmfs): gmf = ground_motion_fields( rupture_mdl, sites, imts, gsim, hc.truncation_level, realizations=realizations, correlation_model=correlation_model) with EnginePerformanceMonitor('saving gmfs', job_id, gmfs): save_gmf(gmfcoll_id, gmf, sites)
def compute_gmfs(job_id, rupture_ids, output_id, task_no, realizations): """ Compute ground motion fields and store them in the db. :param job_id: ID of the currently running job. :param rupture_ids: List of ids of parsed rupture model from which we will generate ground motion fields. :param output_id: output_id idenfitifies the reference to the output record. :param task_no: The task_no in which the calculation results will be placed. This ID basically corresponds to the sequence number of the task, in the context of the entire calculation. :param realizations: Number of realizations which are going to be created. """ hc = models.HazardCalculation.objects.get(oqjob=job_id) rupture_mdl = source.nrml_to_hazardlib( models.ParsedRupture.objects.get(id=rupture_ids[0]).nrml, hc.rupture_mesh_spacing, None, None) imts = [haz_general.imt_to_hazardlib(x) for x in hc.intensity_measure_types] gsim = AVAILABLE_GSIMS[hc.gsim] correlation_model = haz_general.get_correl_model(hc) gmf = ground_motion_fields( rupture_mdl, hc.site_collection, imts, gsim(), hc.truncation_level, realizations=realizations, correlation_model=correlation_model) save_gmf(output_id, gmf, hc.site_collection.mesh, task_no)
def gen_sources(src_ids, apply_uncertainties, rupture_mesh_spacing, width_of_mfd_bin, area_source_discretization): """ Hazardlib source objects generator for a given set of sources. Performs lazy loading, converting and processing of sources. :param src_ids: A list of IDs for :class:`openquake.engine.db.models.ParsedSource` records. :param apply_uncertainties: A function to be called on each generated source. See :meth:`openquake.engine.input.logictree.LogicTreeProcessor.\ parse_source_model_logictree_path` For information about the other parameters, see :func:`openquake.engine.input.source.nrml_to_hazardlib`. """ for src_id in src_ids: parsed_source = models.ParsedSource.objects.get(id=src_id) hazardlib_source = source.nrml_to_hazardlib( parsed_source.nrml, rupture_mesh_spacing, width_of_mfd_bin, area_source_discretization ) apply_uncertainties(hazardlib_source) yield hazardlib_source
def compute_gmfs(job_id, sites, rupture_id, output_id, realizations): """ Compute ground motion fields and store them in the db. :param job_id: ID of the currently running job. :param sites: The subset of the full SiteCollection scanned by this task :param rupture_id: The parsed rupture model from which we will generate ground motion fields. :param output_id: output_id idenfitifies the reference to the output record. :param realizations: Number of realizations to create. """ hc = models.HazardCalculation.objects.get(oqjob=job_id) rupture_mdl = source.nrml_to_hazardlib( models.ParsedRupture.objects.get(id=rupture_id).nrml, hc.rupture_mesh_spacing, None, None) imts = [haz_general.imt_to_hazardlib(x) for x in hc.intensity_measure_types] gsim = AVAILABLE_GSIMS[hc.gsim]() # instantiate the GSIM class correlation_model = haz_general.get_correl_model(hc) gmf = ground_motion_fields( rupture_mdl, sites, imts, gsim, hc.truncation_level, realizations=realizations, correlation_model=correlation_model) save_gmf(output_id, gmf, sites.mesh)
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_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_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 initialize_sources(self): """ Get the rupture_model file from the job.ini file, and set the attribute self.rupture. """ nrml = RuptureModelParser(self.hc.inputs['rupture_model']).parse() rms = self.job.hazard_calculation.rupture_mesh_spacing self.rupture = source.nrml_to_hazardlib(nrml, rms, None, None)
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_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_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_raises_useful_error(self): # Test that the source id and name are included with conversion errors, # to help the users deal with problems in their source models. area_geom = nrml_models.AreaGeometry( wkt='POLYGON((0.0 0.0, 1.0 0.0, 0.0 0.0 ))', upper_seismo_depth=0.0, lower_seismo_depth=10.0, ) area_mfd = nrml_models.IncrementalMFD( min_mag=6.55, bin_width=0.1, occur_rates=[0.0010614989, 8.8291627E-4, 7.3437777E-4, 6.108288E-4, 5.080653E-4], ) area_npd = [ nrml_models.NodalPlane(probability=decimal.Decimal("0.3"), strike=0.0, dip=90.0, rake=0.0), nrml_models.NodalPlane(probability=decimal.Decimal("0.7"), strike=90.0, dip=45.0, rake=90.0), ] area_hdd = [ nrml_models.HypocentralDepth(probability=decimal.Decimal("0.5"), depth=4.0), nrml_models.HypocentralDepth(probability=decimal.Decimal("0.5"), depth=8.0), ] area_src = nrml_models.AreaSource( id='1', name='Quito', trt='Active Shallow Crust', geometry=area_geom, mag_scale_rel='PeerMSR', rupt_aspect_ratio=1.5, mfd=area_mfd, nodal_plane_dist=area_npd, hypo_depth_dist=area_hdd, ) with self.assertRaises(Exception) as ar: source_input.nrml_to_hazardlib(area_src, MESH_SPACING, BIN_WIDTH, AREA_SRC_DISC) expected_error = ( "The following error has occurred with source id='1', " "name='Quito': Could not create geometry because of errors while " "reading input." ) self.assertEqual(expected_error, ar.exception.message)
def initialize_sources(self): """ Parse and validate source logic trees """ logs.LOG.progress("initializing sources") for src_path in logictree.read_logic_trees(self.hc): for src_nrml in nrml_parsers.SourceModelParser( os.path.join(self.hc.base_path, src_path)).parse(): src = source.nrml_to_hazardlib( src_nrml, self.hc.rupture_mesh_spacing, self.hc.width_of_mfd_bin, self.hc.area_source_discretization) if self.filtered_sites(src): if isinstance(src_nrml, PointSource): self.sources_per_model[src_path, 'point'].append(src) else: self.sources_per_model[src_path, 'other'].append(src)
def _prepare_sources(hc, lt_rlz_id): """ Helper function to prepare hazardlib source objects for a calculation. :param hc: :class:`openquake.engine.db.models.HazardCalculation` :param int lt_rlz_id: ID of a :class:`openquake.engine.db.models.LtRealization` :returns: A generator of hazardlib source objects for the given realization of the given calculation. See :mod:`openquake.hazardlib.source` for more info about the source types. """ source_progress = models.SourceProgress.objects.filter( lt_realization=lt_rlz_id) sources = ( source.nrml_to_hazardlib(x.parsed_source.nrml, hc.rupture_mesh_spacing, hc.width_of_mfd_bin, hc.area_source_discretization) for x in source_progress) return sources
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)) # now check that the ParsedSource geometry is correct # it should be the same as the 'rupture-enclosing' geometry for the # hazardlib representation of each source for i, (ns, ps) in enumerate(zip(nrml_sources, parsed_sources)): hazardlib_src = source_input.nrml_to_hazardlib( ns, MESH_SPACING, BIN_WIDTH, AREA_SRC_DISC ) hazardlib_poly = hazardlib_src.get_rupture_enclosing_polygon() # hazardlib 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(hazardlib_poly.wkt) self.assertTrue(expected_poly.almost_equals(actual_poly))