예제 #1
0
    def read_elements(self, elem_file):
        ''' read_elements() - Read an IWFM Element file, and return a list of 
            the nodes making up each element.'''
        # -- read the Element file into array file_lines
        elem_lines = open(
            elem_file).read().splitlines()  # open and read input file

        line_index = 0
        line_index = iwfm.skip_ahead(line_index, elem_lines, 0)

        self.elements = int(re.findall('\d+', elem_lines[line_index])[0])

        line_index = iwfm.skip_ahead(line_index + 1, elem_lines, 0)

        subregions = int(re.findall('\d+', elem_lines[line_index])[0])

        line_index = iwfm.skip_ahead(line_index + 1, elem_lines, 0)
        line_index = iwfm.skip_ahead(line_index + 1, elem_lines,
                                     subregions - 1)

        self.e_nos = []  # initialize list of elem nos
        self.d_elem_nodes = {}  # initialize list of elem nodes
        self.d_elem_sub = {}  # initialize list of elem subregions
        for i in range(0, self.elements):  # read element information
            l = elem_lines[line_index + i].split()  # get the next line
            this_elem = int(l.pop(0))  # element no of this element
            self.e_nos.append(this_elem)  # add element no of this element
            nodes = [int(s) for s in l]
            self.d_elem_sub[this_elem] = nodes.pop(
                4)  # subregion of this element
            if nodes[3] == 0:
                nodes.pop(3)  # remove empty node on triangles
            self.d_elem_nodes[this_elem] = nodes  # nodes of this element
        self.elems2poly()  # build polygons
        return
예제 #2
0
    def read_nodes(self, node_file):
        ''' read_nodes() - Read an IWFM Node file, and return a list of the 
            nodes and their coordinates.'''

        # -- read the Node file into array file_lines
        node_lines = open(node_file).read().splitlines()

        line_index = 0  # start at the top
        line_index = iwfm.skip_ahead(line_index, node_lines,
                                     0)  # skip comments

        self.inodes = int(re.findall('\d+', node_lines[line_index])[0])

        line_index = iwfm.skip_ahead(line_index + 1, node_lines,
                                     0)  # skip comments

        factor = float(node_lines[line_index].split()[0])  # read factor

        line_index = iwfm.skip_ahead(line_index + 1, node_lines,
                                     0)  # skip comments

        self.d_nodes = {}  # initialize nodal info dictionary
        self.d_nodexy = {}  # initialize elemental info dictionary
        for i in range(0, self.inodes):  # read nodes information
            l = node_lines[line_index + i].split()  # get next line
            inode = int(l.pop(0))  # node number
            self.d_nodes[i] = inode
            coords = [float(s) * factor for s in l]
            self.d_nodexy[inode] = coords
        return
예제 #3
0
 def read_lake_pre(self, lake_file):
     ''' read_lake() - Read an IWFM Lake file and return (a) a list of 
         elements and (b) a list of properties for each lake.'''
     lake_lines = open(
         lake_file).read().splitlines()  # open and read input file
     lake_index = 0  # start at the top
     lake_index = iwfm.skip_ahead(lake_index, lake_lines,
                                  0)  # skip comments
     self.nlakes = int(lake_lines[lake_index].split()[0])
     self.lakes = []
     self.lake_elems = []
     for i in range(0, self.nlakes):
         lake_index = iwfm.skip_ahead(lake_index + 1, lake_lines,
                                      0)  # skip comments
         l = lake_lines[lake_index].split(
         )  # read first line of lake description
         lake_id = int(l.pop(0))
         max_elev = float(l.pop(0))
         next = int(l.pop(0))
         nelem = int(l.pop(0))
         self.lakes.append([lake_id, max_elev, next, nelem])
         for j in range(0, nelem):
             e = []
             if j > 0:  # need to read next line
                 lake_index = iwfm.skip_ahead(lake_index + 1, lake_lines, 0)
                 l = lake_lines[lake_index].split()  # get next line
             e.append(lake_id)  # lake number
             e.append(int(l[0]))  # element number
             self.lake_elems.append(e)
     return
예제 #4
0
def sub_pp_nodes(elem_file, elem_list):
    ''' sub_pp_nodes() - Read the element file and return a list of the
        nodes in the submodel

    Parameters
    ----------
    elem_file : str
        existing model preprocessor element file name
    
    elem_list : list of ints
        list of existing model elements in submodel

    Returns
    -------
    node_list : list of ints
        list of existing model nodes in submodel

    '''
    import iwfm as iwfm

    comments = ['Cc*#']
    elems = []
    for e in elem_list:
        elems.append(int(e[0]))

    elem_lines = open(
        elem_file).read().splitlines()  # open and read input file

    line_index = iwfm.skip_ahead(0, elem_lines, 0)  # skip comments
    # -- skip to number of subregions
    line_index = iwfm.skip_ahead(line_index + 1, elem_lines, 0)
    # -- skip to start of subregion list
    line_index = iwfm.skip_ahead(line_index + 1, elem_lines, 0)
    # -- skip the subregion lines
    while elem_lines[line_index][0] not in comments:
        line_index += 1
    # -- skip to start of element list
    line_index = iwfm.skip_ahead(line_index + 1, elem_lines, 0)

    # -- get node list
    node_list = []
    for i in range(line_index, len(elem_lines)):
        temp = [int(n) for n in elem_lines[i].split()]
        elem = temp[0]
        nodes = temp[1:5]
        if elem in elems:
            for node in nodes:
                if node not in node_list:
                    node_list.append(node)
    node_list.sort()
    # remove 0, it is not a node number, just indicates a triangular element
    if (node_list[0] == 0):
        node_list.pop(0)
    return node_list
