Ejemplo n.º 1
0
def arc_wksp_setup():
    """Setup ArcPy workspace"""
    arcpy.env.overwriteOutput = True
    arcpy.env.cellSize = "MAXOF"  # Setting to default. For batch runs.
    if arcpy.Exists(cc_env.out_dir):
        cc_util.delete_features(cc_env.out_dir)
    arcpy.env.workspace = cc_util.mk_proj_dir(cc_env.out_dir)
    arcpy.env.scratchWorkspace = cc_util.mk_proj_dir(cc_env.tmp_dir)
Ejemplo n.º 2
0
def arc_wksp_setup():
    """Setup ArcPy workspace"""
    arcpy.env.overwriteOutput = True
    arcpy.env.cellSize = "MAXOF"  # Setting to default. For batch runs.
    if arcpy.Exists(cc_env.out_dir):
        cc_util.delete_features(cc_env.out_dir)
    arcpy.env.workspace = cc_util.mk_proj_dir(cc_env.out_dir)
    arcpy.env.scratchWorkspace = cc_util.mk_proj_dir(cc_env.tmp_dir)
Ejemplo n.º 3
0
def grass_cwd(core_list):
    """Creating CWD and Back rasters using GRASS r.walk function"""
    cur_path = subprocess.Popen("echo %PATH%",
                                stdout=subprocess.PIPE,
                                shell=True).stdout.read()
    gisdbase = os.path.join(cc_env.proj_dir, "gwksp")

    ccr_grassrc = os.path.join(cc_env.proj_dir, "ccr_grassrc")
    climate_asc = os.path.join(cc_env.out_dir, "cc_climate.asc")
    resist_asc = os.path.join(cc_env.out_dir, "cc_resist.asc")
    core_asc = os.path.join(cc_env.out_dir, "cc_cores.asc")
    climate_lyr = "climate"
    resist_lyr = "resist"
    core_lyr = "cores"

    try:
        lm_util.gprint("\nRUNNING GRASS TO CREATE COST-WEIGHTED DISTANCE "
                       "RASTERS")

        # Convert input GRID rasters to ASCII
        lm_util.gprint("Converting ARCINFO GRID rasters to ASCII")
        # Note: consider moving these to main:
        arcpy.RasterToASCII_conversion(cc_env.prj_climate_rast, climate_asc)
        arcpy.RasterToASCII_conversion(cc_env.prj_resist_rast, resist_asc)
        arcpy.RasterToASCII_conversion(cc_env.prj_core_rast, core_asc)

        # Create resource file and setup workspace
        write_grassrc(ccr_grassrc, gisdbase)

        setup_wrkspace(gisdbase, ccr_grassrc, climate_asc)

        # Make cwd folder for Linkage Mapper
        lm_util.make_cwd_paths(max(core_list))

        # Import files into GRASS
        lm_util.gprint("Importing raster files into GRASS")
        run_grass_cmd("r.in.arc", input=climate_asc, output=climate_lyr)
        run_grass_cmd("r.in.arc", input=resist_asc, output=resist_lyr)
        run_grass_cmd("r.in.arc", input=core_asc, output=core_lyr)

        # Generate CWD and Back rasters
        gen_cwd_back(core_list, climate_lyr, resist_lyr, core_lyr)

    except Exception:
        raise
    finally:
        os.environ['PATH'] = cur_path  # Revert to original windows path
        if not cc_util.remove_grass_wkspc(gisdbase):
            arcpy.AddWarning("Unable to delete temporary GRASS folder. "
                             "Program will contine.")
        cc_util.delete_features(
            [climate_asc, resist_asc, core_asc, ccr_grassrc])
