Exemple #1
0
          [1.537,  4.238,   4.15,   17.05],
          [1.757,  4.387,    5.2,   24.03],
          [1.976,  4.497,   6.27,   32.02],
          [2.196,  4.606,   7.37,   40.86],
          [2.415,  4.716,   8.49,   50.51],
          [2.635,  4.826,   9.63,   60.94],
          [3.771, 63.882,  86.79,  311.2],
          [4.907, 71.162, 163.46,  747.96],
          [6.043, 78.442, 248.35, 1356.32],
          [7.179, 83.771, 340.12, 2146.83],
          [8.315, 91.541, 438.68, 3060.87],
          ]

# add the reach info to the subbasin

subbasin.add_reach(name, maxelev, minelev, slopelen, ftable = ftable)

# subbasin land use info (to create perlnds and implnds)

landuse_names = ['FOREST', 'ROWCRP', 'GRASS', 'Developed']
areas         = [4428.9,     641.63,  776.87,      120.18]  # acres

# fraction of developed land that is impervious (assume all impervious land)

ifraction = 1.

# add the landuse

subbasin.add_landuse(1988, landuse_names, areas)

# create a dictionary of the subbasins
Exemple #2
0
def build_watershed(subbasinfile, flowfile, outletfile, damfile, gagefile,
                    landfile, aggregatefile, VAAfile, years, HUC8, output, 
                    plots = True, overwrite = False, format = 'png'):

    # create a dictionary to store subbasin data

    subbasins = {}

    # create a dictionary to keep track of subbasin inlets

    inlets = {}

    # read in the flow plane data into an instance of the FlowPlane class

    sf = Reader(subbasinfile, shapeType = 5)

    comid_index = sf.fields.index(['ComID',      'N',  9, 0]) - 1
    len_index   = sf.fields.index(['PlaneLenM',  'N',  8, 2]) - 1
    slope_index = sf.fields.index(['PlaneSlope', 'N',  9, 6]) - 1
    area_index  = sf.fields.index(['AreaSqKm',   'N', 10, 2]) - 1
    cx_index    = sf.fields.index(['CenX',       'N', 12, 6]) - 1
    cy_index    = sf.fields.index(['CenY',       'N', 12, 6]) - 1
    elev_index  = sf.fields.index(['AvgElevM',   'N',  8, 2]) - 1

    for record in sf.records():
        comid     = '{}'.format(record[comid_index])
        length    = record[len_index]
        slope     = record[slope_index]
        tot_area  = record[area_index]
        centroid  = [record[cx_index], record[cy_index]]
        elevation = record[elev_index]

        subbasin  = Subbasin(comid)
        subbasin.add_flowplane(length, slope, 0, centroid, elevation)

        subbasins[comid] = subbasin

    # read in the flowline data to an instance of the Reach class

    sf = Reader(flowfile)

    outcomid_index   = sf.fields.index(['OutComID',   'N',  9, 0]) - 1
    gnis_index       = sf.fields.index(['GNIS_NAME',  'C', 65, 0]) - 1
    reach_index      = sf.fields.index(['REACHCODE',  'C',  8, 0]) - 1
    incomid_index    = sf.fields.index(['InletComID', 'N',  9, 0]) - 1
    maxelev_index    = sf.fields.index(['MaxElev',    'N',  9, 2]) - 1
    minelev_index    = sf.fields.index(['MinElev',    'N',  9, 2]) - 1
    slopelen_index   = sf.fields.index(['SlopeLenKM', 'N',  6, 2]) - 1
    slope_index      = sf.fields.index(['Slope',      'N',  8, 5]) - 1
    inflow_index     = sf.fields.index(['InFlowCFS',  'N',  8, 3]) - 1
    outflow_index    = sf.fields.index(['OutFlowCFS', 'N',  8, 3]) - 1
    velocity_index   = sf.fields.index(['VelFPS',     'N',  7, 4]) - 1
    traveltime_index = sf.fields.index(['TravTimeHR', 'N',  8, 2]) - 1

    for record in sf.records():

        outcomid   = '{}'.format(record[outcomid_index])
        gnis       = record[gnis_index]
        reach      = record[reach_index]
        incomid    = '{}'.format(record[incomid_index])
        maxelev    = record[maxelev_index] / 100
        minelev    = record[minelev_index] / 100
        slopelen   = record[slopelen_index]
        slope      = record[slope_index]
        inflow     = record[inflow_index]
        outflow    = record[outflow_index]
        velocity   = record[velocity_index]
        traveltime = record[traveltime_index]

        if isinstance(gnis, bytes): gnis = ''

        subbasin = subbasins[outcomid]

        flow = (inflow + outflow) / 2
        subbasin.add_reach(gnis, maxelev, minelev, slopelen, flow = flow, 
                           velocity = velocity, traveltime = traveltime)
        inlets[outcomid] = incomid

    # open up the outlet file and see if the subbasin has a gage or dam

    sf = Reader(outletfile)

    records = sf.records()

    comid_index = sf.fields.index(['COMID',   'N',  9, 0]) - 1
    nid_index   = sf.fields.index(['NIDID',   'C',  7, 0]) - 1
    nwis_index  = sf.fields.index(['SITE_NO', 'C', 15, 0]) - 1

    nids = {'{}'.format(r[comid_index]):r[nid_index] for r in records 
            if isinstance(r[nid_index], str)}

    nwiss = {'{}'.format(r[comid_index]):r[nwis_index] for r in records 
             if r[nwis_index] is not None}

    # open up the dam file and read in the information for the dams

    sf = Reader(damfile)

    records = sf.records()

    name_index  = sf.fields.index(['DAM_NAME',   'C', 65,   0]) - 1
    nid_index   = sf.fields.index(['NIDID',      'C', 7,    0]) - 1
    long_index  = sf.fields.index(['LONGITUDE',  'N', 19,  11]) - 1
    lat_index   = sf.fields.index(['LATITUDE',   'N', 19,  11]) - 1
    river_index = sf.fields.index(['RIVER',      'C', 65,   0]) - 1
    owner_index = sf.fields.index(['OWN_NAME',   'C', 65,   0]) - 1
    type_index  = sf.fields.index(['DAM_TYPE',   'C', 10,   0]) - 1
    purp_index  = sf.fields.index(['PURPOSES',   'C', 254,  0]) - 1
    year_index  = sf.fields.index(['YR_COMPL',   'C', 10,   0]) - 1
    high_index  = sf.fields.index(['NID_HEIGHT', 'N', 19,  11]) - 1
    mstor_index = sf.fields.index(['MAX_STOR',   'N', 19,  11]) - 1
    nstor_index = sf.fields.index(['NORMAL_STO', 'N', 19,  11]) - 1
    area_index  = sf.fields.index(['SURF_AREA',  'N', 19,  11]) - 1

    # iterate through the subbasins and see if they have a dam

    for comid, subbasin in subbasins.items():

        if comid in nids:

            # if the subbasin has a dam, find the data info in the file

            nid = nids[comid]

            r = records[[r[nid_index] for r in records].index(nid)]

            subbasin.add_dam(nid,
                             r[name_index],
                             r[long_index],
                             r[lat_index],
                             r[river_index],
                             r[owner_index],
                             r[type_index],
                             r[purp_index],
                             r[year_index],
                             r[high_index],
                             r[mstor_index],
                             r[nstor_index],
                             r[area_index]
                             )

    # open up the aggregate file to get the landuse group map

    m, landtypes, groups = get_aggregate_map(aggregatefile)

    # convert to a list of landuse names

    names = [landtypes[group] for group in groups]

    # read the land use data for each year into the subbasins

    with open(landfile, 'rb') as f: landyears, landuse = pickle.load(f)

    for comid in subbasins:

        subbasin      = subbasins[comid]
        subbasin_data = landuse[comid]

        for year, data in zip(landyears, zip(*subbasin_data)):

            subbasin.add_landuse(year, names, data)

    # create an instance of the watershed class

    watershed = Watershed(HUC8, subbasins)

    # open up the flowline VAA file to use to establish mass linkages

    with open(VAAfile, 'rb') as f: flowlines = pickle.load(f)
            
    # create a dictionary to connect the comids to hydroseqs

    hydroseqs = {'{}'.format(flowlines[f].comid): 
                 flowlines[f].hydroseq for f in flowlines}

    # establish the mass linkages using a dictionary "updown" and a list of 
    # head water subbasins

    updown = {}
    
    for comid, subbasin in watershed.subbasins.items():

        # get the flowline instance for the outlet comid

        flowline = flowlines[hydroseqs[comid]]

        # check if the subbasin is a watershed inlet or a headwater source

        inlet = hydroseqs[inlets[comid]]

        if flowlines[inlet].up in flowlines:
            i = '{}'.format(flowlines[flowlines[inlet].up].comid)
            subbasin.add_inlet(i)
        elif flowlines[inlet].up != 0:
            watershed.add_inlet(comid)
        else: 
            watershed.add_headwater(comid)

        # check if the subbasin is a watershed outlet, and if it is not, then
        # find the downstream reach

        if flowline.down in flowlines:
            flowline = flowlines[flowline.down]
            while '{}'.format(flowline.comid) not in subbasins:
                flowline = flowlines[flowline.down]
            updown[comid] = '{}'.format(flowline.comid)
        else: 
            updown[comid] = 0
            watershed.add_outlet('{}'.format(comid))

        # open 

    watershed.add_mass_linkage(updown)

    if output is None: 
        filename = os.getcwd() + '/watershed'
        plotname = os.getcwd() + '/masslink.%s' % format
    else:              
        filename = output + '/%s/watershed' % HUC8
        plotname = output + '/%s/images/%smasslink.%s' % (HUC8, HUC8, format)

    if not os.path.isfile(filename) or overwrite:
        with open(filename, 'wb') as f: pickle.dump(watershed, f)

    if not os.path.isfile(plotname) and plots or overwrite and plots: 
        plot_mass_flow(watershed, plotname)