예제 #5
0
    def read_strat(self, strat_file):

        strat_lines = open(
            strat_file).read().splitlines()  # open and read input file

        line_index = 0  # start at the top
        line_index = iwfm.skip_ahead(line_index, strat_lines,
                                     0)  # skip comments
        layers = int(re.findall('\d+',
                                strat_lines[line_index])[0])  # read no. layers

        line_index = iwfm.skip_ahead(line_index + 1, strat_lines,
                                     0)  # skip comments
        factor = float(re.findall('\d+',
                                  strat_lines[line_index])[0])  # read factor

        line_index = iwfm.skip_ahead(line_index + 1, strat_lines,
                                     0)  # skip comments
        self.strat = []  # initialize list
        for i in range(0, len(self.d_nodes)):
            l = strat_lines[line_index + i].split()
            s = []  # initialize accumulator
            s.append(int(l.pop(0)))  # node no
            for j in range(0, len(l)):
                s.append(factor * float(l.pop(0)))  # lse, etc as floats
            self.strat.append(s)

        self.nlayers = int((len(self.strat[0]) - 1) / 2)
        self.elevation = [i[0] for i in self.strat]

        self.d_nodeelev = {}
        for i in range(0, len(
                self.strat)):  # cycle through stratigraphy of each node
            l = self.strat[i]

            this_node = l.pop(0)
            lse = l.pop(0)

            depth = 0
            n_strat = []
            n_strat.append(lse)
            for j in range(0,
                           self.nlayers):  # cycle through layers for each node
                t = l.pop(0)  # thickness of aquitard
                depth += t  # add to total depth
                n_strat.append(lse -
                               depth)  # bottom of aquitard/top of aquifer
                a = l.pop(0)  # thickness of aquifer
                depth += a  # add to total depth
                n_strat.append(lse -
                               depth)  # bottom of aquifer/top of next aqiutard
            self.d_nodeelev[this_node] = n_strat
        return
예제 #6
0
def iwfm_read_lake(lake_file):
    ''' iwfm_read_lake() - Read an IWFM Lake file and returns 
        (a) a list of elements and (b) a list of properties for each lake

    Parameters
    ----------
    lake_file : str
        IWFM Preprocessor Lake file name

    Returns
    -------
    lake_elems : list
        element numbers for each lake
    
    lakes : list
        configuration info for each lake
          lake_id : int
              lake number
          max_elev : int
              column number in maximum elevation time series file
          dest : int
              destination stream node or lake id
          nelem : int
              number of elements in lake

    '''
    import iwfm as iwfm

    iwfm.file_test(lake_file)
    lake_lines = open(lake_file).read().splitlines()

    lake_index = iwfm.skip_ahead(0, lake_lines, 0)
    nlakes = int(lake_lines[lake_index].split()[0])

    lakes, lake_elems = [], []
    for i in range(0, nlakes):
        lake_index = iwfm.skip_ahead(lake_index + 1, lake_lines, 0)
        l = lake_lines[lake_index].split()
        lake_id = int(l.pop(0))
        max_elev = float(l.pop(0))
        dest = int(l.pop(0))
        nelem = int(l.pop(0))
        lakes.append([lake_id, max_elev, dest, nelem])
        for j in range(0, nelem):
            e = []
            if j > 0:
                lake_index = iwfm.skip_ahead(lake_index + 1, lake_lines, 0)
                l = lake_lines[lake_index].split()
            e.append(lake_id)
            e.append(int(l[0]))
            lake_elems.append(e)
    return lake_elems, lakes
예제 #7
0
def iwfm_read_elements(elem_file, verbose=False):
    ''' iwfm_read_elements() - Read an IWFM Element file, and return a list
        of the nodes making up each element

    Parameters
    ----------
    elem_file : str
        IWFM Preprocessor Elements file name

    Returns
    -------
    elem_ids : list
        element numbers
    
    elem_nodes : list
        nodes for each element
    
    elem_sub : list
        subregion for each element

    '''
    import re
    import iwfm as iwfm

    iwfm.file_test(elem_file)

    elem_lines = open(elem_file).read().splitlines()  
    line_index = iwfm.skip_ahead(0, elem_lines, 0) 

    elements = int(re.findall('\d+', elem_lines[line_index])[0])  

    line_index = iwfm.skip_ahead(line_index + 1, elem_lines, 0)  

    subregions = int(re.findall('\d+', elem_lines[line_index])[0]) 

    line_index = iwfm.skip_ahead(line_index + 1, elem_lines, 0)  
    line_index = iwfm.skip_ahead(line_index + 1, elem_lines, subregions - 1)

    elem_ids, elem_nodes, elem_sub = [], [], []
    for i in range(0, elements):  
        l = elem_lines[line_index + i].split()
        this_elem = int(l.pop(0))
        elem_ids.append(this_elem)
        nodes = [int(s) for s in l]
        elem_sub.append(nodes.pop(4))
        if nodes[3] == 0:
            nodes.pop(3)  # remove empty node on triangles
        elem_nodes.append(nodes)
    if verbose:
        print(f'  Read {len(elem_nodes):,} elements from {elem_file}')
    return elem_ids, elem_nodes, elem_sub
예제 #8
0
def iwfm_read_nodes(node_file, factor=0.0):
    ''' iwfm_read_nodes() - Read an IWFM Node file and return a list of the
        nodes and their coordinates

    Parameters
    ----------
    node_file : str
        IWFM preprocessor node file

    Returns
    -------
    node_coord : list
        Nodes and coordinates

    node_list : list
        Node numbers

    factor : float
        If factor = 0.0, use the factor from the input file
        Else if factor <> 0.0 use this as the factor

    '''
    import iwfm as iwfm
    import re

    iwfm.file_test(node_file)

    node_lines = open(node_file).read().splitlines()

    line_index = iwfm.skip_ahead(0, node_lines, 0)

    inodes = int(re.findall('\d+', node_lines[line_index])[0])

    line_index = iwfm.skip_ahead(line_index + 1, node_lines, 0)

    read_factor = float(node_lines[line_index].split()[0])

    if factor == 0:
        factor = read_factor

    line_index = iwfm.skip_ahead(line_index + 1, node_lines, 0)

    node_list, node_coord = [], []
    for i in range(0, inodes):
        l = node_lines[line_index + i].split()
        node_list.append(int(l.pop(0)))
        coords = [float(s) * factor for s in l]
        node_coord.append(coords)

    return node_coord, node_list
예제 #9
0
def sub_pp_lake_file(lake_file, new_lake_file, lake_info):
    ''' sub_pp_lake_file() - Copy the old lake file and replace the contents with
        those of the new model, and write out the new IWFM lake file

    Parameters
    ----------
    lake_file : str
        name of existing preprocessor node file
    
    new_lake_file : str
        name of submodel preprocessor node file
    
    lake_info : list
        info describing of each lake in the submodel

    Returns
    -------
    nothing

    '''
    import iwfm as iwfm

    lake_lines = open(
        lake_file).read().splitlines()  # open and read input file

    line_index = iwfm.skip_ahead(0, lake_lines, 0)  # skip comments
    lake_lines[line_index] = iwfm.pad_both(str(
        len(lake_info)), f=4, b=35) + ' '.join(
            lake_lines[line_index].split()[1:])

    line_index = iwfm.skip_ahead(line_index + 1, lake_lines, 0)

    new_lake_lines = lake_lines[:line_index]

    for i in range(0, len(lake_info)):
        new_lake_lines.append('\t' + '\t'.join(lake_info[i][0:4]) + '\t' +
                              str(lake_info[i][5][0]) + '\t' + lake_info[i][4])

        for j in range(1, len(lake_info[i][5])):
            new_lake_lines.append('\t\t\t\t\t' + str(lake_info[i][5][j]))

    new_lake_lines.append('')

    with open(new_lake_file, 'w') as outfile:
        outfile.write('\n'.join(new_lake_lines))

    return