Ejemplo n.º 4
0
def delete_proj_files():
    """Delete project input files on ending of analysis

    Keep prj_resist_rast, prj_core_fc and out_dir for reruns.

    """
    cpath = os.getcwd()  # For files left behind by arcpy
    prj_files = (
        [cc_env.prj_climate_rast, cc_env.prj_core_rast, cc_env.tmp_dir,
         os.path.join(cpath, ".prj"), os.path.join(cpath, "info")])
    if cc_env.simplify_cores:
        prj_files.append(cc_env.core_simp)
    cc_util.delete_features(prj_files)
Ejemplo n.º 5
0
def grass_cwd(core_list):
    """Creating CWD and Back rasters using GRASS r.walk function"""
    cur_path = subprocess.Popen("echo %PATH%", stdout=subprocess.PIPE,
                                shell=True).stdout.read()
    gisdbase = os.path.join(cc_env.proj_dir, "gwksp")

    ccr_grassrc = os.path.join(cc_env.proj_dir, "ccr_grassrc")
    climate_asc = os.path.join(cc_env.out_dir, "cc_climate.asc")
    resist_asc = os.path.join(cc_env.out_dir, "cc_resist.asc")
    core_asc = os.path.join(cc_env.out_dir, "cc_cores.asc")
    climate_lyr = "climate"
    resist_lyr = "resist"
    core_lyr = "cores"

    try:
        lm_util.gprint("\nRUNNING GRASS TO CREATE COST-WEIGHTED DISTANCE "
                       "RASTERS")

        # Convert input GRID rasters to ASCII
        lm_util.gprint("Converting ARCINFO GRID rasters to ASCII")
        # Note: consider moving these to main:
        arcpy.RasterToASCII_conversion(cc_env.prj_climate_rast, climate_asc)
        arcpy.RasterToASCII_conversion(cc_env.prj_resist_rast, resist_asc)
        arcpy.RasterToASCII_conversion(cc_env.prj_core_rast, core_asc)

        # Create resource file and setup workspace
        write_grassrc(ccr_grassrc, gisdbase)

        setup_wrkspace(gisdbase, ccr_grassrc, climate_asc)

        # Make cwd folder for Linkage Mapper
        lm_util.make_cwd_paths(max(core_list))

        # Import files into GRASS
        lm_util.gprint("Importing raster files into GRASS")
        run_grass_cmd("r.in.arc", input=climate_asc, output=climate_lyr)
        run_grass_cmd("r.in.arc", input=resist_asc, output=resist_lyr)
        run_grass_cmd("r.in.arc", input=core_asc, output=core_lyr)

        # Generate CWD and Back rasters
        gen_cwd_back(core_list, climate_lyr, resist_lyr, core_lyr)

    except Exception:
        raise
    finally:
        os.environ['PATH'] = cur_path  # Revert to original windows path
        if not cc_util.remove_grass_wkspc(gisdbase):
            arcpy.AddWarning("Unable to delete temporary GRASS folder. "
                             "Program will contine.")
        cc_util.delete_features(
            [climate_asc, resist_asc, core_asc, ccr_grassrc])
