def preclassical(srcs, srcfilter, params, monitor): """ Weight the sources. Also split them if split_sources is true. If ps_grid_spacing is set, grid the point sources before weighting them. NB: srcfilter can be on a reduced site collection for performance reasons """ # src.id -> nrups, nsites, time, task_no calc_times = AccumDict(accum=numpy.zeros(4, F32)) sources = [] grp_id = srcs[0].grp_id trt = srcs[0].tectonic_region_type md = params['maximum_distance'](trt) pd = (params['pointsource_distance'](trt) if params['pointsource_distance'] else 0) with monitor('splitting sources'): # this can be slow for src in srcs: t0 = time.time() if srcfilter.sitecol: src.nsites = len(srcfilter.close_sids(src)) else: src.nsites = 1 # don't discard # NB: it is crucial to split only the close sources, for # performance reasons (think of Ecuador in SAM)q splits = split_source(src) if (params['split_sources'] and src.nsites) else [src] sources.extend(splits) nrups = src.count_ruptures() if src.nsites else 0 dt = time.time() - t0 calc_times[src.id] += F32([nrups, src.nsites, dt, 0]) for arr in calc_times.values(): arr[3] = monitor.task_no dic = grid_point_sources(sources, params['ps_grid_spacing'], monitor) with monitor('weighting sources'): # this is normally fast for src in dic[grp_id]: if not src.nsites: # filtered out src.nsites = EPS is_ps = isinstance(src, PointSource) if is_ps and srcfilter.sitecol: # NB: using cKDTree would not help, performance-wise cdist = srcfilter.sitecol.get_cdist(src.location) src.nsites = (cdist <= md + pd).sum() or EPS src.num_ruptures = src.count_ruptures() if pd and is_ps: nphc = src.count_nphc() if nphc > 1: close = (cdist <= pd * BUFFER).sum() far = src.nsites - close factor = (close + (far + EPS) / nphc) / (close + far + EPS) src.num_ruptures *= factor dic['calc_times'] = calc_times dic['before'] = len(sources) dic['after'] = len(dic[grp_id]) if params['ps_grid_spacing']: dic['ps_grid/%02d' % monitor.task_no] = [ src for src in dic[grp_id] if src.nsites > EPS ] return dic
def preclassical(srcs, sites, cmaker, monitor): """ Weight the sources. Also split them if split_sources is true. If ps_grid_spacing is set, grid the point sources before weighting them. NB: srcfilter can be on a reduced site collection for performance reasons """ split_sources = [] spacing = cmaker.ps_grid_spacing grp_id = srcs[0].grp_id if sites is None: # in csm2rup just split the sources and count the ruptures for src in srcs: ss = split_source(src) if len(ss) > 1: for ss_ in ss: ss_.nsites = 1 split_sources.extend(ss) src.num_ruptures = src.count_ruptures() dic = {grp_id: split_sources} dic['before'] = len(srcs) dic['after'] = len(dic[grp_id]) return dic with monitor('splitting sources'): sf = SourceFilter(sites, cmaker.maximum_distance) for src in srcs: # NB: this is approximate, since the sites are sampled src.nsites = len(sf.close_sids(src)) # can be 0 # NB: it is crucial to split only the close sources, for # performance reasons (think of Ecuador in SAM) splits = split_source(src) if (cmaker.split_sources and src.nsites) else [src] split_sources.extend(splits) dic = grid_point_sources(split_sources, spacing, monitor) with monitor('weighting sources'): # this is also prefiltering again, to have a good representative # of what will be done during the classical phase cmaker.set_weight(dic[grp_id], sf) dic['before'] = len(split_sources) dic['after'] = len(dic[grp_id]) if spacing: dic['ps_grid/%02d' % monitor.task_no] = dic[grp_id] return dic
def test(self): # make sure the et_id is transferred also for single split # sources, since this caused hard to track bugs fname = gettemp(characteric_source) [[char]] = nrml.to_python(fname) char.id = 1 char.et_id = 1 os.remove(fname) [src] = split_source(char) self.assertEqual(char.id, src.id) self.assertEqual(char.source_id, src.source_id) self.assertEqual(char.et_id, src.et_id)