예제 #10
0
def igsm_read_lake(lake_file):
    ''' igsm_read_lake() - Read an IGSM Lake file and returns (a) a list of
        elements and (b) a list of properties for each lake
        
    Parameters
    ----------
    lake_file : str
        name of IGSM lake file

    Returns
    -------
    lake_elems : list
        all lake elements
    
    lakes : list
        [lake_id, max_elev, next, nelem] for each lake

    '''
    import iwfm as iwfm

    lake_lines = open(
        lake_file).read().splitlines()  # open and read input file
    lake_index = 0  # start at the top
    lake_index = iwfm.skip_ahead(lake_index, lake_lines, 0)  # skip comments
    nlakes = int(lake_lines[lake_index].split()[0])
    lake_index = iwfm.skip_ahead(lake_index + 1, lake_lines,
                                 0)  # skip comments
    lakes = []
    lake_elems = []
    l = lake_lines[lake_index].split()  # read first line of lake description
    for i in range(0, nlakes):
        lake_id = int(l.pop(0))
        max_elev = float(l.pop(0))
        next = int(l.pop(0))
        nelem = int(l.pop(0))
        lakes.append([lake_id, max_elev, next, nelem])
        j = 0
        while j < nelem:
            e = []
            e.append(lake_id)  # lake number
            e.append(int(l.pop(0)))  # element number
            e.append(float(l.pop(0)))  # area
            lake_elems.append(e)
            j += 1
            l = lake_lines[lake_index + i + j].split()  # get next line
        i += j
    return lake_elems, lakes
예제 #11
0
def iwfm_read_strat(strat_file, node_coords):
    ''' iwfm_read_strat() - Read an IWFM Stratigraphy file and return a 
        list of stratigraphy for each node
    
    Parameters:
    -----------
    strat_file : str
        name of existing IWFM stratigraphy file
    
    node_coords : list
        (x,y) locations of IWFM model nodes

    Returns
    -------
    strat : list
        stratigraphy for each node
    
    nlayers : int
        number of layers

    '''
    import iwfm as iwfm
    import re

    iwfm.file_test(strat_file)

    strat_lines = open(strat_file).read().splitlines()
    line_index = iwfm.skip_ahead(0, strat_lines, 0)

    layers = int(re.findall('\d+', strat_lines[line_index])[0])

    line_index = iwfm.skip_ahead(line_index + 1, strat_lines, 0)
    factor = float(re.findall('\d+', strat_lines[line_index])[0])

    line_index = iwfm.skip_ahead(line_index + 1, strat_lines, 0)

    strat = []
    for i in range(0, len(node_coords)):
        l = strat_lines[line_index + i].split()
        s = []
        s.append(int(l.pop(0)))
        for j in range(0, len(l)):
            s.append(factor * float(l.pop(0)))
        strat.append(s)
    nlayers = int((len(strat[0]) - 1) / 2)
    return strat, nlayers
예제 #12
0
def igsm_read_elements(elem_file):
    ''' igsm_read_elements() - Read an IGSM Element file, and returns a list
        of the nodes making up each element
    
    Parameters
    ----------
    elem_file : str
        name of IGSM elements file
    
    Returns
    -------
    elem_nodes : list
        list of elements and nodes for each element
    
    elem_list : list
        list of elements
    
    '''
    import iwfm as iwfm

    # -- read the Element file into array file_lines
    elem_lines = open(
        elem_file).read().splitlines()  # open and read input file

    line_index = 0  # start at the top
    line_index = iwfm.skip_ahead(line_index, elem_lines, 0)  # skip comments

    import re

    elements = int(re.findall(
        '\d+', elem_lines[line_index])[0])  # read number of elements

    line_index = iwfm.skip_ahead(line_index + 1, elem_lines,
                                 0)  # skip comments

    elem_nodes, elem_list = [], []
    for i in range(0, elements):  # read element information
        l = elem_lines[line_index + i].split()
        this_elem = int(l.pop(0))
        nodes = [int(s) for s in l]
        if nodes[3] == 0:
            nodes.pop(3)  # remove empty node on triangles
        elem_nodes.append(nodes)
        elem_list.append(this_elem)
    return elem_nodes, elem_list
예제 #13
0
def sub_pp_strat_file(strat_file, new_strat_file, node_list):
    ''' sub_pp_strat_file() - Ccopy the original stratigraphy file 
        and replace the contents with those of the new submodel,
        and write out the new file

    Parameters
    ----------
    strat_file : str
        name of existing preprocessor stratigraphy file
    
    new_strat_file : str
        name of submodel preprocessor stratigraphy file
    
    node_list : list of ints
        list of submodel nodes

    Returns
    -------
    nothing

    '''
    import iwfm as iwfm

    strat_lines = open(strat_file).read().splitlines()

    while len(strat_lines[-1]) < 2:
        strat_lines.pop()

    line_index = iwfm.skip_ahead(0, strat_lines, 0)  # skip comments

    line_index = iwfm.skip_ahead(line_index + 3, strat_lines,
                                 0)  # skip comments
    new_strat_lines = strat_lines[:line_index]

    for i in range(line_index, len(strat_lines)):
        if int(strat_lines[i].split()[0]) in node_list:
            new_strat_lines.append(strat_lines[i])

    new_strat_lines.append('')

    with open(new_strat_file, 'w') as outfile:
        outfile.write('\n'.join(new_strat_lines))

    return