Exemple #3
0
name       = 'dave stream' # something descriptive
maxelev    = 110           # elevation at the top of the reach (m)
minelev    = 100           # elevation at the bottom of the reach (m)
slopelen   = 10            # the reach length (km)

# HSPF uses "FTABLES" to specify the stage-discharge relationship for a reach.
# PyHSPF can estimate the FTABLE using the average flow and velocity, or the
# FTABLE can be specified directly. here the FTABLE for this subbasin reach 
# is generated from average flow and velocity.

flow       = 10            # the inflow (cfs) must use these units
velocity   = 1             # velocity (fps) again must use these units

# add the reach to the subbasin

subbasin.add_reach(name, maxelev, minelev, slopelen, flow = flow, 
                   velocity = velocity)

# here is an alternative set of statements to supply the FTABLE directly.
# An FTABLE consists of 4 columns representing the relationships between
# depth, surface area, volume, and flow for a reach. HSPF does a linear 
# interpolation between the depths in the first column to estimate the 
# other parameters. Up to 18 rows can be used.

#ftable = [[0,0,0,0],
#          [1,1,100,1],
#          ]

#subbasin.add_reach(name, maxelev, minelev, slopelen, ftable = ftable)

# another piece of info needed for the subbasins is the land use (used to 
# subdivide the subbasins into land segments, e.g. soils). so here this subbasin
Exemple #4
0
centroid = [-90, 40]  # long, lat
name = 'stream'  # something descriptive
maxelev = 110  # elevation at the top of the reach (m)
minelev = 100  # elevation at the bottom of the reach (m)
slopelen = 10  # the reach length (km)
flow = 12  # the average flow must be in cfs
velocity = 1  # velocity must be in fps
landuse_names = ['Developed', 'Agriculture', 'Forest']
areas = [20, 40, 40]

