Beispiel #1
0
    def to_sfr(self, roughness=0.037, streambed_thickness=1, streambedK=1,
               icalc=1,
               iupseg=0, iprior=0, nstrpts=0, flow=0, runoff=0, etsw=0, pptsw=0,
               roughch=0, roughbk=0, cdepth=0, fdepth=0, awdth=0, bwdth=0):


        # create a working dataframe
        self.df = self.fl[self.fl_cols].join(self.pfvaa[self.pfvaa_cols], how='inner')

        print '\nclipping flowlines to active area...'
        inside = [g.intersects(self.domain) for g in self.df.geometry]
        self.df = self.df.ix[inside].copy()
        self.df.sort('COMID', inplace=True)
        flowline_geoms = self.df.geometry.tolist()
        grid_geoms = self.grid.geometry.tolist()

        print "intersecting flowlines with grid cells..."
        grid_intersections = GISops.intersect_rtree(grid_geoms, flowline_geoms)

        print "setting up segments..."
        self.list_updown_comids()
        self.assign_segments()
        fl_segments = self.df.segment.tolist()
        fl_comids = self.df.COMID.tolist()

        m1 = make_mat1(flowline_geoms, fl_segments, fl_comids, grid_intersections, grid_geoms)

        print "computing widths..."
        m1['length'] = np.array([g.length for g in m1.geometry])
        lengths = m1[['segment', 'length']].copy()
        groups = lengths.groupby('segment')
        reach_asums = np.concatenate([np.cumsum(grp.length.values[::-1])[::-1] for s, grp in groups])
        segment_asums = np.array([self.df.ArbolateSu.values[s-1] for s in m1.segment.values])
        reach_asums = -1 * self.to_km * reach_asums + segment_asums # arbolate sums are computed in km
        width = width_from_arbolate(reach_asums) # widths are returned in m
        if self.GISunits != 'm':
            width = width / 0.3048
        m1['width'] = width * self.mf_units_mult
        m1['length'] = m1.length * self.mf_units_mult

        m1['roughness'] = roughness
        m1['sbthick'] = streambed_thickness
        m1['sbK'] = streambedK
        m1['sbtop'] = 0

        if self.nrows is not None:
            m1['row'] = np.floor(m1.node / self.ncols) + 1
        if self.ncols is not None:
            column = m1.node.values % self.ncols
            column[column == 0] = self.ncols # last column has remainder of 0
            m1['column'] = column
        m1['layer'] = 1

        self.m1 = m1

        print "setting up Mat2..."
        self.m2 = self.df[['segment', 'outseg']]
        self.m2['icalc'] = icalc
        self.m2.index = self.m2.segment
        print 'Done'
Beispiel #2
0
    def to_sfr(
        self,
        roughness=0.037,
        streambed_thickness=1,
        streambedK=1,
        icalc=1,
        iupseg=0,
        iprior=0,
        nstrpts=0,
        flow=0,
        runoff=0,
        etsw=0,
        pptsw=0,
        roughch=0,
        roughbk=0,
        cdepth=0,
        fdepth=0,
        awdth=0,
        bwdth=0,
    ):

        # create a working dataframe
        self.df = self.fl[self.fl_cols].join(self.pfvaa[self.pfvaa_cols], how="inner")

        print "\nclipping flowlines to active area..."
        inside = [g.intersects(self.domain) for g in self.df.geometry]
        self.df = self.df.ix[inside].copy()
        self.df.sort("COMID", inplace=True)
        flowline_geoms = self.df.geometry.tolist()
        grid_geoms = self.grid.geometry.tolist()

        print "intersecting flowlines with grid cells..."
        grid_intersections = GISops.intersect_rtree(grid_geoms, flowline_geoms)

        print "setting up segments..."
        self.list_updown_comids()
        self.assign_segments()
        fl_segments = self.df.segment.tolist()
        fl_comids = self.df.COMID.tolist()

        m1 = make_mat1(flowline_geoms, fl_segments, fl_comids, grid_intersections, grid_geoms)

        print "computing widths..."
        m1["length"] = np.array([g.length for g in m1.geometry])
        lengths = m1[["segment", "length"]].copy()
        groups = lengths.groupby("segment")
        reach_asums = np.concatenate([np.cumsum(grp.length.values[::-1])[::-1] for s, grp in groups])
        segment_asums = np.array([self.df.ArbolateSu.values[s - 1] for s in m1.segment.values])
        reach_asums = -1 * self.to_km * reach_asums + segment_asums  # arbolate sums are computed in km
        width = width_from_arbolate(reach_asums)  # widths are returned in m
        if self.GISunits != "m":
            width = width / 0.3048
        m1["width"] = width * self.mf_units_mult
        m1["length"] = m1.length * self.mf_units_mult

        m1["roughness"] = roughness
        m1["sbthick"] = streambed_thickness
        m1["sbK"] = streambedK
        m1["sbtop"] = 0

        if self.nrows is not None:
            m1["row"] = np.floor(m1.node / self.ncols) + 1
        if self.ncols is not None:
            column = m1.node.values % self.ncols
            column[column == 0] = self.ncols  # last column has remainder of 0
            m1["column"] = column
        m1["layer"] = 1

        self.m1 = m1

        print "setting up Mat2..."
        self.m2 = self.df[["segment", "outseg"]]
        self.m2["icalc"] = icalc
        self.m2.index = self.m2.segment
        print "Done"