예제 #14
0
def sub_pp_node_file(node_file, new_node_file, node_list):
    ''' sub_pp_node_file() - Copy the original node file, replace the 
        contents with those of the new model, and write out the new file

    Parameters
    ----------
    node_file : str
        name of existing preprocessor node file
    
    new_node_file : str
        name of submodel preprocessor node file
    
    node_list : llist of ints
        list of submodel nodes

    Returns
    -------
    nothing

    '''
    import iwfm as iwfm

    node_lines = open(
        node_file).read().splitlines()  # open and read input file

    line_index = iwfm.skip_ahead(0, node_lines, 0)  # skip comments
    node_lines[line_index] = iwfm.pad_both(str(
        len(node_list)), f=4, b=35) + ' '.join(
            node_lines[line_index].split()[1:])

    line_index = iwfm.skip_ahead(line_index + 2, node_lines, 0)

    new_node_lines = node_lines[:line_index]

    for i in range(line_index, len(node_lines)):
        if int(node_lines[i].split()[0]) in node_list:
            new_node_lines.append(node_lines[i])
    new_node_lines.append('')

    with open(new_node_file, 'w') as outfile:
        outfile.write('\n'.join(new_node_lines))

    return
예제 #15
0
    def read_preproc(self, pre_file):
        ''' read_prepcoc() - Read an IWFM Preprocessor main input file, and 
            return a list of the files called and some settings.'''
        # -- read the preprocessor file into array file_lines
        pre_lines = open(
            pre_file).read().splitlines()  # open and read input file

        line_index = iwfm.skip_ahead(0, pre_lines, 3)  # skip comments

        # -- read input file names and create a dictionary ------------------
        self.pre_files_dict = {}
        self.pre_files_dict['preout'] = pre_lines[line_index].split()[0]

        line_index = iwfm.skip_ahead(line_index + 1, pre_lines, 0)
        self.pre_files_dict['elem_file'] = pre_lines[line_index].split()[0]

        line_index = iwfm.skip_ahead(line_index + 1, pre_lines, 0)
        self.pre_files_dict['node_file'] = pre_lines[line_index].split()[0]

        line_index = iwfm.skip_ahead(line_index + 1, pre_lines, 0)
        self.pre_files_dict['strat_file'] = pre_lines[line_index].split()[0]

        line_index = iwfm.skip_ahead(line_index + 1, pre_lines, 0)
        self.pre_files_dict['stream_file'] = pre_lines[line_index].split()[0]

        line_index = iwfm.skip_ahead(line_index + 1, pre_lines, 0)
        lake_file = pre_lines[line_index].split()[0]
        if lake_file[0] == '/':
            lake_file = ''
        self.pre_files_dict['lake_file'] = lake_file
        return
예제 #16
0
def igsm_read_strat(strat_file, node_coords):
    ''' igsm_read_strat() - Read an IGSM Stratigraphy file and return a list
        of stratigraphy for each node

    Parameters
    ----------
    strat_file : str
        IGSM nodal stratigraphy file name
    
    node_coords: list
        nodes and coordinates

    Returns
    -------
    strat : list
        stratigraphy information
    
    nlayers : int
        number of aquifer layers
    
    '''
    import iwfm as iwfm

    strat_lines = open(strat_file).read().splitlines()

    strat_index = iwfm.skip_ahead(0, strat_lines, 0)  # skip comments
    layers = strat_lines[strat_index].split()[0]

    strat = []
    strat_index = iwfm.skip_ahead(strat_index + 1, strat_lines, 0)
    for i in range(0, len(node_coords)):
        s = []
        l = strat_lines[strat_index + i].split()
        s.append(int(l.pop(0)))
        for j in range(0, len(l)):
            s.append(float(l.pop(0)))
        strat.append(s)
    nlayers = int((len(strat[0]) - 1) / 2)
    return strat, nlayers
예제 #17
0
def hyd_dict(gwhyd_info_file):
    ''' hyd_dict() - Read hydrograph info from Groundwater.dat file and build
        a dictionary of groundwater hydrograph info

    Parameters
    ----------
    gwhyd_info_file : str
        IWFM Groundwaer.dat file name

    Returns
    -------
    well_dict : dictionary
        key = well name (i.e. state well ID), value = well information, 
                                
    '''
    import iwfm as iwfm

    well_dict = {}
    gwhyd_info = open(
        gwhyd_info_file).read().splitlines()  # open and read input file

    # skip to NOUTH, number of hydrographs
    line_index = iwfm.skip_ahead(1, gwhyd_info, 20)
    nouth = int(gwhyd_info[line_index].split()[0])

    line_index = iwfm.skip_ahead(line_index, gwhyd_info,
                                 3)  # skip to first hydrograph
    for i in range(0, nouth):
        items = []
        line = gwhyd_info[line_index].split()
        items.append(line[5].lower())  # well name = key
        items.append(int(line[0]))  # column number in hydrograph file
        items.append(float(line[3]))  # x
        items.append(float(line[4]))  # y
        items.append(int(line[2]))  # model layer
        items.append(line[5].lower())  # well name
        well_dict[items[0]] = items[1:]
        line_index += 1
    return well_dict
예제 #18
0
def read_wells(infile):
    ''' read_wells() - Read IWFM Groundwater.dat file and build a dictionary
        of groundwater hydrograph info and gwhyd_sim columns

    Parameters
    ----------
    infile : str
        IWFM Groundwaer.dat file name

    Returns
    -------
    well_dict : dictionary
        key = well name (i.e. state ID), values = simulated heads

    '''
    import iwfm as iwfm

    gwhyd_info = open(infile).read().splitlines()

    # skip to NOUTH, number of hydrographs
    line_index = iwfm.skip_ahead(1, gwhyd_info, 20)
    nouth = int(gwhyd_info[line_index].split()[0])

    well_dict = {}
    line_index = iwfm.skip_ahead(line_index, gwhyd_info,
                                 3)  # skip to first hydrograph
    for i in range(0, nouth):
        items = []
        line = gwhyd_info[line_index].split()
        items.append(line[5].upper())  # well name = key
        items.append(int(line[0]))  # column number in hydrograph file
        items.append(float(line[3]))  # x
        items.append(float(line[4]))  # y
        items.append(int(line[2]))  # model layer
        items.append(line[5].lower())  # well name (state well number)
        key, values = items[0], items[1:]
        well_dict[key] = values
        line_index = line_index + 1
    return well_dict
