コード例 #1
0
ファイル: getRiskMXD.py プロジェクト: affes-dss/FireGUARD
def getRiskMXD(i, is_actuals, run_output, fire, extent, perim, score):
    """!
    Save risk map for given inputs
    @param i Index of simulation date to use
    @param is_actuals Whether or not simulation was run for actual weather
    @param run_output Folder simulation output was saved to
    @param fire Fire simulation was for
    @param extent Extent to use for map
    @param perim Perimeter to display on map
    @param score Score for given day
    @return Path used for saving output with given inputs
    @return MapDocument with opened output
    @return extent Extent that was applied to the map
    """
    logging.debug("Running getRiskMXD() for {}".format(i))
    prefix = 'actuals_' if is_actuals else 'wxshield_'
    map_output = getMapOutput(run_output)
    copyMXD = getRiskMXDName(i, is_actuals, run_output, fire, extent, perim)
    shutil.copyfile(os.path.join(Settings.HOME_DIR, "mxds", "rampart.mxd"),
                    copyMXD)
    theMXD = arcpy.mapping.MapDocument(copyMXD)
    extent, prob = setDayCommon(i, is_actuals, theMXD, run_output, fire, perim,
                                extent)
    prob_input = os.path.join(run_output, prob)
    total_path = os.path.join(
        map_output,
        prob_input.replace(prefix, 'RA_').replace('.asc', '.tif'))
    setDataSource(theMXD, "*Relative Risk*", total_path)
    setText(theMXD, "txtScore", score)
    arcpy.RefreshActiveView()
    theMXD.save()
    return copyMXD, theMXD, extent
コード例 #2
0
def getFuelMXDName(fire_prefix, run_output, fire, extent, perim):
    """!
    Get path to save fuel map for given inputs to
    @param fire_prefix prefix to use for file name
    @param run_output Folder simulation output was saved to
    @param fire Fire simulation was for
    @param extent Extent to use for map
    @param perim Perimeter to display on map
    @return Path to use for saving output with given inputs
    """
    map_output = getMapOutput(run_output)
    return os.path.join(map_output, fire_prefix + "_fuels.mxd")
コード例 #3
0
ファイル: arc_util.py プロジェクト: affes-dss/FireGUARD
def setDayCommon(i, is_actuals, theMXD, run_output, fire, perim, extent):
    """!
    Set common attributes on maps that are for a specific day
    @param i Index of date that map is for
    @param is_actuals Whether or not this is for actual weather
    @param theMXD mxd to apply settings to
    @param run_output Folder that simulation outputs are in
    @param fire Fire that simulation was for
    @param perim Perimeter to show on map
    @param extent Extent to apply to map
    @return Extent after applying to map
    @return Probability contour that was used
    """
    prefix = 'actuals_' if is_actuals else 'wxshield_'
    fire_prefix = fire + "_" + ('actual_' if is_actuals else '')
    probs = [
        x for x in os.listdir(os.path.join(Settings.HOME_DIR, run_output))
        if x.startswith(prefix) and x[-3:] == "asc"
    ]
    day0 = find_day(probs[0]) - 1
    jds = map(find_day, probs)
    dates = map(find_date, probs)
    days = map(lambda x: x - day0, jds)
    sim_output = readSimOutput(run_output)
    txtSize, txtAssumptions = getSizeAndAssumptions(i, sim_output, days, dates)
    map_output = getMapOutput(run_output)
    f = os.path.join(
        run_output, probs[i].replace(prefix, 'sizes_').replace('.asc', '.csv'))
    size_graph = makeSizeGraphName(f)
    setSourceImage(theMXD, "graph_stats", size_graph)
    prob_source = os.path.join(
        map_output, probs[i].replace(".asc",
                                     "_class_poly.shp").replace("-", "_"))
    low_prob = setDataSource(theMXD, "Low Probability", prob_source)
    gtr10 = setDataSource(theMXD, "> 10%", prob_source)
    df = arcpy.mapping.ListDataFrames(theMXD, "Layers")[0]
    df.spatialReference = arcpy.Describe(prob_source).spatialReference
    if not extent:
        # only set extent based on final map so that they all cover the same area
        #~ extent = gtr10.getSelectedExtent()
        extent = low_prob.getSelectedExtent()
        # HACK: do this here so the same extent gets applied to subsequent maps
        applyExtent(extent, theMXD, df.spatialReference)
        extent = df.extent
    setCommon(theMXD, fire + "\n" + dates[i] + ' - Day ' + str(days[i]),
              txtAssumptions, txtSize, run_output, fire, perim, extent,
              prob_source)
    return df.extent, probs[i]
