示例#1
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)
示例#2
0
文件: intro02.py 项目: djibi2/PyHSPF
# add the landuse

subbasin.add_landuse(1988, landuse_names, areas)

# create a dictionary of the subbasins

subbasins = {sname: subbasin}

# create an updown dictionary for the reach network (trivial with only 1)

updown = {}

# create an instance of the watershed class to store the data to build the model

watershed = Watershed(description, subbasins)

# add the network and the outlet subbasin

watershed.add_mass_linkage(updown)
watershed.add_outlet(sname)

# make the HSPFModel instance (the data for this example use the non-default
# option of English instead of metric units)

from pyhspf import HSPFModel

hspfmodel = HSPFModel(units = 'English')

# since the climate data are provided with hspexp in an export file called
# "huntobs.exp."  WDMUtil has a method to automatically import the data to a 
示例#3
0
文件: intro01.py 项目: djibi2/PyHSPF
                   velocity = velocity)

# for simplicity just assume the same landuse types and areas

subbasin.add_landuse(2001, landuse_names, areas)

# and add the subbasin to the subbasins dictionary

subbasins[number] = subbasin

# now that that subbasins are specified it is possible to create an instance 
# of the Watershed class that is used to build the HSPF input files.

watershed_name = 'Dave'

watershed = Watershed(watershed_name, subbasins)

# another key piece of information for the watershed is the flow network. 
# it should be provided as  an "updown" dictionary--that is, subbasin names
# are supplied as keys, and the dictionary returns the downstream subbasin 
# names as values. So for this example the netword is just subbasin reach "100"
# goes into "101." 

updown = {'100':'101'}

# add the mass linkage dictionary to the watershed

watershed.add_mass_linkage(updown)

# need to tell HSPF that subbasin "101" is an outlet where mass leaves. this
# information is needed because PyHSPF starts at the outlet and works 
示例#4
0
minelev = 90
flow = 12

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)
subbasins[number] = subbasin

# build the watershed

watershed = Watershed('Dave', subbasins)

# flow network dictionary

updown = {'100': '101'}

# add the info to the watershed and outlet

watershed.add_mass_linkage(updown)
watershed.add_outlet('101')

# names of the files used in the simulation (the HSPF input and output files
# are generated automatically); can also specify a directory to use elsewhere

filename = 'example06'
wdmoutfile = filename + '_out.wdm'
reachShp = shapefile.Reader(parentDir + shapeDir +
                            '/siletz_river_reaches_HSPF.shp')

basinRecords = basinShp.records()

reachRecords = reachShp.records()

# Send the import data to the pre-build processors
subbasins = create_subbasins(basinRecords, reachRecords, 2011, lc_codes,
                             hru_df, fTables)

flow_network = create_flownetwork(basinRecords)

# CREATE HSPF MODEL
watershedSiletz = Watershed("Siletz River", subbasins)

watershedSiletz.add_mass_linkage(flow_network)

for basin in range(0, len(basinRecords)):

    if basinRecords[basin][6] == 0:

        watershedSiletz.add_outlet(str(basin + 1))  # Assumes basin numbers

    x = 1  # Don't need this but the loop wants to include 'hspfmodel...'

# Build the model
hspfmodel = HSPFModel(units='Metric')

filename = 'siletz_river'
示例#6
0
文件: intro03.py 项目: waternk/PyHSPF
# hydrology default values

landuse_names = ['Forest', 'Agriculture', 'Pasture/grass', 'Developed']
areas = [3078, 449, 540, 35]

# add the landuse

subbasin.add_landuse(1988, landuse_names, areas)

# add the subbasin to the dictionary

subbasins['32'] = subbasin

# create an instance of the watershed class from the subbasin information

watershed = Watershed(description, subbasins)

# add the network and the outlet subbasin

watershed.add_mass_linkage(updown)
watershed.add_outlet('30')

# since the climate data are provided with hspexp in an export file called
# "huntobs.exp."  WDMUtil has a method to automatically import the data to a
# WDM file.

wdm = WDMUtil()

# the data from the export file (*.exp) provided with hspexp need to be
# imported into a wdm file. WDMUtil has a method for this.
示例#7
0
文件: intro02.py 项目: waternk/PyHSPF
# add the landuse

subbasin.add_landuse(1988, landuse_names, areas)

# create a dictionary of the subbasins

subbasins = {sname: subbasin}

# create an updown dictionary for the reach network (trivial with only 1)

updown = {}

# create an instance of the watershed class to store the data to build the model

watershed = Watershed(description, subbasins)

# add the network and the outlet subbasin

watershed.add_mass_linkage(updown)
watershed.add_outlet(sname)

# make the HSPFModel instance (the data for this example use the non-default
# option of English instead of metric units)

from pyhspf import HSPFModel

hspfmodel = HSPFModel(units='English')

# since the climate data are provided with hspexp in an export file called
# "huntobs.exp."  WDMUtil has a method to automatically import the data to a
示例#8
0
文件: intro03.py 项目: djibi2/PyHSPF
# hydrology default values

landuse_names = ['Forest', 'Agriculture', 'Pasture/grass', 'Developed']
areas         = [3078, 449, 540, 35]

# add the landuse

subbasin.add_landuse(1988, landuse_names, areas)

# add the subbasin to the dictionary

subbasins['32'] = subbasin

# create an instance of the watershed class from the subbasin information

watershed = Watershed(description, subbasins)

# add the network and the outlet subbasin

watershed.add_mass_linkage(updown)
watershed.add_outlet('30')

# since the climate data are provided with hspexp in an export file called
# "huntobs.exp."  WDMUtil has a method to automatically import the data to a 
# WDM file.

wdm = WDMUtil()

# the data from the export file (*.exp) provided with hspexp need to be 
# imported into a wdm file. WDMUtil has a method for this.
示例#9
0
                   velocity=velocity)

# for simplicity just assume the same landuse types and areas

subbasin.add_landuse(2001, landuse_names, areas)

# and add the subbasin to the subbasins dictionary

subbasins[number] = subbasin

# now that that subbasins are specified it is possible to create an instance
# of the Watershed class that is used to build the HSPF input files.

watershed_name = 'Dave'

watershed = Watershed(watershed_name, subbasins)

# another key piece of information for the watershed is the flow network.
# it should be provided as  an "updown" dictionary--that is, subbasin names
# are supplied as keys, and the dictionary returns the downstream subbasin
# names as values. So for this example the netword is just subbasin reach "100"
# goes into "101."

updown = {'100': '101'}

# add the mass linkage dictionary to the watershed

watershed.add_mass_linkage(updown)

# need to tell HSPF that subbasin "101" is an outlet where mass leaves. this
# information is needed because PyHSPF starts at the outlet and works