예제 #19
0
def read_sim_wells(gw_file):
    ''' read_sim_wells() - Read Groundwater.dat file and build a dictionary of 
        groundwater hydrograph info and gwhyd_sim columns, and returns the 
        dictionary

    Parameters
    ----------
    gw_file : str
        IWFM Groundwater.dat file name

    Returns
    -------
    well_dict : dictionary
        key = well name, values = well information (hydrograph file column,
        x, y, model layer, well name)
    
    '''
    import iwfm as iwfm

    well_dict, well_list = {}, []
    gwhyd_info = open(gw_file).read().splitlines()

    line_index = iwfm.skip_ahead(1, gwhyd_info, 20)  # skip to NOUTH
    nouth = int(gwhyd_info[line_index].split()[0])

    line_index = iwfm.skip_ahead(line_index, gwhyd_info,
                                 3)  # skip to first hydrograph
    for i in range(0, nouth):
        items, line = [], gwhyd_info[line_index].split()
        items.append(line[5].upper())  # state well number = key
        items.append(int(line[0]))  # column number in hydrograph file
        items.append(float(line[3]))  # x
        items.append(float(line[4]))  # y
        items.append(int(line[2]))  # model layer
        items.append(line[5].lower())  # well name (state well number)
        well_dict[items[0]] = items[1:]
        well_list.append(items[0])
        line_index += 1
    return well_dict, well_list
예제 #20
0
def sub_unsat_file(old_filename, new_filename, elem_list, verbose=False):
    '''sub_unsat_file() - Read the original unsaturated zone file, determine 
        which elements are in the submodel, and write out a new file

    Parameters
    ----------
    old_filename : str
        name of existing model unsaturated zone file

    new_filename : str
        name of new subnmodel unsaturated zone file

    elem_list : list of ints
        list of existing model elements in submodel

    verbose : bool, default=False
        turn command-line output on or off

    Returns
    -------
    nothing

    '''
    import iwfm as iwfm

    comments = ['Cc*#']
    elems = []
    for e in elem_list:
        elems.append(e[0])

    unsat_lines = open(old_filename).read().splitlines()
    unsat_lines.append('')

    line_index = iwfm.skip_ahead(0, unsat_lines,
                                 9)  # skip factors and comments

    while line_index < len(unsat_lines):
        if (len(unsat_lines[line_index]) > 1
                and unsat_lines[line_index][0] not in comments):
            if int(unsat_lines[line_index].split()
                   [0]) not in elems:  # remove the line
                del unsat_lines[line_index]
                line_index -= 1
        line_index += 1

    unsat_lines.append('')

    with open(new_filename, 'w') as outfile:
        outfile.write('\n'.join(unsat_lines))

    return
예제 #21
0
def iwfm_read_sim_file(sim_file):
    ''' iwfm_read_sim_file() - Read an IWFM Simulation main input file
        and return a list of the files called and some settings

    Parameters
    ----------
    sim_file : str
        name of existing nmodel main input file

    Returns
    -------
    sim_dict : dicttionary
        dictionary of existing model file names
    
    have_lake : bool
        True of existing model has a lake file

    '''
    import iwfm as iwfm

    sim_lines = open(sim_file).read().splitlines()  # open and read input file
    line_index = iwfm.skip_ahead(0, sim_lines, 3)  # skip comments

    sim_dict = {}
    sim_dict['preout'] = sim_lines[line_index].split()[
        0]  # preproc output file

    line_index = iwfm.skip_ahead(line_index + 1, sim_lines, 0)
    sim_dict['gw_file'] = sim_lines[line_index].split()[0]  # element file

    line_index = iwfm.skip_ahead(line_index + 1, sim_lines, 0)
    sim_dict['stream_file'] = sim_lines[line_index].split()[0]  # node file

    line_index = iwfm.skip_ahead(line_index + 1, sim_lines, 0)
    lake_file = sim_lines[line_index].split()[0]  # lake file
    have_lake = True
    if lake_file[0] == '/':
        lake_file = ''
        have_lake = False
    sim_dict['lake_file'] = lake_file

    line_index = iwfm.skip_ahead(line_index + 1, sim_lines, 0)
    sim_dict['root_file'] = sim_lines[line_index].split()[
        0]  # stratigraphy file

    line_index = iwfm.skip_ahead(line_index + 1, sim_lines, 0)
    sim_dict['swshed_file'] = sim_lines[line_index].split()[0]  # stream file

    line_index = iwfm.skip_ahead(line_index + 1, sim_lines, 0)
    sim_dict['unsat_file'] = sim_lines[line_index].split()[0]  # stream file

    return sim_dict, have_lake
예제 #22
0
def iwfm_read_preproc(pre_file):
    ''' iwfm_read_preproc() - Read an IWFM Preprocessor main input file, 
        and return a dictionary with file names and some settings

    Parameters
    ----------
    pre_file : str
        name of existing preprocessor main input file

    Returns
    -------
    pre_dict : dictionary
        dictionary of preprocessor file names
    
    have_lake : bool
        True = the existing model has a lake file

    '''
    import iwfm as iwfm

    pre_lines = open(pre_file).read().splitlines()  # open and read input file

    pre_dict = {}

    line_index = iwfm.skip_ahead(0, pre_lines, 3)  # skip comments
    pre_dict['preout'] = pre_lines[line_index].split()[
        0]  # preproc output file

    line_index = iwfm.skip_ahead(line_index + 1, pre_lines, 0)
    pre_dict['elem_file'] = pre_lines[line_index].split()[0]  # element file

    line_index = iwfm.skip_ahead(line_index + 1, pre_lines, 0)
    pre_dict['node_file'] = pre_lines[line_index].split()[0]  # node file

    line_index = iwfm.skip_ahead(line_index + 1, pre_lines, 0)
    pre_dict['strat_file'] = pre_lines[line_index].split()[
        0]  # stratigraphy file

    line_index = iwfm.skip_ahead(line_index + 1, pre_lines, 0)
    pre_dict['stream_file'] = pre_lines[line_index].split()[0]  # stream file

    line_index = iwfm.skip_ahead(line_index + 1, pre_lines, 0)
    lake_file = pre_lines[line_index].split()[0]  # lake file
    # -- is there a lake file?
    have_lake = True
    if lake_file[0] == '/':
        lake_file = ''
        have_lake = False
    pre_dict['lake_file'] = lake_file

    return pre_dict, have_lake
예제 #23
0
    def read_chars(self, char_file, elem_nodes):
        ''' read_chars() - Read an IWFM Element Characteristics file and return
            a list of characteristics for each element.'''

        char_lines = open(
            char_file).read().splitlines()  # open and read input file

        char_index = 0  # start at the top
        char_index = iwfm.skip_ahead(char_index, char_lines,
                                     0)  # skip comments
        self.elem_char = []
        for i in range(0, len(elem_nodes)):
            l = char_lines[char_index + i].split()
            this_elem = int(l.pop(0))
            chars = []
            chars.append(int(l.pop(0)))  # rain station
            chars.append(float(l.pop(0)))  # rain factor
            chars.append(int(l.pop(0)))  # drainage
            chars.append(int(l.pop(0)))  # subregion
            temp = int(l.pop(0))  # don't use
            chars.append(float(l.pop(0)))  # soil type
            self.elem_char.append(chars)
        return
