예제 #1
0
def get_exposures(grid,
                  pop_file,
                  shakefile=None,
                  shakethreshtype=None,
                  shakethresh=0.0,
                  probthresh=None,
                  stdgrid2D=None,
                  stdtype='mean',
                  maxP=1.):
    """
    Get exposure-based statistics.

    Args:
        grid: Model grid.
        pop_file (str):  Path to the landscan population grid.
        shakefile (str): Optional, path to shakemap file to use for ground
            motion threshold.
        shakethreshtype(str): Optional, Type of ground motion to use for
            shakethresh, 'pga', 'pgv', or 'mmi'.
        shakethresh: Optional, Float or list of shaking thresholds in %g for
            pga, cm/s for pgv, float for mmi.
        probthresh: Optional, None or float, exclude any cells with
            probabilities less than or equal to this value
        stdgrid2D: grid2D object of model standard deviations (optional)
        stdtype (str): assumption of spatial correlation used to compute
            the stdev of the statistics, 'max', 'min' or 'mean' of max and min

    Returns:
        dict: Dictionary with keys named exp_pop_# where # is the shakethresh
            and exp_std_# if stdgrid2D is supplied (stdev of exp_pop)
            and elim_#, the maximum exposure value possible with the
            applied thresholds and given maxP value
            p_exp_# beta distribution shape factor p (sometimes called alpha)
            q_exp_# beta distribution shape factor q (sometimes called beta)
    """

    # If probthresh defined, zero out any areas less than or equal to
    # probthresh before proceeding
    if type(shakethresh) != list and type(shakethresh) != np.ndarray:
        shakethresh = [shakethresh]
    if probthresh is not None:
        origdata = grid.getData()
        moddat = origdata.copy()
        moddat[moddat <= probthresh] = 0.0
        moddat[np.isnan(origdata)] = float('nan')
        if stdgrid2D is not None:
            stddat = stdgrid2D.getData().copy()
            stddat[moddat <= probthresh] = 0.0
            stddat[np.isnan(origdata)] = 0.0
    else:
        moddat = grid.getData().copy()
        if stdgrid2D is not None:
            stddat = stdgrid2D.getData().copy()

    mdict = grid.getGeoDict()

    # Cut out area from population file
    popcut = quickcut(pop_file,
                      mdict,
                      precise=False,
                      extrasamp=2.,
                      method='nearest')
    popdat = popcut.getData()
    pdict = popcut.getGeoDict()

    # Pad grid with nans to beyond extent of pdict
    pad_dict = {}
    pad_dict['padleft'] = int(
        np.abs(np.ceil((mdict.xmin - pdict.xmin) / mdict.dx)))
    pad_dict['padright'] = int(
        np.abs(np.ceil((pdict.xmax - mdict.xmax) / mdict.dx)))
    pad_dict['padbottom'] = int(
        np.abs(np.ceil((mdict.ymin - pdict.ymin) / mdict.dy)))
    pad_dict['padtop'] = int(
        np.abs(np.ceil((pdict.ymax - mdict.ymax) / mdict.dy)))

    padgrid, mdict2 = Grid2D.padGrid(moddat, mdict, pad_dict)  # padds with inf
    padgrid[np.isinf(padgrid)] = float('nan')  # change to pad with nan
    padgrid = Grid2D(data=padgrid, geodict=mdict2)  # Turn into grid2d object

    if stdgrid2D is not None:
        padstdgrid, mdict3 = Grid2D.padGrid(stddat, mdict,
                                            pad_dict)  # padds with inf
        padstdgrid[np.isinf(padstdgrid)] = float(
            'nan')  # change to pad with nan
        padstdgrid = Grid2D(data=padstdgrid,
                            geodict=mdict3)  # Turn into grid2d object

    # Resample model grid so as to be the nearest integer multiple of popdict
    factor = np.round(pdict.dx / mdict2.dx)

    # Create geodictionary that is a factor of X higher res but otherwise
    # identical
    ndict = GeoDict.createDictFromBox(pdict.xmin, pdict.xmax, pdict.ymin,
                                      pdict.ymax, pdict.dx / factor,
                                      pdict.dy / factor)

    # Resample
    grid2 = padgrid.interpolate2(ndict, method='linear')

    # Get proportion of each cell that has values (to account properly
    # for any nans)
    prop = block_reduce(~np.isnan(grid2.getData().copy()),
                        block_size=(int(factor), int(factor)),
                        cval=float('nan'),
                        func=np.sum) / (factor**2.)

    # Now block reduce to same geodict as popfile
    modresamp = block_reduce(grid2.getData().copy(),
                             block_size=(int(factor), int(factor)),
                             cval=float('nan'),
                             func=np.nanmean)

    if stdgrid2D is not None:
        grid2std = padstdgrid.interpolate2(ndict, method='linear')
        propstd = block_reduce(~np.isnan(grid2std.getData().copy()),
                               block_size=(int(factor), int(factor)),
                               cval=float('nan'),
                               func=np.sum) / (factor**2.)
        modresampstd = block_reduce(grid2std.getData().copy(),
                                    block_size=(int(factor), int(factor)),
                                    cval=float('nan'),
                                    func=np.nanmean)

    exp_pop = {}
    if shakefile is not None:
        # Resample shakefile to population grid
        # , doPadding=True, padValue=0.)
        shakemap = ShakeGrid.load(shakefile, resample=False)
        shakemap = shakemap.getLayer(shakethreshtype)
        shakemap = shakemap.interpolate2(pdict)
        shkdat = shakemap.getData()
        for shaket in shakethresh:
            threshmult = shkdat > shaket
            threshmult = threshmult.astype(float)
            mu = np.nansum(popdat * prop * modresamp * threshmult)
            exp_pop['exp_pop_%1.2fg' % (shaket / 100., )] = mu
            elim = maxP * np.nansum(popdat * prop * threshmult)
            exp_pop['elim_%1.2fg' % (shaket / 100., )] = elim
            if stdgrid2D is not None:
                totalmax = np.nansum(popdat * propstd * modresampstd *
                                     threshmult)
                totalmin = np.sqrt(
                    np.nansum(
                        (popdat * propstd * modresampstd * threshmult)**2.))
                if stdtype == 'max':
                    exp_pop['exp_std_%1.2fg' % (shaket / 100., )] = totalmax
                elif stdtype == 'min':
                    exp_pop['exp_std_%1.2fg' % (shaket / 100., )] = totalmin
                else:
                    exp_pop['exp_std_%1.2fg' %
                            (shaket / 100., )] = (totalmax + totalmin) / 2.
                # Beta distribution shape factors
                var = exp_pop['exp_std_%1.2fg' % (shaket / 100., )]**2.
                exp_pop['p_exp_%1.2fg' % (shaket / 100., )] = (mu / elim) * (
                    (elim * mu - mu**2) / var - 1)
                exp_pop['q_exp_%1.2fg' %
                        (shaket / 100., )] = (1 - mu / elim) * (
                            (elim * mu - mu**2) / var - 1)

    else:
        mu = np.nansum(popdat * prop * modresamp)
        exp_pop['exp_pop_0.00g'] = mu
        elim = maxP * np.nansum(popdat * prop)
        exp_pop['elim_0.00g'] = elim
        if stdgrid2D is not None:
            totalmax = np.nansum(popdat * propstd * modresampstd)
            totalmin = np.sqrt(np.nansum(
                (popdat * propstd * modresampstd)**2.))
            if stdtype == 'max':
                exp_pop['exp_std_0.00g'] = totalmax
            elif stdtype == 'min':
                exp_pop['exp_std_0.00g'] = totalmin
            else:
                exp_pop['exp_std_0.00g'] = (totalmax + totalmin) / 2.
            # Beta distribution shape factors
            var = exp_pop['exp_std_0.00g']**2.
            exp_pop['exp_std_0.00g'] = (mu / elim) * (
                (elim * mu - mu**2) / var - 1)
            exp_pop['exp_std_0.00g'] = (1 - mu / elim) * (
                (elim * mu - mu**2) / var - 1)
            #exp_pop['exp_std_0.00g'] = np.nansum(popdat * propstd * modresampstd)

    return exp_pop