Ejemplo n.º 6
0
def grass_cwd(core_list):
    """Creating CWD and Back rasters using GRASS r.walk function"""
    gisdbase = os.path.join(cc_env.proj_dir, "gwksp")

    ccr_grassrc = os.path.join(cc_env.proj_dir, "ccr_grassrc")
    climate_asc = os.path.join(cc_env.out_dir, "cc_climate.asc")
    resist_asc = os.path.join(cc_env.out_dir, "cc_resist.asc")
    core_asc = os.path.join(cc_env.out_dir, "cc_cores.asc")
    climate_lyr = "climate"
    resist_lyr = "resist"
    core_lyr = "cores"

    try:
        lm_util.gprint("\nRUNNING GRASS TO CREATE COST-WEIGHTED DISTANCE "
                       "RASTERS")

        # Convert input GRID rasters to ASCII
        lm_util.gprint("Converting ARCINFO GRID rasters to ASCII")
        arcpy.RasterToASCII_conversion(cc_env.prj_climate_rast, climate_asc)
        arcpy.RasterToASCII_conversion(cc_env.prj_resist_rast, resist_asc)
        arcpy.RasterToASCII_conversion(cc_env.prj_core_rast, core_asc)

        # Create resource file and setup workspace
        start_path = os.environ["PATH"]
        os.environ["PATH"] = cc_env.gpath
        write_grassrc(ccr_grassrc, gisdbase)
        setup_wrkspace(gisdbase, ccr_grassrc, climate_asc)

        # Make cwd folder for Linkage Mapper
        lm_util.make_cwd_paths(max(core_list))

        # Import files into GRASS
        lm_util.gprint("Importing raster files into GRASS")
        run_grass_cmd("r.in.gdal", input=climate_asc, output=climate_lyr)
        run_grass_cmd("r.in.gdal", input=resist_asc, output=resist_lyr)
        run_grass_cmd("r.in.gdal", input=core_asc, output=core_lyr)

        # Generate CWD and Back rasters
        gen_cwd_back(core_list, climate_lyr, resist_lyr, core_lyr)

    except Exception:
        raise
    finally:
        os.environ["PATH"] = start_path
        if not cc_util.remove_grass_wkspc(gisdbase):
            lm_util.warn("Unable to delete temporary GRASS folder. "
                             "Program will contine.")
        cc_util.delete_features(
            [climate_asc, resist_asc, core_asc, ccr_grassrc])
Ejemplo n.º 7
0
def delete_proj_files():
    """Delete project input files on ending of analysis

    Keep prj_resist_rast, prj_core_fc and out_dir for reruns.

    """
    cpath = os.getcwd()  # For files left behind by arcpy
    prj_files = ([
        cc_env.prj_climate_rast, cc_env.prj_core_rast, cc_env.tmp_dir,
        os.path.join(cpath, ".prj"),
        os.path.join(cpath, "info")
    ])
    if cc_env.simplify_cores:
        prj_files.append(cc_env.core_simp)
    cc_util.delete_features(prj_files)
Ejemplo n.º 8
0
def limit_cores(pair_tbl, stats_tbl):
    """Limit core pairs based upon climate threshold"""
    pair_vw = "dist_tbvw"
    stats_vw = "stats_tbvw"
    core_id = cc_env.core_fld.upper()

    try:
        lm_util.gprint("\nLIMITING CORE PAIRS BASED UPON CLIMATE "
                       "THRESHOLD")

        arcpy.MakeTableView_management(pair_tbl, pair_vw)
        arcpy.MakeTableView_management(stats_tbl, stats_vw)

        # Add basic stats to distance table
        lm_util.gprint("Joining zonal statistics to pairings table")
        add_stats(stats_vw, core_id, "fr", pair_vw, TO_COL)
        add_stats(stats_vw, core_id, "to", pair_vw, FR_COL)

        # Calculate difference of 2 std
        lm_util.gprint("Calculating difference of 2 std")
        diffu_2std = "diffu_2std"
        arcpy.AddField_management(pair_vw, diffu_2std, "Float", "", "",
                                  "", "", "NULLABLE")
        arcpy.CalculateField_management(pair_vw, diffu_2std,
                                        "abs(!frumin2std! - !toumin2std!)",
                                        "PYTHON")

        # Filter distance table based on inputed threshold and delete rows
        lm_util.gprint("Filtering table based on threshold")
        diffu2std_fld = arcpy.AddFieldDelimiters(pair_vw, diffu_2std)
        expression = diffu2std_fld + " <= " + str(cc_env.climate_threshold)
        arcpy.SelectLayerByAttribute_management(pair_vw, "NEW_SELECTION",
                                                expression)
        rows_del = int(arcpy.GetCount_management(pair_vw).getOutput(0))
        if rows_del > 0:
            arcpy.DeleteRows_management(pair_vw)
        lm_util.gprint(str(rows_del) + " rows deleted")

    except Exception:
        raise
    finally:
        cc_util.delete_features([stats_vw, pair_vw])