예제 #24
0
def iwfm_read_chars(char_file, elem_nodes):
    ''' iwfm_read_chars() - Read an IWFM Element Characteristics file and 
        return a list of characteristics for each element

    Parameters
    ----------
    char_file : str
        IWFM Element Characteristics file name
    
    elem_nodes : list
        elements and their nodes

    Returns
    -------
    elem_char : list
        elements and their characteristics
    
    '''
    import iwfm as iwfm

    char_lines = open(
        char_file).read().splitlines()  # open and read input file

    char_index = iwfm.skip_ahead(0, char_lines, 0)  # skip comments
    elem_char = []
    for i in range(0, len(elem_nodes)):
        l = char_lines[char_index + i].split()
        this_elem = int(l.pop(0))
        chars = []
        chars.append(int(l.pop(0)))  # rain station
        chars.append(float(l.pop(0)))  # rain factor
        chars.append(int(l.pop(0)))  # drainage destination
        chars.append(int(l.pop(0)))  # subregion
        temp = int(l.pop(0))  # don't use
        chars.append(float(l.pop(0)))  # soil type
        elem_char.append(chars)
    return elem_char
예제 #25
0
파일: iwfm_lu2sub.py 프로젝트: scantle/iwfm
def iwfm_lu2sub(elem_file,
                lu_file,
                out_file,
                skip=4,
                verbose=False,
                per_line=6):
    ''' iwfm_IWFM_lu2sub() - Read an IWFM Preprocessor Element File for a 
        submodel and an IWFM Land Use File for the base model, and write 
        a new land use file with land use for only the elements in the 
        Elements File

    Parameters
    ----------
    elem_file : str
        IWFM submodel Preprocessor Element file name
    
    lu_file : str
        IWFM base model land use area file
    
    out_file : str
        IWFM submodel land use area file name (output)
    
    skip : int, default=4
        number of non-comment lines to skip in each file
    
    verbose : bool, default=False
        True = command-line output on

    per_line : int, default=6
        if verbose==True, items per line to write to the console
    
    Returns
    -------
    nothing
    
    '''
    import sys, re, os
    import iwfm as iwfm

    iwfm.file_test(elem_file)
    iwfm.file_test(lu_file)

    elem_ids, _, _ = iwfm.iwfm_read_elements(elem_file)
    elem_ids.sort()

    lu_lines = open(lu_file).read().splitlines()  # open and read input file
    line_index = iwfm.skip_ahead(0, lu_lines, 4)  # skip comments
    header = line_index

    if verbose:
        outport = iwfm.Unbuffered(
            sys.stdout)  # to write unbuffered output to console

    out_lines, print_count = [], 0
    while line_index < len(lu_lines):
        out = []
        this_line = lu_lines[line_index].split()
        if re.search('/', lu_lines[line_index]):  # catch date
            this_date = this_line.pop(0)

            if verbose:  # write progress to console
                if print_count > per_line - 2:
                    outport.write(' ' + this_date[:10])
                    print_count = 0
                else:
                    if print_count == 0:
                        outport.write('\n  ' + this_date[:10])
                    else:
                        outport.write(' ' + this_date[:10])
                    print_count += 1

        # -- build the output line
        if int(this_line[0]) in elem_ids:
            if int(this_line[0]) == elem_ids[0]:  # first element -> add date
                out.append(this_date)
            for j in range(0, len(this_line)):  # add the rest of the line
                out.append('\t' + this_line[j])
            out_lines.append(out)
        line_index += 1
    outport.write('\n')

    with open(out_file, 'w') as f:
        for i in range(0, header):  # copy top of input file to output
            f.write(lu_lines[i])
            f.write('\n')
        for i in range(0, len(out_lines)):
            this_line = out_lines[i]
            for j in range(0, len(this_line)):
                f.write(this_line[j])
            f.write('\n')
    return len(out_lines)
예제 #26
0
def igsm2shp(main_file, shape_name, verbose=False):
    ''' igsm2shp() - Read the names of the preprocessor component input files, 
        read the contents of these files, and create node, element, stream 
        node and stream reach shapefiles

    Parameters
    ----------
    main_file : str
        IGSM Preprocessor input file name
    
    shape_name : str
        output shapefiles base name

    Returns
    -------
    nothing

    '''

    import iwfm as iwfm
    import iwfm.gis as gis

    main_lines = open(main_file).read().splitlines() 
    line_index = iwfm.skip_ahead(0, main_lines, 6)
    elem_file = main_lines[line_index].split()[0]
    line_index += 1
    node_file = main_lines[line_index].split()[0]
    line_index += 1
    strat_file = main_lines[line_index].split()[0]
    line_index += 1
    stream_file = main_lines[line_index].split()[0]
    line_index += 1
    lake_file = main_lines[line_index].split()[0]
    if lake_file[0] == '/': # no lake file listed
        lake_file = ''
    line_index += 2
    char_file = main_lines[line_index].split()[0]

    iwfm.file_test(elem_file)
    iwfm.file_test(node_file)
    iwfm.file_test(strat_file)
    iwfm.file_test(stream_file)
    if len(lake_file) > 1:
        iwfm.file_test(lake_file)
    iwfm.file_test(char_file)


    elem_nodes, elem_list = iwfm.igsm_read_elements(elem_file)
    if verbose:
        print(f'  Read nodes of {len(elem_nodes):,} elements from {elem_file}')

    node_coords, node_list = iwfm.igsm_read_nodes(node_file)
    if verbose:
        print(f'  Read coordinates of {len(node_coords):,} nodes from {node_file}')

    elem_char = iwfm.igsm_read_chars(char_file, elem_nodes)
    if verbose:
        print(f'  Read characteristics for {len(elem_char):,} elements from {char_file}')

    node_strat, nlayers = iwfm.igsm_read_strat(strat_file, node_coords)
    if verbose:
        print(f'  Read stratigraphy for {len(node_strat):,} nodes from {strat_file}')

    if len(lake_file) > 1:
        lake_elems, lakes = iwfm.igsm_read_lake(lake_file)
        if verbose:
            if len(lakes) > 1:
                print(f'  Read info for {len(lakes):,} lakes from {lake_file}')
            elif len(lakes) == 1:
                print(f'  Read info for {len(lakes):,} lake from {lake_file}')
    else:
        lake_elems = [[0,0,0]]  
        if verbose:
            print(f'  No lakes')

    reach_list, stnodes_dict, nsnodes = iwfm.igsm_read_streams(stream_file)
    if verbose:
        print(f'  Read info for {len(reach_list):,} stream reaches and {nsnodes:,} stream nodes from {stream_file}\n')


    gis.nodes2shp(node_coords, node_strat, nlayers, shape_name, verbose=verbose)

    gis.igsm_elem2shp(elem_nodes,node_coords,elem_char,lake_elems,
        shape_name,verbose=verbose)

    gis.snodes2shp(nsnodes, stnodes_dict, node_coords, shape_name, verbose=verbose)

    gis.reach2shp(reach_list, stnodes_dict, node_coords, shape_name, verbose=verbose)

    if verbose:
        print(f'  Wrote node, element, stream node and stream reache shapefiles\n')

    return
