def read(self, nrml_file, validate=False, simple_fault_spacing=1.0, complex_mesh_spacing=5.0, mfd_spacing=0.1): """ Build the source model from nrml format """ self.source_file = nrml_file if validate: converter = SourceConverter(1.0, simple_fault_spacing, complex_mesh_spacing, mfd_spacing, 10.0) converter.fname = nrml_file root = nrml.read(nrml_file) if root['xmlns'] == 'http://openquake.org/xmlns/nrml/0.4': sg_nodes = [root.sourceModel.nodes] else: # NRML 0.5 sg_nodes = root.sourceModel.nodes sources = [] for sg_node in sg_nodes: for no, src_node in enumerate(sg_node, 1): if validate: print("Validating Source %s" % src_node.attrib["id"]) converter.convert_node(src_node) sources.append(src_node) return SourceModel(sources)
def read_simplefault_source(simplefault_source_file, rupture_mesh_spacing=10): """Read nrml source model into simpmle fault objects """ converter = SourceConverter(50, rupture_mesh_spacing, width_of_mfd_bin=0.1, area_source_discretization=200.) parser = SourceModelParser(converter) try: sources = parser.parse_sources(simplefault_source_file) except AttributeError: # Handle version 2.1 and above sources = [] groups = parser.parse_src_groups(simplefault_source_file) for group in groups: for source in group: sources.append(source) for fault in sources: # print [method for method in dir(fault)] # print [method for method in dir(fault.mfd)] #######Probably not actually needed now # Add max_mag attribute if needed: # try: # print fault.mfd.max_mag # except AttributeError: # min_mag, max_mag = fault.mfd.get_min_max_mag() # fault.mfd.max_mag = max_mag # print fault.mfd.max_mag pass return sources
def test_load_mfs(self): datadir = os.path.join(os.path.dirname(__file__), 'data', 'sections') sec_xml = os.path.join(datadir, 'sections_kite.xml') src_xml = os.path.join(datadir, 'sources.xml') conv = SourceConverter() sec = nrml.to_python(sec_xml, conv).sections expected = [Point(11, 45, 0), Point(11, 45.5, 10)] # Check geometry info self.assertEqual(expected[0], sec[1].surface.profiles[0].points[0]) self.assertEqual(expected[1], sec[1].surface.profiles[0].points[1]) self.assertEqual(sec[1].sec_id, 's2') ssm = nrml.to_python(src_xml, conv) self.assertIsInstance(ssm, nrml.SourceModel) ssm[0][0].create_inverted_index(sec) # fix sections rups = list(ssm[0][0].iter_ruptures()) # Check data for the second rupture msg = 'Rake for rupture #0 is wrong' self.assertEqual(rups[0].rake, 90.0, msg) # Check data for the second rupture msg = 'Rake for rupture #1 is wrong' self.assertEqual(rups[1].rake, -90.0, msg) # Check mfd expected = numpy.array([0.9, 0.1]) numpy.testing.assert_almost_equal(rups[1].probs_occur, expected)
def _get_source_model(source_file, investigation_time=1., rupture_mesh_spacing=10.0, complex_fault_mesh_spacing=10.0, width_of_mfd_bin=0.1, area_source_discretization=20., **kwargs): """ Read and build a source model from an xml file :parameter source_file The name of a file containing the source model :parameter float inv_time: A positive float :paramater float simple_mesh_spacing: A positive float :parameter float complex_mesh_spacing: A positive float :parameter float mfd_spacing: A positive float :parameter float area_discretisation: A positive float :returns: A list of :class:`~openquake.hazardlib.sourceconverter.SourceGroup` instances """ conv = SourceConverter(investigation_time, rupture_mesh_spacing, complex_fault_mesh_spacing, width_of_mfd_bin, area_source_discretization, **kwargs) srcs = to_python(source_file, conv) return srcs.src_groups
def from_model_files(cls, limits, input_model, investigation_time=1.0, simple_mesh_spacing=1.0, complex_mesh_spacing=5.0, mfd_width=0.1, area_discretisation=10.0): """ Reads the hazard model from a file :param list limits: Grid configuration [west, east, xspc, south, north, yspc, upper, lower, zspc] :param str input_model: Path to input source model :param float investigation_time: Investigation time of Poisson model :param float simple_mesh_spacing: Rupture mesh spacing of simple fault (km) :param float complex_mesh_spacing: Rupture mesh spacing of complex fault (km) :param float mfd_width: Spacing (in magnitude units) of MFD :param float area_discretisation: Spacing of discretisation of area source (km) """ converter = SourceConverter(investigation_time, simple_mesh_spacing, complex_mesh_spacing, mfd_width, area_discretisation) sources = [] for grp in nrml.to_python(input_model, converter): sources.extend(grp.sources) return cls(limits, sources, area_discretisation)
def test_is_writeable(self): parser = SourceModelParser(SourceConverter(50., 1., 10, 0.1, 10.)) groups = [copy.deepcopy(grp) for grp in parser.parse_groups(ALT_MFDS)] # there are a SimpleFaultSource and a CharacteristicFaultSource fd, fname = tempfile.mkstemp(suffix='.xml') with os.fdopen(fd, 'wb'): write_source_model(fname, groups, 'Test Source Model')
def test_tom_poisson_no_rate(self): testfile = os.path.join(testdir, 'tom_poisson_no_rate.xml') sc = SourceConverter(area_source_discretization=10.) sg = nrml.to_python(testfile, sc) src = sg[0].sources[0] msg = "Wrong time span in the temporal occurrence model" self.assertEqual(src.temporal_occurrence_model.time_span, 50, msg)
def test_tom_poisson_not_defined(self): """ Read area source without tom """ testfile = os.path.join(testdir, 'area-source.xml') sc = SourceConverter(area_source_discretization=10.) sg = nrml.to_python(testfile, sc) src = sg[0].sources[0] self.assertEqual(src.temporal_occurrence_model.time_span, 50, "Wrong time span in the temporal occurrence model")
def test_source_group_with_tom(self): testfile = os.path.join(testdir, 'source_group_with_tom.xml') sc = SourceConverter(area_source_discretization=10.) sg = nrml.to_python(testfile, sc) msg = "Wrong occurrence rate in the temporal occurrence model" expected = sg[0].temporal_occurrence_model.occurrence_rate self.assertEqual(expected, 0.01, msg) msg = "Wrong cluster definition" self.assertEqual(sg[0].cluster, False, msg)
def get_source_model(source_file, inv_time, simple_mesh_spacing=1.0, complex_mesh_spacing=10.0, mfd_spacing=0.1, area_discretisation=10.): """ Read and build a source model from an xml file """ conv = SourceConverter(inv_time, simple_mesh_spacing, complex_mesh_spacing, mfd_spacing, area_discretisation) parser = SourceModelParser(conv) return parser.parse_src_groups(source_file)
def test_simple_fault_source(self): d = os.path.dirname(os.path.dirname(__file__)) tmps = 'simple-fault-source.xml' source_model = os.path.join(d, 'source_model', tmps) groups = nrml.to_python( source_model, SourceConverter(investigation_time=50., rupture_mesh_spacing=2.)) src = groups[0].sources[0] rup = src.get_one_rupture(ses_seed=0) self.assertEqual(rup.mag, 5.2)
def read(self, input_shapefile, validate=False, simple_fault_spacing=1.0, complex_mesh_spacing=5.0, mfd_spacing=0.1): """ Build the source model from a shapefile """ reader = shapefile.Reader(input_shapefile) fields = [field[0] for field in reader.fields[1:]] shapes = reader.shapes() records = reader.records() sources = [] if validate: converter = SourceConverter(1.0, simple_fault_spacing, complex_mesh_spacing, mfd_spacing, 10.0) for iloc in range(reader.numRecords): # Build record dictionary record = record_to_dict(records[iloc], fields) shape = shapes[iloc] if "pointSource" in record["sourcetype"]: src = build_point_source_from_shp(shape, record) elif "areaSource" in record["sourcetype"]: src = build_area_source_from_shp(shape, record) elif "simpleFaultSource" in record["sourcetype"]: src = build_simple_fault_source_from_shp(shape, record) elif "complexFaultSource" in record["sourcetype"]: src = build_complex_fault_source_from_shp(shape, record) elif "characteristicFaultSource" in record["sourcetype"]: print("Characteristic Fault Source Not Yet Supported - Sorry!") src = None elif "multiPointSource" in record["sourcetype"]: print("Characteristic Fault Source Not Yet Supported - Sorry!") src = None if src and validate: print("Validating Source %s" % src.attrib["id"]) converter.convert_node(src) if src: sources.append(src) return SourceModel(sources)
def setUp(self): testfile = os.path.join(DATA, 'source_group_cluster.xml') sc = SourceConverter(area_source_discretization=10., investigation_time=1.) # This provides a SourceModel self.sg = getattr(nrml.to_python(testfile, sc), 'src_groups') self.imtls = DictArray({'PGA': [0.01, 0.1, 0.2, 0.3, 1.0]}) gsim = SadighEtAl1997() self.gsim_by_trt = {TRT.ACTIVE_SHALLOW_CRUST: gsim} site = Site(Point(1.0, -0.1), 800, z1pt0=30., z2pt5=1.) self.sites = SiteCollection([site])
def test(self): source_model = os.path.join(os.path.dirname(__file__), 'nankai.xml') groups = nrml.parse(source_model, SourceConverter( investigation_time=50., rupture_mesh_spacing=2.)) site = Site(Point(135.68, 35.68), 800, True, z1pt0=100., z2pt5=1.) s_filter = SourceFilter(SiteCollection([site]), None) imtls = DictArray({'PGV': [20, 40, 80]}) gsim_by_trt = {'Subduction Interface': SiMidorikawa1999SInter()} hcurves = calc_hazard_curves_ext(groups, s_filter, imtls, gsim_by_trt) npt.assert_almost_equal([0.91149953, 0.12548556, 0.00177583], hcurves['PGV'][0])
def test(self): source_model = os.path.join(os.path.dirname(__file__), 'nankai.xml') groups = nrml.to_python(source_model, SourceConverter( investigation_time=50., rupture_mesh_spacing=2.)) site = Site(Point(135.68, 35.68), 800, True, z1pt0=100., z2pt5=1.) s_filter = SourceFilter(SiteCollection([site]), {}) imtls = DictArray({'PGV': [20, 40, 80]}) gsim_by_trt = {'Subduction Interface': SiMidorikawa1999SInter()} hcurves = calc_hazard_curves(groups, s_filter, imtls, gsim_by_trt) npt.assert_almost_equal( [1.1262869e-01, 3.9968668e-03, 3.1005840e-05], hcurves['PGV'][0])
def check_mfds(fname_input_pattern: str, fname_config: str, *, src_id: str = None): """ Given a set of .xml files and a configuration file with GR params, this code compares the total MFD of the sources against the original one in the configuration file. The ID of the source if not provided is taken from the name of the files (i.e., last label preceded by `_`) """ for fname in sorted(glob(fname_input_pattern)): if src_id is None: src_id = _get_src_id(fname) model = toml.load(fname_config) binw = 0.1 sourceconv = SourceConverter(investigation_time=1.0, rupture_mesh_spacing=5.0, complex_fault_mesh_spacing=5.0, width_of_mfd_bin=binw) ssm = to_python(fname, sourceconv) for grp in ssm: for i, src in enumerate(grp): if i == 0: nmfd = EEvenlyDiscretizedMFD.from_mfd(src.mfd, binw) else: ged = get_evenlyDiscretizedMFD_from_truncatedGRMFD tmfd = ged(src.mfd, nmfd.bin_width) nmfd.stack(tmfd) occ = np.array(nmfd.get_annual_occurrence_rates()) bgr = model["sources"][src_id]["bgr_weichert"] agr = model["sources"][src_id]["agr_weichert"] tmp = occ[:, 0] - binw mfd = 10.0**(agr - bgr * tmp[:-1]) - 10.0**(agr - bgr * (tmp[:-1] + binw)) _ = plt.figure(figsize=(8, 6)) plt.plot(occ[:, 0], occ[:, 1], 'o') plt.plot(tmp[:-1] + binw / 2, mfd, 'x') print(mfd) plt.title(fname) plt.xlabel('Magnitude') plt.ylabel('Annual occurrence rate') plt.yscale('log') plt.show()
def setUp(self): d = os.path.dirname(os.path.dirname(__file__)) source_model = os.path.join(d, 'source_model/multi-point-source.xml') [self.sources] = nrml.parse( source_model, SourceConverter(investigation_time=50., rupture_mesh_spacing=2.)) self.site = Site(Point(0.1, 0.1), 800, True, z1pt0=100., z2pt5=1.) self.imt = PGA() self.iml = 0.1 self.truncation_level = 1 self.trt = 'Stable Continental Crust' self.gsims = {self.trt: Campbell2003()}
def check_round_trip(self, fname): parser = SourceModelParser(SourceConverter(50., 1., 10, 0.1, 10.)) groups = parser.parse_src_groups(fname) fd, name = tempfile.mkstemp(suffix='.xml') with os.fdopen(fd, 'wb'): write_source_model(name, groups, 'Test Source Model') with hdf5.File.temporary() as f: for group in groups: hdf5write(f, group) print('written %s' % f.path) if open(name).read() != open(fname).read(): raise Exception('Different files: %s %s' % (name, fname)) os.remove(name)
def read(self, nrml_file, validate=False, simple_fault_spacing=1.0, complex_mesh_spacing=5.0, mfd_spacing=0.1): """ Build the source model from nrml format """ self.source_file = nrml_file if validate: converter = SourceConverter(1.0, simple_fault_spacing, complex_mesh_spacing, mfd_spacing, 10.0) converter.fname = nrml_file src_nodes = nrml.read(nrml_file).sourceModel sources = [] for no, src_node in enumerate(src_nodes, 1): if validate: print("Validating Source %s" % src_node.attrib["id"]) converter.convert_node(src_node) sources.append(src_node) return SourceModel(sources)
def test(self): # mutually exclusive ruptures d = os.path.dirname(os.path.dirname(__file__)) tmps = 'nonparametric-source-mutex-ruptures.xml' source_model = os.path.join(d, 'source_model', tmps) groups = nrml.to_python(source_model, SourceConverter( investigation_time=50., rupture_mesh_spacing=2.)) site = Site(Point(143.5, 39.5), 800, z1pt0=100., z2pt5=1.) sitecol = SiteCollection([site]) imtls = DictArray({'PGA': [0.01, 0.1, 0.2, 0.5]}) gsim_by_trt = {'Some TRT': Campbell2003()} hcurves = calc_hazard_curves(groups, sitecol, imtls, gsim_by_trt) # expected results obtained with an ipython notebook expected = [4.3998728e-01, 1.1011728e-01, 7.5495312e-03, 8.5812844e-06] npt.assert_almost_equal(hcurves['PGA'][0], expected)
def read_pt_source(pt_source_file): """Read nrml source model into pt source objects """ converter = SourceConverter(50, 2, width_of_mfd_bin=0.1, area_source_discretization=10.) parser = SourceModelParser(converter) try: sources = parser.parse_sources(pt_source_file) except AttributeError: # Handle version 2.1 and above sources = [] groups = parser.parse_src_groups(pt_source_file) for group in groups: for source in group: sources.append(source) # for pt in sources: # print pt.mfd.max_mag return sources
def get_composite_source_model(oq): """ :param oq: :class:`openquake.commonlib.oqvalidation.OqParam` instance :returns: a `class:`openquake.commonlib.source.CompositeSourceModel` """ [src_group] = nrml.to_python( oq.inputs["source_model"], SourceConverter(oq.investigation_time, oq.rupture_mesh_spacing)) source_models = [] gsim_lt = readinput.get_gsim_lt(oq, [DEFAULT_TRT]) smlt = readinput.get_source_model_lt(oq) for sm in smlt.gen_source_models(gsim_lt): sg = copy.copy(src_group) sg.id = sm.ordinal sm.src_groups = [sg] sg.sources = [sg[0].new(sm.ordinal, sm.names)] source_models.append(sm) return source.CompositeSourceModel(gsim_lt, smlt, source_models)
def test(self): d = os.path.dirname(os.path.dirname(__file__)) source_model = os.path.join(d, 'source_model/multi-point-source.xml') groups = nrml.to_python(source_model, SourceConverter( investigation_time=50., rupture_mesh_spacing=2.)) site = Site(Point(0.1, 0.1), 800, True, z1pt0=100., z2pt5=1.) sitecol = SiteCollection([site]) imtls = DictArray({'PGA': [0.01, 0.02, 0.04, 0.08, 0.16]}) gsim_by_trt = {'Stable Continental Crust': Campbell2003()} hcurves = calc_hazard_curves(groups, sitecol, imtls, gsim_by_trt) expected = [0.99999778, 0.9084039, 0.148975348, 0.0036909656, 2.76326e-05] npt.assert_almost_equal(hcurves['PGA'][0], expected) # splitting in point sources [[mps1, mps2]] = groups psources = list(mps1) + list(mps2) hcurves = calc_hazard_curves(psources, sitecol, imtls, gsim_by_trt) npt.assert_almost_equal(hcurves['PGA'][0], expected)
def get_sources(source_model_file, discretisation=50.): """Calls OpenQuake parsers to read source model from source_mode.xml type file, and return to calculate ruptures. A more generic verions than that above. :params source_model_file: nrml format file of source model :params discretisation: Grid size (km) for the area source discretisation, which defines the distance between resulting point sources. :returns sources Source for the source model """ converter = SourceConverter(50, 10, width_of_mfd_bin=0.1, area_source_discretization=discretisation) parser = SourceModelParser(converter) try: sources = parser.parse_sources(source_model_file) except AttributeError: # Handle version 2.1 and above sources = [] groups = parser.parse_src_groups(source_model_file) for group in groups: for source in group: sources.append(source) # name = 'test_point_model' new_sources = {} for source in sources: #pt_sources = area_to_point_sources(source) #for pt in pt_sources: # pt.source_id = pt.source_id.replace(':','') # pt.name = pt.name.replace(':','_') try: new_sources[source.tectonic_region_type].append(source) except KeyError: new_sources[source.tectonic_region_type] = [source] return new_sources
def check_mfds(fname_input_pattern: str, fname_config: str): for fname in sorted(glob(fname_input_pattern)): src_id = _get_src_id(fname) model = toml.load(fname_config) binw = 0.1 sourceconv = SourceConverter(investigation_time=1.0, rupture_mesh_spacing=5.0, complex_fault_mesh_spacing=5.0, width_of_mfd_bin=binw) ssm = to_python(fname, sourceconv) for grp in ssm: for i, src in enumerate(grp): if i == 0: nmfd = EEvenlyDiscretizedMFD.from_mfd(src.mfd, binw) else: tmfd = get_evenlyDiscretizedMFD_from_truncatedGRMFD(src.mfd, nmfd.bin_width) nmfd.stack(tmfd) occ = np.array(nmfd.get_annual_occurrence_rates()) bgr = model["sources"][src_id]["bgr_weichert"] agr = model["sources"][src_id]["agr_weichert"] tmp = occ[:,0] - binw mfd = 10.0**(agr-bgr*tmp[:-1])-10.0**(agr-bgr*(tmp[:-1]+binw)) fig = plt.figure(figsize=(8, 6)) plt.plot(occ[:, 0], occ[:, 1], 'o') plt.plot(tmp[:-1]+binw/2, mfd, 'x') print(mfd) plt.title(fname) plt.xlabel('Magnitude') plt.ylabel('Annual occurrence rate') plt.yscale('log') plt.show()
def test_mmax_simple_fault_src(self): """ Test the modify_recompute_mmax method """ # We test the method used to recompute the maximum magnitude after # a change in the geometry of the surface of the fault. We start from # the simple fault source used in the demos. d = os.path.dirname(os.path.abspath(__file__)) fname = 'simple_fault_source_recompute_mmax.xml' source_model = os.path.join(d, 'data', fname) groups = nrml.to_python( source_model, SourceConverter(investigation_time=1., rupture_mesh_spacing=2., width_of_mfd_bin=0.1)) src = groups[0][0] # We increase the lower seismogenic depth from 15 to 20 km the area # will increase of 50% from 1623 to about 2433 km2. The magnitude we # get using WC1194 for an area or 2433 km2 is 7.37 src.lower_seismogenic_depth = 20.0 src.modify_recompute_mmax() area = src.get_fault_surface_area() msg = "The recomputed mmax does not match the expected value" self.assertAlmostEqual(7.377, src.mfd.max_mag, msg=msg, places=2) print(area, src.mfd.max_mag, src.lower_seismogenic_depth) # Now we test the case where we recompute mmax with a value of episilon # (i.e., number of standard deviations) different than one src.modify_recompute_mmax(1) self.assertAlmostEqual(7.377 + 0.25, src.mfd.max_mag, msg=msg, places=2) src.modify_recompute_mmax(-1) self.assertAlmostEqual(7.377 - 0.25, src.mfd.max_mag, msg=msg, places=2)
def nrml2sourcelist(area_source_file, investigation_time=50, rupture_mesh_spacing=10., width_of_mfd_bin=0.1, area_source_discretisation=10.): """Parser nrml file containing area sources and read into a list of source objects """ converter = SourceConverter( 50, 10, width_of_mfd_bin=0.1, area_source_discretization=area_source_discretisation) parser = SourceModelParser(converter) try: sources = parser.parse_sources(area_source_file) except AttributeError: # Handle version 2.1 and above sources = [] groups = parser.parse_src_groups(area_source_file) for group in groups: for source in group: sources.append(source) return sources
def get_sources_from_rlz(rlz, oqparam, ssm_lt, sourcefilter=None): """ :param rlz: "openquake.commonlib.logictree.Realization" instance :param oqparam: "openquake.commonlib.oqvalidation.OqParam" instance :param ssm_lt: instance of class "openquake.commonlib.logictree.SourceModelLogicTreeCollection" :param sourcefilter: instance of class "openquake.hazardlib.calc.filters.SourceFilter", apply a filtering of seismic sources based a maximum integration distance. Default: None :return : a list of seismic sources instances, e.g. "openquake.hazardlib.source.area.AreaSource" NOTE/ Incompatibility: method ssm_lt.apply_incertainties() has been removed in openquake.engine versions >= 3.9 """ # Creating a source converter conv = SourceConverter(oqparam.investigation_time, oqparam.rupture_mesh_spacing, oqparam.complex_fault_mesh_spacing, oqparam.width_of_mfd_bin, oqparam.area_source_discretization) # Set the name of the model ssm_fname = os.path.join(oqparam.base_path, rlz.value) # Read the source model ssm = to_python(ssm_fname, conv) # Set-up filter if required: if sourcefilter is None: filter_func = lambda x: x # No filter elif isinstance(sourcefilter, SourceFilter): filter_func = sourcefilter.filter # filtering based on maximum integration distance # Loop over groups included in the source model sources = [] for grp in ssm: # Update source group for the current realisation: updated_group = ssm_lt.apply_uncertainties(rlz.lt_path, grp) # Loop over sources: for src in filter_func(updated_group): sources.append(src) return sources
'source_model/alternative-mfds_4test.xml') COLLECTION = os.path.join(os.path.dirname(__file__), 'source_model/source_group_collection.xml') MUTEX = os.path.join(os.path.dirname(__file__), 'source_model/nonparametric-source-mutex-ruptures.xml') MULTIPOINT = os.path.join(os.path.dirname(__file__), 'source_model/multi-point-source.xml') GRIDDED = os.path.join(os.path.dirname(__file__), 'source_model/gridded.xml') TOML = os.path.join(os.path.dirname(__file__), 'expected_sources.toml') conv = SourceConverter(50., 1., 10, 0.1, 10.) class SourceWriterTestCase(unittest.TestCase): def check_round_trip(self, fname): smodel = nrml.to_python(fname, conv) fd, name = tempfile.mkstemp(suffix='.xml') with os.fdopen(fd, 'wb'): write_source_model(name, smodel) with open(name + '.toml', 'w') as f: tomldump(smodel, f) if open(name).read() != open(fname).read(): raise Exception('Different files: %s %s' % (name, fname)) os.remove(name) os.remove(name + '.toml') return smodel
def test_source_group_cluster(self): testfile = os.path.join(testdir, 'source_group_cluster.xml') sc = SourceConverter(area_source_discretization=10.) sg = nrml.to_python(testfile, sc) msg = "Wrong cluster definition" self.assertEqual(sg[0].cluster, True, msg)