Example #1
0
def disaggregate(ctxs, tom, g_by_z, iml2dict, eps3, sid=0, bin_edges=()):
    """
    :param ctxs: a list of U RuptureContexts
    :param tom: a temporal occurrence model
    :param g_by_z: an array of gsim indices
    :param iml2dict: a dictionary of arrays imt -> (P, Z)
    :param eps3: a triplet (truncnorm, epsilons, eps_bands)
    """
    # disaggregate (separate) PoE in different contributions
    U, E, M = len(ctxs), len(eps3[2]), len(iml2dict)
    iml2 = next(iter(iml2dict.values()))
    P, Z = iml2.shape
    dists = numpy.zeros(U)
    lons = numpy.zeros(U)
    lats = numpy.zeros(U)

    # switch to logarithmic intensities
    iml3 = numpy.zeros((M, P, Z))
    for m, (imt, iml2) in enumerate(iml2dict.items()):
        # 0 values are converted into -inf
        iml3[m] = to_distribution_values(iml2, imt)

    truncnorm, epsilons, eps_bands = eps3
    cum_bands = numpy.array([eps_bands[e:].sum() for e in range(E)] + [0])
    G = len(ctxs[0].mean_std)
    mean_std = numpy.zeros((2, U, M, G), numpy.float32)
    for u, ctx in enumerate(ctxs):
        # search the index associated to the site ID; for instance
        # searchsorted([2, 4, 6], 4) => 1
        idx = numpy.searchsorted(ctx.sids, sid)
        dists[u] = ctx.rrup[idx]  # distance to the site
        lons[u] = ctx.clon[idx]  # closest point of the rupture lon
        lats[u] = ctx.clat[idx]  # closest point of the rupture lat
        for g in range(G):
            mean_std[:, u, :, g] = ctx.mean_std[g][:, :, idx]  # (2, M)
    poes = numpy.zeros((U, E, M, P, Z))
    pnes = numpy.ones((U, E, M, P, Z))
    for (m, p, z), iml in numpy.ndenumerate(iml3):
        if iml == -numpy.inf:  # zero hazard
            continue
        # discard the z contributions coming from wrong realizations: see
        # the test disagg/case_2
        try:
            g = g_by_z[z]
        except KeyError:
            continue
        lvls = (iml - mean_std[0, :, m, g]) / mean_std[1, :, m, g]
        idxs = numpy.searchsorted(epsilons, lvls)
        poes[:, :, m, p, z] = _disagg_eps(truncnorm.sf(lvls), idxs, eps_bands,
                                          cum_bands)
    for u, ctx in enumerate(ctxs):
        pnes[u] *= get_probability_no_exceedance(ctx, poes[u], tom)  # slow
    bindata = BinData(dists, lons, lats, pnes)
    DEBUG[idx].append(pnes.mean())
    if not bin_edges:
        return bindata
    return _build_disagg_matrix(bindata, bin_edges)
Example #2
0
def compose(ctxs, poe):
    pnes = [get_probability_no_exceedance(ctx, poe, tom) for ctx in ctxs]
    return 1. - numpy.prod(pnes), pnes