Example #1
0
def compute_disagg(dstore, idxs, cmaker, iml3, trti, bin_edges, oq, monitor):
    # see https://bugs.launchpad.net/oq-engine/+bug/1279247 for an explanation
    # of the algorithm used
    """
    :param dstore
        a DataStore instance
    :param idxs:
        an array of indices to ruptures
    :param cmaker:
        a :class:`openquake.hazardlib.gsim.base.ContextMaker` instance
    :param iml3:
        an ArrayWrapper of shape (N, P, Z) with an attribute imt
    :param trti:
        tectonic region type index
    :param bin_egdes:
        a quintet (mag_edges, dist_edges, lon_edges, lat_edges, eps_edges)
    :param monitor:
        monitor of the currently running job
    :returns:
        a dictionary sid -> 8D-array
    """
    with monitor('reading rupdata', measuremem=True):
        dstore.open('r')
        sitecol = dstore['sitecol']
        rupdata = {k: dstore['rup/' + k][idxs] for k in dstore['rup']}
    RuptureContext.temporal_occurrence_model = PoissonTOM(
        oq.investigation_time)
    pne_mon = monitor('disaggregate_pne', measuremem=False)
    mat_mon = monitor('build_disagg_matrix', measuremem=True)
    gmf_mon = monitor('disagg mean_std', measuremem=False)
    for sid, iml2 in zip(sitecol.sids, iml3):
        singlesite = sitecol.filtered([sid])
        bins = disagg.get_bins(bin_edges, sid)
        gsim_by_z = {}
        for z in range(iml3.shape[-1]):
            try:
                gsim = cmaker.gsim_by_rlzi[iml3.rlzs[sid, z]]
            except KeyError:
                pass
            else:
                gsim_by_z[z] = gsim
        ctxs = []
        ok, = numpy.where(
            rupdata['rrup_'][:, sid] <= cmaker.maximum_distance(cmaker.trt))
        for ridx in ok:  # consider only the ruptures close to the site
            ctx = RuptureContext((par, rupdata[par][ridx])
                                 for par in rupdata if not par.endswith('_'))
            for par in rupdata:
                if par.endswith('_'):
                    setattr(ctx, par[:-1], rupdata[par][ridx, [sid]])
            ctxs.append(ctx)
        if not ctxs:
            continue
        eps3 = disagg._eps3(cmaker.trunclevel, oq.num_epsilon_bins)
        matrix = numpy.zeros([len(b) - 1 for b in bins] + list(iml2.shape))
        for z, gsim in gsim_by_z.items():
            with gmf_mon:
                ms = disagg.get_mean_stdv(singlesite, ctxs, iml3.imt, gsim)
            bdata = disagg.disaggregate(
                ms, ctxs, iml3.imt, iml2[:, z], eps3, pne_mon)
            if bdata.pnes.sum():
                with mat_mon:
                    matrix[..., z] = disagg.build_disagg_matrix(bdata, bins)
        if matrix.any():
            yield {'trti': trti, 'imti': iml3.imti, sid: matrix}
