def build_fault_model(self, collapse=False, rendered_msr=WC1994(), mfd_config=None): ''' Constructs a full fault model with epistemic uncertainty by enumerating all the possible recurrence models of each fault as separate faults, with the recurrence rates multiplied by the corresponding weights. :param bool collapse: Determines whether or not to collapse the branches :param rendered_msr: If the option is taken to collapse the branches then a recurrence model for rendering must be defined :param list/dict mfd_config: Universal list or dictionay of configuration parameters for the magnitude frequency distribution - will overwrite whatever is previously defined for the fault! ''' self.source_model = mtkSourceModel(self.id, self.name) for fault in self.faults: fault.generate_recurrence_models(collapse, config=mfd_config, rendered_msr=rendered_msr) src_model, src_weight = fault.generate_fault_source_model() for iloc, model in enumerate(src_model): new_model = deepcopy(model) new_model.id = str(model.id) + '_%g' % (iloc + 1) new_model.mfd.occurrence_rates = \ (np.array(new_model.mfd.occurrence_rates) * src_weight[iloc]).tolist() self.source_model.sources.append(new_model)
def read_file(self, identifier, mfd_spacing=0.1, simple_mesh_spacing=1.0, complex_mesh_spacing=4.0, area_discretization=10.): """ Reads in the source model in returns an instance of the :class: openquake.hmtk.sourcs.source_model.mtkSourceModel """ sm_node = node_from_xml(self.input_file)[0] if sm_node[0].tag.startswith('{http://openquake.org/xmlns/nrml/0.4}'): node_sets = [sm_node] sm_name = sm_node.get("name", "") else: # format NRML 0.5+ node_sets = sm_node sm_name = sm_node["name"] source_model = mtkSourceModel(identifier, name=sm_name) for node_set in node_sets: for node in node_set: if "pointSource" in node.tag: source_model.sources.append( parse_point_source_node(node, mfd_spacing)) elif "areaSource" in node.tag: source_model.sources.append( parse_area_source_node(node, mfd_spacing)) elif "simpleFaultSource" in node.tag: source_model.sources.append( parse_simple_fault_node(node, mfd_spacing, simple_mesh_spacing)) elif "complexFaultSource" in node.tag: source_model.sources.append( parse_complex_fault_node(node, mfd_spacing, complex_mesh_spacing)) # TODO: multiPointSource are not supported else: print("Source typology %s not recognised - skipping!" % node.tag) return source_model
def read_file(self, identifier, mfd_spacing=0.1, simple_mesh_spacing=1.0, complex_mesh_spacing=4.0, area_discretization=10.): """ Reads in the source model in returns an instance of the :class: openquake.hmtk.sourcs.source_model.mtkSourceModel """ node_set = node_from_xml(self.input_file)[0] source_model = mtkSourceModel(identifier, name=node_set.attrib["name"]) for node in node_set: if "pointSource" in node.tag: source_model.sources.append( parse_point_source_node(node, mfd_spacing)) elif "areaSource" in node.tag: source_model.sources.append( parse_area_source_node(node, mfd_spacing)) elif "simpleFaultSource" in node.tag: source_model.sources.append( parse_simple_fault_node(node, mfd_spacing, simple_mesh_spacing)) elif "complexFaultSource" in node.tag: source_model.sources.append( parse_complex_fault_node(node, mfd_spacing, complex_mesh_spacing)) else: print("Source typology %s not recognised - skipping!" % node.tag) return source_model
def test_core_instantiation(self): ''' Simple test to ensure the class is correctly instantiated ''' self.source_model = mtkSourceModel('101', 'Model Name') self.assertEqual(self.source_model.id, '101') self.assertEqual(self.source_model.name, 'Model Name') # No sources on input self.assertEqual(self.source_model.get_number_sources(), 0) # Input correctly good_model = [mtkPointSource('101', 'Point 1'), mtkPointSource('102', 'Point 2')] self.source_model = mtkSourceModel('1001', 'Good Model', good_model) self.assertEqual(self.source_model.get_number_sources(), 2) # Input incorrectly - source not as list with self.assertRaises(ValueError) as ver: self.source_model = mtkSourceModel( '1002', 'Bad Model', mtkPointSource('103', 'Point 3')) self.assertEqual(str(ver.exception), 'Sources must be input as list!')
def df2nrml(df, model_name): ''' Write pandas DataFrame of source models to NRML. Sources are twinned by magnitude to support alternative tectonic region types for large-magnitude events. ''' if model_name.endswith('.xml'): model_name = model_name[:-4] nrml_file = model_name.replace(' ', '_') + '.xml' aseismic = df.a == 0 if any(aseismic): print('Dropping zones with no seismicity from NRML: ' + ', '.join(str(item) for item in df.loc[aseismic].index)) df = df.loc[~aseismic].copy() df = add_name_id(df) df = twin_source_by_magnitude(df) _check_columns(df) df = natural_sort(df, by='id') # this may do nothing ... source_list = source_df_to_list(df) source_model = mtkSourceModel(name=model_name, sources=source_list) source_model = source_model.convert_to_oqhazardlib(tom.PoissonTOM(1.0)) # apply per-zone discretization for item in source_model: try: item.area_discretization = df.loc[df.id == item.source_id, 'discretization'].squeeze() except KeyError: pass print('Writing: %s' % os.path.abspath(nrml_file)) write_source_model(nrml_file, source_model, name=model_name) return source_model