Ejemplo n.º 9
0
def limit_cores(pair_tbl, stats_tbl):
    """Limit core pairs based upon climate threshold"""
    pair_vw = "dist_tbvw"
    stats_vw = "stats_tbvw"
    core_id = cc_env.core_fld.upper()

    try:
        lm_util.gprint("\nLIMITING CORE PAIRS BASED UPON CLIMATE " "THRESHOLD")

        arcpy.MakeTableView_management(pair_tbl, pair_vw)
        arcpy.MakeTableView_management(stats_tbl, stats_vw)

        # Add basic stats to distance table
        lm_util.gprint("Joining zonal statistics to pairings table")
        add_stats(stats_vw, core_id, "fr", pair_vw, TO_COL)
        add_stats(stats_vw, core_id, "to", pair_vw, FR_COL)

        # Calculate difference of 2 std
        lm_util.gprint("Calculating difference of 2 std")
        diffu_2std = "diffu_2std"
        arcpy.AddField_management(pair_vw, diffu_2std, "Float", "", "", "", "",
                                  "NULLABLE")
        arcpy.CalculateField_management(pair_vw, diffu_2std,
                                        "abs(!frumin2std! - !toumin2std!)",
                                        "PYTHON_9.3")

        # Filter distance table based on inputed threshold and delete rows
        lm_util.gprint("Filtering table based on threshold")
        diffu2std_fld = arcpy.AddFieldDelimiters(pair_vw, diffu_2std)
        expression = diffu2std_fld + " <= " + str(cc_env.climate_threshold)
        arcpy.SelectLayerByAttribute_management(pair_vw, "NEW_SELECTION",
                                                expression)
        rows_del = int(arcpy.GetCount_management(pair_vw).getOutput(0))
        if rows_del > 0:
            arcpy.DeleteRows_management(pair_vw)
        lm_util.gprint(str(rows_del) + " rows deleted")

    except Exception:
        raise
    finally:
        cc_util.delete_features([stats_vw, pair_vw])
Ejemplo n.º 10
0
def create_lnk_tbl(corefc, core_pairs, frm_cores):
    """Create link table file and limit based on near table results"""
    fcore_vw = "fcore_vw"
    tcore_vw = "tcore_vw"
    jtocore_fn = cc_env.core_fld[:8] + "_1"  # dbf field length
    near_tbl = os.path.join(cc_env.out_dir, "neartbl.dbf")
    link_file = os.path.join(lm_env.DATAPASSDIR, "linkTable_s2.csv")

    link_tbl, srow, srows = None, None, None

    try:
        link_tbl = open(link_file, 'wb')
        writer = csv.writer(link_tbl, delimiter=',')
        headings = [
            "# link", "coreId1", "coreId2", "cluster1", "cluster2", "linkType",
            "eucDist", "lcDist", "eucAdj", "cwdAdj"
        ]
        writer.writerow(headings)

        core_list = set()
        no_cores = str(len(frm_cores))
        i = 1

        coreid_fld = arcpy.AddFieldDelimiters(corefc, cc_env.core_fld)

        for core_no, frm_core in enumerate(frm_cores):
            # From cores
            expression = coreid_fld + " = " + frm_core
            arcpy.MakeFeatureLayer_management(corefc, fcore_vw, expression)

            # To cores
            to_cores_lst = [x[1] for x in core_pairs if frm_core == x[0]]
            to_cores = ', '.join(to_cores_lst)
            expression = coreid_fld + " in (" + to_cores + ")"
            arcpy.MakeFeatureLayer_management(corefc, tcore_vw, expression)
            lm_util.gprint("Calculating Euclidean distance/s from Core " +
                           frm_core + " to " + str(len(to_cores_lst)) +
                           " other cores" + " (" + str(core_no + 1) + "/" +
                           no_cores + ")")

            # Generate near table for these core pairings
            arcpy.GenerateNearTable_analysis(fcore_vw, tcore_vw, near_tbl,
                                             cc_env.max_euc_dist,
                                             "NO_LOCATION", "NO_ANGLE", "ALL")

            # Join near table to core table
            arcpy.JoinField_management(near_tbl, "IN_FID", corefc, "FID",
                                       cc_env.core_fld)
            arcpy.JoinField_management(near_tbl, "NEAR_FID", corefc, "FID",
                                       cc_env.core_fld)

            # Limit pairings based on inputed Euclidean distances
            srow, srows = None, None
            euc_dist_fld = arcpy.AddFieldDelimiters(near_tbl, "NEAR_DIST")
            expression = (euc_dist_fld + " > " + str(cc_env.min_euc_dist))
            srows = arcpy.SearchCursor(near_tbl, expression, "",
                                       jtocore_fn + "; NEAR_DIST",
                                       jtocore_fn + " A; NEAR_DIST A")

            # Process near table and output into a link table
            srow = srows.next()
            if srow:
                core_list.add(int(frm_core))
                while srow:
                    to_coreid = srow.getValue(jtocore_fn)
                    dist_value = srow.getValue("NEAR_DIST")
                    writer.writerow([
                        i, frm_core, to_coreid, -1, -1, 1, dist_value, -1, -1,
                        -1
                    ])
                    core_list.add(to_coreid)
                    srow = srows.next()
                    i += 1

    except Exception:
        raise
    finally:
        cc_util.delete_features(
            [near_tbl, os.path.splitext(corefc)[0] + "_Pnt.shp"])
        if link_tbl:
            link_tbl.close()
        if srow:
            del srow
        if srows:
            del srows

    return core_list
