예제 #1
0
def test():
    print('Testing decimal to roman number conversion...')
    assert text.dec_to_roman(10) == 'X'
    print('Passed decimal to roman number conversion...')

    print('Testing setting number precision...')
    assert text.set_num_precision(7642, 2) == 7600
    assert text.set_num_precision(321, 2) == 320
    print('Passed setting number precision...')

    print('Testing rounding population value...')
    assert text.pop_round(7642) == '8,000'
    print('Passed rounding population value...')

    print('Testing rounding dollar value...')
    assert text.dollar_round(1.234e9, digits=2, mode='short') == '$1.2B'
    assert text.dollar_round(1.234e9, digits=2, mode='long') == '$1.2 billion'
    print('Passed rounding population value...')

    print('Testing abbreviating population value...')
    assert text.pop_round_short(1024125) == '1,024k'
    print('Passed abbreviating population value...')

    print('Testing rounding to nearest integer value...')
    assert text.round_to_nearest(998, round_value=1000) == 1000
    assert text.round_to_nearest(78, round_value=100) == 100
    print('Passed rounding population value...')

    print('Testing flooring to nearest integer value...')
    assert text.floor_to_nearest(1501, floor_value=1000) == 1000
    assert text.floor_to_nearest(51, floor_value=100) == 0
    print('Passed flooring population value...')

    print('Testing ceiling to nearest integer value...')
    assert text.ceil_to_nearest(1001, ceil_value=1000) == 2000
    assert text.ceil_to_nearest(49, ceil_value=100) == 100
    print('Passed ceiling population value...')

    print('Testing commify...')
    assert text.commify(1234567) == '1,234,567'
    print('Passed commify...')

    assert text.floor_to_nearest(0.56, floor_value=0.1) == 0.5
    assert text.ceil_to_nearest(0.44, ceil_value=0.1) == 0.5
    assert text.round_to_nearest(0.48, round_value=0.1) == 0.5
    assert text.pop_round_short(125) == '125'
    assert text.pop_round_short(1.23e6, usemillion=True) == '1m'
    assert text.pop_round_short(0) == '0'
    assert text.dollar_round(1.23, digits=2, mode='short') == '$1'
    assert text.dollar_round(1.23e3, digits=2, mode='short') == '$1.2K'
    assert text.dollar_round(1.23e3, digits=2, mode='long') == '$1.2 thousand'
    assert text.dollar_round(1.23e6, digits=2, mode='short') == '$1.2M'
    assert text.dollar_round(1.23e6, digits=2, mode='long') == '$1.2 million'
    assert text.dec_to_roman(10) == 'X'
예제 #2
0
def get_gdp_comment(ecodict, ecomodel, econexposure, event_year, epicode):
    """Create a comment on the GDP impact of a given event in the most impacted country.

    :param ecodict:
      Dictionary containing country code keys and integer population estimations of economic loss.
    :param ecomodel:
      Instance of the EmpiricalLoss class.
    :param econexposure:
      Dictionary containing country code (ISO2) keys, and values of
      10 element arrays representing population exposure to MMI 1-10.
      Dictionary will contain an additional key 'Total', with value of exposure across all countries.
    :param event_year:
      Year in which event occurred.
    :param epicode:
      Two letter country code of epicenter or 'UK' if not a country (usu. ocean).
    :returns:
      A string which indicates what fraction of the country's GDP the losses represent.
    """
    # get the gdp comment
    # get the G value for the economic losses
    eco_gvalue = ecomodel.getCombinedG(ecodict)
    # get the country code of the country with the highest losses
    dccode = ''
    dmax = 0
    expected = ecodict['TotalDollars'] / 1e6
    if ecodict['TotalDollars'] > 0:
        for ccode, value in ecodict.items():
            if ccode == 'TotalDollars':
                continue
            if value > dmax:
                dmax = value
                dccode = ccode
    else:
        # how do I compare economic exposure between countries?
        # do I want to compare that, or just grab the country of epicenter?
        for ccode, value in ecodict.items():
            if ccode == 'TotalDollars':
                continue
            rates = ecomodel.getLossRates(ccode, np.arange(1, 10))
            emploss = np.nansum(rates * value)
            if emploss > dmax:
                dmax = emploss
                dccode = ccode

    if dccode == '':
        dccode = epicode
    gdp_obj = GDP.fromDefault()
    gdp, outccode = gdp_obj.getGDP(dccode, event_year)
    country = Country()
    print('ccode: %s, dccode: %s, outccode: %s' % (ccode, dccode, outccode))
    cinfo = country.getCountry(outccode)
    if cinfo != 'UK':
        pop = cinfo['Population']
    else:
        pop = 0
    T = (pop * gdp) / 1e6
    if T == 0:
        return ''
    percent = erf(1 / np.sqrt(2))
    plow = round(
        np.exp(np.log(max(expected, EPS)) - eco_gvalue * invphi(percent)))
    phigh = round(
        np.exp(eco_gvalue * invphi(percent) + np.log(max(expected, EPS))))
    if plow != 0:
        ptlow = int(plow * 1e2 / T)
    else:
        ptlow = 0
    if phigh != 0:
        pthigh = int(phigh * 1e2 / T)
    else:
        pthigh = 0
    if dccode in ['XF', 'EU', 'WU']:
        cname = 'the United States'
    else:
        cname = cinfo['Name']
    if pthigh < 1.0:
        strtxt = 'Estimated economic losses are less than 1%% of GDP of %s.' % cname
    else:
        if ptlow < 100:
            ptlow = set_num_precision(ptlow, 1)
        else:
            ptlow = set_num_precision(ptlow, 2)
        if pthigh < 100:
            pthigh = set_num_precision(pthigh, 1)
        else:
            pthigh = set_num_precision(pthigh, 2)
        if pthigh >= 100:
            strtxt = 'Estimated economic losses may exceed the GDP of %s.' % cname
        else:
            strtxt = 'Estimated economic losses are %i-%i%% GDP of %s.' % (
                ptlow, pthigh, cname)
    return strtxt