Example #2
0
def compute_disagg(dstore, slc, cmaker, hmap4, magi, bin_edges, monitor):
    # see https://bugs.launchpad.net/oq-engine/+bug/1279247 for an explanation
    # of the algorithm used
    """
    :param dstore:
        a DataStore instance
    :param slc:
        a slice of ruptures
    :param cmaker:
        a :class:`openquake.hazardlib.gsim.base.ContextMaker` instance
    :param hmap4:
        an ArrayWrapper of shape (N, M, P, Z)
    :param magi:
        magnitude bin indices
    :param bin_egdes:
        a quartet (dist_edges, lon_edges, lat_edges, eps_edges)
    :param monitor:
        monitor of the currently running job
    :returns:
        a dictionary sid, imti -> 6D-array
    """
    with monitor('reading contexts', measuremem=True):
        dstore.open('r')
        allctxs = cmaker.read_ctxs(dstore, slc)
        for magidx, ctx in zip(magi, allctxs):
            ctx.magi = magidx
    dis_mon = monitor('disaggregate', measuremem=False)
    ms_mon = monitor('disagg mean_std', measuremem=True)
    N, M, P, Z = hmap4.shape
    g_by_z = AccumDict(accum={})  # dict s -> z -> g
    for g, rlzs in enumerate(cmaker.gsims.values()):
        for (s, z), r in numpy.ndenumerate(hmap4.rlzs):
            if r in rlzs:
                g_by_z[s][z] = g
    eps3 = disagg._eps3(cmaker.trunclevel, cmaker.num_epsilon_bins)
    imts = [from_string(im) for im in cmaker.imtls]
    for magi, ctxs in groupby(allctxs, operator.attrgetter('magi')).items():
        res = {'trti': cmaker.trti, 'magi': magi}
        with ms_mon:
            # compute mean and std (N * U * M * G * 16 bytes)
            disagg.set_mean_std(ctxs, imts, cmaker.gsims)

        # disaggregate by site, IMT
        for s, iml3 in enumerate(hmap4):
            close = [ctx for ctx in ctxs if ctx.magi == magi and s in ctx.sids]
            if not g_by_z[s] or not close:
                # g_by_z[s] is empty in test case_7
                continue
            # dist_bins, lon_bins, lat_bins, eps_bins
            bins = (bin_edges[1], bin_edges[2][s], bin_edges[3][s],
                    bin_edges[4])
            iml2 = dict(zip(imts, iml3))
            with dis_mon:
                # 7D-matrix #distbins, #lonbins, #latbins, #epsbins, M, P, Z
                matrix = disagg.disaggregate(close, cmaker.tom, g_by_z[s],
                                             iml2, eps3, s, bins)  # 7D-matrix
                for m in range(M):
                    mat6 = matrix[..., m, :, :]
                    if mat6.any():
                        res[s, m] = output(mat6)
        yield res
Example #3
0
def compute_disagg(dstore, rctx, cmaker, hmap4, trti, bin_edges, oq, monitor):
    # see https://bugs.launchpad.net/oq-engine/+bug/1279247 for an explanation
    # of the algorithm used
    """
    :param dstore:
        a DataStore instance
    :param rctx:
        an array of rupture parameters
    :param cmaker:
        a :class:`openquake.hazardlib.gsim.base.ContextMaker` instance
    :param hmap4:
        an ArrayWrapper of shape (N, M, P, Z)
    :param trti:
        tectonic region type index
    :param magi:
        magnitude bin index
    :param bin_egdes:
        a quartet (dist_edges, lon_edges, lat_edges, eps_edges)
    :param monitor:
        monitor of the currently running job
    :returns:
        a dictionary sid, imti -> 6D-array
    """
    RuptureContext.temporal_occurrence_model = PoissonTOM(
        oq.investigation_time)
    with monitor('reading contexts', measuremem=True):
        dstore.open('r')
        ctxs, close_ctxs = read_ctxs(
            dstore, rctx, req_site_params=cmaker.REQUIRES_SITES_PARAMETERS)

    magi = numpy.searchsorted(bin_edges[0], rctx[0]['mag']) - 1
    if magi == -1:  # when the magnitude is on the edge
        magi = 0
    dis_mon = monitor('disaggregate', measuremem=False)
    ms_mon = monitor('disagg mean_std', measuremem=True)
    N, M, P, Z = hmap4.shape
    g_by_z = AccumDict(accum={})  # dict s -> z -> g
    for g, rlzs in enumerate(cmaker.gsims.values()):
        for (s, z), r in numpy.ndenumerate(hmap4.rlzs):
            if r in rlzs:
                g_by_z[s][z] = g
    eps3 = disagg._eps3(cmaker.trunclevel, oq.num_epsilon_bins)
    res = {'trti': trti, 'magi': magi}
    imts = [from_string(im) for im in oq.imtls]
    with ms_mon:
        # compute mean and std for a single IMT to save memory
        # the size is N * U * G * 16 bytes
        disagg.set_mean_std(ctxs, imts, cmaker.gsims)

    # disaggregate by site, IMT
    for s, iml3 in enumerate(hmap4):
        if not g_by_z[s] or not close_ctxs[s]:
            # g_by_z[s] is empty in test case_7
            continue
        # dist_bins, lon_bins, lat_bins, eps_bins
        bins = (bin_edges[1], bin_edges[2][s], bin_edges[3][s], bin_edges[4])
        iml2 = dict(zip(imts, iml3))
        with dis_mon:
            # 7D-matrix #distbins, #lonbins, #latbins, #epsbins, M, P, Z
            matrix = disagg.disaggregate(close_ctxs[s], g_by_z[s], iml2, eps3,
                                         s, bins)  # 7D-matrix
            for m in range(M):
                mat6 = matrix[..., m, :, :]
                if mat6.any():
                    res[s, m] = output(mat6)
    return res