Ejemplo n.º 11
0
def cc_copy_inputs():
    """Clip Climate Linkage Mapper inputs to smallest extent"""
    ext_poly = os.path.join(cc_env.out_dir, "ext_poly.shp")  # Extent polygon
    try:
        lm_util.gprint("\nCOPYING LAYERS AND, IF NECESSARY, REDUCING EXTENT")
        if not arcpy.Exists(cc_env.inputs_gdb):
            arcpy.CreateFileGDB_management(os.path.dirname(cc_env.inputs_gdb),
                                           os.path.basename(cc_env.inputs_gdb))
        climate_extent = arcpy.Raster(cc_env.climate_rast).extent

        if cc_env.resist_rast is not None:
            resist_extent = arcpy.Raster(cc_env.resist_rast).extent
            xmin = max(climate_extent.XMin, resist_extent.XMin)
            ymin = max(climate_extent.YMin, resist_extent.YMin)
            xmax = min(climate_extent.XMax, resist_extent.XMax)
            ymax = min(climate_extent.YMax, resist_extent.YMax)

            # Set to minimum extent if resistance raster was given
            arcpy.env.extent = arcpy.Extent(xmin, ymin, xmax, ymax)

            # Want climate and resistance rasters in same spatial ref
            # with same nodata cells
            proj_resist_rast = sa.Con(sa.IsNull(cc_env.climate_rast),
                                      sa.Int(cc_env.climate_rast),
                                      cc_env.resist_rast)
            proj_resist_rast.save(cc_env.prj_resist_rast)
        else:
            xmin = climate_extent.XMin
            ymin = climate_extent.YMin
            xmax = climate_extent.XMax
            ymax = climate_extent.YMax

            ones_resist_rast = sa.Con(sa.IsNull(cc_env.climate_rast),
                                      sa.Int(cc_env.climate_rast), 1)
            ones_resist_rast.save(cc_env.prj_resist_rast)

        arcpy.CopyRaster_management(cc_env.climate_rast,
                                    cc_env.prj_climate_rast)

        # Create core raster
        arcpy.env.extent = arcpy.Extent(xmin, ymin, xmax, ymax)
        lm_util.delete_data(cc_env.prj_core_rast)
        arcpy.FeatureToRaster_conversion(
            cc_env.core_fc, cc_env.core_fld, cc_env.prj_core_rast,
            arcpy.Describe(cc_env.climate_rast).MeanCellHeight)
        arcpy.env.extent = None

        # Create array of boundary points
        array = arcpy.Array()
        pnt = arcpy.Point(xmin, ymin)
        array.add(pnt)
        pnt = arcpy.Point(xmax, ymin)
        array.add(pnt)
        pnt = arcpy.Point(xmax, ymax)
        array.add(pnt)
        pnt = arcpy.Point(xmin, ymax)
        array.add(pnt)
        # Add in the first point of the array again to close polygon boundary
        array.add(array.getObject(0))
        # Create a polygon geometry object using the array object
        ext_feat = arcpy.Polygon(array)
        arcpy.CopyFeatures_management(ext_feat, ext_poly)
        # Clip core feature class
        arcpy.Clip_analysis(cc_env.core_fc, ext_poly, cc_env.prj_core_fc)
    except Exception:
        raise
    finally:
        cc_util.delete_features(ext_poly)
