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