def ucerf_classical(rupset_idx, ucerf_source, src_filter, gsims, monitor): """ :param rupset_idx: indices of the rupture sets :param ucerf_source: an object taking the place of a source for UCERF :param src_filter: a source filter returning the sites affected by the source :param gsims: a list of GSIMs :param monitor: a monitor instance :returns: a ProbabilityMap """ t0 = time.time() truncation_level = monitor.oqparam.truncation_level imtls = monitor.oqparam.imtls ucerf_source.src_filter = src_filter # so that .iter_ruptures() work grp_id = ucerf_source.src_group_id mag = ucerf_source.mags[rupset_idx].max() ridx = set() for idx in rupset_idx: ridx.update(ucerf_source.get_ridx(idx)) ucerf_source.rupset_idx = rupset_idx ucerf_source.num_ruptures = nruptures = len(rupset_idx) # prefilter the sites close to the rupture set s_sites = ucerf_source.get_rupture_sites(ridx, src_filter, mag) if s_sites is None: # return an empty probability map pm = ProbabilityMap(len(imtls.array), len(gsims)) acc = AccumDict({grp_id: pm}) acc.calc_times = { ucerf_source.source_id: numpy.array([nruptures, 0, time.time() - t0, 1]) } acc.eff_ruptures = {grp_id: 0} return acc # compute the ProbabilityMap cmaker = ContextMaker(gsims, src_filter.integration_distance) imtls = DictArray(imtls) ctx_mon = monitor('make_contexts', measuremem=False) poe_mon = monitor('get_poes', measuremem=False) pmap = cmaker.poe_map(ucerf_source, s_sites, imtls, truncation_level, ctx_mon, poe_mon) nsites = len(s_sites) acc = AccumDict({grp_id: pmap}) acc.calc_times = { ucerf_source.source_id: numpy.array([nruptures * nsites, nsites, time.time() - t0, 1]) } acc.eff_ruptures = {grp_id: ucerf_source.num_ruptures} return acc
def build_ruptures(sources, src_filter, param, monitor): """ :param sources: a list with a single UCERF source :param param: extra parameters :param monitor: a Monitor instance :returns: an AccumDict grp_id -> EBRuptures """ [src] = sources res = AccumDict() res.calc_times = [] sampl_mon = monitor('sampling ruptures', measuremem=True) res.trt = DEFAULT_TRT background_sids = src.get_background_sids(src_filter) samples = getattr(src, 'samples', 1) n_occ = AccumDict(accum=0) t0 = time.time() with sampl_mon: for sam_idx in range(samples): for ses_idx, ses_seed in param['ses_seeds']: seed = sam_idx * TWO16 + ses_seed rups, occs = generate_event_set(src, background_sids, src_filter, ses_idx, seed) for rup, occ in zip(rups, occs): n_occ[rup] += occ tot_occ = sum(n_occ.values()) dic = {'eff_ruptures': {src.src_group_id: src.num_ruptures}} eb_ruptures = [ EBRupture(rup, src.id, src.src_group_id, n, samples) for rup, n in n_occ.items() ] dic['rup_array'] = stochastic.get_rup_array(eb_ruptures, src_filter) dt = time.time() - t0 n = len(src_filter.sitecol) dic['calc_times'] = {src.id: numpy.array([tot_occ, n, dt], F32)} return dic
def execute(self): """ Run in parallel `core_func(sources, sitecol, monitor)`, by parallelizing on the sources according to their weight and tectonic region type. """ monitor = self.monitor.new(self.core_func.__name__) monitor.oqparam = self.oqparam sources = self.csm.get_sources() zc = zero_curves(len(self.sitecol.complete), self.oqparam.imtls) zerodict = AccumDict((key, zc) for key in self.rlzs_assoc) zerodict.calc_times = [] zerodict.bb_dict = { (smodel.ordinal, site.id): BoundingBox(smodel.ordinal, site.id) for site in self.sitecol for smodel in self.csm.source_models } if self.oqparam.poes_disagg else {} curves_by_trt_gsim = parallel.apply_reduce( self.core_func.__func__, (sources, self.sitecol, 0, self.rlzs_assoc, monitor), agg=self.agg_dicts, acc=zerodict, concurrent_tasks=self.oqparam.concurrent_tasks, weight=operator.attrgetter('weight'), key=operator.attrgetter('trt_model_id')) store_source_chunks(self.datastore) return curves_by_trt_gsim
def classical(group, src_filter, gsims, param, monitor=Monitor()): """ Compute the hazard curves for a set of sources belonging to the same tectonic region type for all the GSIMs associated to that TRT. The arguments are the same as in :func:`calc_hazard_curves`, except for ``gsims``, which is a list of GSIM instances. :returns: a dictionary {grp_id: pmap} with attributes .grp_ids, .calc_times, .eff_ruptures """ if getattr(group, 'src_interdep', None) == 'mutex': mutex_weight = { src.source_id: weight for src, weight in zip(group.sources, group.srcs_weights) } else: mutex_weight = None grp_ids = set() for src in group: grp_ids.update(src.src_group_ids) maxdist = src_filter.integration_distance with GroundShakingIntensityModel.forbid_instantiation(): imtls = param['imtls'] trunclevel = param.get('truncation_level') cmaker = ContextMaker(gsims, maxdist) ctx_mon = monitor('make_contexts', measuremem=False) poe_mon = monitor('get_poes', measuremem=False) pmap = AccumDict({ grp_id: ProbabilityMap(len(imtls.array), len(gsims)) for grp_id in grp_ids }) # AccumDict of arrays with 4 elements weight, nsites, calc_time, split pmap.calc_times = AccumDict(accum=numpy.zeros(4)) pmap.eff_ruptures = AccumDict() # grp_id -> num_ruptures for src, s_sites in src_filter(group): # filter now t0 = time.time() indep = group.rup_interdep == 'indep' if mutex_weight else True poemap = cmaker.poe_map(src, s_sites, imtls, trunclevel, ctx_mon, poe_mon, indep) if mutex_weight: # mutex sources weight = mutex_weight[src.source_id] for sid in poemap: pcurve = pmap[group.id].setdefault(sid, 0) pcurve += poemap[sid] * weight elif poemap: for grp_id in src.src_group_ids: pmap[grp_id] |= poemap src_id = src.source_id.split(':', 1)[0] pmap.calc_times[src_id] += numpy.array( [src.weight, len(s_sites), time.time() - t0, 1]) # storing the number of contributing ruptures too pmap.eff_ruptures += { grp_id: getattr(poemap, 'eff_ruptures', 0) for grp_id in src.src_group_ids } if mutex_weight and group.grp_probability is not None: pmap[group.id] *= group.grp_probability return pmap
def build_ruptures(sources, src_filter, param, monitor): """ :param sources: a list with a single UCERF source :param param: extra parameters :param monitor: a Monitor instance :returns: an AccumDict grp_id -> EBRuptures """ [src] = sources res = AccumDict() res.calc_times = [] sampl_mon = monitor('sampling ruptures', measuremem=True) res.trt = DEFAULT_TRT background_sids = src.get_background_sids(src_filter) samples = getattr(src, 'samples', 1) n_occ = AccumDict(accum=0) t0 = time.time() with sampl_mon: for sam_idx in range(samples): for ses_idx, ses_seed in param['ses_seeds']: seed = sam_idx * TWO16 + ses_seed rups, occs = generate_event_set( src, background_sids, src_filter, ses_idx, seed) for rup, occ in zip(rups, occs): n_occ[rup] += occ tot_occ = sum(n_occ.values()) dic = {'eff_ruptures': {src.src_group_id: src.num_ruptures}} eb_ruptures = [EBRupture(rup, src.id, src.src_group_id, n, samples) for rup, n in n_occ.items()] dic['rup_array'] = stochastic.get_rup_array(eb_ruptures, src_filter) dt = time.time() - t0 dic['calc_times'] = {src.id: numpy.array([tot_occ, dt], F32)} return dic
def compute_hazard(sources_or_ruptures, src_filter, rlzs_by_gsim, param, monitor): """ Compute events, ruptures, gmfs and hazard curves """ res = AccumDict() with monitor('building ruptures', measuremem=True): if isinstance(sources_or_ruptures, RuptureGetter): grp_id = sources_or_ruptures.grp_id res['ruptures'] = {} ruptures = list(sources_or_ruptures) sitecol = src_filter else: grp_id = sources_or_ruptures[0].src_group_id dic = sample_ruptures(sources_or_ruptures, src_filter, rlzs_by_gsim, param, monitor) ruptures = dic['eb_ruptures'] res.num_events = dic['num_events'] res.calc_times = dic['calc_times'] res.eff_ruptures = {grp_id: dic['num_ruptures']} res['ruptures'] = {grp_id: ruptures} res.num_ruptures = len(ruptures) sitecol = src_filter.sitecol res['num_ruptures'] = len(ruptures) getter = GmfGetter(rlzs_by_gsim, ruptures, sitecol, param['oqparam'], param['min_iml'], param['samples']) res.update(getter.compute_gmfs_curves(monitor)) if param['oqparam'].save_ruptures is False: res.events = get_events(ruptures) res['ruptures'] = {} return res
def execute(self): """ Run in parallel `core_task(sources, sitecol, monitor)`, by parallelizing on the sources according to their weight and tectonic region type. """ monitor = self.monitor(self.core_task.__name__) monitor.oqparam = oq = self.oqparam self.src_filter = SourceFilter(self.sitecol, oq.maximum_distance) self.nsites = [] acc = AccumDict({ grp_id: ProbabilityMap(len(oq.imtls.array), len(gsims)) for grp_id, gsims in self.gsims_by_grp.items() }) acc.calc_times = {} acc.eff_ruptures = AccumDict() # grp_id -> eff_ruptures acc.bb_dict = {} # just for API compatibility param = dict(imtls=oq.imtls, truncation_level=oq.truncation_level) for sm in self.csm.source_models: # one branch at the time grp_id = sm.ordinal gsims = self.gsims_by_grp[grp_id] [[ucerf_source]] = sm.src_groups ucerf_source.nsites = len(self.sitecol) self.csm.infos[ucerf_source.source_id] = source.SourceInfo( ucerf_source) logging.info('Getting the background point sources') bckgnd_sources = ucerf_source.get_background_sources( self.src_filter) # since there are two kinds of tasks (background and rupture_set) # we divide the concurrent_tasks parameter by 2; # notice the "or 1" below, to avoid issues when # self.oqparam.concurrent_tasks is 0 or 1 ct2 = (self.oqparam.concurrent_tasks // 2) or 1 # parallelize on the background sources, small tasks args = (bckgnd_sources, self.src_filter, gsims, param, monitor) bg_res = parallel.Starmap.apply(classical, args, name='background_sources_%d' % grp_id, concurrent_tasks=ct2) # parallelize by rupture subsets rup_sets = numpy.arange(ucerf_source.num_ruptures) taskname = 'ucerf_classical_%d' % grp_id acc = parallel.Starmap.apply( ucerf_classical, (rup_sets, ucerf_source, self.src_filter, gsims, monitor), concurrent_tasks=ct2, name=taskname).reduce(self.agg_dicts, acc) # compose probabilities from background sources for pmap in bg_res: acc[grp_id] |= pmap[grp_id] with self.monitor('store source_info', autoflush=True): self.store_source_info(self.csm.infos, acc) return acc # {grp_id: pmap}
def compute_ruptures(branch_info, ucerf, sitecol, oqparam, monitor): """ Returns the ruptures as a TRT set :param str branch_info: Tuple of (ltbr, branch_id, branch_weight) :param ucerf: Instance of the UCERFSESControl object :param sitecol: Site collection :class:`openquake.hazardlib.site.SiteCollection` :param oqparam: Instance of :class:`openquake.commonlib.oqvalidation.OqParam` :param monitor: Instance of :class:`openquake.baselib.performance.Monitor` :returns: Dictionary of rupture instances associated to a TRT ID """ integration_distance = oqparam.maximum_distance[DEFAULT_TRT] res = AccumDict() res.calc_times = AccumDict() serial = 1 filter_mon = monitor('update_background_site_filter', measuremem=False) event_mon = monitor('sampling ruptures', measuremem=False) for src_group_id, (ltbrid, branch_id, _) in enumerate(branch_info): t0 = time.time() with filter_mon: ucerf.update_background_site_filter(sitecol, integration_distance) # set the seed before calling generate_event_set numpy.random.seed(oqparam.random_seed + src_group_id) ses_ruptures = [] for ses_idx in range(1, oqparam.ses_per_logic_tree_path + 1): with event_mon: rups, n_occs = ucerf.generate_event_set( branch_id, sitecol, integration_distance) for i, rup in enumerate(rups): rup.seed = oqparam.random_seed # to think rrup = rup.surface.get_min_distance(sitecol.mesh) r_sites = sitecol.filter(rrup <= integration_distance) if r_sites is None: continue indices = r_sites.indices events = [] for j in range(n_occs[i]): # NB: the first 0 is a placeholder for the eid that will be # set later, in EventBasedRuptureCalculator.post_execute; # the second 0 is the sampling ID events.append((0, ses_idx, j, 0)) if len(events): ses_ruptures.append( event_based.EBRupture( rup, indices, numpy.array(events, event_based.event_dt), ucerf.source_id, src_group_id, serial)) serial += 1 dt = time.time() - t0 res.calc_times[src_group_id] = (ltbrid, dt) res[src_group_id] = ses_ruptures res.trt = DEFAULT_TRT return res
def zerodict(self): """ Initial accumulator, a dictionary (trt_id, gsim) -> curves """ zd = AccumDict() zd.calc_times = [] zd.eff_ruptures = AccumDict() return zd
def zerodict(self): """ Initial accumulator, a dictionary (grp_id, gsim) -> curves """ zd = AccumDict() zd.calc_times = [] zd.eff_ruptures = AccumDict() return zd
def compute_ruptures(sources, src_filter, gsims, param, monitor): """ :param sources: a list with a single UCERF source :param src_filter: a SourceFilter instance :param gsims: a list of GSIMs :param param: extra parameters :param monitor: a Monitor instance :returns: an AccumDict grp_id -> EBRuptures """ [src] = sources res = AccumDict() res.calc_times = AccumDict() serial = 1 sampl_mon = monitor('sampling ruptures', measuremem=True) filt_mon = monitor('filtering ruptures', measuremem=False) res.trt = DEFAULT_TRT t0 = time.time() ebruptures = [] background_sids = src.get_background_sids(src_filter) sitecol = src_filter.sitecol idist = src_filter.integration_distance for sample in range(param['samples']): for ses_idx, ses_seed in param['ses_seeds']: seed = sample * event_based.TWO16 + ses_seed with sampl_mon: rups, n_occs = src.generate_event_set(background_sids, src_filter, seed) with filt_mon: for rup, n_occ in zip(rups, n_occs): rup.seed = seed try: r_sites, rrup = idist.get_closest(sitecol, rup) except FarAwayRupture: continue indices = (numpy.arange(len(r_sites)) if r_sites.indices is None else r_sites.indices) events = [] for _ in range(n_occ): events.append((0, src.src_group_id, ses_idx, sample)) if events: evs = numpy.array(events, calc.event_dt) ebruptures.append( calc.EBRupture(rup, indices, evs, serial)) serial += 1 res.num_events = event_based.set_eids(ebruptures) res[src.src_group_id] = ebruptures res.calc_times[src.src_group_id] = { src.source_id: numpy.array([src.weight, len(sitecol), time.time() - t0, 1]) } if not param['save_ruptures']: res.events_by_grp = { grp_id: event_based.get_events(res[grp_id]) for grp_id in res } res.eff_ruptures = {src.src_group_id: src.num_ruptures} return res
def classical(group, src_filter, gsims, param, monitor=Monitor()): """ Compute the hazard curves for a set of sources belonging to the same tectonic region type for all the GSIMs associated to that TRT. The arguments are the same as in :func:`calc_hazard_curves`, except for ``gsims``, which is a list of GSIM instances. :returns: a dictionary {grp_id: pmap} with attributes .grp_ids, .calc_times, .eff_ruptures """ grp_ids = set() for src in group: if not src.num_ruptures: # src.num_ruptures is set when parsing the XML, but not when # the source is instantiated manually, so it is set here src.num_ruptures = src.count_ruptures() grp_ids.update(src.src_group_ids) maxdist = src_filter.integration_distance imtls = param['imtls'] trunclevel = param.get('truncation_level') cmaker = ContextMaker(gsims, maxdist, param, monitor) pmap = AccumDict({ grp_id: ProbabilityMap(len(imtls.array), len(gsims)) for grp_id in grp_ids }) # AccumDict of arrays with 3 elements weight, nsites, calc_time pmap.calc_times = AccumDict(accum=numpy.zeros(3, numpy.float32)) pmap.eff_ruptures = AccumDict() # grp_id -> num_ruptures src_mutex = param.get('src_interdep') == 'mutex' rup_mutex = param.get('rup_interdep') == 'mutex' for src, s_sites in src_filter(group): # filter now t0 = time.time() try: poemap = cmaker.poe_map(src, s_sites, imtls, trunclevel, not rup_mutex) except Exception as err: etype, err, tb = sys.exc_info() msg = '%s (source id=%s)' % (str(err), src.source_id) raise etype(msg).with_traceback(tb) if src_mutex: # mutex sources, there is a single group for sid in poemap: pcurve = pmap[src.src_group_id].setdefault(sid, 0) pcurve += poemap[sid] * src.mutex_weight elif poemap: for gid in src.src_group_ids: pmap[gid] |= poemap pmap.calc_times[src.id] += numpy.array( [src.weight, len(s_sites), time.time() - t0]) # storing the number of contributing ruptures too pmap.eff_ruptures += { gid: getattr(poemap, 'eff_ruptures', 0) for gid in src.src_group_ids } if src_mutex and param.get('grp_probability'): pmap[src.src_group_id] *= param['grp_probability'] return pmap
def zerodict(self): """ Initial accumulator, a dictionary trt_model_id -> list of ruptures """ smodels = self.rlzs_assoc.csm_info.source_models zd = AccumDict((tm.id, []) for smodel in smodels for tm in smodel.trt_models) zd.calc_times = [] return zd
def compute_ruptures(branch_info, source, sitecol, oqparam, monitor): """ Returns the ruptures as a TRT set :param str branch_info: Tuple of (ltbr, branch_id, branch_weight) :param source: Instance of the UCERFSESControl object :param sitecol: Site collection :class: openquake.hazardlib.site.SiteCollection :param info: Instance of the :class: openquake.commonlib.source.CompositionInfo :returns: Dictionary of rupture instances associated to a TRT ID """ integration_distance = oqparam.maximum_distance[DEFAULT_TRT] res = AccumDict() res.calc_times = AccumDict() serial = 1 filter_mon = monitor('update_background_site_filter', measuremem=False) event_mon = monitor('sampling ruptures', measuremem=False) for trt_model_id, (ltbrid, branch_id, _) in enumerate(branch_info): t0 = time.time() with filter_mon: source.update_background_site_filter(sitecol, integration_distance) # set the seed before calling generate_event_set numpy.random.seed(oqparam.random_seed + trt_model_id) ses_ruptures = [] for ses_idx in range(1, oqparam.ses_per_logic_tree_path + 1): with event_mon: rups, n_occs = source.generate_event_set( branch_id, sitecol, integration_distance) for i, rup in enumerate(rups): rup.seed = oqparam.random_seed # to think rrup = rup.surface.get_min_distance(sitecol.mesh) r_sites = sitecol.filter(rrup <= integration_distance) if r_sites is None: continue indices = r_sites.indices events = [] for j in range(n_occs[i]): # NB: the first 0 is a placeholder for the eid that will be # set later, in EventBasedRuptureCalculator.post_execute; # the second 0 is the sampling ID events.append((0, ses_idx, j, 0)) if len(events): ses_ruptures.append( event_based.EBRupture( rup, indices, numpy.array(events, event_based.event_dt), source.source_id, trt_model_id, serial)) serial += 1 dt = time.time() - t0 res.calc_times[trt_model_id] = (ltbrid, dt) res[trt_model_id] = ses_ruptures res.trt = DEFAULT_TRT return res
def zerodict(self): """ Initial accumulator, a dictionary (grp_id, gsim) -> curves """ zd = AccumDict() zd.calc_times = [] zd.eff_ruptures = AccumDict() self.grp_trt = self.csm_info.grp_trt() return zd
def ucerf_classical_hazard_by_branch(branchnames, ucerf_source, src_group_id, src_filter, gsims, monitor): """ :param branchnames: a list of branch names :param ucerf_source: a source-like object for the UCERF model :param src_group_id: an ordinal number for the source :param source filter: a filter returning the sites affected by the source :param gsims: a list of GSIMs :param monitor: a monitor instance :returns: an AccumDict rlz -> curves """ truncation_level = monitor.oqparam.truncation_level imtls = monitor.oqparam.imtls trt = ucerf_source.tectonic_region_type max_dist = monitor.oqparam.maximum_distance[trt] dic = AccumDict() dic.bbs = [] dic.calc_times = [] for branchname in branchnames: # Two step process here - the first generates the hazard curves from # the rupture sets monitor.eff_ruptures = 0 # Apply the initial rupture to site filtering rupset_idx = ucerf_source.get_rupture_indices(branchname) rupset_idx, s_sites = \ ucerf_source.filter_sites_by_distance_from_rupture_set( rupset_idx, src_filter.sitecol, max_dist) if len(s_sites): dic[src_group_id] = hazard_curves_per_rupture_subset( rupset_idx, ucerf_source, src_filter, imtls, gsims, truncation_level, bbs=dic.bbs, monitor=monitor) else: dic[src_group_id] = ProbabilityMap(len(imtls.array), len(gsims)) dic.calc_times += monitor.calc_times # added by pmap_from_grp dic.eff_ruptures = {src_group_id: monitor.eff_ruptures} # idem logging.info('Branch %s', branchname) # Get the background point sources background_sids = ucerf_source.get_background_sids( src_filter.sitecol, max_dist) bckgnd_sources = ucerf_source.get_background_sources(background_sids) if bckgnd_sources: pmap = pmap_from_grp( bckgnd_sources, src_filter, imtls, gsims, truncation_level, bbs=dic.bbs, monitor=monitor) dic[src_group_id] |= pmap dic.eff_ruptures[src_group_id] += monitor.eff_ruptures dic.calc_times += monitor.calc_times return dic
def compute_hazard(sources, src_filter, rlzs_by_gsim, param, monitor): """ :param sources: a list with a single UCERF source :param src_filter: a SourceFilter instance :param rlzs_by_gsim: a dictionary gsim -> rlzs :param param: extra parameters :param monitor: a Monitor instance :returns: an AccumDict grp_id -> EBRuptures """ [src] = sources res = AccumDict() res.calc_times = [] serial = 1 sampl_mon = monitor('sampling ruptures', measuremem=True) filt_mon = monitor('filtering ruptures', measuremem=False) res.trt = DEFAULT_TRT ebruptures = [] background_sids = src.get_background_sids(src_filter) sitecol = src_filter.sitecol cmaker = ContextMaker(rlzs_by_gsim, src_filter.integration_distance) for sample in range(param['samples']): for ses_idx, ses_seed in param['ses_seeds']: seed = sample * TWO16 + ses_seed with sampl_mon: rups, n_occs = generate_event_set(src, background_sids, src_filter, seed) with filt_mon: for rup, n_occ in zip(rups, n_occs): rup.serial = serial try: rup.sctx, rup.dctx = cmaker.make_contexts(sitecol, rup) indices = rup.sctx.sids except FarAwayRupture: continue events = [] for _ in range(n_occ): events.append((0, src.src_group_id, ses_idx, sample)) if events: evs = numpy.array(events, stochastic.event_dt) ebruptures.append(EBRupture(rup, src.id, indices, evs)) serial += 1 res.num_events = len(stochastic.set_eids(ebruptures)) res['ruptures'] = {src.src_group_id: ebruptures} if param['save_ruptures']: res.ruptures_by_grp = {src.src_group_id: ebruptures} else: res.events_by_grp = { src.src_group_id: event_based.get_events(ebruptures) } res.eff_ruptures = {src.src_group_id: src.num_ruptures} if param.get('gmf'): getter = getters.GmfGetter(rlzs_by_gsim, ebruptures, sitecol, param['oqparam'], param['min_iml'], param['samples']) res.update(getter.compute_gmfs_curves(monitor)) return res
def zerodict(self): """ Initial accumulator, a dictionary (grp_id, gsim) -> curves """ zd = AccumDict() zd.calc_times = [] zd.eff_ruptures = AccumDict() self.eid = collections.Counter() # sm_id -> event_id self.sm_by_grp = self.csm.info.get_sm_by_grp() return zd
def count_eff_ruptures(sources, sitecol, gsims, monitor): """ Count the number of ruptures contained in the given sources and return a dictionary src_group_id -> num_ruptures. All sources belong to the same tectonic region type. """ acc = AccumDict() acc.grp_id = sources[0].src_group_id acc.calc_times = [] acc.eff_ruptures = {acc.grp_id: sum(src.num_ruptures for src in sources)} return acc
def classical(sources, sitecol, siteidx, rlzs_assoc, monitor): """ :param sources: a non-empty sequence of sources of homogeneous tectonic region type :param sitecol: a SiteCollection instance :param siteidx: index of the first site (0 if there is a single tile) :param rlzs_assoc: a RlzsAssoc instance :param monitor: a monitor instance :returns: an AccumDict rlz -> curves """ truncation_level = monitor.oqparam.truncation_level imtls = monitor.oqparam.imtls trt_model_id = sources[0].trt_model_id # sanity check: the trt_model must be the same for all sources for src in sources[1:]: assert src.trt_model_id == trt_model_id gsims = rlzs_assoc.gsims_by_trt_id[trt_model_id] trt = sources[0].tectonic_region_type try: max_dist = monitor.oqparam.maximum_distance[trt] except KeyError: max_dist = monitor.oqparam.maximum_distance['default'] dic = AccumDict() dic.siteslice = slice(siteidx, siteidx + len(sitecol)) if monitor.oqparam.poes_disagg: sm_id = rlzs_assoc.get_sm_id(trt_model_id) dic.bbs = [BoundingBox(sm_id, sid) for sid in sitecol.sids] else: dic.bbs = [] # NB: the source_site_filter below is ESSENTIAL for performance inside # hazard_curves_per_trt, since it reduces the full site collection # to a filtered one *before* doing the rupture filtering curves_by_gsim = hazard_curves_per_trt( sources, sitecol, imtls, gsims, truncation_level, source_site_filter=source_site_distance_filter(max_dist), maximum_distance=max_dist, bbs=dic.bbs, monitor=monitor) dic.calc_times = monitor.calc_times # added by hazard_curves_per_trt dic.eff_ruptures = {trt_model_id: monitor.eff_ruptures} # idem for gsim, curves in zip(gsims, curves_by_gsim): dic[trt_model_id, str(gsim)] = curves return dic
def zerodict(self): """ Initial accumulator, a dict grp_id -> ProbabilityMap(L, G) """ csm_info = self.csm.info zd = AccumDict() num_levels = len(self.oqparam.imtls.array) for grp in self.csm.src_groups: num_gsims = len(csm_info.gsim_lt.get_gsims(grp.trt)) zd[grp.id] = ProbabilityMap(num_levels, num_gsims) zd.calc_times = [] zd.eff_ruptures = AccumDict() # grp_id -> eff_ruptures return zd
def zerodict(self): """ Initial accumulator, a dictionary (trt_id, gsim) -> curves """ zc = zero_curves(len(self.sitecol.complete), self.oqparam.imtls) zd = AccumDict((key, zc) for key in self.rlzs_assoc) zd.calc_times = [] zd.eff_ruptures = AccumDict() # trt_id -> eff_ruptures zd.bb_dict = { (smodel.ordinal, site.id): BoundingBox(smodel.ordinal, site.id) for site in self.sitecol for smodel in self.csm.source_models } if self.oqparam.poes_disagg else {} return zd
def execute(self): """ Split the computation by tiles which are run in parallel. """ acc = AccumDict( {trt_gsim: zero_curves(len(self.sitecol), self.oqparam.imtls) for trt_gsim in self.rlzs_assoc}) acc.calc_times = [] acc.n = len(self.sitecol) hint = math.ceil(acc.n / self.oqparam.sites_per_tile) tiles = self.sitecol.split_in_tiles(hint) logging.info('Generating %d tiles of %d sites each', len(tiles), len(tiles[0])) sources = self.csm.get_sources() rlzs_assoc = self.csm.get_rlzs_assoc() ctasks = self.oqparam.concurrent_tasks or 1 maxweight = math.ceil(self.csm.weight / ctasks) siteidx = 0 tmanagers = [] maximum_distance = self.oqparam.maximum_distance # try to produce more tasks than self.oqparam.concurrent_tasks num_blocks = math.ceil(self.MORE_TASKS * ctasks / len(tiles)) splitmap = {} for i, tile in enumerate(tiles, 1): monitor = self.monitor.new() monitor.oqparam = self.oqparam with self.monitor('filtering sources per tile', autoflush=True): filtered_sources = [ src for src in sources if src.filter_sites_by_distance_to_source( maximum_distance, tile) is not None] if not filtered_sources: continue blocks = split_in_blocks( split_sources(sources, maxweight, splitmap), num_blocks, weight=operator.attrgetter('weight'), key=operator.attrgetter('trt_model_id')) tm = parallel.starmap( classical, ((blk, tile, siteidx, rlzs_assoc, monitor) for blk in blocks), name='tile_%d/%d' % (i, len(tiles))) tmanagers.append(tm) siteidx += len(tile) logging.info('Total number of tasks submitted: %d', sum(len(tm.results) for tm in tmanagers)) for tm in tmanagers: tm.reduce(self.agg_dicts, acc) self.rlzs_assoc = self.csm.get_rlzs_assoc( partial(is_effective_trt_model, acc)) return acc
def compute_ruptures(sources, src_filter, gsims, param, monitor): """ :param sources: a list with a single UCERF source :param src_filter: a SourceFilter instance :param gsims: a list of GSIMs :param param: extra parameters :param monitor: a Monitor instance :returns: an AccumDict grp_id -> EBRuptures """ [src] = sources res = AccumDict() res.calc_times = [] serial = 1 sampl_mon = monitor('sampling ruptures', measuremem=True) filt_mon = monitor('filtering ruptures', measuremem=False) res.trt = DEFAULT_TRT ebruptures = [] background_sids = src.get_background_sids(src_filter) sitecol = src_filter.sitecol cmaker = ContextMaker(gsims, src_filter.integration_distance) for sample in range(param['samples']): for ses_idx, ses_seed in param['ses_seeds']: seed = sample * TWO16 + ses_seed with sampl_mon: rups, n_occs = generate_event_set(src, background_sids, src_filter, seed) with filt_mon: for rup, n_occ in zip(rups, n_occs): rup.serial = serial rup.seed = seed try: rup.sctx, rup.dctx = cmaker.make_contexts(sitecol, rup) indices = rup.sctx.sids except FarAwayRupture: continue events = [] for _ in range(n_occ): events.append((0, src.src_group_id, ses_idx, sample)) if events: evs = numpy.array(events, stochastic.event_dt) ebruptures.append(EBRupture(rup, indices, evs)) serial += 1 res.num_events = len(stochastic.set_eids(ebruptures)) res[src.src_group_id] = ebruptures if not param['save_ruptures']: res.events_by_grp = { grp_id: event_based.get_events(res[grp_id]) for grp_id in res } res.eff_ruptures = {src.src_group_id: src.num_ruptures} return res
def compute_hazard(sources, src_filter, rlzs_by_gsim, param, monitor): """ :param sources: a list with a single UCERF source :param src_filter: a SourceFilter instance :param rlzs_by_gsim: a dictionary gsim -> rlzs :param param: extra parameters :param monitor: a Monitor instance :returns: an AccumDict grp_id -> EBRuptures """ [src] = sources res = AccumDict() res.calc_times = [] serial = 1 sampl_mon = monitor('sampling ruptures', measuremem=True) filt_mon = monitor('filtering ruptures', measuremem=False) res.trt = DEFAULT_TRT background_sids = src.get_background_sids(src_filter) sitecol = src_filter.sitecol cmaker = ContextMaker(rlzs_by_gsim, src_filter.integration_distance) num_ses = param['ses_per_logic_tree_path'] samples = getattr(src, 'samples', 1) n_occ = AccumDict(accum=numpy.zeros((samples, num_ses), numpy.uint16)) with sampl_mon: for sam_idx in range(samples): for ses_idx, ses_seed in param['ses_seeds']: seed = sam_idx * TWO16 + ses_seed rups, occs = generate_event_set(src, background_sids, src_filter, seed) for rup, occ in zip(rups, occs): n_occ[rup][sam_idx, ses_idx] = occ rup.serial = serial serial += 1 with filt_mon: rlzs = numpy.concatenate(list(rlzs_by_gsim.values())) ebruptures = stochastic.build_eb_ruptures(src, rlzs, num_ses, cmaker, sitecol, n_occ.items()) res.num_events = sum(ebr.multiplicity for ebr in ebruptures) res['ruptures'] = {src.src_group_id: ebruptures} if param['save_ruptures']: res.ruptures_by_grp = {src.src_group_id: ebruptures} else: res.events_by_grp = { src.src_group_id: event_based.get_events(ebruptures) } res.eff_ruptures = {src.src_group_id: src.num_ruptures} if param.get('gmf'): getter = getters.GmfGetter(rlzs_by_gsim, ebruptures, sitecol, param['oqparam'], param['min_iml'], samples) res.update(getter.compute_gmfs_curves(monitor)) return res
def zerodict(self): """ Initial accumulator, a dictionary (trt_id, gsim) -> curves """ zc = zero_curves(len(self.sitecol.complete), self.oqparam.imtls) zd = AccumDict((key, zc) for key in self.rlzs_assoc) zd.calc_times = [] zd.eff_ruptures = AccumDict() # trt_id -> eff_ruptures zd.bb_dict = { (smodel.ordinal, site.id): BoundingBox(smodel.ordinal, site.id) for site in self.sitecol for smodel in self.csm.source_models } if self.oqparam.poes_disagg else {} return zd
def compute_ruptures(sources, src_filter, gsims, monitor): """ :param sources: List of commonlib.source.Source tuples :param src_filter: a source site filter :param gsims: a list of GSIMs for the current tectonic region model :param monitor: monitor instance :returns: a dictionary src_group_id -> [Rupture instances] """ # NB: by construction each block is a non-empty list with # sources of the same src_group_id grp_id = sources[0].src_group_id trt = sources[0].tectonic_region_type eb_ruptures = [] calc_times = [] rup_mon = monitor('filtering ruptures', measuremem=False) num_samples = monitor.samples num_events = 0 # Compute and save stochastic event sets for src, s_sites in src_filter(sources): t0 = time.time() if s_sites is None: continue max_dist = src_filter.integration_distance[trt] rupture_filter = functools.partial( filter_sites_by_distance_to_rupture, integration_distance=max_dist, sites=s_sites) num_occ_by_rup = sample_ruptures( src, monitor.ses_per_logic_tree_path, num_samples, monitor.seed) # NB: the number of occurrences is very low, << 1, so it is # more efficient to filter only the ruptures that occur, i.e. # to call sample_ruptures *before* the filtering for ebr in build_eb_ruptures( src, num_occ_by_rup, rupture_filter, monitor.seed, rup_mon): eb_ruptures.append(ebr) num_events += ebr.multiplicity dt = time.time() - t0 calc_times.append((src.id, dt)) res = AccumDict({grp_id: eb_ruptures}) res.num_events = num_events res.calc_times = calc_times res.rup_data = {grp_id: calc.RuptureData(trt, gsims).to_array(eb_ruptures)} return res
def compute_ruptures(sources, sitecol, gsims, monitor): """ :param sources: a sequence of UCERF sources :param sitecol: a SiteCollection instance :param gsims: a list of GSIMs :param monitor: a Monitor instance :returns: an AccumDict grp_id -> EBRuptures """ [src] = sources # there is a single source per UCERF branch integration_distance = monitor.maximum_distance[DEFAULT_TRT] res = AccumDict() res.calc_times = AccumDict() serial = 1 event_mon = monitor('sampling ruptures', measuremem=False) res.num_events = 0 res.trt = DEFAULT_TRT t0 = time.time() # set the seed before calling generate_event_set numpy.random.seed(monitor.seed + src.src_group_id) ebruptures = [] eid = 0 src.build_idx_set() background_sids = src.get_background_sids(sitecol, integration_distance) for ses_idx in range(1, monitor.ses_per_logic_tree_path + 1): with event_mon: rups, n_occs = src.generate_event_set(background_sids) for rup, n_occ in zip(rups, n_occs): rup.seed = monitor.seed # to think rrup = rup.surface.get_min_distance(sitecol.mesh) r_sites = sitecol.filter(rrup <= integration_distance) if r_sites is None: continue indices = r_sites.indices events = [] for occ in range(n_occ): events.append((eid, ses_idx, occ, 0)) # 0 is the sampling eid += 1 if events: ebruptures.append( event_based.EBRupture( rup, indices, numpy.array(events, event_based.event_dt), src.source_id, src.src_group_id, serial)) serial += 1 res.num_events += len(events) res[src.src_group_id] = ebruptures res.calc_times[src.src_group_id] = ( src.source_id, len(sitecol), time.time() - t0) return res
def ucerf_classical_hazard_by_rupture_set( rupset_idx, branchname, ucerf_source, src_group_id, sitecol, gsims, monitor): """ :param rupset_idx: indices of the rupture sets :param branchname: name of the branch :param ucerf_source: an object taking the place of a source for UCERF :param src_group_id: source group index :param sitecol: a SiteCollection instance :param gsims: a list of GSIMs :param monitor: a monitor instance :returns: an AccumDict rlz -> curves """ truncation_level = monitor.oqparam.truncation_level imtls = monitor.oqparam.imtls max_dist = monitor.oqparam.maximum_distance[DEFAULT_TRT] dic = AccumDict() dic.bbs = [] dic.calc_times = [] monitor.eff_ruptures = 0 monitor.calc_times = [] # Apply the initial rupture to site filtering rupset_idx, s_sites = \ ucerf_source.filter_sites_by_distance_from_rupture_set( rupset_idx, sitecol, monitor.oqparam.maximum_distance[DEFAULT_TRT]) if len(s_sites): dic[src_group_id] = hazard_curves_per_rupture_subset( rupset_idx, ucerf_source, s_sites, imtls, gsims, truncation_level, maximum_distance=max_dist, bbs=dic.bbs, monitor=monitor) else: dic[src_group_id] = ProbabilityMap(len(imtls.array), len(gsims)) dic.calc_times += monitor.calc_times # added by pmap_from_grp dic.eff_ruptures = {src_group_id: monitor.eff_ruptures} # idem return dic
def pmap_from_trt(sources, src_filter, gsims, param, monitor=Monitor()): """ Compute the hazard curves for a set of sources belonging to the same tectonic region type for all the GSIMs associated to that TRT. :returns: a dictionary {grp_id: pmap} with attributes .grp_ids, .calc_times, .eff_ruptures """ maxdist = src_filter.integration_distance srcs = [] grp_ids = set() for src in sources: if hasattr(src, '__iter__'): # MultiPointSource srcs.extend(src) else: srcs.append(src) grp_ids.update(src.src_group_ids) del sources with GroundShakingIntensityModel.forbid_instantiation(): imtls = param['imtls'] trunclevel = param.get('truncation_level') cmaker = ContextMaker(gsims, maxdist) ctx_mon = monitor('making contexts', measuremem=False) pne_mons = [ monitor('%s.get_poes' % gsim, measuremem=False) for gsim in gsims ] pmap = AccumDict({ grp_id: ProbabilityMap(len(imtls.array), len(gsims)) for grp_id in grp_ids }) pmap.calc_times = [] # pairs (src_id, delta_t) pmap.eff_ruptures = AccumDict() # grp_id -> num_ruptures for src, s_sites in src_filter(srcs): t0 = time.time() poe = poe_map(src, s_sites, imtls, cmaker, trunclevel, ctx_mon, pne_mons) for grp_id in src.src_group_ids: pmap[grp_id] |= poe pmap.calc_times.append( (src.source_id, src.weight, len(s_sites), time.time() - t0)) # storing the number of contributing ruptures too pmap.eff_ruptures += { grp_id: poe.eff_ruptures for grp_id in src.src_group_ids } return pmap
def classical(sources, sitecol, siteidx, rlzs_assoc, monitor): """ :param sources: a non-empty sequence of sources of homogeneous tectonic region type :param sitecol: a SiteCollection instance :param siteidx: index of the first site (0 if there is a single tile) :param rlzs_assoc: a RlzsAssoc instance :param monitor: a monitor instance :returns: an AccumDict rlz -> curves """ truncation_level = monitor.oqparam.truncation_level imtls = monitor.oqparam.imtls trt_model_id = sources[0].trt_model_id # sanity check: the trt_model must be the same for all sources for src in sources[1:]: assert src.trt_model_id == trt_model_id gsims = rlzs_assoc.gsims_by_trt_id[trt_model_id] trt = sources[0].tectonic_region_type try: max_dist = monitor.oqparam.maximum_distance[trt] except KeyError: max_dist = monitor.oqparam.maximum_distance['default'] dic = AccumDict() dic.siteslice = slice(siteidx, siteidx + len(sitecol)) if monitor.oqparam.poes_disagg: sm_id = rlzs_assoc.get_sm_id(trt_model_id) dic.bbs = [BoundingBox(sm_id, sid) for sid in sitecol.sids] else: dic.bbs = [] # NB: the source_site_filter below is ESSENTIAL for performance inside # hazard_curves_per_trt, since it reduces the full site collection # to a filtered one *before* doing the rupture filtering curves_by_gsim = hazard_curves_per_trt( sources, sitecol, imtls, gsims, truncation_level, source_site_filter=source_site_distance_filter(max_dist), maximum_distance=max_dist, bbs=dic.bbs, monitor=monitor) dic.calc_times = monitor.calc_times # added by hazard_curves_per_trt dic.eff_ruptures = {trt_model_id: monitor.eff_ruptures} # idem for gsim, curves in zip(gsims, curves_by_gsim): dic[trt_model_id, str(gsim)] = curves return dic
def compute_ruptures(sources, src_filter, gsims, param, monitor): """ :param sources: List of commonlib.source.Source tuples :param src_filter: a source site filter :param gsims: a list of GSIMs for the current tectonic region model :param param: a dictionary of additional parameters :param monitor: monitor instance :returns: a dictionary src_group_id -> [Rupture instances] """ # NB: by construction each block is a non-empty list with # sources of the same src_group_id grp_id = sources[0].src_group_id eb_ruptures = [] calc_times = [] rup_mon = monitor('making contexts', measuremem=False) # Compute and save stochastic event sets num_ruptures = 0 cmaker = ContextMaker(gsims, src_filter.integration_distance) for src, s_sites in src_filter(sources): t0 = time.time() if s_sites is None: continue num_ruptures += src.num_ruptures num_occ_by_rup = sample_ruptures( src, param['ses_per_logic_tree_path'], sources.samples, param['seed']) # NB: the number of occurrences is very low, << 1, so it is # more efficient to filter only the ruptures that occur, i.e. # to call sample_ruptures *before* the filtering for ebr in _build_eb_ruptures( src, num_occ_by_rup, cmaker, s_sites, param['seed'], rup_mon): eb_ruptures.append(ebr) dt = time.time() - t0 calc_times.append((src.id, dt)) res = AccumDict({grp_id: eb_ruptures}) res.num_events = set_eids(eb_ruptures) res.calc_times = calc_times res.eff_ruptures = {grp_id: num_ruptures} return res
def zerodict(self): """ Initial accumulator, a dict grp_id -> ProbabilityMap(L, G) """ zd = AccumDict() num_levels = len(self.oqparam.imtls.array) for grp in self.csm.src_groups: num_gsims = len(self.rlzs_assoc.gsims_by_grp_id[grp.id]) zd[grp.id] = ProbabilityMap(num_levels, num_gsims) zd.calc_times = [] zd.eff_ruptures = AccumDict() # grp_id -> eff_ruptures zd.bb_dict = BBdict() if self.oqparam.poes_disagg or self.oqparam.iml_disagg: for sid in self.sitecol.sids: for smodel in self.csm.source_models: zd.bb_dict[smodel.ordinal, sid] = BoundingBox(smodel.ordinal, sid) return zd
def zerodict(self): """ Initial accumulator, a dict grp_id -> ProbabilityMap(L, G) """ zd = AccumDict() num_levels = len(self.oqparam.imtls.array) for grp in self.csm.src_groups: num_gsims = len(self.rlzs_assoc.gsims_by_grp_id[grp.id]) zd[grp.id] = ProbabilityMap(num_levels, num_gsims) zd.calc_times = [] zd.eff_ruptures = AccumDict() # grp_id -> eff_ruptures zd.bb_dict = BBdict() if self.oqparam.poes_disagg: for sid in self.sitecol.sids: for smodel in self.csm.source_models: zd.bb_dict[smodel.ordinal, sid] = BoundingBox( smodel.ordinal, sid) return zd
def count_eff_ruptures(sources, srcfilter, gsims, param, monitor): """ Count the effective number of ruptures contained in the given sources within the integration distance and return a dictionary src_group_id -> num_ruptures. All sources must belong to the same tectonic region type. """ acc = AccumDict() acc.grp_id = sources[0].src_group_id acc.calc_times = [] count = 0 for src in sources: t0 = time.time() sites = srcfilter.get_close_sites(src) if sites is not None: count += src.num_ruptures dt = time.time() - t0 acc.calc_times.append((src.source_id, len(sites), dt)) acc.eff_ruptures = {acc.grp_id: count} return acc
def pmap_from_trt(sources, src_filter, gsims, param, monitor=Monitor()): """ Compute the hazard curves for a set of sources belonging to the same tectonic region type for all the GSIMs associated to that TRT. :returns: a dictionary {grp_id: pmap} with attributes .grp_ids, .calc_times, .eff_ruptures """ grp_ids = set() for src in sources: grp_ids.update(src.src_group_ids) maxdist = src_filter.integration_distance srcs = sum([split_source(src) for src in sources], []) # split first with GroundShakingIntensityModel.forbid_instantiation(): imtls = param['imtls'] trunclevel = param.get('truncation_level') cmaker = ContextMaker(gsims, maxdist) ctx_mon = monitor('make_contexts', measuremem=False) poe_mon = monitor('get_poes', measuremem=False) pmap = AccumDict({ grp_id: ProbabilityMap(len(imtls.array), len(gsims)) for grp_id in grp_ids }) pmap.calc_times = [] # pairs (src_id, delta_t) pmap.eff_ruptures = AccumDict() # grp_id -> num_ruptures for src, s_sites in src_filter(srcs): # filter now t0 = time.time() poemap = cmaker.poe_map(src, s_sites, imtls, trunclevel, ctx_mon, poe_mon) if poemap: for grp_id in src.src_group_ids: pmap[grp_id] |= poemap pmap.calc_times.append( (src.source_id, src.weight, len(s_sites), time.time() - t0)) # storing the number of contributing ruptures too pmap.eff_ruptures += { grp_id: getattr(poemap, 'eff_ruptures', 0) for grp_id in src.src_group_ids } return pmap
def count_ruptures(sources, srcfilter, gsims, param, monitor): """ Count the number of ruptures contained in the given sources by applying a raw source filtering on the integration distance. Return a dictionary src_group_id -> {}. All sources must belong to the same tectonic region type. """ dic = groupby(sources, operator.attrgetter('src_group_id')) acc = AccumDict({grp_id: {} for grp_id in dic}) acc.eff_ruptures = {grp_id: 0 for grp_id in dic} acc.calc_times = [] for grp_id in dic: for src in sources: t0 = time.time() sites = srcfilter.get_close_sites(src) if sites is not None: acc.eff_ruptures[grp_id] += src.num_ruptures dt = time.time() - t0 acc.calc_times.append( (src.source_id, len(sites), src.weight, dt)) return acc
def pmap_from_grp(group, src_filter, gsims, param, monitor=Monitor()): """ Compute the hazard curves for a set of sources belonging to the same tectonic region type for all the GSIMs associated to that TRT. The arguments are the same as in :func:`calc_hazard_curves`, except for ``gsims``, which is a list of GSIM instances. :returns: a dictionary {grp_id: ProbabilityMap instance} """ mutex_weight = { src.source_id: weight for src, weight in zip(group.sources, group.srcs_weights) } maxdist = src_filter.integration_distance srcs = sum([split_source(src) for src in group.sources], []) with GroundShakingIntensityModel.forbid_instantiation(): imtls = param['imtls'] trunclevel = param.get('truncation_level') cmaker = ContextMaker(gsims, maxdist) ctx_mon = monitor('make_contexts', measuremem=False) poe_mon = monitor('get_poes', measuremem=False) pmap = ProbabilityMap(len(imtls.array), len(gsims)) calc_times = [] # pairs (src_id, delta_t) for src, s_sites in src_filter(srcs): t0 = time.time() poemap = cmaker.poe_map(src, s_sites, imtls, trunclevel, ctx_mon, poe_mon, group.rup_interdep == 'indep') weight = mutex_weight[src.source_id] for sid in poemap: pcurve = pmap.setdefault(sid, 0) pcurve += poemap[sid] * weight calc_times.append( (src.source_id, src.weight, len(s_sites), time.time() - t0)) if group.grp_probability is not None: pmap *= group.grp_probability acc = AccumDict({group.id: pmap}) # adding the number of contributing ruptures too acc.eff_ruptures = {group.id: ctx_mon.counts} acc.calc_times = calc_times return acc
def build_ruptures(sources, src_filter, param, monitor): """ :param sources: a list with a single UCERF source :param src_filter: a SourceFilter instance :param param: extra parameters :param monitor: a Monitor instance :returns: an AccumDict grp_id -> EBRuptures """ [src] = sources res = AccumDict() res.calc_times = [] sampl_mon = monitor('sampling ruptures', measuremem=True) filt_mon = monitor('filtering ruptures', measuremem=False) res.trt = DEFAULT_TRT background_sids = src.get_background_sids(src_filter) sitecol = src_filter.sitecol cmaker = ContextMaker(param['gsims'], src_filter.integration_distance) num_ses = param['ses_per_logic_tree_path'] samples = getattr(src, 'samples', 1) n_occ = AccumDict(accum=0) t0 = time.time() with sampl_mon: for sam_idx in range(samples): for ses_idx, ses_seed in param['ses_seeds']: seed = sam_idx * TWO16 + ses_seed rups, occs = generate_event_set(src, background_sids, src_filter, ses_idx, seed) for rup, occ in zip(rups, occs): n_occ[rup] += occ tot_occ = sum(n_occ.values()) dic = {'eff_ruptures': {src.src_group_id: src.num_ruptures}} with filt_mon: eb_ruptures = stochastic.build_eb_ruptures(src, num_ses, cmaker, sitecol, n_occ.items()) dic['rup_array'] = (stochastic.get_rup_array(eb_ruptures) if eb_ruptures else ()) dt = time.time() - t0 dic['calc_times'] = {src.id: numpy.array([tot_occ, len(sitecol), dt], F32)} return dic
def count_ruptures(sources, srcfilter, gsims, param, monitor): """ Count the number of ruptures contained in the given sources by applying a raw source filtering on the integration distance. Return a dictionary src_group_id -> {}. All sources must belong to the same tectonic region type. """ dic = groupby(sources, lambda src: src.src_group_ids[0]) acc = AccumDict({grp_id: {} for grp_id in dic}) acc.eff_ruptures = {grp_id: 0 for grp_id in dic} acc.calc_times = AccumDict(accum=numpy.zeros(4)) for grp_id in dic: for src in sources: t0 = time.time() src_id = src.source_id.split(':')[0] sites = srcfilter.get_close_sites(src) if sites is not None: acc.eff_ruptures[grp_id] += src.num_ruptures dt = time.time() - t0 acc.calc_times[src_id] += numpy.array( [src.weight, len(sites), dt, 1]) return acc
def classical(sources, sitecol, gsims, monitor): """ :param sources: a non-empty sequence of sources of homogeneous tectonic region type :param sitecol: a SiteCollection instance :param gsims: a list of GSIMs for the current tectonic region type :param monitor: a monitor instance :returns: an AccumDict rlz -> curves """ truncation_level = monitor.truncation_level imtls = monitor.imtls src_group_id = sources[0].src_group_id # sanity check: the src_group must be the same for all sources for src in sources[1:]: assert src.src_group_id == src_group_id trt = sources[0].tectonic_region_type max_dist = monitor.maximum_distance[trt] dic = AccumDict() if monitor.poes_disagg: sm_id = monitor.sm_id dic.bbs = [BoundingBox(sm_id, sid) for sid in sitecol.sids] else: dic.bbs = [] # NB: the source_site_filter below is ESSENTIAL for performance inside # pmap_from_grp, since it reduces the full site collection # to a filtered one *before* doing the rupture filtering dic[src_group_id] = pmap_from_grp( sources, sitecol, imtls, gsims, truncation_level, maximum_distance=max_dist, bbs=dic.bbs, monitor=monitor) dic.calc_times = monitor.calc_times # added by pmap_from_grp dic.eff_ruptures = {src_group_id: monitor.eff_ruptures} # idem return dic
def compute_ruptures(sources, src_filter, gsims, param, monitor): """ :param sources: a sequence of sources of the same group :param src_filter: a source site filter :param gsims: a list of GSIMs for the current tectonic region model :param param: a dictionary of additional parameters :param monitor: monitor instance :returns: a dictionary src_group_id -> [Rupture instances] """ # NB: by construction each block is a non-empty list with # sources of the same src_group_id grp_id = sources[0].src_group_id dic = sample_ruptures(sources, src_filter, gsims, param, monitor) res = AccumDict({grp_id: dic['eb_ruptures']}) res.num_events = dic['num_events'] res.calc_times = dic['calc_times'] res.eff_ruptures = {grp_id: dic['num_ruptures']} return res
def compute_ruptures(sources, sitecol, gsims, monitor): """ :param sources: List of commonlib.source.Source tuples :param sitecol: a :class:`openquake.hazardlib.site.SiteCollection` instance :param gsims: a list of GSIMs for the current tectonic region model :param monitor: monitor instance :returns: a dictionary src_group_id -> [Rupture instances] """ # NB: by construction each block is a non-empty list with # sources of the same src_group_id src_group_id = sources[0].src_group_id trt = sources[0].tectonic_region_type max_dist = monitor.maximum_distance[trt] cmaker = ContextMaker(gsims) params = sorted(cmaker.REQUIRES_RUPTURE_PARAMETERS) rup_data_dt = numpy.dtype( [('rupserial', U32), ('multiplicity', U16), ('numsites', U32), ('occurrence_rate', F64)] + [ (param, F64) for param in params]) eb_ruptures = [] rup_data = [] calc_times = [] rup_mon = monitor('filtering ruptures', measuremem=False) num_samples = monitor.samples num_events = 0 # Compute and save stochastic event sets for src in sources: t0 = time.time() s_sites = src.filter_sites_by_distance_to_source(max_dist, sitecol) if s_sites is None: continue rupture_filter = functools.partial( filter_sites_by_distance_to_rupture, integration_distance=max_dist, sites=s_sites) num_occ_by_rup = sample_ruptures( src, monitor.ses_per_logic_tree_path, num_samples, monitor.seed) # NB: the number of occurrences is very low, << 1, so it is # more efficient to filter only the ruptures that occur, i.e. # to call sample_ruptures *before* the filtering for ebr in build_eb_ruptures( src, num_occ_by_rup, rupture_filter, monitor.seed, rup_mon): nsites = len(ebr.indices) try: rate = ebr.rupture.occurrence_rate except AttributeError: # for nonparametric sources rate = numpy.nan rc = cmaker.make_rupture_context(ebr.rupture) ruptparams = tuple(getattr(rc, param) for param in params) rup_data.append((ebr.serial, ebr.multiplicity, nsites, rate) + ruptparams) eb_ruptures.append(ebr) num_events += ebr.multiplicity dt = time.time() - t0 calc_times.append((src.id, dt)) res = AccumDict({src_group_id: eb_ruptures}) res.num_events = num_events res.calc_times = calc_times res.rup_data = numpy.array(rup_data, rup_data_dt) res.trt = trt return res
def compute_ruptures_gmfs_curves( source_models, sitecol, rlzs_assoc, monitor): """ Returns the ruptures as a TRT set :param source_models: A list of UCERF source models, one per branch :param sitecol: Site collection :class:`openquake.hazardlib.site.SiteCollection` :param rlzs_assoc: Instance of :class:`openquake.commonlib.source.RlzsAssoc` :param monitor: Instance of :class:`openquake.baselib.performance.Monitor` :returns: Dictionary of rupture instances associated to a TRT ID """ oq = monitor.oqparam correl_model = oq.get_correl_model() imts = list(oq.imtls) min_iml = calc.fix_minimum_intensity(oq.minimum_intensity, imts) integration_distance = oq.maximum_distance[DEFAULT_TRT] res = AccumDict() res.calc_times = AccumDict() serial = 1 event_mon = monitor('sampling ruptures', measuremem=False) res['ruptures'] = rupdic = AccumDict() rupdic.num_events = 0 rupdic.trt = DEFAULT_TRT rlzs_by_grp = rlzs_assoc.get_rlzs_by_grp_id() for grp_id, source_model in enumerate(source_models): [grp] = source_model.src_groups # one source group per source model [ucerf] = grp # one source per source group t0 = time.time() # set the seed before calling generate_event_set numpy.random.seed(oq.random_seed + grp_id) ses_ruptures = [] eid = 0 ucerf.idx_set = ucerf.build_idx_set() background_sids = ucerf.get_background_sids( sitecol, integration_distance) for ses_idx in range(1, oq.ses_per_logic_tree_path + 1): with event_mon: rups, n_occs = ucerf.generate_event_set(background_sids) for i, rup in enumerate(rups): rup.seed = oq.random_seed # to think rrup = rup.surface.get_min_distance(sitecol.mesh) r_sites = sitecol.filter(rrup <= integration_distance) if r_sites is None: continue indices = r_sites.indices events = [] for j in range(n_occs[i]): events.append((eid, ses_idx, j, 0)) # 0 is the sampling ID eid += 1 if events: ses_ruptures.append( event_based.EBRupture( rup, indices, numpy.array(events, event_based.event_dt), ucerf.source_id, grp_id, serial)) serial += 1 rupdic.num_events += len(events) res['ruptures'][grp_id] = ses_ruptures gsims = [dic[DEFAULT_TRT] for dic in rlzs_assoc.gsim_by_trt] gg = riskinput.GmfGetter(gsims, ses_ruptures, sitecol, imts, min_iml, oq.truncation_level, correl_model, rlzs_assoc.samples[grp_id]) rlzs = rlzs_by_grp[grp_id] res.update(event_based.compute_gmfs_and_curves(gg, rlzs, monitor)) res.calc_times[grp_id] = (ucerf.source_id, len(sitecol), time.time() - t0) return res
def compute_ruptures(sources, sitecol, siteidx, rlzs_assoc, monitor): """ :param sources: List of commonlib.source.Source tuples :param sitecol: a :class:`openquake.hazardlib.site.SiteCollection` instance :param siteidx: always equal to 0 :param rlzs_assoc: a :class:`openquake.commonlib.source.RlzsAssoc` instance :param monitor: monitor instance :returns: a dictionary trt_model_id -> [Rupture instances] """ assert siteidx == 0, ( 'siteidx can be nonzero only for the classical_tiling calculations: ' 'tiling with the EventBasedRuptureCalculator is an error') # NB: by construction each block is a non-empty list with # sources of the same trt_model_id trt_model_id = sources[0].trt_model_id oq = monitor.oqparam trt = sources[0].tectonic_region_type max_dist = oq.maximum_distance[trt] cmaker = ContextMaker(rlzs_assoc.gsims_by_trt_id[trt_model_id]) params = cmaker.REQUIRES_RUPTURE_PARAMETERS rup_data_dt = numpy.dtype([('rupserial', U32), ('multiplicity', U16), ('numsites', U32)] + [(param, F32) for param in params]) eb_ruptures = [] rup_data = [] calc_times = [] rup_mon = monitor('filtering ruptures', measuremem=False) num_samples = rlzs_assoc.samples[trt_model_id] # Compute and save stochastic event sets for src in sources: t0 = time.time() s_sites = src.filter_sites_by_distance_to_source(max_dist, sitecol) if s_sites is None: continue rupture_filter = functools.partial(filter_sites_by_distance_to_rupture, integration_distance=max_dist, sites=s_sites) num_occ_by_rup = sample_ruptures(src, oq.ses_per_logic_tree_path, num_samples, rlzs_assoc.seed) # NB: the number of occurrences is very low, << 1, so it is # more efficient to filter only the ruptures that occur, i.e. # to call sample_ruptures *before* the filtering for ebr in build_eb_ruptures(src, num_occ_by_rup, rupture_filter, oq.random_seed, rup_mon): nsites = len(ebr.indices) rc = cmaker.make_rupture_context(ebr.rupture) ruptparams = tuple(getattr(rc, param) for param in params) rup_data.append((ebr.serial, len(ebr.etags), nsites) + ruptparams) eb_ruptures.append(ebr) dt = time.time() - t0 calc_times.append((src.id, dt)) res = AccumDict({trt_model_id: eb_ruptures}) res.calc_times = calc_times res.rup_data = numpy.array(rup_data, rup_data_dt) res.trt = trt return res
def execute(self): """ Run in parallel `core_task(sources, sitecol, monitor)`, by parallelizing on the sources according to their weight and tectonic region type. """ monitor = self.monitor.new(self.core_task.__name__) monitor.oqparam = oq = self.oqparam ucerf_source = self.src_group.sources[0] max_dist = oq.maximum_distance[DEFAULT_TRT] acc = AccumDict({ grp_id: ProbabilityMap(len(oq.imtls.array), len(gsims)) for grp_id, gsims in self.rlzs_assoc.gsims_by_grp_id.items()}) acc.calc_times = [] acc.eff_ruptures = AccumDict() # grp_id -> eff_ruptures acc.bb_dict = {} if len(self.csm) > 1: # when multiple branches, parallelise by branch branches = [br.value for br in self.smlt.branches.values()] rup_res = parallel.starmap( ucerf_classical_hazard_by_branch, self.gen_args(branches, ucerf_source, monitor)).submit_all() else: # single branch gsims = self.rlzs_assoc.gsims_by_grp_id[0] [(branch_id, branch)] = self.smlt.branches.items() branchname = branch.value ucerf_source.src_group_id = 0 ucerf_source.weight = 1 ucerf_source.nsites = len(self.sitecol) self.infos[0, ucerf_source.source_id] = source.SourceInfo( ucerf_source) logging.info('Getting the background point sources') with self.monitor('getting background sources', autoflush=True): ucerf_source.build_idx_set() background_sids = ucerf_source.get_background_sids( self.sitecol, max_dist) bckgnd_sources = ucerf_source.get_background_sources( background_sids) # parallelize on the background sources, small tasks args = (bckgnd_sources, self.sitecol, oq.imtls, gsims, self.oqparam.truncation_level, 'SourceSitesFilter', max_dist, (), monitor) bg_res = parallel.apply( pmap_from_grp, args, concurrent_tasks=self.oqparam.concurrent_tasks).submit_all() # parallelize by rupture subsets tasks = self.oqparam.concurrent_tasks * 2 # they are big tasks rup_sets = ucerf_source.get_rupture_indices(branchname) rup_res = parallel.apply( ucerf_classical_hazard_by_rupture_set, (rup_sets, branchname, ucerf_source, self.src_group.id, self.sitecol, gsims, monitor), concurrent_tasks=tasks).submit_all() # compose probabilities from background sources for pmap in bg_res: acc[0] |= pmap self.save_data_transfer(bg_res) pmap_by_grp_id = functools.reduce(self.agg_dicts, rup_res, acc) with self.monitor('store source_info', autoflush=True): self.store_source_info(self.infos) self.save_data_transfer(rup_res) self.datastore['csm_info'] = self.csm.info self.rlzs_assoc = self.csm.info.get_rlzs_assoc( functools.partial(self.count_eff_ruptures, pmap_by_grp_id)) self.datastore['csm_info'] = self.csm.info return pmap_by_grp_id
def compute_ruptures(sources, sitecol, siteidx, rlzs_assoc, monitor): """ :param sources: List of commonlib.source.Source tuples :param sitecol: a :class:`openquake.hazardlib.site.SiteCollection` instance :param siteidx: always equal to 0 :param rlzs_assoc: a :class:`openquake.commonlib.source.RlzsAssoc` instance :param monitor: monitor instance :returns: a dictionary src_group_id -> [Rupture instances] """ assert siteidx == 0, ( 'siteidx can be nonzero only for the classical_tiling calculations: ' 'tiling with the EventBasedRuptureCalculator is an error') # NB: by construction each block is a non-empty list with # sources of the same src_group_id src_group_id = sources[0].src_group_id oq = monitor.oqparam trt = sources[0].tectonic_region_type max_dist = oq.maximum_distance[trt] cmaker = ContextMaker(rlzs_assoc.gsims_by_grp_id[src_group_id]) params = sorted(cmaker.REQUIRES_RUPTURE_PARAMETERS) rup_data_dt = numpy.dtype( [('rupserial', U32), ('multiplicity', U16), ('numsites', U32), ('occurrence_rate', F32)] + [ (param, F32) for param in params]) eb_ruptures = [] rup_data = [] calc_times = [] rup_mon = monitor('filtering ruptures', measuremem=False) num_samples = rlzs_assoc.samples[src_group_id] # Compute and save stochastic event sets for src in sources: t0 = time.time() s_sites = src.filter_sites_by_distance_to_source(max_dist, sitecol) if s_sites is None: continue rupture_filter = functools.partial( filter_sites_by_distance_to_rupture, integration_distance=max_dist, sites=s_sites) num_occ_by_rup = sample_ruptures( src, oq.ses_per_logic_tree_path, num_samples, rlzs_assoc.seed) # NB: the number of occurrences is very low, << 1, so it is # more efficient to filter only the ruptures that occur, i.e. # to call sample_ruptures *before* the filtering for ebr in build_eb_ruptures( src, num_occ_by_rup, rupture_filter, oq.random_seed, rup_mon): nsites = len(ebr.indices) try: rate = ebr.rupture.occurrence_rate except AttributeError: # for nonparametric sources rate = numpy.nan rc = cmaker.make_rupture_context(ebr.rupture) ruptparams = tuple(getattr(rc, param) for param in params) rup_data.append((ebr.serial, len(ebr.etags), nsites, rate) + ruptparams) eb_ruptures.append(ebr) dt = time.time() - t0 calc_times.append((src.id, dt)) res = AccumDict({src_group_id: eb_ruptures}) res.calc_times = calc_times res.rup_data = numpy.array(rup_data, rup_data_dt) res.trt = trt return res