Beispiel #3
0
print 'building UZF package IRUNBND array from {}'.format(MFgrid)
MFgrid_joined = GISio.shp2df(os.path.join(os.getcwd(),
                                          'MFgrid_catchments.shp'),
                             geometry=True)
MFgrid_joined.index = MFgrid_joined.node
nrows, ncols = np.max(MFgrid_joined.row), np.max(MFgrid_joined.column)

# make new column of SFR segment for each grid cell
MFgrid_joined['segment'] = MFgrid_joined.FEATUREID.apply(
    segments_dict.get).fillna(0)

print 'writing {}'.format(out_IRUNBND)
# should add code to allow for a dataframe that only includes a subset of model cells
# (could build a DF of zeros for each cellnum, and then merge with DF containing UZF cells, replacing the zeros for those cells
IRUNBND = np.reshape(MFgrid_joined['segment'].sort_index().values,
                     (nrows, ncols))
np.savetxt(out_IRUNBND, IRUNBND, fmt='%i', delimiter=' ')

print 'writing {}'.format(out_IRUNBND_shp)
#df, shpname, geo_column, prj
GISio.df2shp(MFgrid_joined, os.path.join(os.getcwd(), 'MFgrid_segments.shp'),
             'geometry',
             os.path.join(os.getcwd(), 'MFgrid_catchments.shp')[:-4] + '.prj')

MFgrid_joined_dissolved = GISops.dissolve_df(MFgrid_joined, 'segment')

GISio.df2shp(MFgrid_joined_dissolved,
             os.path.join(os.getcwd(), 'MFgrid_segments_dissolved.shp'),
             'geometry',
             os.path.join(os.getcwd(), 'MFgrid_catchments.shp')[:-4] + '.prj')
    segments_dict[cmt] = segment
    # can also use values_count() to get a frequency table for segments (reaches) in each catchment

print 'building UZF package IRUNBND array from {}'.format(MFgrid)
MFgrid_joined = GISio.shp2df(os.path.join(os.getcwd(), 'MFgrid_catchments.shp'), geometry=True)
MFgrid_joined.index = MFgrid_joined.node
nrows, ncols = np.max(MFgrid_joined.row), np.max(MFgrid_joined.column)

# make new column of SFR segment for each grid cell
MFgrid_joined['segment'] = MFgrid_joined.FEATUREID.apply(segments_dict.get).fillna(0)

print 'writing {}'.format(out_IRUNBND)
# should add code to allow for a dataframe that only includes a subset of model cells
# (could build a DF of zeros for each cellnum, and then merge with DF containing UZF cells, replacing the zeros for those cells
IRUNBND = np.reshape(MFgrid_joined['segment'].sort_index().values, (nrows, ncols))
np.savetxt(out_IRUNBND, IRUNBND, fmt='%i', delimiter=' ')

print 'writing {}'.format(out_IRUNBND_shp)
#df, shpname, geo_column, prj
GISio.df2shp(MFgrid_joined,
             os.path.join(os.getcwd(), 'MFgrid_segments.shp'),
             'geometry',
             os.path.join(os.getcwd(), 'MFgrid_catchments.shp')[:-4]+'.prj')