コード例 #4
0
def getProjectionMXDName(i, is_actuals, run_output, fire, extent, perim):
    """!
    Generate name of mxd to output to when using given parameters
    @param i index of date to use
    @param is_actuals Whether or not this is for actual observations
    @param run_output Folder that output is in
    @param fire Name of fire
    @param extent Extent to set on map
    @param perim Perimeter to use draw on map
    @return Name of mxd that would be output with given parameters
    """
    prefix = 'actuals_' if is_actuals else 'wxshield_'
    fire_prefix = fire + "_" + ('actual_' if is_actuals else '')
    probs = [x for x in os.listdir(os.path.join(Settings.HOME_DIR, run_output)) if x.startswith(prefix) and x[-3:] == "asc"]
    map_output = getMapOutput(run_output)
    dates = map(find_date, probs)
    return os.path.join(map_output, fire_prefix + dates[i] + ".mxd")
コード例 #5
0
ファイル: getRiskMXD.py プロジェクト: affes-dss/FireGUARD
def getRiskMXDName(i, is_actuals, run_output, fire, extent, perim):
    """!
    Get path to save risk map for given inputs to
    @param i Index of simulation date to use
    @param is_actuals Whether or not simulation was run for actual weather
    @param run_output Folder simulation output was saved to
    @param fire Fire simulation was for
    @param extent Extent to use for map
    @param perim Perimeter to display on map
    @return Path to use for saving output with given inputs
    """
    prefix = 'actuals_' if is_actuals else 'wxshield_'
    fire_prefix = fire + "_" + ('actual_' if is_actuals else '')
    probs = [
        x for x in os.listdir(os.path.join(Settings.HOME_DIR, run_output))
        if x.startswith(prefix) and x[-3:] == "asc"
    ]
    map_output = getMapOutput(run_output)
    dates = map(find_date, probs)
    return os.path.join(map_output, fire_prefix + dates[i] + "_risk.mxd")
コード例 #6
0
ファイル: getImpactMXD.py プロジェクト: affes-dss/FireGUARD
def getImpactMXD(fire_prefix, run_output, fire, extent, perim):
    """!
    Save impact map for given inputs
    @param fire_prefix prefix to use for file name
    @param run_output Folder simulation output was saved to
    @param fire Fire simulation was for
    @param extent Extent to use for map
    @param perim Perimeter to display on map
    @return Path used for saving output with given inputs
    @return MapDocument with opened output
    @return extent Extent that was applied to the map
    """
    logging.debug("Called getImpactMXD()")
    sim_output = readSimOutput(run_output)
    map_output = getMapOutput(run_output)
    copyMXD = getImpactMXDName(fire_prefix, run_output, fire, extent, perim)
    shutil.copyfile(os.path.join(Settings.HOME_DIR, "mxds", "impact.mxd"),
                    copyMXD)
    theMXD = arcpy.mapping.MapDocument(copyMXD)
    impact = Settings.RAMPART_MASK.format(
        'high', findSuffix(findFuelRaster(sim_output)))
    setDataSource(theMXD, "*Potential Impact*", impact)
    txtAssumptions = (
        "Potential Impact is based on staff assessment of impact on a 1 - 10 scale,\n"
        "representing the loss from the damage or disruption from various types of RA data\n"
        "burned with a 4000+ kW/m head fire intensity. Each cell is coloured based on the\n"
        "amount and type of RA within it. Potential Impact is the 'worst case'\n"
        "and the risk calculation on subsequent maps is a downscaling of this (e.g., burned\n"
        "with lower fire intensity and/or lower probability). Warning: use with caution and\n"
        "awareness of the assumptions and simplifications. Impact does not include indirect\n"
        "(e.g. smoke) or long-term effects. A hectare must burn in the model to show any risk;\n"
        "limitations of FireSTARR apply. RA may be missing from the GIS database, affecting\n"
        "results.")
    setCommon(theMXD, fire, txtAssumptions, " ", run_output, fire, perim,
              extent, impact)
    arcpy.RefreshActiveView()
    theMXD.save()
    return copyMXD, theMXD