예제 #27
0
def sub_pp_streams(stream_file, node_list):
    ''' sub_pp_streams()  - Read the stream specification file and return
        stream reach and rating table info for the submodel

    Parameters
    ----------
    stream_file : str
        existing model preprocessor stream file name
    
    node_list : list
        list of existing model nodes in submodel

    Returns
    -------
    sub_reach_info : list
        reach info line for reaches in submodel
    
    snode_dict : dictionary
        key = existing model stream nodes in submodel,
            value = groundwater node
    
    sub_rattab_dict : dictionray
        key = stream node, values = rating table
    
    rating_header : str
        header info for rating tables including factors
    
    stream_aq : str
        stream-aquifer section of stream preprocessor file

    '''
    import iwfm as iwfm

    nodes = []
    for n in node_list:
        nodes.append(int(n))

    stream_lines = open(stream_file).read().splitlines()

    stream_type = stream_lines[0][1:]

    line_index = iwfm.skip_ahead(0, stream_lines, 0)  # skip comments
    nreach = int(stream_lines[line_index].split()[0])

    line_index = iwfm.skip_ahead(line_index + 1, stream_lines, 0)
    nrate = int(stream_lines[line_index].split()[0])

    if stream_type == '4.0':
        # placeholder for iwfm.get_stream_list_40()
        # snode_ids, snode_dict, reach_info, rattab_dict, rating_header, stream_aq = iwfm.get_stream_list_40(stream_lines,line_index,nreach,nrate)
        exit_now(stream_type)
    elif stream_type == '4.1':
        # placeholder for iwfm.get_stream_list_41()
        # snode_ids, snode_dict, reach_info, rattab_dict, rating_header, stream_aq = iwfm.get_stream_list_41(stream_lines,line_index,nreach,nrate)
        exit_now(stream_type)
    elif stream_type == '4.2':
        (
            snode_ids,
            snode_dict,
            reach_info,
            rattab_dict,
            rating_header,
            stream_aq,
        ) = iwfm.get_stream_list_42(stream_lines, line_index, nreach, nrate)
    else:
        exit_now(stream_type)

    sub_snodes = []
    for sn in snode_ids:
        if snode_dict[sn] in nodes:
            sub_snodes.append(sn)

    # -- cycle through stream reaches, determine if all in, part in, or out of submodel
    sub_reach_info = []
    for i in range(0, len(reach_info)):
        reach_snodes = []
        for j in range(0, len(reach_info[i][4])):
            if reach_info[i][4][j] in sub_snodes:
                reach_snodes.append(reach_info[i][4][j])
        if len(reach_snodes) > 0:
            temp = reach_info[i][0:4]
            temp.append(reach_snodes)
            sub_reach_info.append(temp)

    # -- cycle through rating tables, keeping those in submodel
    rattab_sns = [*rattab_dict]
    sub_rattab_dict = {}
    for sn in rattab_sns:
        if sn in sub_snodes:
            sub_rattab_dict[sn] = rattab_dict[sn]

    return sub_reach_info, snode_dict, sub_rattab_dict, rating_header, stream_aq
예제 #28
0
def sub_pp_stream_file(
    stream_file,
    new_stream_file,
    snode_dict,
    reach_info,
    rattab_dict,
    rating_header,
    stream_aq,
):
    ''' sub_pp_stream_file() - Copy the original stream specification file 
        and replace the contents with those of the new model, and write
        out the new file

    Parameters
    ----------
    stream_file : str
        name of existing preprocessor node file
    
    new_stream_file : str
        name of submodel preprocessor node file
    
    snode_dict : ints
        dictionary of existing model stream nodes in submodel
    
    reach_info : str
        reach info line for reaches in submodel
    
    rattab_dict : dict
        rating tables for stream nodes in submodel
    
    rating_header : str
        header info for rating tables including factors
    
    stream_aq : str
        stream-aquifer section of stream preprocessor file

    Returns
    -------
    nothing

    '''
    import iwfm as iwfm

    stream_lines = open(stream_file).read().splitlines()

    stream_type = stream_lines[0][1:]

    line_index = iwfm.skip_ahead(0, stream_lines, 0)  # skip comments
    sub_stream_lines = stream_lines[:line_index]

    # -- number of stream reaches
    sub_stream_lines.append(
        iwfm.pad_both(str(len(reach_info)), f=4, b=35) +
        ' '.join(stream_lines[line_index].split()[1:]))

    # -- number of points in each rating table
    rattab_sns = [*rattab_dict]
    sub_stream_lines.append(
        iwfm.pad_both(str(len(rattab_dict[rattab_sns[0]])), f=4, b=35) +
        ' '.join(stream_lines[line_index].split()[1:]))

    # -- write stream reach and rating table information
    if stream_type == '4.0':
        # placeholder for add_streams_40()
        # sub_stream_lines = add_streams_40(sub_stream_lines, reach_info, snode_dict, rattab_dict, rating_header, stream_aq)
        exit_now(stream_type)
    elif stream_type == '4.1':
        # placeholder for add_streams_41()
        # sub_stream_lines = add_streams_41(sub_stream_lines, reach_info, snode_dict, rattab_dict, rating_header, stream_aq)
        exit_now(stream_type)
    elif stream_type == '4.2':
        sub_stream_lines = add_streams_42(
            sub_stream_lines,
            reach_info,
            snode_dict,
            rattab_dict,
            rating_header,
            stream_aq,
        )
    else:
        exit_now(stream_type)

    sub_stream_lines.append('')
    # -- write new stream specification file
    with open(new_stream_file, 'w') as outfile:
        outfile.write('\n'.join(sub_stream_lines))

    return