MFgrid_joined_dissolved = GISops.dissolve_df(MFgrid_joined, 'segment')

GISio.df2shp(MFgrid_joined_dissolved,
             os.path.join(os.getcwd(), 'MFgrid_segments_dissolved.shp'),
             'geometry',
             os.path.join(os.getcwd(), 'MFgrid_catchments.shp')[:-4]+'.prj')
Beispiel #5
0
    def join_SFR_out2streams(self, use_arcpy=True):

        # get model info
        try:
            DX, DY, NLAY, NROW, NCOL, i = disutil.read_meta_data(self.DISfile)
        except:
            raise IOError("Cannot read MODFLOW DIS file {0}".format(self.DISfile))

        print "\naggregating flow information by cellnum..."
        indata = open(self.SFR_out).readlines()
        for line in indata[8:]:
        
            line = line.strip().split()
            
            # Kludge! terminates with blank line (only reads stress per. 1)
            # need to add support for transient.
            if len(line) == 0:
                break

            r, c = int(line[1]), int(line[2])
            cellnum = (r-1)*NCOL + c
            seg_rch = "{0} {1}; ".format(line[3], line[4])
            flow = 0.5 * (float(line[5]) + float(line[7]))
            loss = float(line[6])
            overland = float(line[8])
            stage = float(line[11])
            depth = float(line[12])

            try:
                existingflow = self.flow_by_cellnum[cellnum]
                seg_rch_info = self.seg_rch_by_cellnum[cellnum]
            except KeyError:
                existingflow = 0
                seg_rch_info = 'segs  rchs: '

            # determine state
            if flow == 0:
                state = 'dry'
            elif loss > 0:
                state = 'losing'
            elif loss < 0:
                state = 'gaining'
            else:
                print 'Stream reach in cell {} has flow, but no interaction with aquifer.'.format(cellnum)

            self.flow_by_cellnum[cellnum] = existingflow + flow
            self.seg_rch_by_cellnum[cellnum] = seg_rch_info + seg_rch
            self.loss_by_cellnum[cellnum] = loss
            self.state_by_cellnum[cellnum] = state
            self.overland_by_cellnum[cellnum] = overland
            self.stage_by_cellnum[cellnum] = stage
            self.depth_by_cellnum[cellnum] = depth

        # write to temporary output file
        ofp = open(os.path.join(self.outpath, 'temp.csv'), 'w')
        ofp.write('{},row,column,seg_reach,flow,loss,overland,state,stage,depth\n'.format(self.node_num_attribute))
        for cn in self.flow_by_cellnum.keys():
            ofp.write('{0},{1},{2},"{3}",{4:.6e},{5},{6},{7},{8},{9}\n'.format(cn, 1, 1,
                                                                   self.seg_rch_by_cellnum[cn],
                                                                   self.flow_by_cellnum[cn],
                                                                   self.loss_by_cellnum[cn],
                                                                   self.overland_by_cellnum[cn],
                                                                   self.state_by_cellnum[cn],
                                                                   self.stage_by_cellnum[cn],
                                                                   self.depth_by_cellnum[cn]))
        ofp.close()

        outfile = os.path.join(self.outpath, "{0}.shp".format(self.SFR_out[:-4]))
        if use_arcpy:
            try:
                import arcpy
                import SFR_arcpy
            except:
                print 'module arcpy not found!'

            # make feature/table layers
            arcpy.env.workspace = self.outpath
            arcpy.env.overwriteOutput = True
            arcpy.CopyFeatures_management(self.streams_shp, self.streams_shp[:-4]+'_backup.shp')
            arcpy.MakeFeatureLayer_management(self.streams_shp[:-4]+'_backup.shp', "streams")
            arcpy.CopyRows_management(os.path.join(self.outpath, 'temp.csv'), os.path.join(self.outpath, 'temp.dbf'))


            # drop all fields except for cellnum from stream linework
            Fields = arcpy.ListFields("streams")
            Fields = [f.name for f in Fields if f.name not in ["FID", "Shape", self.node_num_attribute]]
            if len(Fields) > 0:
                arcpy.DeleteField_management("streams", Fields)

            SFR_arcpy.general_join(outfile, "streams", self.node_num_attribute, "temp.dbf", self.node_num_attribute, keep_common=True)

        else:
            import sys
            sys.path.append('../../GIS_utils')
            try:
                import GISops
            except:
                print 'GIS_utils.GISops not found!'
            GISops.join_csv2shp(self.streams_shp, self.node_num_attribute, os.path.join(self.outpath, 'temp.csv'), self.node_num_attribute, outfile, how='inner')
