def split_filter_source(src, src_filter): """ :param src: a source to split :param src_filter: a SourceFilter instance :returns: a list of split sources """ has_serial = hasattr(src, 'serial') split_sources = [] start = 0 try: splits = split_map[src] # read from the cache except KeyError: # fill the cache splits = split_map[src] = list(sourceconverter.split_source(src)) if len(splits) > 1: logging.info( 'Splitting %s "%s" in %d sources', src.__class__.__name__, src.source_id, len(splits)) for split in splits: if has_serial: nr = split.num_ruptures split.serial = src.serial[start:start + nr] start += nr if src_filter.get_close_sites(split) is not None: split_sources.append(split) return split_sources
def test(self): npd = PMF([(0.5, NodalPlane(1, 20, 3)), (0.5, NodalPlane(2, 2, 4))]) hd = PMF([(1, 14)]) mesh = Mesh(numpy.array([0, 1]), numpy.array([0.5, 1])) tom = PoissonTOM(50.) mmfd = MultiMFD('incrementalMFD', size=2, min_mag=[4.5], bin_width=[2.0], occurRates=[[.3, .1], [.4, .2, .1]]) mps = MultiPointSource('mp1', 'multi point source', 'Active Shallow Crust', mmfd, 2.0, PeerMSR(), 1.0, tom, 10, 20, npd, hd, mesh) mps.src_group_id = 1 # test the splitting splits = list(split_source(mps)) self.assertEqual(len(splits), 2) for split in splits: self.assertEqual(split.src_group_id, mps.src_group_id) got = obj_to_node(mps).to_str() print(got) self.assertEqual(got, '''\ multiPointSource{id='mp1', name='multi point source', tectonicRegion='Active Shallow Crust'} multiPointGeometry gml:posList [0, 0.5, 1, 1.0] upperSeismoDepth 10 lowerSeismoDepth 20 magScaleRel 'PeerMSR' ruptAspectRatio 1.0 multiMFD{kind='incrementalMFD', size=2} bin_width [2.0] min_mag [4.5] occurRates [0.29999999999999999, 0.10000000000000001, 0.40000000000000002, 0.20000000000000001, 0.10000000000000001] lengths [2, 3] nodalPlaneDist nodalPlane{dip=20, probability=0.5, rake=3, strike=1} nodalPlane{dip=2, probability=0.5, rake=4, strike=2} hypoDepthDist hypoDepth{depth=14, probability=1.0} ''')
def test(self): npd = PMF([(0.5, NodalPlane(1, 20, 3)), (0.5, NodalPlane(2, 2, 4))]) hd = PMF([(1, 14)]) mesh = Mesh(numpy.array([0, 1]), numpy.array([0.5, 1])) tom = PoissonTOM(50.) mmfd = MultiMFD('incrementalMFD', min_mag=[4.5, 4.5], bin_width=[2.0, 2.0], occurRates=[[.3, .1], [.4, .2, .1]]) mps = MultiPointSource('mp1', 'multi point source', 'Active Shallow Crust', mmfd, 2.0, PeerMSR(), 1.0, tom, 10, 20, npd, hd, mesh) mps.src_group_id = 1 # test the splitting splits = list(split_source(mps)) self.assertEqual(len(splits), 2) for split in splits: self.assertEqual(split.src_group_id, mps.src_group_id) self.assertEqual(obj_to_node(mps).to_str(), '''\ multiPointSource{id='mp1', name='multi point source', tectonicRegion='Active Shallow Crust'} multiPointGeometry gml:posList [0, 0.5, 1, 1.0] upperSeismoDepth 10 lowerSeismoDepth 20 magScaleRel 'PeerMSR' ruptAspectRatio 1.0 multiMFD{kind='incrementalMFD'} bin_width [2.0, 2.0] min_mag [4.5, 4.5] occurRates [0.3, 0.1, 0.4, 0.2, 0.1] lengths [2, 3] nodalPlaneDist nodalPlane{dip=20, probability=0.5, rake=3, strike=1} nodalPlane{dip=2, probability=0.5, rake=4, strike=2} hypoDepthDist hypoDepth{depth=14, probability=1.0} ''')
def full_disaggregation(self): """ Run the disaggregation phase after hazard curve finalization. """ oq = self.oqparam tl = self.oqparam.truncation_level bb_dict = self.datastore['bb_dict'] sitecol = self.sitecol mag_bin_width = self.oqparam.mag_bin_width eps_edges = numpy.linspace(-tl, tl, self.oqparam.num_epsilon_bins + 1) logging.info('%d epsilon bins from %s to %s', len(eps_edges) - 1, min(eps_edges), max(eps_edges)) self.bin_edges = {} curves_dict = {sid: self.get_curves(sid) for sid in sitecol.sids} all_args = [] num_trts = sum(len(sm.src_groups) for sm in self.csm.source_models) nblocks = math.ceil(oq.concurrent_tasks / num_trts) for smodel in self.csm.source_models: sm_id = smodel.ordinal trt_names = tuple(mod.trt for mod in smodel.src_groups) max_mag = max(mod.max_mag for mod in smodel.src_groups) min_mag = min(mod.min_mag for mod in smodel.src_groups) mag_edges = mag_bin_width * numpy.arange( int(numpy.floor(min_mag / mag_bin_width)), int(numpy.ceil(max_mag / mag_bin_width) + 1)) logging.info('%d mag bins from %s to %s', len(mag_edges) - 1, min_mag, max_mag) for src_group in smodel.src_groups: if src_group.id not in self.rlzs_assoc.gsims_by_grp_id: continue # the group has been filtered away for sid, site in zip(sitecol.sids, sitecol): curves = curves_dict[sid] if not curves: continue # skip zero-valued hazard curves bb = bb_dict[sm_id, sid] if not bb: logging.info( 'location %s was too far, skipping disaggregation', site.location) continue dist_edges, lon_edges, lat_edges = bb.bins_edges( oq.distance_bin_width, oq.coordinate_bin_width) logging.info('%d dist bins from %s to %s', len(dist_edges) - 1, min(dist_edges), max(dist_edges)) logging.info('%d lon bins from %s to %s', len(lon_edges) - 1, bb.west, bb.east) logging.info('%d lat bins from %s to %s', len(lon_edges) - 1, bb.south, bb.north) self.bin_edges[sm_id, sid] = (mag_edges, dist_edges, lon_edges, lat_edges, eps_edges) bin_edges = {} for sid, site in zip(sitecol.sids, sitecol): if (sm_id, sid) in self.bin_edges: bin_edges[sid] = self.bin_edges[sm_id, sid] src_filter = SourceFilter(sitecol, oq.maximum_distance) split_sources = [] for src in src_group: for split, _sites in src_filter( sourceconverter.split_source(src), sitecol): split_sources.append(split) mon = self.monitor('disaggregation') for srcs in split_in_blocks(split_sources, nblocks): all_args.append( (src_filter, srcs, src_group.id, self.rlzs_assoc, trt_names, curves_dict, bin_edges, oq, mon)) results = parallel.Starmap(compute_disagg, all_args).reduce(self.agg_result) self.save_disagg_results(results)
def full_disaggregation(self): """ Run the disaggregation phase after hazard curve finalization. """ oq = self.oqparam tl = self.oqparam.truncation_level sitecol = self.sitecol eps_edges = numpy.linspace(-tl, tl, self.oqparam.num_epsilon_bins + 1) self.bin_edges = {} curves = [self.get_curves(sid) for sid in sitecol.sids] # determine the number of effective source groups sg_data = self.datastore['csm_info/sg_data'] num_grps = sum(1 for effrup in sg_data['effrup'] if effrup > 0) nblocks = math.ceil(oq.concurrent_tasks / num_grps) src_filter = SourceFilter(sitecol, oq.maximum_distance) R = len(self.rlzs_assoc.realizations) max_poe = numpy.zeros(R, oq.imt_dt()) # build trt_edges trts = tuple( sorted( set(sg.trt for smodel in self.csm.source_models for sg in smodel.src_groups))) # build mag_edges min_mag = min(sg.min_mag for smodel in self.csm.source_models for sg in smodel.src_groups) max_mag = max(sg.max_mag for smodel in self.csm.source_models for sg in smodel.src_groups) mag_edges = oq.mag_bin_width * numpy.arange( int(numpy.floor(min_mag / oq.mag_bin_width)), int(numpy.ceil(max_mag / oq.mag_bin_width) + 1)) # build dist_edges maxdist = max(oq.maximum_distance(trt, max_mag) for trt in trts) dist_edges = oq.distance_bin_width * numpy.arange( 0, int(numpy.ceil(maxdist / oq.distance_bin_width) + 1)) logging.info('dist = %s...%s', min(dist_edges), max(dist_edges)) # build eps_edges eps_edges = numpy.linspace(-tl, tl, oq.num_epsilon_bins + 1) # build lon_edges, lat_edges per sid bbs = src_filter.get_bounding_boxes(mag=max_mag) for sid, bb in zip(self.sitecol.sids, bbs): lon_edges, lat_edges = disagg.lon_lat_bins(bb, oq.coordinate_bin_width) logging.info('site %d, lon = %s...%s', sid, min(lon_edges), max(lon_edges)) logging.info('site %d, lat = %s...%s', sid, min(lat_edges), max(lat_edges)) self.bin_edges[sid] = bs = (mag_edges, dist_edges, lon_edges, lat_edges, eps_edges) shape = [len(edges) - 1 for edges in bs] + [len(trts)] logging.info('%s for sid %d', shape, sid) # check poes for smodel in self.csm.source_models: sm_id = smodel.ordinal for i, site in enumerate(sitecol): sid = sitecol.sids[i] curve = curves[i] # populate max_poe array for rlzi, poes in curve.items(): for imt in oq.imtls: max_poe[rlzi][imt] = max(max_poe[rlzi][imt], poes[imt].max()) if not curve: continue # skip zero-valued hazard curves # check for too big poes_disagg for poe in oq.poes_disagg: for rlz in self.rlzs_assoc.rlzs_by_smodel[sm_id]: rlzi = rlz.ordinal for imt in oq.imtls: min_poe = max_poe[rlzi][imt] if poe > min_poe: raise ValueError( self.POE_TOO_BIG % (poe, sm_id, smodel.name, min_poe, rlzi, imt)) # build all_args all_args = [] for smodel in self.csm.source_models: for sg in smodel.src_groups: split_sources = [] for src in sg: for split, _sites in src_filter( sourceconverter.split_source(src), sitecol): split_sources.append(split) if not split_sources: continue mon = self.monitor('disaggregation') rlzs_by_gsim = self.rlzs_assoc.get_rlzs_by_gsim( sg.trt, smodel.ordinal) cmaker = ContextMaker(rlzs_by_gsim, src_filter.integration_distance) imls = [ disagg.make_imldict(rlzs_by_gsim, oq.imtls, oq.iml_disagg, oq.poes_disagg, curve) for curve in curves ] for srcs in split_in_blocks(split_sources, nblocks): all_args.append((src_filter, srcs, cmaker, imls, trts, self.bin_edges, oq, mon)) self.cache_info = numpy.zeros(2) # operations, cache_hits results = parallel.Starmap(compute_disagg, all_args).reduce(self.agg_result) ops, hits = self.cache_info logging.info('Cache speedup %s', ops / (ops - hits)) self.save_disagg_results(results)