예제 #3
0
def _draw_mmi_legend(fig, palette, gmice, process_time, map_version,
                     point_source, tdict):
    """Create a legend axis for MMI plots.

    Args:
        fig (Figure): Matplotlib Figure object.
        palette (ColorPalette): ColorPalette using range of input data and
            IMT_CMAP.
        gmice: A gmice object.
        process_time (str): Process time.
        map_version (int): ShakeMap version.
        point_source (bool): Is the rupture a PointRupture?
        tdict (dict): Dictionary containing the text strings for printing
            on the maps (in the language of the user's choice).

    """
    cax = fig.add_axes([0.1, 0.00, 0.8, 0.15])
    plt.axis('off')
    cax_xmin, cax_xmax = cax.get_xlim()
    bottom, top = cax.get_ylim()
    plt.xlim(cax_xmin, cax_xmax)
    plt.ylim(bottom, top)

    acceleration = [tdict['mmi_scale']['acc_label']]
    velocity = [tdict['mmi_scale']['vel_label']]

    imt_edges = np.array([0.5, 1.5, 3.5, 4.5, 5.5, 6.5, 7.5, 8.5, 9.5, 10.5])
    mmi_centers = np.array([1.0, 2.5, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0])
    pga_values, _ = gmice.getGMfromMI(mmi_centers, imt.from_string('PGA'))
    pgv_values, _ = gmice.getGMfromMI(mmi_centers, imt.from_string('PGV'))
    pga_values = np.exp(pga_values)*100
    pgv_values = np.exp(pgv_values)
    pga_labels = ["{0:.3g}".format(set_num_precision(
        pga, 3, mode='float')) for pga in pga_values]
    pgv_labels = ["{0:.3g}".format(set_num_precision(
        pgv, 3, mode='float')) for pgv in pgv_values]

    pga_labels[0] = '<'+pga_labels[0]
    pga_labels[-1] = '>'+pga_labels[-1]
    pgv_labels[0] = '<'+pgv_labels[0]
    pgv_labels[-1] = '>'+pgv_labels[-1]

    acceleration += pga_labels
    velocity += pgv_labels

    yloc_first_row = 13/14
    yloc_second_row = 11/14
    yloc_third_row = 9/14
    yloc_fourth_row = 7/14
    yloc_fifth_row = 5/14
    yloc_sixth_row = 3/14
    yloc_seventh_row = 1.5/14

    yloc_first_line = 12/14
    yloc_second_line = 10/14
    yloc_third_line = 8/14
    yloc_fourth_line = 6/14
    # yloc_fifth_line = 4/14

    bottom = 4/14

    font0 = FontProperties()
    alignment = {
        'horizontalalignment': 'center',
        'verticalalignment': 'center'
    }
    font0.set_weight('bold')

    font1 = FontProperties()
    font1.set_weight('normal')

    # draw vertical cell separators
    sumwidth = 0.0
    gridleft = 0.0
    plt.plot([gridleft, gridleft], [bottom, top],
             'k', clip_on=False)  # left edge
    plt.plot([0, 1], [top, top], 'k', clip_on=False)
    plt.plot([0, 1], [bottom, bottom], 'k', clip_on=False)

    plt.plot([0, 1], [yloc_first_line, yloc_first_line],
             'k', clip_on=False)
    plt.plot([0, 1], [yloc_second_line, yloc_second_line],
             'k', clip_on=False)
    plt.plot([0, 1], [yloc_third_line, yloc_third_line],
             'k', clip_on=False)
    plt.plot([0, 1], [yloc_fourth_line, yloc_fourth_line],
             'k', clip_on=False)

    # Explanation of symbols: triangle is instrument, circle is mmi,
    # epicenter is black star
    # thick black line is rupture (if available)
    item_sep = [0.2, 0.28, 0.15]
    left_offset = 0.005
    label_pad = 0.02

    # Instrument
    triangle_marker_x = left_offset
    triangle_text_x = triangle_marker_x + label_pad
    plt.plot(triangle_marker_x, yloc_seventh_row, '^', markerfacecolor='w',
             markeredgecolor='k', markersize=6, mew=0.5, clip_on=False)
    plt.text(triangle_text_x,
             yloc_seventh_row,
             tdict['legend']['instrument'],
             va='center',
             ha='left')

    # Macroseismic
    circle_marker_x = triangle_text_x + item_sep[0]
    circle_text_x = circle_marker_x + label_pad
    plt.plot(circle_marker_x,
             yloc_seventh_row, 'o',
             markerfacecolor='w',
             markeredgecolor='k',
             markersize=4,
             mew=0.5)
    plt.text(circle_text_x,
             yloc_seventh_row,
             tdict['legend']['intensity'],
             va='center',
             ha='left')

    # Epicenter
    star_marker_x = circle_marker_x + item_sep[1]
    star_text_x = star_marker_x + label_pad
    plt.plot(star_marker_x,
             yloc_seventh_row, 'k*',
             markersize=12,
             mew=0.5)
    plt.text(star_text_x,
             yloc_seventh_row,
             tdict['legend']['epicenter'],
             va='center',
             ha='left')

    if not point_source:
        rup_marker_x = star_marker_x + item_sep[2]
        rup_text_x = rup_marker_x + label_pad
        rwidth = 0.02
        rheight = 0.05
        rup = patches.Rectangle(
            xy=(rup_marker_x - rwidth,
                yloc_seventh_row-0.5*rheight),
            width=rwidth,
            height=rheight,
            linewidth=2,
            edgecolor='k',
            facecolor='w'
        )
        cax.add_patch(rup)
        plt.text(rup_text_x,
                 yloc_seventh_row,
                 tdict['legend']['rupture'],
                 va='center',
                 ha='left')

    # Add conversion reference and shakemap version/process time
    version_x = 1.0
    tpl = (tdict['legend']['version'], map_version,
           tdict['legend']['processed'], process_time)
    plt.text(version_x, yloc_sixth_row,
             '%s %i: %s %s' % tpl,
             ha='right', va='center')

    ref = gmice.name
    refx = 0
    plt.text(refx, yloc_sixth_row,
             '%s %s' % (tdict['legend']['scale'], ref),
             va='center')

    nsteps = 10
    for i, width in enumerate(tdict['mmi_scale']['box_widths']):
        width /= 100
        textleft = sumwidth + width/2
        sumwidth += width
        plt.text(textleft, yloc_first_row,
                 tdict['mmi_scale']['shaking_labels'][i],
                 fontproperties=font1, **alignment)
        plt.text(textleft, yloc_second_row,
                 tdict['mmi_scale']['damage_labels'][i],
                 fontproperties=font1, **alignment)
        plt.text(textleft, yloc_third_row, acceleration[i],
                 fontproperties=font1, **alignment)
        plt.text(textleft, yloc_fourth_row, velocity[i],
                 fontproperties=font1, **alignment)

        if i == 0:
            font = font1
        else:
            font = font0
        th = plt.text(textleft, yloc_fifth_row,
                      tdict['mmi_scale']['intensity_labels'][i],
                      fontproperties=font, **alignment)
        th.set_path_effects([path_effects.Stroke(linewidth=2.0,
                                                 foreground='white'),
                             path_effects.Normal()])

        # draw right edge of cell
        plt.plot([gridleft+width, gridleft+width],
                 [bottom, top], 'k', clip_on=False)  # right

        # draw little colored rectangles inside the MMI cells
        if i > 0:
            left = gridleft
            ptop = yloc_fourth_line
            imt_min = imt_edges[i-1]
            imt_max = imt_edges[i]
            imts = np.linspace(imt_min, imt_max, nsteps)
            rights = np.linspace(gridleft, gridleft+width, nsteps)
            for mmi, right in zip(imts, rights):
                px = [left, right, right, left, left]
                py = [ptop, ptop, bottom, bottom, ptop]
                mmicolor = palette.getDataColor(mmi, color_format='hex')
                left = right
                plt.fill(px, py, mmicolor, ec=mmicolor)

        gridleft += width