Beispiel #6
0
    def join_SFR_out2streams(self, use_arcpy=True):

        # get model info
        try:
            DX, DY, NLAY, NROW, NCOL, i = disutil.read_meta_data(self.DISfile)
        except:
            raise IOError("Cannot read MODFLOW DIS file {0}".format(
                self.DISfile))

        print "\naggregating flow information by cellnum..."
        indata = open(self.SFR_out).readlines()
        for line in indata[8:]:

            line = line.strip().split()

            # Kludge! terminates with blank line (only reads stress per. 1)
            # need to add support for transient.
            if len(line) == 0:
                break

            r, c = int(line[1]), int(line[2])
            cellnum = (r - 1) * NCOL + c
            seg_rch = "{0} {1}; ".format(line[3], line[4])
            flow = 0.5 * (float(line[5]) + float(line[7]))
            loss = float(line[6])
            overland = float(line[8])
            stage = float(line[11])
            depth = float(line[12])

            try:
                existingflow = self.flow_by_cellnum[cellnum]
                seg_rch_info = self.seg_rch_by_cellnum[cellnum]
            except KeyError:
                existingflow = 0
                seg_rch_info = 'segs  rchs: '

            # determine state
            if flow == 0:
                state = 'dry'
            elif loss > 0:
                state = 'losing'
            elif loss < 0:
                state = 'gaining'
            else:
                print 'Stream reach in cell {} has flow, but no interaction with aquifer.'.format(
                    cellnum)

            self.flow_by_cellnum[cellnum] = existingflow + flow
            self.seg_rch_by_cellnum[cellnum] = seg_rch_info + seg_rch
            self.loss_by_cellnum[cellnum] = loss
            self.state_by_cellnum[cellnum] = state
            self.overland_by_cellnum[cellnum] = overland
            self.stage_by_cellnum[cellnum] = stage
            self.depth_by_cellnum[cellnum] = depth

        # write to temporary output file
        ofp = open(os.path.join(self.outpath, 'temp.csv'), 'w')
        ofp.write(
            '{},row,column,seg_reach,flow,loss,overland,state,stage,depth\n'.
            format(self.node_num_attribute))
        for cn in self.flow_by_cellnum.keys():
            ofp.write('{0},{1},{2},"{3}",{4:.6e},{5},{6},{7},{8},{9}\n'.format(
                cn, 1, 1, self.seg_rch_by_cellnum[cn],
                self.flow_by_cellnum[cn], self.loss_by_cellnum[cn],
                self.overland_by_cellnum[cn], self.state_by_cellnum[cn],
                self.stage_by_cellnum[cn], self.depth_by_cellnum[cn]))
        ofp.close()

        outfile = os.path.join(self.outpath,
                               "{0}.shp".format(self.SFR_out[:-4]))
        if use_arcpy:
            try:
                import arcpy
                import SFR_arcpy
            except:
                print 'module arcpy not found!'

            # make feature/table layers
            arcpy.env.workspace = self.outpath
            arcpy.env.overwriteOutput = True
            arcpy.CopyFeatures_management(
                self.streams_shp, self.streams_shp[:-4] + '_backup.shp')
            arcpy.MakeFeatureLayer_management(
                self.streams_shp[:-4] + '_backup.shp', "streams")
            arcpy.CopyRows_management(os.path.join(self.outpath, 'temp.csv'),
                                      os.path.join(self.outpath, 'temp.dbf'))

            # drop all fields except for cellnum from stream linework
            Fields = arcpy.ListFields("streams")
            Fields = [
                f.name for f in Fields
                if f.name not in ["FID", "Shape", self.node_num_attribute]
            ]
            if len(Fields) > 0:
                arcpy.DeleteField_management("streams", Fields)

            SFR_arcpy.general_join(outfile,
                                   "streams",
                                   self.node_num_attribute,
                                   "temp.dbf",
                                   self.node_num_attribute,
                                   keep_common=True)

        else:
            import sys
            sys.path.append('../../GIS_utils')
            try:
                import GISops
            except:
                print 'GIS_utils.GISops not found!'
            GISops.join_csv2shp(self.streams_shp,
                                self.node_num_attribute,
                                os.path.join(self.outpath, 'temp.csv'),
                                self.node_num_attribute,
                                outfile,
                                how='inner')