def compute_disagg(dstore, idxs, cmaker, iml4, trti, magi, bin_edges, oq,
                   monitor):
    # see https://bugs.launchpad.net/oq-engine/+bug/1279247 for an explanation
    # of the algorithm used
    """
    :param dstore:
        a DataStore instance
    :param idxs:
        an array of indices to ruptures
    :param cmaker:
        a :class:`openquake.hazardlib.gsim.base.ContextMaker` instance
    :param iml4:
        an ArrayWrapper of shape (N, M, P, Z)
    :param trti:
        tectonic region type index
    :param magi:
        magnitude bin index
    :param bin_egdes:
        a quartet (dist_edges, lon_edges, lat_edges, eps_edges)
    :param monitor:
        monitor of the currently running job
    :returns:
        a dictionary sid -> 7D-array
    """
    res = {'trti': trti, 'magi': magi}
    with monitor('reading rupdata', measuremem=True):
        dstore.open('r')
        sitecol = dstore['sitecol']
        # NB: using dstore['rup/' + k][idxs] would be ultraslow!
        a, b = idxs.min(), idxs.max() + 1
        rupdata = {k: dstore['rup/' + k][a:b][idxs-a] for k in dstore['rup']}
    RuptureContext.temporal_occurrence_model = PoissonTOM(
        oq.investigation_time)
    pne_mon = monitor('disaggregate_pne', measuremem=False)
    mat_mon = monitor('build_disagg_matrix', measuremem=False)
    ms_mon = monitor('disagg mean_std', measuremem=True)
    eps3 = disagg._eps3(cmaker.trunclevel, oq.num_epsilon_bins)
    with ms_mon:
        ctxs = _prepare_ctxs(rupdata, cmaker, sitecol)  # ultra-fast
        mean_std = disagg.get_mean_std(ctxs, oq.imtls, cmaker.gsims)

    for s, iml3 in enumerate(iml4):
        iml2dict = {imt: iml3[m] for m, imt in enumerate(oq.imtls)}

        # z indices by gsim
        M, P, Z = iml3.shape
        zs_by_g = AccumDict(accum=[])
        for g, rlzs in enumerate(cmaker.gsims.values()):
            for z in range(Z):
                if iml4.rlzs[s, z] in rlzs:
                    zs_by_g[g].append(z)

        # sanity check: the zs are disjoint
        counts = numpy.zeros(Z, numpy.uint8)
        for zs in zs_by_g.values():
            counts[zs] += 1
        assert (counts <= 1).all(), counts

        # dist_bins, lon_bins, lat_bins, eps_bins
        bins = bin_edges[0], bin_edges[1][s], bin_edges[2][s], bin_edges[3]
        # build 7D-matrix #distbins, #lonbins, #latbins, #epsbins, M, P, Z
        matrix = disagg.disaggregate(
            ctxs, mean_std, zs_by_g, iml2dict, eps3, s, bins, pne_mon, mat_mon)
        if matrix.any():
            res[s] = matrix
    return res