예제 #4
0
def create_info(event_dir,
                lsmodels=None,
                lqmodels=None,
                eventsource='',
                eventsourcecode='',
                point=True):
    """Create info.json for ground failure product.

    Args:
        event_dir (srt): Directory containing ground failure results.
        lsmodels (list): List of dictionaries of model summary info compiled
            by the hazdev function. If not specified, code will search for
            the hdf5 files for the preferred model and will create this
            dictionary and will apply default colorbars and bins.
        lqmodels (list): Same as above for liquefaction.
        point (bool): if True, event is a point source and warning should be
            displayed

    Returns:
        creates info.json for this event
    """
    filenames = []
    # Find the shakemap grid.xml file
    with open(os.path.join(event_dir, 'shakefile.txt'), 'r') as f:
        shakefile = f.read()

    files = os.listdir(event_dir)

    if lsmodels is None and lqmodels is None:

        # Read in the "preferred" model for landslides and liquefaction
        ls_mod_file = [f2 for f2 in files if 'jessee_2017.hdf5' in f2]
        if len(ls_mod_file) == 1:
            ls_file = os.path.join(event_dir, ls_mod_file[0])
            ls_mod = loadlayers(ls_file)
            # get extents
            lsext = get_zoomextent(ls_mod['model']['grid'])
        else:
            raise OSError("Preferred landslide model result not found.")
        lq_mod_file = [f2 for f2 in files if 'zhu_2017_general.hdf5' in f2]
        if len(lq_mod_file) == 1:
            lq_file = os.path.join(event_dir, lq_mod_file[0])
            lq_mod = loadlayers(lq_file)
            # get extents
            lqext = get_zoomextent(lq_mod['model']['grid'])
        else:
            raise OSError("Preferred liquefaction model result not found.")

        # Read in extents
        ls_extent_file = [
            f2 for f2 in files if 'jessee_2017_extent.json' in f2
        ]
        if len(ls_extent_file) == 1:
            ls_file = os.path.join(event_dir, ls_extent_file[0])
            with open(ls_file) as f:
                jessee_extent = json.load(f)
        else:
            raise OSError("Landslide extent not found.")
        lq_extent_file = [
            f2 for f2 in files if 'zhu_2017_general_extent.json' in f2
        ]
        if len(lq_extent_file) == 1:
            lq_file = os.path.join(event_dir, lq_extent_file[0])
            with open(lq_file) as f:
                zhu_extent = json.load(f)
        else:
            raise OSError("Liquefaction extent not found.")

        # Read in default paths to get location of the population grid
        default_file = os.path.join(os.path.expanduser('~'), '.gfail_defaults')
        defaults = ConfigObj(default_file)
        pop_file = defaults['popfile']

        # Landslide alert statistics
        ls_stats = computeStats(ls_mod['model']['grid'],
                                probthresh=None,
                                shakefile=shakefile,
                                shakethresh=10.0,
                                shakethreshtype='pga',
                                statprobthresh=None,
                                pop_file=pop_file)

        # Liquefaction alert statistics
        lq_stats = computeStats(lq_mod['model']['grid'],
                                probthresh=None,
                                shakefile=shakefile,
                                shakethresh=10.0,
                                shakethreshtype='pga',
                                statprobthresh=None,
                                pop_file=pop_file)

        # Get alert levels
        ls_haz_level = ls_stats['hagg_0.10g']
        lq_haz_level = lq_stats['hagg_0.10g']
        ls_pop_level = ls_stats['exp_pop_0.10g']
        lq_pop_level = lq_stats['exp_pop_0.10g']

        # If hazard alert level is less than 0.1, zero it out
        # (due to rounding to 2 sig digits later, this can give
        #  overly precise results, e.g., 0.000012 if we don't clip,
        #  but this doesn't happen with pop alerts because they are
        #  integers)
        if ls_haz_level < 0.1:
            ls_haz_level = 0.0
        if lq_haz_level < 0.1:
            lq_haz_level = 0.0

        # Convert levels into categories
        alert_info = get_alert(ls_haz_level, lq_haz_level, ls_pop_level,
                               lq_pop_level)
        # Unpack info (I think we are now assuming that the statements will be
        # constructed on the website and so we don't need them here)
        ls_haz_alert, ls_pop_alert, lq_haz_alert, lq_pop_alert, \
            ls_alert, lq_alert = alert_info

        if lsmodels is None:
            lsmodels = [{
                'id': 'nowicki_jessee_2017',
                'title': 'Nowicki Jessee and others (2017)',
                'overlay': 'jessee_2017.png',
                'extent': jessee_extent,
                'units': "Proportion of area affected",
                'preferred': True,
                'alert': ls_alert,
                'hazard_alert': {
                    'color': ls_haz_alert,
                    'value': set_num_precision(ls_haz_level, 2, 'float'),
                    'parameter': 'Aggregate Hazard',
                    'units': 'km^2'
                },
                'population_alert': {
                    'color': ls_pop_alert,
                    'value': set_num_precision(ls_pop_level, 2, 'int'),
                    'parameter': 'Population exposure',
                    'units': 'people'
                },
                'probability': {
                    'max': float("%.2f" % ls_stats['Max']),
                    'std': float("%.2f" % ls_stats['Std']),
                    'hagg0.1g': float("%.2f" % ls_stats['hagg_0.10g']),
                    'popexp0.1g': float("%.2f" % ls_stats['exp_pop_0.10g'])
                }
            }]
        if lqmodels is None:
            lqmodels = [{
                'id': 'zhu_2017',
                'title': 'Zhu and others (2017)',
                'overlay': 'zhu_2017.png',
                'extent': zhu_extent,
                'units': "Proportion of area affected",
                'preferred': True,
                'alert': lq_alert,
                'hazard_alert': {
                    'color': lq_haz_alert,
                    'value': set_num_precision(lq_haz_level, 2, 'float'),
                    'parameter': 'Aggregate Hazard',
                    'units': 'km^2'
                },
                'population_alert': {
                    'color': lq_pop_alert,
                    'value': set_num_precision(lq_pop_level, 2, 'int'),
                    'parameter': 'Population exposure',
                    'units': 'people'
                },
                'probability': {
                    'max': float("%.2f" % lq_stats['Max']),
                    'std': float("%.2f" % lq_stats['Std']),
                    'hagg0.1g': float("%.2f" % ls_stats['hagg_0.10g']),
                    'popexp0.1g': float("%.2f" % ls_stats['exp_pop_0.10g'])
                }
            }]
    else:
        # Get all info from dictionaries of preferred events, add in extent
        # and filename
        for lsm in lsmodels:
            # Add extent and filename for preferred model
            if lsm['preferred']:
                filesnippet = lsm['id']
                # Read in extents
                flnm = '%s_extent.json' % filesnippet
                ls_extent_file = [f for f in files if flnm in f]
                if len(ls_extent_file) == 1:
                    ls_file = os.path.join(event_dir, ls_extent_file[0])
                    with open(ls_file) as f:
                        ls_extent = json.load(f)
                else:
                    raise OSError("Landslide extent not found.")
                lsm['extent'] = ls_extent
                # lsm['filename'] = flnm
                lsext = lsm['zoomext']  # Get zoom extent
                ls_alert = lsm['alert']
                rmkeys = ['bin_edges', 'bin_colors', 'zoomext']
            else:
                # Remove any alert keys
                rmkeys = [
                    'bin_edges', 'bin_colors', 'zoomext', 'population_alert',
                    'alert', 'hazard_alert'
                ]
            for key in rmkeys:
                if key in lsm:
                    lsm.pop(key)

        for lqm in lqmodels:
            if lqm['preferred']:
                filesnippet = lqm['id']
                # Read in extents
                flnm = '%s_extent.json' % filesnippet
                lq_extent_file = [f2 for f2 in files if flnm in f2]
                if len(lq_extent_file) == 1:
                    lq_file = os.path.join(event_dir, lq_extent_file[0])
                    with open(lq_file) as f:
                        lq_extent = json.load(f)
                else:
                    raise OSError("Liquefaction extent not found.")
                lqm['extent'] = lq_extent
                # lqm['filename'] = flnm
                lqext = lqm['zoomext']  # Get zoom extent
                lq_alert = lqm['alert']
                rmkeys = ['bin_edges', 'bin_colors', 'zoomext']
            else:
                # Remove any alert keys
                rmkeys = [
                    'bin_edges', 'bin_colors', 'zoomext', 'population_alert',
                    'alert', 'hazard_alert'
                ]
            for key in rmkeys:
                if key in lqm:
                    lqm.pop(key)

    # Try to get event info
    shake_grid = ShakeGrid.load(shakefile, adjust='res')
    event_dict = shake_grid.getEventDict()
    sm_dict = shake_grid.getShakeDict()
    base_url = 'https://earthquake.usgs.gov/earthquakes/eventpage/'

    # Is this a point source?
    # point = is_grid_point_source(shake_grid)
    # Temporarily hard code this until we can get a better solution via
    # new grid.xml attributes.
    #point = True

    net = eventsource
    code = eventsourcecode
    time = event_dict['event_timestamp'].strftime('%Y-%m-%dT%H:%M:%SZ')

    event_url = '%s%s%s#executive' % (base_url, net, code)

    # Get extents that work for both unless one is green and the other isn't
    if lq_alert == 'green' and ls_alert != 'green' and ls_alert is not None:
        xmin = lsext['xmin']
        xmax = lsext['xmax']
        ymin = lsext['ymin']
        ymax = lsext['ymax']
    elif lq_alert != 'green' and ls_alert == 'green' and lq_alert is not None:
        xmin = lqext['xmin']
        xmax = lqext['xmax']
        ymin = lqext['ymin']
        ymax = lqext['ymax']
    else:
        xmin = np.min((lqext['xmin'], lsext['xmin']))
        xmax = np.max((lqext['xmax'], lsext['xmax']))
        ymin = np.min((lqext['ymin'], lsext['ymin']))
        ymax = np.max((lqext['ymax'], lsext['ymax']))

    # Should we display the warning about point source?
    rupture_warning = False
    if point and event_dict['magnitude'] > 6.5:
        rupture_warning = True

    # Create info.json for website rendering and metadata purposes
    info_dict = {
        'Summary': {
            'code': code,
            'net': net,
            'magnitude': event_dict['magnitude'],
            'depth': event_dict['depth'],
            'time': time,
            'lat': event_dict['lat'],
            'lon': event_dict['lon'],
            'event_url': event_url,
            'shakemap_version': sm_dict['shakemap_version'],
            'rupture_warning': rupture_warning,
            'point_source': point,
            'zoom_extent': [xmin, xmax, ymin, ymax]
        },
        'Landslides': lsmodels,
        'Liquefaction': lqmodels
    }

    info_file = os.path.join(event_dir, 'info.json')
    with open(info_file, 'w') as f:
        json.dump(info_dict, f)  # allow_nan=False)
    filenames.append(info_file)
    return filenames