Beispiel #7
0
    def to_sfr(self, roughness=0.037, streambed_thickness=1, streambedK=1,
               icalc=1,
               iupseg=0, iprior=0, nstrpts=0, flow=0, runoff=0, etsw=0, pptsw=0,
               roughch=0, roughbk=0, cdepth=0, fdepth=0, awdth=0, bwdth=0):


        # create a working dataframe
        self.df = self.fl[self.fl_cols].join(self.pfvaa[self.pfvaa_cols], how='inner')

        # bring in elevations from elevslope table
        self.df = self.df.join(self.elevs[['Max', 'Min']], how='inner')

        print('\nclipping flowlines to active area...')
        inside = np.array([g.intersects(self.domain) for g in self.df.geometry])
        self.df = self.df.ix[inside].copy()
        self.df.sort_values(by='COMID', inplace=True)
        flowline_geoms = [g.intersection(self.domain) for g in self.df.geometry]
        grid_geoms = self.grid.geometry.tolist()

        print("intersecting flowlines with grid cells...") # this part crawls in debug mode
        grid_intersections = GISops.intersect_rtree(grid_geoms, flowline_geoms)

        print("setting up segments... (may take a few minutes for large networks)")
        ta = time.time()
        self.list_updown_comids()
        self.assign_segments()
        fl_segments = self.df.segment.tolist()
        fl_comids = self.df.COMID.tolist()
        print("finished in {:.2f}s\n".format(time.time() - ta))

        print("setting up reaches and Mat1... (may take a few minutes for large grids)")
        ta = time.time()
        m1 = make_mat1(flowline_geoms, fl_segments, fl_comids, grid_intersections, grid_geoms)
        print("finished in {:.2f}s\n".format(time.time() - ta))

        print("computing widths...")
        m1['length'] = np.array([g.length for g in m1.geometry])
        lengths = m1[['segment', 'length']].copy()
        groups = lengths.groupby('segment')
        # compute arbolate sum at reach midpoints
        reach_asums = np.concatenate([np.cumsum(grp.length.values[::-1])[::-1] - 0.5*grp.length.values
                                      for s, grp in groups])
        segment_asums = np.array([self.df.ArbolateSu.values[s-1] for s in m1.segment.values])
        reach_asums = -1 * self.to_km * reach_asums + segment_asums # arbolate sums are computed in km
        width = width_from_arbolate(reach_asums) # widths are returned in m
        if self.GISunits != 'm':
            width = width / 0.3048

        print("multiplying length units by {} to convert from GIS to MODFLOW...".format(self.mf_units_mult))
        m1['width'] = width * self.mf_units_mult
        m1['length'] = m1.length * self.mf_units_mult

        m1['roughness'] = roughness
        m1['sbthick'] = streambed_thickness
        m1['sbK'] = streambedK
        m1['sbtop'] = 0

        if self.nrows is not None:
            m1['row'] = np.floor(m1.node / self.ncols) + 1
        if self.ncols is not None:
            column = m1.node.values % self.ncols
            column[column == 0] = self.ncols # last column has remainder of 0
            m1['column'] = column
        m1['layer'] = 1

        self.m1 = m1

        print("\nsetting up Mat2...")
        ta = time.time()
        self.m2 = self.df[['segment', 'outseg', 'Max', 'Min']].copy()
        self.m2['icalc'] = icalc
        self.renumber_segments() # enforce best segment numbering
        self.m2.index = self.m2.segment
        print("finished in {:.2f}s\n".format(time.time() - ta))

        # add outseg information to Mat1
        self.m1['outseg'] = [self.m2.outseg[s] for s in self.m1.segment]
        self.m1.sort_values(by=['segment', 'reach'], inplace=True)
        print('\nDone creating SFR dataset.')