# add the data for subbasin 100

subbasin.add_flowplane(length, planeslope, centroid, elev)
subbasin.add_reach(name,
                   maxelev,
                   minelev,
                   slopelen,
                   flow=flow,
                   velocity=velocity)
subbasin.add_landuse(2001, landuse_names, areas)

# add the subbasin to the dictionary of subbasins

subbasins[number] = subbasin

# make another subbasin

number = '101'
subbasin = Subbasin(number)
maxelev = 100
minelev = 90
flow = 12
Exemple #5
0
# the ftable is supplied in the UCI file and replicated here

ftable = [[0.0, 0.0, 0.0, 0.0], [0.22, 0.294, 0.04, 0.11],
          [0.439, 0.588, 0.14, 0.7], [0.659, 0.882, 0.32, 2.04],
          [0.878, 1.176, 0.56, 4.4], [1.098, 1.398, 0.86, 8.16],
          [1.318, 1.534, 1.22, 13.6], [1.537, 1.63, 1.6, 20.46],
          [1.757, 1.688, 2.0, 28.84], [1.976, 1.73, 2.42, 38.42],
          [2.196, 1.772, 2.84, 49.03], [2.415, 1.814, 3.26, 60.61],
          [2.635, 1.856, 3.7, 73.13], [3.771, 24.57, 33.38, 373.44],
          [4.907, 27.368, 62.86, 897.55], [6.043, 30.168, 95.52, 1627.58],
          [7.179, 32.218, 130.82, 2576.2], [8.315, 35.206, 168.72, 3673.04]]

# add the reach info to the subbasin

subbasin.add_reach(name, maxelev, minelev, slopelen, ftable=ftable)

# subbasin land use info (to create perlnds and implnds)

landuse_names = ['Forest', 'Pasture/grass']
areas = [32, 6]

# fraction of developed land that is impervious

ifraction = 1.

# add the landuse

subbasin.add_landuse(1988, landuse_names, areas)

# add the subbasin to the dictionary