예제 #29
0
def iwfm_read_sim(sim_file):
    ''' iwfm_read_sim() - Read an IWFM Simulation main input file, and 
        return a dictionary with the files called and some settings

    Parameters
    ----------
    sim_file : str
        Name of IWFM Simulation file

    Returns
    -------
    sim_dict : dictionary
        Dictionary with fixed keys, file names for corresponding values
          Keys            Refers to
          ----            ----------
          preout          Preprocessor output file name
          gw              Groundwater main file name
          stream          Stream main file name
          lake            Lake main file name
          rootzone        Rootzone main file name
          smallwatershed  Small Watershed file name
          unsat           Unsaturated Zone file name
          irrfrac         Irrigation Fractions file name
          supplyadj       Supply Adjustment file name
          precip          Precipitaiton file name
          et              Evapotranspiration file name
          start           Starting data (DSS format)
          step            Time step (IWFM fixed set)
          end             Ending date (DSS format)

    '''
    import iwfm as iwfm

    sim_dict = {}
    sim_lines = open(sim_file).read().splitlines()

    line_index = iwfm.skip_ahead(0, sim_lines, 3)  # skip comments
    sim_dict['preout'] = iwfm.file_get_path(sim_lines[line_index].split()[0])  
    
    line_index = iwfm.skip_ahead(line_index + 1, sim_lines, 0)  
    sim_dict['gw'] = iwfm.file_file_get_path(sim_lines[line_index].split()[0])
    
    line_index = iwfm.skip_ahead(line_index + 1, sim_lines, 0)  
    sim_dict['stream'] = iwfm.file_get_path(sim_lines[line_index].split()[0])
    
    line_index = iwfm.skip_ahead(line_index + 1, sim_lines, 0)  
    temp = sim_lines[line_index].split()[0]
    if temp[0] == '/':   # check for presence of lake file
        lake_file = ''
    else:
        lake_file = iwfm.file_get_path(temp)  
    sim_dict['lake'] = lake_file

    line_index = iwfm.skip_ahead(line_index + 1, sim_lines, 0)  
    sim_dict['rootzone'] = iwfm.file_get_path(sim_lines[line_index].split()[0])
    
    line_index = iwfm.skip_ahead(line_index + 1, sim_lines, 0)  
    sim_dict['smallwatershed'] = iwfm.file_get_path(sim_lines[line_index].split()[0])
    
    line_index = iwfm.skip_ahead(line_index + 1, sim_lines, 0)  
    sim_dict['unsat'] = iwfm.file_get_path(sim_lines[line_index].split()[0])
    
    line_index = iwfm.skip_ahead(line_index + 1, sim_lines, 0)  
    sim_dict['irrfrac'] = iwfm.file_get_path(sim_lines[line_index].split()[0])

    line_index = iwfm.skip_ahead(line_index + 1, sim_lines, 0)  
    sim_dict['supplyadj'] = iwfm.file_get_path(sim_lines[line_index].split()[0])

    line_index = iwfm.skip_ahead(line_index + 1, sim_lines, 0)  
    sim_dict['precip'] = sim_lines[line_index].split()[0]

    line_index = iwfm.skip_ahead(line_index + 1, sim_lines, 0)  
    sim_dict['et'] = iwfm.file_get_path(sim_lines[line_index].split()[0])
    
    line_index = iwfm.skip_ahead(line_index + 1, sim_lines, 0)  
    sim_dict['start'] = sim_lines[line_index].split()[0] 
    
    line_index = iwfm.skip_ahead(line_index + 1, sim_lines, 0)  
    sim_dict['step'] = sim_lines[line_index].split()[0]  

    line_index = iwfm.skip_ahead(line_index + 1, sim_lines, 0)  
    sim_dict['end'] = sim_lines[line_index].split()[0]  

    return sim_dict
예제 #30
0
def igsm_read_streams(stream_file):
    ''' igsm_read_streams() - Reads an IGSM Stream Geometry file and returns 
        (a) a list of stream reaches and (b) a dictionary of stream nodes, and 
        (c) the number of stream nodes

    Parameters
    ----------
    stream_file : str
        Name of existing IWFM stream file

    Returns
    -------
    reach_list : list
        Stream reach information

    stnodes_dict : dict
        Stream nodes dictionary

    len(snodes_list) : int
        Number of stream nodes

    '''
    import iwfm as iwfm

    stream_lines = open(stream_file).read().splitlines()
    stream_index = 0  # start at the top
    stream_index = iwfm.skip_ahead(stream_index, stream_lines, 0)
    nreach = int(stream_lines[stream_index].split()[0])
    stream_index += 1
    rating = stream_lines[stream_index].split()[0]
    reach_list = []
    snodes_list = []
    nsnodes = 0

    for i in range(0, nreach):
        # read reach information
        stream_index = iwfm.skip_ahead(stream_index + 1, stream_lines, 0)
        l = stream_lines[stream_index].split()
        reach = int(l.pop(0))
        upper = int(l.pop(0))
        lower = int(l.pop(0))
        oflow = int(l.pop(0))
        reach_list.append([reach, upper, lower, oflow])
        # read stream node information
        snodes = lower - upper + 1
        for j in range(0, snodes):
            stream_index = iwfm.skip_ahead(stream_index, stream_lines, 1)
            l = stream_lines[stream_index].split()
            t = [int(l[0]), int(l[1]), int(l[2]), reach]
            snodes_list.append(t)
    stream_index = iwfm.skip_ahead(stream_index + 1, stream_lines, 0)
    selev = []

    # cycle through stream nodes in rating table section
    for i in range(0, len(snodes_list)):
        l = stream_lines[stream_index].split()
        selev.append(int(l[1]))
        if i < len(snodes_list) - 1:
            stream_index = iwfm.skip_ahead(stream_index + 1, stream_lines, 4)

    # put stream node info into a dictionary
    stnodes_dict = {}
    for i in range(0, len(snodes_list)):
        j = 0
        while snodes_list[j][0] != i + 1:
            j += 1
        # key = snode, values = GW Node, Subregion, Reach, Bottom
        key, values = i + 1, [
            snodes_list[j][1], snodes_list[j][2], snodes_list[j][3], selev[i]
        ]
        stnodes_dict[key] = values

    return reach_list, stnodes_dict, len(snodes_list)