コード例 #7
0
ファイル: mxd.py プロジェクト: affes-dss/FireGUARD
def makeMaps(scenario, run_output, force_maps, hide):
    """!
    @param scenario Scenario to use settings from
    @param run_output Folder where simulation output resides
    @param force_maps Whether or not to force making maps if they already exist
    @param hide Whether or not to show perimeter closest to date on map
    @return Path to final output pdf
    """
    import pdf
    from pdf import makePDF
    perimeters = PerimeterList(scenario.year, scenario.fire)
    sim_output = readSimOutput(run_output)
    startup = find_lines(sim_output, 'Startup indices ')
    startup = startup[0] if (
        len(startup) > 0) else "Startup indices are not valid"
    prefix = 'actuals_' if scenario.actuals_only else 'wxshield_'
    fire_prefix = scenario.fire + "_" + ('actual_'
                                         if scenario.actuals_only else '')
    probs = [
        x for x in os.listdir(os.path.join(Settings.HOME_DIR, run_output))
        if x.startswith(prefix) and x[-3:] == "asc"
    ]
    day0 = find_day(probs[0]) - 1
    jds = map(find_day, probs)
    dates = map(find_date, probs)
    days = map(lambda x: x - day0, jds)
    extent = None
    perim = None
    ensure_dir(scenario.outbase)
    out_dir = os.path.join(scenario.outbase, scenario.fire[:3])
    ensure_dir(out_dir)
    for_time = os.path.basename(scenario.run_output)
    pdf_output = os.path.abspath(
        os.path.join(out_dir, fire_prefix + for_time + ".pdf"))
    copied = os.path.join(scenario.outbase, os.path.basename(pdf_output))
    # HACK: if any one map is required then make them all
    if not (force_maps or not os.path.exists(pdf_output)):
        logging.info("Maps already exist for " + scenario.fire)
        return copied
    for_time = os.path.basename(scenario.run_output)
    mapflag = os.path.join(out_dir,
                           scenario.fire + "_" + for_time + "_mapsinprogress")
    if os.path.exists(mapflag):
        logging.info("Maps already being made for " + scenario.fire)
        return copied
    write_file(os.path.dirname(mapflag), os.path.basename(mapflag), " ")
    map_output = getMapOutput(run_output)
    logging.info("Making maps for " + scenario.fire)
    # HACK: run in parallel but assume this works for now
    wxshield = getWxSHIELDFile(dates[0], scenario.fire, map_output)
    processes = []
    run_what = r'python.exe firestarr\getWxshield.py {} {} {} {} {} "{}"'.format(
        scenario.lat, scenario.lon, dates[0], days[-1], scenario.fire,
        map_output)
    if 'overridden' in startup:
        startup_values = map(lambda x: x.strip(),
                             startup[startup.find('(') + 1:-1].split(','))
        logging.debug(startup_values)
        # HACK: just use known positions for now
        #~ (0.0mm, FFMC 92.0, DMC 59.0, DC 318.0)
        #~ print(startup_values[0][:-2], startup_values[1][5:].strip(), startup_values[2][4:].strip(), startup_values[0][3:].strip())
        apcp = float(startup_values[0][:-2])
        ffmc = float(startup_values[1][5:].strip())
        dmc = float(startup_values[2][4:].strip())
        dc = float(startup_values[3][3:].strip())
        run_what += ' --apcp_0800 {} --ffmc {} --dmc {} --dc {}'.format(
            apcp, ffmc, dmc, dc)
    logging.debug(run_what)
    processes.append(
        start_process(run_what, Settings.PROCESS_FLAGS, Settings.HOME_DIR))
    arcpy.env.overwriteOutput = True
    ensure_dir(os.path.dirname(out_dir))
    ensure_dir(out_dir)
    # keep these until the end so they lock the file names
    mxd_paths = []
    mxd_names = []
    risk_paths = []
    risk_names = []
    scores = []
    txtFuelRaster = find_line(sim_output, 'Fuel raster is ', 'Fuel raster is ')
    suffix = findSuffix(txtFuelRaster)
    env_push()
    png_processes = []
    arcpy.env.scratchWorkspace = ensure_dir(
        arcpy.CreateScratchName(scenario.fire + os.path.basename(run_output),
                                "", "Workspace",
                                arcpy.GetSystemEnvironment('TEMP')))
    for i in reversed(xrange(len(days))):
        f = os.path.join(
            run_output, probs[i].replace(prefix,
                                         'sizes_').replace('.asc', '.csv'))
        run_what = r'python.exe firestarr\plotsize.py "{}" "{}"'.format(
            f, days[i])
        png_processes = [
            start_process(run_what, Settings.PROCESS_FLAGS, Settings.HOME_DIR)
        ] + png_processes
    for i in reversed(xrange(len(days))):
        finish_process(png_processes[i])
        arcpy.env.addOutputsToMap = False
        prob_input = os.path.join(run_output, probs[i])
        c_prob = arcpy.sa.Int(arcpy.sa.Raster(prob_input) * 10)
        shp_class = os.path.join(
            map_output, probs[i].replace(".asc",
                                         "_class_poly.shp").replace("-", "_"))
        # keep getting 'WARNING: Error of opening hash table for code page.' when we save to file plan
        poly = "in_memory\poly"
        logging.debug("Converting to polygon")
        arcpy.RasterToPolygon_conversion(c_prob, poly, "SIMPLIFY")
        del c_prob
        #~ print(shp_class)
        arcpy.CopyFeatures_management(poly, shp_class)
        del poly
        perim = None if hide else perimeters.find_perim(
            scenario.fire, dates[i])
        copyMXD = None
        if len(days) - 1 == i:
            # we need to get the extent from the last map
            copyMXD, theMXD, extent = getProjectionMXD(i,
                                                       scenario.actuals_only,
                                                       scenario.run_output,
                                                       scenario.fire, extent,
                                                       perim)
            run_what = r'python.exe firestarr\saveboth.py "{}" "{}"'.format(
                copyMXD, fire_prefix + dates[i] + ".png")
            processes.append(
                start_process(run_what, Settings.PROCESS_FLAGS,
                              Settings.HOME_DIR))
            del theMXD
            run_what = r'python.exe firestarr\assets.py {} "{}" {} "{}" {}'.format(
                i, scenario.run_output, scenario.fire, extent, prefix)
        else:
            copyMXD = getProjectionMXDName(i, scenario.actuals_only,
                                           scenario.run_output, scenario.fire,
                                           extent, perim)
            run_what = r'python.exe firestarr\getProjectionMXD.py {} "{}" {} "{}"'.format(
                i, scenario.run_output, scenario.fire, extent)
            if scenario.actuals_only:
                run_what += ' --actuals'
            if perim:
                run_what += ' --perim "{}"'.format(perim)
        processes.append(
            start_process(run_what, Settings.PROCESS_FLAGS, Settings.HOME_DIR))
        mxd_paths = [copyMXD] + mxd_paths
        mxd_names = [fire_prefix + dates[i] + ".png"] + mxd_names
        start_raster = os.path.join(run_output, scenario.fire + '.tif')
        fire_raster = None
        if os.path.exists(start_raster):
            fire_raster = arcpy.sa.Raster(start_raster)
        # need to make sure the extent is the same for all rasters or they don't add properly
        env_push()
        setSnapAndExtent(prob_input)

        def by_intensity(intensity):
            letter = intensity.upper()[0]
            prob_i = os.path.join(
                run_output,
                prob_input.replace(prefix, 'intensity_{}_'.format(letter)))
            ra = Settings.RAMPART_MASK.format(intensity, suffix)
            logging.debug(prob_i)
            raster = arcpy.sa.Int(
                arcpy.sa.Raster(prob_i) * arcpy.sa.Raster(ra))
            if fire_raster is not None:
                # don't count anything in the starting perimeter
                # HACK: will not consider fires that start from just a size
                raster = arcpy.sa.Con(arcpy.sa.IsNull(fire_raster), raster, 0)
            raster = arcpy.sa.Con(arcpy.sa.IsNull(raster), 0, raster)
            return raster

        low_raster = by_intensity('low')
        moderate_raster = by_intensity('moderate')
        high_raster = by_intensity('high')
        total_raster = low_raster + moderate_raster + high_raster
        total_raster = arcpy.sa.SetNull(0 == total_raster, total_raster)
        total_path = os.path.join(
            map_output,
            prob_input.replace(prefix, 'RA_').replace('.asc', '.tif'))
        total_raster.save(total_path)
        del low_raster
        del moderate_raster
        del high_raster
        score = arcpy.RasterToNumPyArray(total_raster, nodata_to_value=0).sum()
        # .58 so that 10 for social & economic gives a 10 total score
        score = fixK(score / 1000000.0 / 0.58)
        env_pop()
        run_what = r'python.exe firestarr\getRiskMXD.py {} "{}" {} "{}" "{}"'.format(
            i, scenario.run_output, scenario.fire, extent, score)
        if scenario.actuals_only:
            run_what += ' --actuals'
        if perim:
            run_what += ' --perim "{}"'.format(perim)
        processes.append(
            start_process(run_what, Settings.PROCESS_FLAGS, Settings.HOME_DIR))
        copyMXD = getRiskMXDName(i, scenario.actuals_only, scenario.run_output,
                                 scenario.fire, extent, perim)
        risk_paths = [copyMXD] + risk_paths
        risk_names = [
            os.path.join(os.path.dirname(copyMXD),
                         fire_prefix + dates[i] + "_risk.png")
        ] + risk_names
        scores = [score] + scores
    env_pop()
    copyMXD = getFuelMXDName(fire_prefix, scenario.run_output, scenario.fire,
                             extent, perim)
    run_what = r'python.exe firestarr\getFuelMXD.py {} "{}" {} "{}"'.format(
        fire_prefix, scenario.run_output, scenario.fire, extent)
    if perim:
        run_what += ' --perim "{}"'.format(perim)
    processes.append(
        start_process(run_what, Settings.PROCESS_FLAGS, Settings.HOME_DIR))
    mxd_paths = [copyMXD] + mxd_paths
    mxd_names = [fire_prefix + "_fuels.png"] + mxd_names
    mxd_names = map(lambda x: os.path.abspath(os.path.join(map_output, x)),
                    mxd_names)
    copyMXD = getImpactMXDName(fire_prefix, scenario.run_output, scenario.fire,
                               extent, perim)
    run_what = r'python.exe firestarr\getImpactMXD.py {} "{}" {} "{}"'.format(
        fire_prefix, scenario.run_output, scenario.fire, extent)
    if perim:
        run_what += ' --perim "{}"'.format(perim)
    processes.append(
        start_process(run_what, Settings.PROCESS_FLAGS, Settings.HOME_DIR))
    risk_paths = [copyMXD] + risk_paths
    risk_names = [
        os.path.join(os.path.dirname(copyMXD), fire_prefix + "_impact.png")
    ] + risk_names
    for process in processes:
        finish_process(process)
    # HACK: put in not generated images for any missing maps
    if len(mxd_names) < 6:
        mxd_names = (
            mxd_names +
            [os.path.join(Settings.HOME_DIR, 'not_generated.png')] * 6)[:6]
    if len(risk_names) < 6:
        risk_names = (
            risk_names +
            [os.path.join(Settings.HOME_DIR, 'not_generated.png')] * 6)[:6]
    logging.debug(mxd_names + [wxshield] + risk_names)
    makePDF(scenario.fire, days, dates, mxd_names, wxshield, risk_names,
            sim_output, pdf_output, scores)
    try_copy(pdf_output, copied)
    # HACK: use known file name for assets
    csv_orig = os.path.abspath(
        os.path.join(run_output, fire_prefix + for_time + "_assets.csv"))
    csv_output = os.path.abspath(
        os.path.join(out_dir, os.path.basename(csv_orig)))
    csv_copied = os.path.join(scenario.outbase, os.path.basename(csv_orig))
    try_copy(csv_orig, csv_output)
    try_copy(csv_orig, csv_copied)
    fixtime(scenario.fire, parse(for_time.replace('_', ' ')),
            [pdf_output, copied, csv_orig, csv_copied])
    try:
        tryForceRemove(mapflag)
    except:
        pass
    # shouldn't need any of these intermediary outputs
    shutil.rmtree(map_output, True)
    return copied