Ejemplo n.º 12
0
def create_lnk_tbl(corefc, core_pairs, frm_cores):
    """Create link table file and limit based on near table results"""
    fcore_vw = "fcore_vw"
    tcore_vw = "tcore_vw"
    jtocore_fn = cc_env.core_fld[:8] + "_1"  # dbf field length
    near_tbl = os.path.join(cc_env.out_dir, "neartbl.dbf")
    link_file = os.path.join(lm_env.DATAPASSDIR, "linkTable_s2.csv")

    link_tbl, srow, srows = None, None, None

    try:
        link_tbl = open(link_file, 'wb')
        writer = csv.writer(link_tbl, delimiter=',')
        headings = ["# link", "coreId1", "coreId2", "cluster1", "cluster2",
                    "linkType", "eucDist", "lcDist", "eucAdj", "cwdAdj"]
        writer.writerow(headings)

        core_list = set()
        no_cores = str(len(frm_cores))
        i = 1

        coreid_fld = arcpy.AddFieldDelimiters(corefc, cc_env.core_fld)

        for core_no, frm_core in enumerate(frm_cores):
            # From cores
            expression = coreid_fld + " = " + frm_core
            arcpy.MakeFeatureLayer_management(corefc, fcore_vw, expression)

            # To cores
            to_cores_lst = [x[1] for x in core_pairs if frm_core == x[0]]
            to_cores = ', '.join(to_cores_lst)
            expression = coreid_fld + " in (" + to_cores + ")"
            arcpy.MakeFeatureLayer_management(corefc, tcore_vw, expression)
            lm_util.gprint("Calculating Euclidean distance/s from Core "
                           + frm_core + " to " + str(len(to_cores_lst))
                           + " other cores" + " (" + str(core_no + 1) + "/"
                           + no_cores + ")")

            # Generate near table for these core pairings
            arcpy.GenerateNearTable_analysis(
                fcore_vw, tcore_vw, near_tbl,
                cc_env.max_euc_dist, "NO_LOCATION", "NO_ANGLE", "ALL")

            # Join near table to core table
            arcpy.JoinField_management(near_tbl, "IN_FID", corefc,
                                       "FID", cc_env.core_fld)
            arcpy.JoinField_management(near_tbl, "NEAR_FID", corefc,
                                       "FID", cc_env.core_fld)

            # Limit pairings based on inputed Euclidean distances
            srow, srows = None, None
            euc_dist_fld = arcpy.AddFieldDelimiters(near_tbl, "NEAR_DIST")
            expression = (euc_dist_fld + " > " + str(cc_env.min_euc_dist))
            srows = arcpy.SearchCursor(near_tbl, expression, "",
                                       jtocore_fn + "; NEAR_DIST",
                                       jtocore_fn + " A; NEAR_DIST A")

            # Process near table and output into a link table
            srow = srows.next()
            if srow:
                core_list.add(int(frm_core))
                while srow:
                    to_coreid = srow.getValue(jtocore_fn)
                    dist_value = srow.getValue("NEAR_DIST")
                    writer.writerow([i, frm_core, to_coreid, -1, -1, 1,
                                     dist_value, -1, -1, -1])
                    core_list.add(to_coreid)
                    srow = srows.next()
                    i += 1

    except Exception:
        raise
    finally:
        cc_util.delete_features(
            [near_tbl, os.path.splitext(corefc)[0] + "_Pnt.shp"])
        if link_tbl:
            link_tbl.close()
        if srow:
            del srow
        if srows:
            del srows

    return core_list