예제 #5
0
def hazdev(maplayerlist,
           configs,
           shakemap,
           outfolder=None,
           alpha=0.7,
           shakethreshtype='pga',
           probthresh=None,
           shakethresh=10.,
           prefLS='Nowicki Jessee and others (2017)',
           prefLQ='Zhu and others (2017)',
           pop_file=None,
           defaultcolors=True,
           point=True,
           pager_alert='',
           eventsource='',
           eventsourcecode=''):
    """Create all files needed for product page creation
    Assumes gfail has been run already with -w flag

    Args:
        maplayerlist (list): List of model outputs from gfail.
        configs (list): List of dictionaries of config files corresponding to
            each model in maplayerlist and in the same order.
        shakemap (str): path to shakemap .xml file.
        outfolder (str): Location in which to save outputs. If None, will use
            current directory.
        alpha (float): Transparency to use for overlay pngs, value from 0 to 1.
        shakethreshtype (str): Type of ground motion to use for shakethresh,
            'pga', 'pgv', or 'mmi'.
        probthresh: Optional. Float or list of probability thresholds to apply
            before computing stats.
        shakethresh: Float or list of shaking thresholds in %g for pga, cm/s
            for pgv, float for mmi. Used for Hagg and Exposure computation.
        prefLS (str): shortref of "preferred" landslide model.
        prefLQ (str): shortref of "preferred" liquefaction model.
        pop_filt (str): file path to population file used to compute
            population-based alert levels.
        defaultcolors (bool): If True, will use DFCOLORS for all layers instead
            of determining new ones. This will crash if any of the layers have
            a different number of bins than the number of DFCOLORS
        point (bool): if True, event is a point source and warning should be
            displayed
        pager_alert (str): PAGER alert level, e.g., 'green'. 'pending', ...

    Returns:
        Files that need to be sent to comcat for hazdev to create the product
            webpage including:
                - info.json
                - transparent png overlays of all models
    """
    event_id = maplayerlist[0]['model']['description']['event_id']

    if pop_file is None:
        # Read in default paths to get location of the population grid
        default_file = os.path.join(os.path.expanduser('~'), '.gfail_defaults')
        defaults = ConfigObj(default_file)
        pop_file = defaults['popfile']

    if outfolder is None:
        outfolder = os.path.join(os.getcwd(), event_id)

    filenames = []

    # Separate the LS and LQ models

    concLS = []
    concLQ = []

    lsmodels = []
    lqmodels = []
    logLS = []
    limLS = []
    colLS = []
    logLQ = []
    limLQ = []
    colLQ = []

    for conf, maplayer in zip(configs, maplayerlist):
        mdict = maplayer['model']['description']
        # config = ConfigObj(conf)

        if 'landslide' in mdict['parameters']['modeltype'].lower():
            title = maplayer['model']['description']['name']
            plotorder, logscale, lims, colormaps, maskthreshes = \
                parseConfigLayers(maplayer, conf, keys=['model'])
            logLS.append(logscale[0])
            limLS.append(lims[0])
            colLS.append(colormaps[0])
            concLS.append(title)

            if 'godt' in maplayer['model']['description']['name'].lower():
                statprobthresh = None
                id1 = 'godt_2008'
                maxP = 1.
            else:
                # Since logistic models can't equal one, need to eliminate
                # placeholder zeros before computing stats
                if 'jessee' in maplayer['model']['description']['name'].lower(
                ):
                    id1 = 'jessee_2017'
                    statprobthresh = 0.002
                    maxP = 0.26
                else:
                    id1 = 'nowicki_2014_global'
                    statprobthresh = 0.0
                    maxP = 1.

            if 'std' in list(maplayer.keys()):
                stdgrid2D = maplayer['std']['grid']
            else:
                stdgrid2D = None

            stats = computeStats(maplayer['model']['grid'],
                                 stdgrid2D=stdgrid2D,
                                 probthresh=probthresh,
                                 shakefile=shakemap,
                                 shakethresh=shakethresh,
                                 statprobthresh=statprobthresh,
                                 pop_file=pop_file,
                                 shakethreshtype=shakethreshtype,
                                 stdtype='mean',
                                 maxP=maxP)

            metadata = maplayer['model']['description']
            if len(maplayer) > 1:
                inputs = {}
                inkeys = list(maplayer.keys())
                for key in inkeys:
                    if key != 'model':
                        newkey = maplayer[key]['label']
                        inputs[newkey] = maplayer[key]['description']
                metadata['inputs'] = inputs

            if title == prefLS:
                on = True
                ls_haz_alert, ls_pop_alert, _, _, ls_alert, _ = get_alert(
                    stats['hagg_0.10g'], 0., stats['exp_pop_0.10g'], 0.)
                lsext = get_zoomextent(maplayer['model']['grid'])
                ls_haz_value = set_num_precision(stats['hagg_0.10g'], 2,
                                                 'float')
                ls_pop_value = set_num_precision(stats['exp_pop_0.10g'], 2,
                                                 'int')
            else:
                on = False
                ls_haz_alert = None
                ls_pop_alert = None
                ls_haz_value = None
                ls_pop_value = None
                ls_alert = None
                lsext = None

            ls_haz_std = None
            ls_pop_std = None
            ls_hlim = None
            ls_elim = None
            ls_hp = None
            ls_hq = None
            ls_ep = None
            ls_eq = None

            if stdgrid2D is not None and title == prefLS:
                ls_haz_std = float("%.4f" % stats['hagg_std_0.10g'])
                ls_pop_std = float("%.4f" % stats['exp_std_0.10g'])
                ls_hlim = float("%.4f" % stats['hlim_0.10g'])
                ls_elim = float("%.4f" % stats['elim_0.10g'])
                ls_hp = float("%.4f" % stats['p_hagg_0.10g'])
                ls_hq = float("%.4f" % stats['q_hagg_0.10g'])
                ls_ep = float("%.4f" % stats['p_exp_0.10g'])
                ls_eq = float("%.4f" % stats['q_exp_0.10g'])

            edict = {
                'id': id1,
                'title': metadata['name'],
                'overlay': '%s.png' % id1,
                'extent': '%s_extent.json' % id1,
                'units': metadata['units'],
                'preferred': on,
                'alert': ls_alert,
                'hazard_alert': {
                    'color': ls_haz_alert,
                    'value': ls_haz_value,
                    'std': ls_haz_std,
                    'parameter': 'Aggregate Hazard',
                    'units': 'km^2'
                },
                'population_alert': {
                    'color': ls_pop_alert,
                    'value': ls_pop_value,
                    'std': ls_pop_std,
                    'parameter': 'Population exposure',
                    'units': 'people'
                },
                'bin_edges': list(lims[0]),
                'probability': {
                    'max': float("%.2f" % stats['Max']),
                    'std': float("%.2f" % stats['Std']),
                    'hagg0.1g': float("%.2f" % stats['hagg_0.10g']),
                    'popexp0.1g': float("%.2f" % stats['exp_pop_0.10g'], ),
                    'hagg0.1g_std': ls_haz_std,
                    'popexp0.1g_std': ls_pop_std,
                    'hlim0.1g': ls_hlim,
                    'elim0.1g': ls_elim,
                    'p_hagg': ls_hp,
                    'q_hagg': ls_hq,
                    'p_exp': ls_ep,
                    'q_exp': ls_eq
                },
                'longref': metadata['longref'],
                'parameters': metadata['parameters'],
                'zoomext': lsext
            }

            lsmodels.append(edict)

        elif 'liquefaction' in mdict['parameters']['modeltype'].lower():
            title = maplayer['model']['description']['name']
            plotorder, logscale, lims, colormaps, maskthreshes = \
                parseConfigLayers(maplayer, conf, keys=['model'])
            logLQ.append(logscale[0])
            limLQ.append(lims[0])
            colLQ.append(colormaps[0])
            concLQ.append(title)

            if '2015' in maplayer['model']['description']['name'].lower():
                id1 = 'zhu_2015'
                statprobthresh = 0.0
                maxP = 1.
            elif '2017' in maplayer['model']['description']['name'].lower():
                id1 = 'zhu_2017_general'
                statprobthresh = 0.005
                maxP = 0.487

            if 'std' in list(maplayer.keys()):
                stdgrid2D = maplayer['std']['grid']
            else:
                stdgrid2D = None

            stats = computeStats(maplayer['model']['grid'],
                                 stdgrid2D=stdgrid2D,
                                 probthresh=probthresh,
                                 shakefile=shakemap,
                                 shakethresh=shakethresh,
                                 pop_file=pop_file,
                                 shakethreshtype=shakethreshtype,
                                 statprobthresh=statprobthresh,
                                 stdtype='mean',
                                 maxP=maxP)

            metadata = maplayer['model']['description']
            if len(maplayer) > 1:
                inputs = {}
                inkeys = list(maplayer.keys())
                for key in inkeys:
                    if key != 'model':
                        newkey = maplayer[key]['label']
                        inputs[newkey] = maplayer[key]['description']
                metadata['inputs'] = inputs

            if title == prefLQ:
                on = True
                _, _, lq_haz_alert, lq_pop_alert, _, lq_alert = get_alert(
                    0., stats['hagg_0.10g'], 0., stats['exp_pop_0.10g'])
                lqext = get_zoomextent(maplayer['model']['grid'])
                lq_haz_value = set_num_precision(stats['hagg_0.10g'], 2,
                                                 'float')
                lq_pop_value = set_num_precision(stats['exp_pop_0.10g'], 2,
                                                 'int')

            else:
                on = False
                lq_haz_alert = None
                lq_pop_alert = None
                lq_haz_value = None
                lq_pop_value = None
                lq_alert = None
                lqext = None

            lq_haz_std = None
            lq_pop_std = None
            lq_hlim = None
            lq_elim = None
            lq_hp = None
            lq_hq = None
            lq_ep = None
            lq_eq = None

            if stdgrid2D is not None and title == prefLQ:
                lq_haz_std = float("%.2f" % stats['hagg_std_0.10g'])
                lq_pop_std = float("%.2f" % stats['exp_std_0.10g'])
                lq_hlim = float("%.4f" % stats['hlim_0.10g'])
                lq_elim = float("%.4f" % stats['elim_0.10g'])
                lq_hp = float("%.4f" % stats['p_hagg_0.10g'])
                lq_hq = float("%.4f" % stats['q_hagg_0.10g'])
                lq_ep = float("%.4f" % stats['p_exp_0.10g'])
                lq_eq = float("%.4f" % stats['q_exp_0.10g'])

            edict = {
                'id': id1,
                'title': metadata['name'],
                'overlay': '%s.png' % id1,
                'extent': '%s_extent.json' % id1,
                'units': metadata['units'],
                'preferred': on,
                'alert': lq_alert,
                'hazard_alert': {
                    'color': lq_haz_alert,
                    'value': lq_haz_value,
                    'std': lq_haz_std,
                    'parameter': 'Aggregate Hazard',
                    'units': 'km^2'
                },
                'population_alert': {
                    'color': lq_pop_alert,
                    'value': lq_pop_value,
                    'std': lq_pop_std,
                    'parameter': 'Population exposure',
                    'units': 'people'
                },
                'bin_edges': list(lims[0]),
                'probability': {
                    'max': float("%.2f" % stats['Max']),
                    'std': float("%.2f" % stats['Std']),
                    'hagg0.1g': float("%.2f" % stats['hagg_0.10g']),
                    'popexp0.1g': float("%.2f" % stats['exp_pop_0.10g']),
                    'hagg0.1g_std': lq_haz_std,
                    'popexp0.1g_std': lq_pop_std,
                    'hlim0.1g': lq_hlim,
                    'elim0.1g': lq_elim,
                    'p_hagg': lq_hp,
                    'q_hagg': lq_hq,
                    'p_exp': lq_ep,
                    'q_exp': lq_eq
                },
                'longref': metadata['longref'],
                'parameters': metadata['parameters'],
                'zoomext': lqext
            }

            lqmodels.append(edict)

        else:
            raise Exception("model type is undefined, check "
                            "maplayer['model']['parameters']"
                            "['modeltype'] to ensure it is defined")

    if defaultcolors:
        for ls in lsmodels:
            ls['bin_colors'] = DFCOLORS
        for lq in lqmodels:
            lq['bin_colors'] = DFCOLORS

    else:
        defaultcolormap = cm.CMRmap_r

        # Get colors and stuff into dictionaries
        sync, colorlistLS, reflims = setupsync(prefLS,
                                               concLS,
                                               limLS,
                                               colLS,
                                               defaultcolormap,
                                               logscale=logLS,
                                               alpha=alpha)

        if reflims is None:
            raise Exception('Check input config files, they must all have the '
                            'same number of bin edges')
        else:
            # Stuff colors into dictionary
            for ls in lsmodels:
                ls['bin_colors'] = list(colorlistLS)

        sync, colorlistLQ, reflims = setupsync(prefLQ,
                                               concLQ,
                                               limLQ,
                                               colLQ,
                                               defaultcolormap,
                                               logscale=logLQ,
                                               alpha=alpha)

        if reflims is None:
            raise Exception('Check input config files, they must all have the '
                            'same number of bin edges')
        else:
            # Stuff colors into dictionary
            for lq in lqmodels:
                lq['bin_colors'] = list(colorlistLQ)

    # Create pngs
    pngfiles = create_png(outfolder, lsmodels, lqmodels)
    filenames.append(pngfiles)

    # If PAGER alert is pending, overwrite our alerts
    if pager_alert == 'pending':
        for ls in lsmodels:
            ls['alert'] = 'pending'
            ls['hazard_alert']['color'] = 'pending'
            ls['population_alert']['color'] = 'pending'
        for lq in lqmodels:
            lq['alert'] = 'pending'
            lq['hazard_alert']['color'] = 'pending'
            lq['population_alert']['color'] = 'pending'

    # Create info.json
    infojson = create_info(outfolder, lsmodels, lqmodels, eventsource,
                           eventsourcecode, point)
    filenames.append(infojson)

    return filenames