Ejemplo n.º 13
0
def cc_copy_inputs():
    """Clip Climate Linkage Mapper inputs to smallest extent"""
    ext_poly = os.path.join(cc_env.out_dir, "ext_poly.shp")  # Extent polygon
    try:
        lm_util.gprint("\nCOPYING LAYERS AND, IF NECESSARY, REDUCING EXTENT")
        if not arcpy.Exists(cc_env.inputs_gdb):
            arcpy.CreateFileGDB_management(os.path.dirname(cc_env.inputs_gdb),
                                           os.path.basename(cc_env.inputs_gdb))
        climate_extent = arcpy.Raster(cc_env.climate_rast).extent

        if cc_env.resist_rast is not None:
            resist_extent = arcpy.Raster(cc_env.resist_rast).extent
            xmin = max(climate_extent.XMin, resist_extent.XMin)
            ymin = max(climate_extent.YMin, resist_extent.YMin)
            xmax = min(climate_extent.XMax, resist_extent.XMax)
            ymax = min(climate_extent.YMax, resist_extent.YMax)

            # Set to minimum extent if resistance raster was given
            arcpy.env.extent = arcpy.Extent(xmin, ymin, xmax, ymax)
            # Want climate and resistance rasters in same spatial ref
            # with same nodata cells
            proj_resist_rast = sa.Con(
                sa.IsNull(cc_env.climate_rast),
                sa.Int(cc_env.climate_rast), cc_env.resist_rast)
            proj_resist_rast.save(cc_env.prj_resist_rast)
        else:
            xmin = climate_extent.XMin
            ymin = climate_extent.YMin
            xmax = climate_extent.XMax
            ymax = climate_extent.YMax
            # Copying to gdb avoids gdal conflict later with ascii conversion
            ones_resist_rast = sa.Con(
                sa.IsNull(cc_env.climate_rast),
                sa.Int(cc_env.climate_rast), 1)
            ones_resist_rast.save(cc_env.prj_resist_rast)

        arcpy.CopyRaster_management(cc_env.climate_rast,
                                    cc_env.prj_climate_rast)

        # Create core raster
        arcpy.env.extent = arcpy.Extent(xmin, ymin, xmax, ymax)
        lm_util.delete_data(cc_env.prj_core_rast)
        arcpy.FeatureToRaster_conversion(
            cc_env.core_fc, cc_env.core_fld,
            cc_env.prj_core_rast,
            arcpy.Describe(cc_env.climate_rast).MeanCellHeight)
        arcpy.env.extent = None

        # Create array of boundary points
        array = arcpy.Array()
        pnt = arcpy.Point(xmin, ymin)
        array.add(pnt)
        pnt = arcpy.Point(xmax, ymin)
        array.add(pnt)
        pnt = arcpy.Point(xmax, ymax)
        array.add(pnt)
        pnt = arcpy.Point(xmin, ymax)
        array.add(pnt)
        # Add in the first point of the array again to close polygon boundary
        array.add(array.getObject(0))
        # Create a polygon geometry object using the array object
        ext_feat = arcpy.Polygon(array)
        arcpy.CopyFeatures_management(ext_feat, ext_poly)
        # Clip core feature class
        arcpy.Clip_analysis(cc_env.core_fc, ext_poly, cc_env.prj_core_fc)
    except Exception:
        raise
    finally:
        cc_util.delete_features(ext_poly)