GISHydroNXT System Documentation

#*********************************************************************************
# Author:       UMD
# Date:         24-07-2018
# Modified:     n/a
# Classes:      DataSelectionFrame() ; GageListThomas() ; SegMergeDialog()
#               MergedSegTable() ; PrcpFrequency() ; SurfaceContours()
#               TcFrame() ; TR20InputFile() ; TR20ControlPanel()
#               ChooseStormDepths() ; AttributeTable()
#
# Functions:    Long list of functions are nested and therefore not provided here. 
#               However it is advised to consult Hydro Library to find more 
#               information about them.
#
# Note:         All buttons require initialization when AddIn is developed to declare 
#               these names as global. These names are same as class names so it helps
#               to initialize them when AddIn is developed. Therefore buttons are 
#               initialized to avoid "global name definition error"
#*********************************************************************************

#*******************************************************************************************************
# Interactive and selection based processing using Frames (wxPython)
#*******************************************************************************************************
#                                           +++++++++++++++++++
#                                           +                 +
#                                           + Dialogue Frames +
#                                           +                 +
#                                           +++++++++++++++++++

class DataSelectionFrame(wx.Frame):
    def __init__(self):
        global optfolder
        global scratchfolder
        global Directory
        mxdloc = arcpy.mapping.MapDocument("CURRENT")
        mxdloc = mxdloc.filePath
        mxdloc = mxdloc.replace("\\", "/")
        Directory = r"" + mxdloc.replace("mdinterface/GISHydroNXT.mxd", "")

        if not os.path.exists(Directory + "/data"):
            pythonaddins.MessageBox("Error: GISHydroNXT data folder is missing","Load Error",0)
            return
        #*******************************************************************************************************
        # checkout ArcGIS10.1 extensions
        #*******************************************************************************************************
        if arcpy.CheckExtension("Spatial") == "Available":
            arcpy.CheckOutExtension("Spatial")
        else:
            pythonaddins.MessageBox("Error: Couldn't get Spatial Analyst extension","Load Error",0)
            return
        #*******************************************************************************************************
        # Create output and intermediate folders
        #*******************************************************************************************************
        timestr = time.strftime("%Y%m%d_%H%M%S")
        data = Directory.replace("/umdgism/","/") + "/temp/"
        optfolder = r"" + data + timestr
        data = Directory.replace("/umdgism/","/") + "/intermediate/"
        scratchfolder = r"" + data + timestr

        arcpy.env.scratchWorkspace = scratchfolder
        arcpy.env.workspace = optfolder
        ########## DATA INPUT FRAME
        
        wx.Frame.__init__(self, None, -1, "Input Data Selection", size=(380, 365))
        self.Bind(wx.EVT_CLOSE, self.OnClose)
        panel = wx.Panel(self, -1)

        wx.StaticBox(panel, -1, "Project Name", (15, 15), size=(325,60))
        self.Proj = wx.TextCtrl(panel, -1, value="My Project", pos=(40, 40), size=(275,20))

        wx.StaticBox(panel, -1, "Data Type Selection", (15, 85), size=(325,180))
        wx.StaticText(panel, -1, "Soil Data Type:", (40, 110))
        wx.StaticText(panel, -1, "Landuse Data Type:", (40, 140))
        wx.StaticText(panel, -1, "Hydrologic Condition Type:", (40, 170))
        wx.StaticText(panel, -1, "Digital Elevation Model:", (40, 200))
        wx.StaticText(panel, -1, "Accumulation Threshold:", (40, 230))

        SoilList = ["Ragan Soils", "SSURGO Soils", "STATSGO Soils"]
        self.Soil = wx.ComboBox(panel, -1, "SSURGO Soils", (190, 105), (125, -1),SoilList, wx.CB_DROPDOWN)
        LanduseList = ["NLCD 2011 Landuse", "NLCD 2006 Landuse", "NLCD 2001 Landuse", "2010 MOP Landuse", "2002 MOP Landuse",
                       "2002 MD/DE Landuse", "Ultimate Landuse", "MRLC Landuse", "1997 MOP Landuse", "1970s USGS Landuse"]
        self.Landuse = wx.ComboBox(panel, -1, "2010 MOP Landuse", (190, 135), (125, -1),LanduseList, wx.CB_DROPDOWN)
        HydList = ["Fair", "Good", "Poor"]
        self.Hyd = wx.ComboBox(panel, -1, "Good", (190, 165), (125, -1),HydList, wx.CB_DROPDOWN)
        DEMList = ["National Elevation Dataset"]            # HERE IT IS POSSIBLE TO ADD MORE DEM'S TO THE LIST
        self.DEMTOT = wx.ComboBox(panel, -1, "National Elevation Dataset", (190, 195), (125, -1),DEMList, wx.CB_DROPDOWN)
        self.FA_Threshold = wx.TextCtrl(panel, -1, value="250", pos=(190, 225), size=(125,-1),style=wx.TE_RIGHT)
        
        self.btnApply = wx.Button(panel, label="Apply", pos=(150, 280))
        self.Bind(wx.EVT_BUTTON, self.OnSet, id=self.btnApply.GetId())
        
        self.Show(True)
        self.Centre(True)

    def OnClose(self, event):
        self.Show(False)

    def OnSet(self, event):
        #*******************************************************************************************************
        # Generate warning message if no data selected or project name specified
        #*******************************************************************************************************
        if len(str(self.Proj.GetValue())) > 50: #NXT does not handle large strings well)
            pythonaddins.MessageBox("Project Name Exceeds Maximum Number of Characters (50)", "Project Name Warning", 0)
            style = self.GetWindowStyle()
            self.SetWindowStyle( style | wx.STAY_ON_TOP )

        elif (str(self.Soil.GetValue()) != "Ragan Soils" and
            str(self.Soil.GetValue()) != "SSURGO Soils" and
            str(self.Soil.GetValue()) != "STATSGO Soils"):
            pythonaddins.MessageBox("Please Select Soil Data", "Data Selection Warning", 0)
            style = self.GetWindowStyle()
            self.SetWindowStyle( style | wx.STAY_ON_TOP )

        elif (str(self.Landuse.GetValue()) != "NLCD 2011 Landuse" and
              str(self.Landuse.GetValue()) != "NLCD 2006 Landuse" and
              str(self.Landuse.GetValue()) != "NLCD 2001 Landuse" and
              str(self.Landuse.GetValue()) != "2010 MOP Landuse" and
              str(self.Landuse.GetValue()) != "2002 MOP Landuse" and
              str(self.Landuse.GetValue()) != "2002 MD/DE Landuse" and
              str(self.Landuse.GetValue()) != "Ultimate Landuse" and
              str(self.Landuse.GetValue()) != "MRLC Landuse"and
              str(self.Landuse.GetValue()) != "1997 MOP Landuse" and
              str(self.Landuse.GetValue()) != "1970s USGS Landuse"):
            pythonaddins.MessageBox("Please Select Landuse Data", "Data Selection Warning", 0)
            style = self.GetWindowStyle()
            self.SetWindowStyle( style | wx.STAY_ON_TOP )
        elif (str(self.Hyd.GetValue()) != "Fair" and
              str(self.Hyd.GetValue()) != "Good" and
              str(self.Hyd.GetValue()) != "Poor"):
            pythonaddins.MessageBox("Please Select Hydrological Condition", "Data Selection Warning", 0)
            style = self.GetWindowStyle()
            self.SetWindowStyle( style | wx.STAY_ON_TOP )
        elif (int(self.FA_Threshold.GetValue()) <= 15):
            pythonaddins.MessageBox("Flow Accumulation Threshold Too Low", "Data Selection Warning", 0)
            style = self.GetWindowStyle()
            self.SetWindowStyle( style | wx.STAY_ON_TOP )
        elif (str(self.Proj.GetValue()) == ""):
            pythonaddins.MessageBox("Please Specify Project Name", "Project Name Warning", 0)
            style = self.GetWindowStyle()
            self.SetWindowStyle( style | wx.STAY_ON_TOP )
        elif (str(self.DEMTOT.GetValue()) != "National Elevation Dataset"):
            pythonaddins.MessageBox("Please Select Elevation Dataset", "DEM Warning", 0)
            style = self.GetWindowStyle()
            self.SetWindowStyle( style | wx.STAY_ON_TOP )
        else:
            self.Show(False) # move it to bottom while checking if there is data skew
            
            #*******************************************************************************************************
            # Generate optfolder and clip data based on extent rectangle and choice of data selection
            #*******************************************************************************************************

            global soil
            soil = str(self.Soil.GetValue())
            global landuse
            landuse = str(self.Landuse.GetValue())
            global hyd
            hyd = str(self.Hyd.GetValue())
            global proj
            proj = str(self.Proj.GetValue())
            global demtot
            demtot = self.DEMTOT.GetValue()
            global fa_thres
            fa_thres = int(self.FA_Threshold.GetValue())
            
            global optfolder
            global scratchfolder
            proj_ = proj.replace(" ","_")
            optfolder = optfolder + "_" + proj_ + "/"
            scratchfolder = scratchfolder + "_" + proj_ + "/"
            
            #*******************************************************************************************************
            # environmental settings
            #*******************************************************************************************************
            os.makedirs(optfolder) # Placed here instead of AoI class to avoid error if tool was closed without selection.
            os.makedirs(scratchfolder) # Scratch folder will be created once data selection is made.
            os.mkdir(optfolder + "/aux_folder")

            arcpy.env.overwriteOutput = True
            arcpy.env.scratchWorkspace = scratchfolder
            arcpy.env.workspace = optfolder

            ######## AREA OF INTEREST
            if demtot == "National Elevation Dataset":
                demname = "neddem"
            #elif demtot == "INSERT DEM NAME"       ## ADD HERE OTHER DEM's (REMEMBER TO CHANGE FLOWDIR, FLOWACC, etc...)

            arcpy.Clip_management(r"" + Directory + "/data/dems/flowdir", "%f %f %f %f" %(extent.XMin, extent.YMin, extent.XMax, extent.YMax),
                                  optfolder + "/flowdir", "#", "#", "NONE")
            arcpy.Clip_management(r"" + Directory + "/data/dems/flowacc", "%f %f %f %f" %(extent.XMin, extent.YMin, extent.XMax, extent.YMax),
                                  optfolder + "/flowacc", "#", "#", "NONE")
            arcpy.Clip_management(r"" + Directory + "/data/dems/" + demname, "%f %f %f %f" %(extent.XMin, extent.YMin, extent.XMax, extent.YMax),
                                  optfolder + "/dem", "#", "#", "NONE")
            arcpy.Clip_management(r"" + Directory + "/data/ssurgo/ssurgo", "%f %f %f %f" %(extent.XMin, extent.YMin, extent.XMax, extent.YMax),
                                  optfolder + "/ssurgo", "#", "#", "NONE")
            domain = arcpy.sa.Con(optfolder + "/flowdir" >= 0, 1, IsNull(optfolder + "/flowdir"))
            domain.save(optfolder + "/domain_int")
            arcpy.RasterToPolygon_conversion(optfolder + "/domain_int", optfolder + "/mask.shp","NO_SIMPLIFY","COUNT") # extent raster to clip statsgo shapfile
                            
            MOP = """

            The LandUse/Land Cover data set you have selected has been
            provided courtesy of the Maryland Department of Planning.
            Any use of that data set outside of this application without
            the permission of the Department of Planning is prohibited.
            The 2010 data are based on superior imagery and a refined
            classification system. The 2002 and earlier Land Use/Land
            Cover datasets are not reconciled with these improvements.
            For more information on Department of Planning data, please
            visit the MDP web site http://www.mdp.state.md.us or
            call (410) 767-4500.
            
            """
            global landuse_global
            if landuse == "2010 MOP Landuse":
                pythonaddins.MessageBox(MOP, "Maryland Department of Planning Data Usage Agreement", 0)
            if landuse == "2002 MOP Landuse":
                pythonaddins.MessageBox(MOP, "Maryland Department of Planning Data Usage Agreement", 0)
            if landuse == "2002 MOP Landuse":
                lan = r"" + Directory + "/data/Landuse/mdplu2002"
            elif landuse == "2002 MD/DE Landuse":
                lan = r"" + Directory + "/data/Landuse/mdde2002"
            elif landuse == "2010 MOP Landuse":
                lan = r"" + Directory + "/data/Landuse/lu2010"
            elif landuse == "Ultimate Landuse":
                lan = r"" + Directory + "/data/Landuse/luult"
            elif landuse == "MRLC Landuse":
                lan = r"" + Directory + "/data/Landuse/mrlc"
            elif landuse == "1970s USGS Landuse":
                lan = r"" + Directory + "/data/Landuse/lu70"
            elif landuse == "1997 MOP Landuse":
                lan = r"" + Directory + "/data/Landuse/lu97m"
            elif landuse == "NLCD 2011 Landuse":
                lan = r"" + Directory + "/data/Landuse/nlcd2011"
            elif landuse == "NLCD 2006 Landuse":
                lan = r"" + Directory + "/data/Landuse/nlcd2006"
            elif landuse == "NLCD 2001 Landuse":
                lan = r"" + Directory + "/data/Landuse/nlcd2001"
            arcpy.env.snapRaster = optfolder + "/dem"
            arcpy.Clip_management(lan, "%f %f %f %f" %(extent.XMin, extent.YMin, extent.XMax, extent.YMax),
                                  optfolder + "/landuse", "#", "#", "NONE")
            landuse_global = landuse
            
#            arcpy.RasterToPolygon_conversion(lan, optfolder + "/lan_poly.shp","NO_SIMPLIFY")
#            if (float(str(arcpy.GetRasterProperties_management(optfolder + "/dem", "LEFT"))) < float(str(arcpy.GetRasterProperties_management(lan, "LEFT"))) 
#                or float(str(arcpy.GetRasterProperties_management(optfolder + "/dem", "RIGHT"))) > float(str(arcpy.GetRasterProperties_management(lan, "RIGHT"))) 
#                or float(str(arcpy.GetRasterProperties_management(optfolder + "/dem", "BOTTOM"))) < float(str(arcpy.GetRasterProperties_management(lan, "BOTTOM"))) 
#                or float(str(arcpy.GetRasterProperties_management(optfolder + "/dem", "TOP"))) > float(str(arcpy.GetRasterProperties_management(lan, "TOP")))):
#                pythonaddins.MessageBox("Area of Interest Outside of Landuse Extent, Select Area of Interest Again.", "Extent Error")
#                mxd = arcpy.mapping.MapDocument("CURRENT")
#                df = arcpy.mapping.ListDataFrames(mxd)[0]
#                layers = arcpy.mapping.ListLayers(mxd, "", df)
#                for lyr in layers:
#                    if lyr.name == "dem":
#                        arcpy.mapping.RemoveLayer(df, lyr)
#                    if lyr.name == "flowdir":
#                        arcpy.mapping.RemoveLayer(df, lyr)
#                    if lyr.name == "flowacc":
#                        arcpy.mapping.RemoveLayer(df, lyr)
#                    if lyr.name == "landuse":
#                        arcpy.mapping.RemoveLayer(df, lyr)
#                    if lyr.name == "ssurgo":
#                        arcpy.mapping.RemoveLayer(df, lyr)
#                    if lyr.name == "mask":
#                        arcpy.mapping.RemoveLayer(df, lyr)
#                if os.path.exists(optfolder + "/landuse.shp"):
#                    arcpy.Delete_management(optfolder + "/landuse","")
#                if os.path.exists(optfolder + "/mask.shp"):
#                    arcpy.Delete_management(optfolder + "/mask.shp","")
#                if os.path.exists(optfolder + "/flowdir"):
#                    arcpy.Delete_management(optfolder + "/flowdir","")
#                if os.path.exists(optfolder + "/flowacc"):
#                    arcpy.Delete_management(optfolder + "/flowacc","")
#                if os.path.exists(optfolder + "/ssurgo"):
#                    arcpy.Delete_management(optfolder + "/ssurgo","")
#                if os.path.exists(optfolder + "/dem"):
#                    arcpy.Delete_management(optfolder + "/dem","")
#                tool1.enabled = True
#                return

            #*******************************************************************************************************
            # Select, clip, and generate CN using soil and landuse rasters
            #*******************************************************************************************************
            # Ragan data
            if soil == "Ragan Soils":
                scs = r"" + Directory + "/data/ragan/ragan"
                arcpy.Clip_management(scs, "%f %f %f %f" %(extent.XMin, extent.YMin, extent.XMax, extent.YMax),
                                      optfolder + "/Soils", "#", "#", "NONE")

                # Landuse and hydrologic condition for CN calculation
                if (landuse == "NLCD 2011 Landuse" and hyd == "Fair"):
                    outGrid = hydro.nlcdlookupfair(optfolder + "/landuse",optfolder + "/Soils")
                    outGrid.save(optfolder + "/curveNumber")
                elif (landuse == "NLCD 2011 Landuse" and hyd == "Good"):
                    outGrid = hydro.nlcdlookupgood(optfolder + "/landuse",optfolder + "/Soils")
                    outGrid.save(optfolder + "/curveNumber")
                elif (landuse == "NLCD 2011 Landuse" and hyd == "Poor"):
                    outGrid = hydro.nlcdlookuppoor(optfolder + "/landuse",optfolder + "/Soils")
                    outGrid.save(optfolder + "/curveNumber")

                if (landuse == "NLCD 2006 Landuse" and hyd == "Fair"):
                    outGrid = hydro.nlcdlookupfair(optfolder + "/landuse",optfolder + "/Soils")
                    outGrid.save(optfolder + "/curveNumber")
                elif (landuse == "NLCD 2006 Landuse" and hyd == "Good"):
                    outGrid = hydro.nlcdlookupgood(optfolder + "/landuse",optfolder + "/Soils")
                    outGrid.save(optfolder + "/curveNumber")
                elif (landuse == "NLCD 2006 Landuse" and hyd == "Poor"):
                    outGrid = hydro.nlcdlookuppoor(optfolder + "/landuse",optfolder + "/Soils")
                    outGrid.save(optfolder + "/curveNumber")

                if (landuse == "NLCD 2001 Landuse" and hyd == "Fair"):
                    outGrid = hydro.nlcdlookupfair(optfolder + "/landuse",optfolder + "/Soils")
                    outGrid.save(optfolder + "/curveNumber")
                elif (landuse == "NLCD 2001 Landuse" and hyd == "Good"):
                    outGrid = hydro.nlcdlookupgood(optfolder + "/landuse",optfolder + "/Soils")
                    outGrid.save(optfolder + "/curveNumber")
                elif (landuse == "NLCD 2001 Landuse" and hyd == "Poor"):
                    outGrid = hydro.nlcdlookuppoor(optfolder + "/landuse",optfolder + "/Soils")
                    outGrid.save(optfolder + "/curveNumber")
                
                if (landuse == "2010 MOP Landuse" and hyd == "Fair"):
                    outGrid = hydro.andlookupfair(optfolder + "/landuse",optfolder + "/Soils")
                    outGrid.save(optfolder + "/curveNumber")
                elif (landuse == "2010 MOP Landuse" and hyd == "Good"):
                    outGrid = hydro.andlookupgood(optfolder + "/landuse",optfolder + "/Soils")
                    outGrid.save(optfolder + "/curveNumber")
                elif (landuse == "2010 MOP Landuse" and hyd == "Poor"):
                    outGrid = hydro.andlookuppoor(optfolder + "/landuse",optfolder + "/Soils")
                    outGrid.save(optfolder + "/curveNumber")

                if (landuse == "2002 MOP Landuse" and hyd == "Fair"):
                    outGrid = hydro.andlookupfair(optfolder + "/landuse",optfolder + "/Soils")
                    outGrid.save(optfolder + "/curveNumber")
                elif (landuse == "2002 MOP Landuse" and hyd == "Good"):
                    outGrid = hydro.andlookupgood(optfolder + "/landuse",optfolder + "/Soils")
                    outGrid.save(optfolder + "/curveNumber")
                elif (landuse == "2002 MOP Landuse" and hyd == "Poor"):
                    outGrid = hydro.andlookuppoor(optfolder + "/landuse",optfolder + "/Soils")
                    outGrid.save(optfolder + "/curveNumber")

                if (landuse == "1997 MOP Landuse" and hyd == "Fair"):
                    outGrid = hydro.andlookupfair(optfolder + "/landuse",optfolder + "/Soils")
                    outGrid.save(optfolder + "/curveNumber")
                elif (landuse == "1997 MOP Landuse" and hyd == "Good"):
                    outGrid = hydro.andlookupgood(optfolder + "/landuse",optfolder + "/Soils")
                    outGrid.save(optfolder + "/curveNumber")
                elif (landuse == "1997 MOP Landuse" and hyd == "Poor"):
                    outGrid = hydro.andlookuppoor(optfolder + "/landuse",optfolder + "/Soils")
                    outGrid.save(optfolder + "/curveNumber")

                if (landuse == "2002 MD/DE Landuse" and hyd == "Fair"):
                    outGrid = hydro.mddelookupfair(optfolder + "/landuse",optfolder + "/Soils")
                    outGrid.save(optfolder + "/curveNumber")
                elif (landuse == "2002 MD/DE Landuse" and hyd == "Good"):
                    outGrid = hydro.mddelookupgood(optfolder + "/landuse",optfolder + "/Soils")
                    outGrid.save(optfolder + "/curveNumber")
                elif (landuse == "2002 MD/DE Landuse" and hyd == "Poor"):
                    outGrid = hydro.mddelookuppoor(optfolder + "/landuse",optfolder + "/Soils")
                    outGrid.save(optfolder + "/curveNumber")

                if (landuse == "Ultimate Landuse" and hyd == "Fair"):
                    outGrid = hydro.zoninglookupfair(optfolder + "/landuse",optfolder + "/Soils")
                    outGrid.save(optfolder + "/curveNumber")
                elif (landuse == "Ultimate Landuse" and hyd == "Good"):
                    outGrid =hydro.zoninglookupgood(optfolder + "/landuse",optfolder + "/Soils")
                    outGrid.save(optfolder + "/curveNumber")
                elif (landuse == "Ultimate Landuse" and hyd == "Poor"):
                    outGrid =hydro.zoninglookuppoor(optfolder + "/landuse",optfolder + "/Soils")
                    outGrid.save(optfolder + "/curveNumber")

                if (landuse == "MRLC Landuse" and hyd == "Fair"):
                    outGrid =hydro.mrlclookupfair(optfolder + "/landuse",optfolder + "/Soils")
                    outGrid.save(optfolder + "/curveNumber")
                elif (landuse == "MRLC Landuse" and hyd == "Good"):
                    outGrid =hydro.mrlclookupgood(optfolder + "/landuse",optfolder + "/Soils")
                    outGrid.save(optfolder + "/curveNumber")
                elif (landuse == "MRLC Landuse" and hyd == "Poor"):
                    outGrid =hydro.mrlclookuppoor(optfolder + "/landuse",optfolder + "/Soils")
                    outGrid.save(optfolder + "/curveNumber")

                if (landuse == "1970s USGS Landuse" and hyd == "Fair"):
                    outGrid =hydro.usgslookupfair(optfolder + "/landuse",optfolder + "/Soils")
                    outGrid.save(optfolder + "/curveNumber")
                elif (landuse == "1970s USGS Landuse" and hyd == "Good"):
                    outGrid =hydro.usgslookupgood(optfolder + "/landuse",optfolder + "/Soils")
                    outGrid.save(optfolder + "/curveNumber")
                elif (landuse == "1970s USGS Landuse" and hyd == "Poor"):
                    outGrid =hydro.usgslookuppoor(optfolder + "/landuse",optfolder + "/Soils")
                    outGrid.save(optfolder + "/curveNumber")

            # SSURGO data
            elif soil == "SSURGO Soils":
                scs = r"" + Directory + "/data/ssurgo/ssurgo"
                arcpy.Clip_management(scs, "%f %f %f %f" %(extent.XMin, extent.YMin, extent.XMax, extent.YMax),
                                      optfolder + "/Soils", "#", "#", "NONE")

                # Landuse and hydrologic condition for CN calculation
                if (landuse == "NLCD 2011 Landuse" and hyd == "Fair"):
                    outGrid =hydro.nlcdlookupfair(optfolder + "/landuse",optfolder + "/Soils")
                    outGrid.save(optfolder + "/curveNumber")
                elif (landuse == "NLCD 2011 Landuse" and hyd == "Good"):
                    outGrid =hydro.nlcdlookupgood(optfolder + "/landuse",optfolder + "/Soils")
                    outGrid.save(optfolder + "/curveNumber")
                elif (landuse == "NLCD 2011 Landuse" and hyd == "Poor"):
                    outGrid =hydro.nlcdlookuppoor(optfolder + "/landuse",optfolder + "/Soils")
                    outGrid.save(optfolder + "/curveNumber")

                if (landuse == "NLCD 2006 Landuse" and hyd == "Fair"):
                    outGrid =hydro.nlcdlookupfair(optfolder + "/landuse",optfolder + "/Soils")
                    outGrid.save(optfolder + "/curveNumber")
                elif (landuse == "NLCD 2006 Landuse" and hyd == "Good"):
                    outGrid =hydro.nlcdlookupgood(optfolder + "/landuse",optfolder + "/Soils")
                    outGrid.save(optfolder + "/curveNumber")
                elif (landuse == "NLCD 2006 Landuse" and hyd == "Poor"):
                    outGrid =hydro.nlcdlookuppoor(optfolder + "/landuse",optfolder + "/Soils")
                    outGrid.save(optfolder + "/curveNumber")

                if (landuse == "NLCD 2001 Landuse" and hyd == "Fair"):
                    outGrid =hydro.nlcdlookupfair(optfolder + "/landuse",optfolder + "/Soils")
                    outGrid.save(optfolder + "/curveNumber")
                elif (landuse == "NLCD 2001 Landuse" and hyd == "Good"):
                    outGrid =hydro.nlcdlookupgood(optfolder + "/landuse",optfolder + "/Soils")
                    outGrid.save(optfolder + "/curveNumber")
                elif (landuse == "NLCD 2001 Landuse" and hyd == "Poor"):
                    outGrid =hydro.nlcdlookuppoor(optfolder + "/landuse",optfolder + "/Soils")
                    outGrid.save(optfolder + "/curveNumber")

                if (landuse == "2010 MOP Landuse" and hyd == "Fair"):
                    outGrid =hydro.andlookupfair(optfolder + "/landuse",optfolder + "/Soils")
                    outGrid.save(optfolder + "/curveNumber")
                elif (landuse == "2010 MOP Landuse" and hyd == "Good"):
                    outGrid =hydro.andlookupgood(optfolder + "/landuse",optfolder + "/Soils")
                    outGrid.save(optfolder + "/curveNumber")
                elif (landuse == "2010 MOP Landuse" and hyd == "Poor"):
                    outGrid =hydro.andlookuppoor(optfolder + "/landuse",optfolder + "/Soils")
                    outGrid.save(optfolder + "/curveNumber")

                if (landuse == "2002 MOP Landuse" and hyd == "Fair"):
                    outGrid =hydro.andlookupfair(optfolder + "/landuse",optfolder + "/Soils")
                    outGrid.save(optfolder + "/curveNumber")
                elif (landuse == "2002 MOP Landuse" and hyd == "Good"):
                    outGrid =hydro.andlookupgood(optfolder + "/landuse",optfolder + "/Soils")
                    outGrid.save(optfolder + "/curveNumber")
                elif (landuse == "2002 MOP Landuse" and hyd == "Poor"):
                    outGrid =hydro.andlookuppoor(optfolder + "/landuse",optfolder + "/Soils")
                    outGrid.save(optfolder + "/curveNumber")

                if (landuse == "1997 MOP Landuse" and hyd == "Fair"):
                    outGrid =hydro.andlookupfair(optfolder + "/landuse",optfolder + "/Soils")
                    outGrid.save(optfolder + "/curveNumber")
                elif (landuse == "1997 MOP Landuse" and hyd == "Good"):
                    outGrid =hydro.andlookupgood(optfolder + "/landuse",optfolder + "/Soils")
                    outGrid.save(optfolder + "/curveNumber")
                elif (landuse == "1997 MOP Landuse" and hyd == "Poor"):
                    outGrid =hydro.andlookuppoor(optfolder + "/landuse",optfolder + "/Soils")
                    outGrid.save(optfolder + "/curveNumber")

                if (landuse == "2002 MD/DE Landuse" and hyd == "Fair"):
                    outGrid =hydro.mddelookupfair(optfolder + "/landuse",optfolder + "/Soils")
                    outGrid.save(optfolder + "/curveNumber")
                elif (landuse == "2002 MD/DE Landuse" and hyd == "Good"):
                    outGrid =hydro.mddelookupgood(optfolder + "/landuse",optfolder + "/Soils")
                    outGrid.save(optfolder + "/curveNumber")
                elif (landuse == "2002 MD/DE Landuse" and hyd == "Poor"):
                    outGrid =hydro.mddelookuppoor(optfolder + "/landuse",optfolder + "/Soils")
                    outGrid.save(optfolder + "/curveNumber")

                if (landuse == "Ultimate Landuse" and hyd == "Fair"):
                    outGrid =hydro.zoninglookupfair(optfolder + "/landuse",optfolder + "/Soils")
                    outGrid.save(optfolder + "/curveNumber")
                elif (landuse == "Ultimate Landuse" and hyd == "Good"):
                    outGrid =hydro.zoninglookupgood(optfolder + "/landuse",optfolder + "/Soils")
                    outGrid.save(optfolder + "/curveNumber")
                elif (landuse == "Ultimate Landuse" and hyd == "Poor"):
                    outGrid =hydro.zoninglookuppoor(optfolder + "/landuse",optfolder + "/Soils")
                    outGrid.save(optfolder + "/curveNumber")

                if (landuse == "MRLC Landuse" and hyd == "Fair"):
                    outGrid =hydro.mrlclookupfair(optfolder + "/landuse",optfolder + "/Soils")
                    outGrid.save(optfolder + "/curveNumber")
                elif (landuse == "MRLC Landuse" and hyd == "Good"):
                    outGrid =hydro.mrlclookupgood(optfolder + "/landuse",optfolder + "/Soils")
                    outGrid.save(optfolder + "/curveNumber")
                elif (landuse == "MRLC Landuse" and hyd == "Poor"):
                    outGrid =hydro.mrlclookuppoor(optfolder + "/landuse",optfolder + "/Soils")
                    outGrid.save(optfolder + "/curveNumber")

                if (landuse == "1970s USGS Landuse" and hyd == "Fair"):
                    outGrid =hydro.usgslookupfair(optfolder + "/landuse",optfolder + "/Soils")
                    outGrid.save(optfolder + "/curveNumber")
                elif (landuse == "1970s USGS Landuse" and hyd == "Good"):
                    outGrid =hydro.usgslookupgood(optfolder + "/landuse",optfolder + "/Soils")
                    outGrid.save(optfolder + "/curveNumber")
                elif (landuse == "1970s USGS Landuse" and hyd == "Poor"):
                    outGrid =hydro.usgslookuppoor(optfolder + "/landuse",optfolder + "/Soils")
                    outGrid.save(optfolder + "/curveNumber")

            # STATSGO data
            else:
                scs = r"" + Directory + "/data/maryland/statsgo_allm.shp"
                mask = optfolder + "/mask.shp"
                output = optfolder + "/Soils.shp"
                arcpy.Clip_analysis(scs, mask, output)
                if (landuse == "NLCD 2011 Landuse" and hyd == "Fair"):
                    opath = optfolder
                    outGrid =hydro.statsgonlcdlookupfair(optfolder + "/landuse", optfolder + "/Soils.shp", opath)
                    outGrid.save(optfolder + "/curveNumber")
                elif (landuse == "NLCD 2011 Landuse" and hyd == "Good"):
                    opath = optfolder
                    outGrid =hydro.statsgonlcdlookupgood(optfolder + "/landuse", optfolder + "/Soils.shp", opath)
                    outGrid.save(optfolder + "/curveNumber")
                elif (landuse == "NLCD 2011 Landuse" and hyd == "Poor"):
                    opath = optfolder
                    outGrid =hydro.statsgonlcdlookuppoor(optfolder + "/landuse", optfolder + "/Soils.shp", opath)
                    outGrid.save(optfolder + "/curveNumber")

                if (landuse == "NLCD 2006 Landuse" and hyd == "Fair"):
                    opath = optfolder
                    outGrid =hydro.statsgonlcdlookupfair(optfolder + "/landuse", optfolder + "/Soils.shp", opath)
                    outGrid.save(optfolder + "/curveNumber")
                elif (landuse == "NLCD 2006 Landuse" and hyd == "Good"):
                    opath = optfolder
                    outGrid =hydro.statsgonlcdlookupgood(optfolder + "/landuse", optfolder + "/Soils.shp", opath)
                    outGrid.save(optfolder + "/curveNumber")
                elif (landuse == "NLCD 2006 Landuse" and hyd == "Poor"):
                    opath = optfolder
                    outGrid =hydro.statsgonlcdlookuppoor(optfolder + "/landuse", optfolder + "/Soils.shp", opath)
                    outGrid.save(optfolder + "/curveNumber")

                if (landuse == "NLCD 2001 Landuse" and hyd == "Fair"):
                    opath = optfolder
                    outGrid =hydro.statsgonlcdlookupfair(optfolder + "/landuse", optfolder + "/Soils.shp", opath)
                    outGrid.save(optfolder + "/curveNumber")
                elif (landuse == "NLCD 2001 Landuse" and hyd == "Good"):
                    opath = optfolder
                    outGrid =hydro.statsgonlcdlookupgood(optfolder + "/landuse", optfolder + "/Soils.shp", opath)
                    outGrid.save(optfolder + "/curveNumber")
                elif (landuse == "NLCD 2001 Landuse" and hyd == "Poor"):
                    opath = optfolder
                    outGrid =hydro.statsgonlcdlookuppoor(optfolder + "/landuse", optfolder + "/Soils.shp", opath)
                    outGrid.save(optfolder + "/curveNumber")

                if (landuse == "2010 MOP Landuse" and hyd == "Fair"):
                    opath = optfolder
                    outGrid =hydro.statsgoandlookupfair(optfolder + "/landuse", optfolder + "/Soils.shp", opath)
                    outGrid.save(optfolder + "/curveNumber")
                elif (landuse == "2010 MOP Landuse" and hyd == "Good"):
                    opath = optfolder
                    outGrid =hydro.statsgoandlookupgood(optfolder + "/landuse", optfolder + "/Soils.shp", opath)
                    outGrid.save(optfolder + "/curveNumber")
                elif (landuse == "2010 MOP Landuse" and hyd == "Poor"):
                    opath = optfolder
                    outGrid =hydro.statsgoandlookuppoor(optfolder + "/landuse", optfolder + "/Soils.shp", opath)
                    outGrid.save(optfolder + "/curveNumber")

                if (landuse == "2002 MOP Landuse" and hyd == "Fair"):
                    opath = optfolder
                    outGrid =hydro.statsgoandlookupfair(optfolder + "/landuse", optfolder + "/Soils.shp", opath)
                    outGrid.save(optfolder + "/curveNumber")
                elif (landuse == "2002 MOP Landuse" and hyd == "Good"):
                    opath = optfolder
                    outGrid =hydro.statsgoandlookupgood(optfolder + "/landuse", optfolder + "/Soils.shp", opath)
                    outGrid.save(optfolder + "/curveNumber")
                elif (landuse == "2002 MOP Landuse" and hyd == "Poor"):
                    opath = optfolder
                    outGrid =hydro.statsgoandlookuppoor(optfolder + "/landuse", optfolder + "/Soils.shp", opath)
                    outGrid.save(optfolder + "/curveNumber")

                if (landuse == "1997 MOP Landuse" and hyd == "Fair"):
                    opath = optfolder
                    outGrid =hydro.statsgoandlookupfair(optfolder + "/landuse", optfolder + "/Soils.shp", opath)
                    outGrid.save(optfolder + "/curveNumber")
                elif (landuse == "1997 MOP Landuse" and hyd == "Good"):
                    opath = optfolder
                    outGrid =hydro.statsgoandlookupgood(optfolder + "/landuse", optfolder + "/Soils.shp", opath)
                    outGrid.save(optfolder + "/curveNumber")
                elif (landuse == "1997 MOP Landuse" and hyd == "Poor"):
                    opath = optfolder
                    outGrid =hydro.statsgoandlookuppoor(optfolder + "/landuse", optfolder + "/Soils.shp", opath)
                    outGrid.save(optfolder + "/curveNumber")

                if (landuse == "2002 MD/DE Landuse" and hyd == "Fair"):
                    opath = optfolder
                    outGrid =hydro.statsgomddelookupfair(optfolder + "/landuse", optfolder + "/Soils.shp", opath)
                    outGrid.save(optfolder + "/curveNumber")
                elif (landuse == "2002 MD/DE Landuse" and hyd == "Good"):
                    opath = optfolder
                    outGrid =hydro.statsgomddelookupgood(optfolder + "/landuse", optfolder + "/Soils.shp", opath)
                    outGrid.save(optfolder + "/curveNumber")
                elif (landuse == "2002 MD/DE Landuse" and hyd == "Poor"):
                    opath = optfolder
                    outGrid =hydro.statsgomddelookuppoor(optfolder + "/landuse", optfolder + "/Soils.shp", opath)
                    outGrid.save(optfolder + "/curveNumber")

                if (landuse == "Ultimate Landuse" and hyd == "Fair"):
                    opath = optfolder
                    outGrid =hydro.statsgozoninglookupfair(optfolder + "/landuse", optfolder + "/Soils.shp", opath)
                    outGrid.save(optfolder + "/curveNumber")
                elif (landuse == "Ultimate Landuse" and hyd == "Good"):
                    opath = optfolder
                    outGrid =hydro.statsgozoninglookupgood(optfolder + "/landuse", optfolder + "/Soils.shp", opath)
                    outGrid.save(optfolder + "/curveNumber")
                elif (landuse == "Ultimate Landuse" and hyd == "Poor"):
                    opath = optfolder
                    outGrid =hydro.statsgozoninglookuppoor(optfolder + "/landuse", optfolder + "/Soils.shp", opath)
                    outGrid.save(optfolder + "/curveNumber")

                if (landuse == "MRLC Landuse" and hyd == "Fair"):
                    opath = optfolder
                    outGrid =hydro.statsgomrlclookupfair(optfolder + "/landuse", optfolder + "/Soils.shp", opath)
                    outGrid.save(optfolder + "/curveNumber")
                elif (landuse == "MRLC Landuse" and hyd == "Good"):
                    opath = optfolder
                    outGrid =hydro.statsgomrlclookupgood(optfolder + "/landuse", optfolder + "/Soils.shp", opath)
                    outGrid.save(optfolder + "/curveNumber")
                elif (landuse == "MRLC Landuse" and hyd == "Poor"):
                    opath = optfolder
                    outGrid =hydro.statsgomrlclookuppoor(optfolder + "/landuse", optfolder + "/Soils.shp", opath)
                    outGrid.save(optfolder + "/curveNumber")

                if (landuse == "1970s USGS Landuse" and hyd == "Fair"):
                    opath = optfolder
                    outGrid =hydro.statsgousgslookupfair(optfolder + "/landuse", optfolder + "/Soils.shp", opath)
                    outGrid.save(optfolder + "/curveNumber")
                elif (landuse == "1970s USGS Landuse" and hyd == "Good"):
                    opath = optfolder
                    outGrid =hydro.statsgousgslookupgood(optfolder + "/landuse", optfolder + "/Soils.shp", opath)
                    outGrid.save(optfolder + "/curveNumber")
                elif (landuse == "1970s USGS Landuse" and hyd == "Poor"):
                    opath = optfolder
                    outGrid =hydro.statsgousgslookuppoor(optfolder + "/landuse", optfolder + "/Soils.shp", opath)
                    outGrid.save(optfolder + "/curveNumber")

            #*******************************************************************************************************
            # clip drainage data to be placed at the top for watershed extraction
            #*******************************************************************************************************

            arcpy.Clip_management(r"" + Directory + "/data/dems/flowacc", "%f %f %f %f" %(extent.XMin, extent.YMin, extent.XMax, extent.YMax),
                                  optfolder + "/mask_flow", "#", "#", "NONE")
            ras = arcpy.Raster(optfolder + "/mask_flow")
            flow_save = arcpy.sa.Con(ras >= fa_thres, optfolder + "/mask_flow")
            flow_save.save(optfolder + "/InfStreams")

            mxd = arcpy.mapping.MapDocument("CURRENT")
            df = arcpy.mapping.ListDataFrames(mxd)[0]
            addLayer = arcpy.mapping.Layer(optfolder + "/InfStreams")
            arcpy.mapping.AddLayer(df, addLayer, "AUTO_ARRANGE")

       #*******************************************************************************************************
        # create "AddasStreams.shp" for to be used in subwatershed delineation
        #*******************************************************************************************************
        spatial_reference = arcpy.Describe(optfolder + "/flowdir").spatialReference
        arcpy.CreateFeatureclass_management(optfolder, "AddasStreams.shp", "POLYLINE", "", "ENABLED", "DISABLED", spatial_reference)

        #*******************************************************************************************************
        # create "AddasOutlets.shp" to add user specified outlets
        #*******************************************************************************************************
        spatial_reference = arcpy.Describe(optfolder + "/flowdir").spatialReference
        arcpy.CreateFeatureclass_management(optfolder, "AddasOutlets.shp", "POINT", "", "ENABLED", "DISABLED", spatial_reference)


        ######## Flow dir reset aux

        #*******************************************************************************************************
        # turn layers ON/OFF in current data frame
        #*******************************************************************************************************
        mxd = arcpy.mapping.MapDocument("CURRENT")
        df = arcpy.mapping.ListDataFrames(mxd)[0]
        layers = arcpy.mapping.ListLayers(mxd, "", df)
        for lyr in layers:
            if lyr.name == "flowdir":
                lyr.visible = False
            if lyr.name == "flowacc":
                lyr.visible = False
            if lyr.name == "Soils":
                lyr.visible = False
            if lyr.name == "MD Quads":
                lyr.visible = False
            if lyr.name == "Inferred Stream":
                lyr.visible = False
            if lyr.name == "DEM":
                lyr.visible = False
            if lyr.name == "mask":
                arcpy.ApplySymbologyFromLayer_management(lyr,r"" + Directory + "/data/mdfiles/legends/extent.lyr")
            if lyr.name == "InfStreams":
                lyr.name = "Inferred Streams"
                arcpy.ApplySymbologyFromLayer_management(lyr,r"" + Directory + "/data/mdfiles/legends/infstreams.lyr")
            if lyr.name == "landuse":
                lyr.visible = False
            if lyr.name == "ssurgo":
                lyr.visible = False
            if lyr.name == "dem":
                arcpy.ApplySymbologyFromLayer_management(lyr,r"" + Directory + "/data/mdfiles/legends/dem.lyr")
            if lyr.name == "soilG_a":
                arcpy.mapping.RemoveLayer(df, lyr)
            if lyr.name == "soilG_b":
                arcpy.mapping.RemoveLayer(df, lyr)
            if lyr.name == "soilG_c":
                arcpy.mapping.RemoveLayer(df, lyr)
            if lyr.name == "soilG_d":
                arcpy.mapping.RemoveLayer(df, lyr)
            if lyr.name == "water_grid":
                arcpy.mapping.RemoveLayer(df, lyr)
            if lyr.name == "mask_flow":
                arcpy.mapping.RemoveLayer(df, lyr)
                arcpy.Delete_management(lyr)

        arcpy.CopyRaster_management(optfolder + "/flowdir", optfolder + "/flowdir_dem")
        mxd = arcpy.mapping.MapDocument("CURRENT")
        df = arcpy.mapping.ListDataFrames(mxd)[0]
        layers = arcpy.mapping.ListLayers(mxd, "", df)
        for lyr in layers:
            if lyr.name == "flowdir_dem":
                arcpy.mapping.RemoveLayer(df, lyr)
            if lyr.name == "flowdir":
                lyr.visible = False

        tables = arcpy.mapping.ListTableViews(mxd, "", df)
        for tbl in tables:
            if tbl.name == "theVTab":
                arcpy.mapping.RemoveTableView(df, tbl)
                
        arcpy.RefreshTOC()
        arcpy.RefreshActiveView()

        #******************************************************************************************************
        # turn AoI OFF and watershed delineation ON
        #******************************************************************************************************
        tool1.enabled = False
        tool2.enabled = True
        button16.enabled = True
        mxd = arcpy.mapping.MapDocument("CURRENT")
        df = arcpy.mapping.ListDataFrames(mxd, "Layers")[0]
        lyr = arcpy.mapping.ListLayers(mxd, "dem", df)[0]
        df.extent = lyr.getSelectedExtent()

class GageListThomas(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, -1, "Please select gage for Tasker analysis adjustment", size=(300, 150))
        self.Bind(wx.EVT_CLOSE, self.OnClose)
        panel = wx.Panel(self, -1)

        wx.StaticText(panel, -1, "Watershed contains USGS Gage(s)", (15, 15))
        GageList = gagelist + ["Perform No Adjustment"]
        self.gage = wx.ComboBox(panel, -1, "'Select'", (30, 30), wx.DefaultSize,GageList, wx.CB_DROPDOWN)
      
        self.btnApply = wx.Button(panel, label="Apply", pos=(80, 65))
        self.Bind(wx.EVT_BUTTON, self.OnSet, id=self.btnApply.GetId())
        
        self.Show(True)
        self.Centre(True)
        style = self.GetWindowStyle()
        self.SetWindowStyle( style | wx.STAY_ON_TOP )

    def OnClose(self, event):
        self.Show(False)
        mxd = arcpy.mapping.MapDocument("CURRENT")
        df = arcpy.mapping.ListDataFrames(mxd)[0]
        layers = arcpy.mapping.ListLayers(mxd, "", df)
        for lyr in layers:
            if lyr.name == "outletbuffer":
                arcpy.Delete_management(lyr)
                arcpy.mapping.RemoveLayer(df, lyr)
            if lyr.name == "gagefield":
                arcpy.Delete_management(lyr)
                arcpy.mapping.RemoveLayer(df, lyr)
            if lyr.name == "mdlayer":
                arcpy.Delete_management(lyr)
                arcpy.mapping.RemoveLayer(df, lyr)

        arcpy.RefreshTOC()
        arcpy.RefreshActiveView()

    def OnSet(self, event):
        arcpy.env.scratchWorkspace = scratchfolder
        arcpy.env.workspace = optfolder
        global gageid
        gageid = str(self.gage.GetValue())
        self.Show(False)

        #******************************************************************************************************
        # read global variables (defined in basin stat) into variable names for use
        # in Thomas peak discharge analysis
        #******************************************************************************************************
        FC = float(hydro.FC) # LI is already declared as global variable
        FC = "{0:.2f}".format(FC)
        DA = areami2
        HA = float(hydro.pctAsoil)
        HC = float(hydro.pctCsoil)
        HD = float(hydro.pctDsoil)
        SLL = float(landslope)
        HCD = float(HC+HD)
        ImpA = float(IA)

        #******************************************************************************************************
        # define initial values and lists. add and index those lists as part of dictionary
        #******************************************************************************************************
        sumarea = 0
        provstring = ""
        outtaskerstring = ""
        sQ1p25 = 0
        sQ1p50 = 0
        sQ1p75 = 0
        sQ2 = 0
        sQ5 = 0
        sQ10 = 0
        sQ25 = 0
        sQ50 = 0
        sQ100 = 0
        sQ200 = 0
        sQ500 = 0
        Q1p25list = [0, 0, 0, 0, 0, 0, 0, 0]
        Q1p50list = [0, 0, 0, 0, 0, 0, 0, 0]
        Q2list = [0, 0, 0, 0, 0, 0, 0, 0]
        Q5list = [0, 0, 0, 0, 0, 0, 0, 0]
        Q10list = [0, 0, 0, 0, 0, 0, 0, 0]
        Q25list = [0, 0, 0, 0, 0, 0, 0, 0]
        Q50list = [0, 0, 0, 0, 0, 0, 0, 0]
        Q100list = [0, 0, 0, 0, 0, 0, 0, 0]
        Q200list = [0, 0, 0, 0, 0, 0, 0, 0]
        Q500list = [0, 0, 0, 0, 0, 0, 0, 0]

        qlist = {"1":[],"2":[],"3":[],"4":[],"5":[],"6":[],"7":[],"8":[],"9":[],"10":[]}
        qlist["1"].extend(Q1p25list)
        qlist["2"].extend(Q1p50list)
        qlist["3"].extend(Q2list)
        qlist["4"].extend(Q5list)
        qlist["5"].extend(Q10list)
        qlist["6"].extend(Q25list)
        qlist["7"].extend(Q50list)
        qlist["8"].extend(Q100list)
        qlist["9"].extend(Q200list)
        qlist["10"].extend(Q500list)

        #******************************************************************************************************
        # copy root tasker files into optfolder 
        #******************************************************************************************************
        src = r"" + Directory + "/data/tasker"
        dst = optfolder + "/tasker"
        shutil.copytree(src, dst)

        #******************************************************************************************************
        # read zonal stat table (theVTab), declare fields into variables, and
        # loop through theVTab fields to getValue
        #******************************************************************************************************
        theVTab = optfolder + "/theVTab.dbf"
        theVTab = arcpy.SearchCursor("theVTab","","","Count","")
        
        #******************************************************************************************************
        # loop to get total count of pixels of basingrid
        #******************************************************************************************************
        for each in theVTab:
            count = each.getValue("Count")
            sumarea = sumarea+count
        sumArea = sumarea

        del each

        theVTab = optfolder + "/theVTab.dbf"
        theVTab = arcpy.SearchCursor("theVTab","","","Province;Count;Q1.25;Q1.50;Q1.75;Q2;Q5;Q10;Q25;Q50;Q100;Q200;Q500","")

        # loop to begin tasker handling and area weighted analysis
        discharge_values = []
        flood_intervals = []
        for row in theVTab:
            AreaField = float(row.getValue("Count"))
            areapercent = float((AreaField/sumArea)* 100)
            if row.getValue("Province") == "A":
                provstring = provstring + "       -Appalachian Plateaus and Allegheny Ridges %s percent of area" "\n" %("{0:.2f}".format(areapercent))
            elif row.getValue("Province") == "B":
                provstring = provstring + "       -Blue Ridge and Great Valley %s percent of area" "\n" %("{0:.2f}".format(areapercent))
            elif row.getValue("Province") == "P":
                provstring = provstring + "       -Piedmont %s percent of area" "\n" %("{0:.2f}".format(areapercent))
            elif row.getValue("Province") == "W":
                provstring = provstring + "       -Western Coastal Plain %s percent of area" "\n" %("{0:.2f}".format(areapercent))
            elif row.getValue("Province") == "E":
                provstring = provstring + "       -Eastern Coastal Plain %s percent of area" "\n" %("{0:.2f}".format(areapercent))
            else:
                pythonaddins.MessageBox("No Province Selected", "Problem...", 0)

            intaskerstring = "thomasout.txt" "\n"
            intaskerstring = intaskerstring + "" "\n"
            if row.getValue("Province") == "A":
                intaskerstring = intaskerstring + "a"  "\n"
                intaskerstring = intaskerstring + "%s" "\n" %(DA)
                intaskerstring = intaskerstring + "%s" "\n" %(SLL)
            elif row.getValue("Province") == "B":
                intaskerstring = intaskerstring + "p"  "\n"
                intaskerstring = intaskerstring + "%s" "\n" %(DA)
                intaskerstring = intaskerstring + "%s" "\n" %(FC)
                intaskerstring = intaskerstring + "%s" "\n" %(LI)
                intaskerstring = intaskerstring + "%s" "\n" %(ImpA)
            elif row.getValue("Province") == "P":
                intaskerstring = intaskerstring + "p"  "\n"
                intaskerstring = intaskerstring + "%s" "\n" %(DA)
                intaskerstring = intaskerstring + "%s" "\n" %(FC)
                intaskerstring = intaskerstring + "%s" "\n" %(LI)
                intaskerstring = intaskerstring + "%s" "\n" %(ImpA)

            elif row.getValue("Province") == "W":
                intaskerstring = intaskerstring + "wc" "\n"
                intaskerstring = intaskerstring + "%s" "\n" %(DA) 
                intaskerstring = intaskerstring + "%s" "\n" %(ImpA)
                intaskerstring = intaskerstring + "%s" "\n" %(HCD)
            elif row.getValue("Province") == "E":
                intaskerstring = intaskerstring + "ec" "\n"
                intaskerstring = intaskerstring + "%s" "\n" %(DA)
                intaskerstring = intaskerstring + "%s" "\n" %(SLL)
                intaskerstring = intaskerstring + "%s" "\n" %(HA)

            if gageid == "Perform No Adjustment":
                intaskerstring = intaskerstring + "N" "\n"
                intaskerstring = intaskerstring + "N" "\n"
            else:
                intaskerstring = intaskerstring + "Y" "\n"
                intaskerstring = intaskerstring + "%s" "\n" %(gageid)
                intaskerstring = intaskerstring + "N" "\n"

            thomas2016 = optfolder + "/tasker/thomas2016.txt"
            thomasin = open(thomas2016, "w")
            thomasin.write(intaskerstring)
            thomasin.close()

            os.chdir(optfolder + "/tasker")
            os.system(optfolder + "/tasker/thomas2016auto.exe")
            time.sleep(4)

            #*****************************************************************************        
            # open "thomasout.txt" file and read peak discharges
            #*****************************************************************************

            infilename = optfolder + "/tasker/thomasout.txt"
            infile = open(infilename,"r").readlines()

            for i in infile:
                outtaskerstring = outtaskerstring + i

            #*****************************************************************************
            # Discharge values for each province for "theVTab" are not possible to write
            # at this time because update cursor can"t be used within search cursor "for"
            # loop -- appended to list "discharge_values" and will be used at the end to
            # update discharge values in "theVTab" 
            #*****************************************************************************
            theline = infile[11].split()
            Q1p25 = theline[1]
            discharge_values.append(Q1p25)
            theline = infile[12].split()
            Q1p50 = theline[1]
            discharge_values.append(Q1p50)
            Q1p75 = -999
            theline = infile[13].split()
            Q2 = theline[1]
            discharge_values.append(Q2)
            theline = infile[14].split()
            Q5 = theline[1]
            discharge_values.append(Q5)
            theline = infile[15].split()
            Q10 = theline[1]
            discharge_values.append(Q10)
            theline = infile[16].split()
            Q25 = theline[1]
            discharge_values.append(Q25)
            theline = infile[17].split()
            Q50 = theline[1]
            discharge_values.append(Q50)
            theline = infile[18].split()
            Q100 = theline[1]
            discharge_values.append(Q100)
            theline = infile[19].split()
            Q200 = theline[1]
            discharge_values.append(Q200)
            theline = infile[20].split()
            Q500 = theline[1]
            discharge_values.append(Q500)

            #*****************************************************************************
            # compute discharge and assign confidence intervals to qlist entries
            #*****************************************************************************
            Q1p25 = float(Q1p25)
            sQ1p25 = sQ1p25 + (Q1p25* AreaField)
            Q1p50 = float(Q1p50)
            sQ1p50 = sQ1p50 + (Q1p50* AreaField)
            Q1p75 = float(Q1p75)
            sQ1p75 = sQ1p75 + (Q1p75* AreaField)
            Q2 = float(Q2)
            sQ2 = sQ2 + (Q2* AreaField)
            Q5 = float(Q5)
            sQ5 = sQ5 + (Q5* AreaField)
            Q10 = float(Q10)
            sQ10 = sQ10 + (Q10* AreaField)
            Q25 = float(Q25)
            sQ25 = sQ25 + (Q25* AreaField)
            Q50 = float(Q50)
            sQ50 = sQ50 + (Q50* AreaField)
            Q100 = float(Q100)
            sQ100 = sQ100 + (Q100* AreaField)
            Q200 = float(Q200)
            sQ200 = sQ200 + (Q200* AreaField)
            Q500 = float(Q500)
            sQ500 = sQ500 + (Q500* AreaField)

            for i, lines in enumerate(infile):
                if i > 24 and i < 35:
                    line = lines.split()
                    a1 = line[1]
                    a2 = line[2]
                    a3 = line[3]
                    a4 = line[4]
                    a5 = line[5]
                    a6 = line[6]
                    a7 = line[7]
                    a8 = line[8]
                    c1 = [(float(a1)* areapercent)/100]
                    c2 = [(float(a2)* areapercent)/100]
                    c3 = [(float(a3)* areapercent)/100]
                    c4 = [(float(a4)* areapercent)/100]
                    c5 = [(float(a5)* areapercent)/100]
                    c6 = [(float(a6)* areapercent)/100]
                    c7 = [(float(a7)* areapercent)/100]
                    c8 = [(float(a8)* areapercent)/100]
                    qlist = [c1,c2,c3,c4,c5,c6,c7,c8]
                    flood_intervals.append(qlist)

        lists = {i:[el[0] for el in v] for i, v in enumerate(flood_intervals, start=1)}
                
        del row

        #******************************************************************************************************
        # index and count number of sub-lists -- prepare for TaskerString function
        #******************************************************************************************************
        number = hydro.FloodIntervalLists(lists)
        if number > 10:
            q_list1 = [sum(i) for i in zip(lists[1],lists[11])]
            q_list2 = [sum(i) for i in zip(lists[2],lists[12])]
            q_list3 = [sum(i) for i in zip(lists[3],lists[13])]
            q_list4 = [sum(i) for i in zip(lists[4],lists[14])]
            q_list5 = [sum(i) for i in zip(lists[5],lists[15])]
            q_list6 = [sum(i) for i in zip(lists[6],lists[16])]
            q_list7 = [sum(i) for i in zip(lists[7],lists[17])]
            q_list8 = [sum(i) for i in zip(lists[8],lists[18])]
            q_list9 = [sum(i) for i in zip(lists[9],lists[19])]
            q_list10 = [sum(i) for i in zip(lists[10],lists[20])]
        else:
            q_list1 = lists[1]
            q_list2 = lists[2]
            q_list3 = lists[3]
            q_list4 = lists[4]
            q_list5 = lists[5]
            q_list6 = lists[6]
            q_list7 = lists[7]
            q_list8 = lists[8]
            q_list9 = lists[9]
            q_list10 = lists[10]

        #******************************************************************************************************
        # discharge computation based on province
        #******************************************************************************************************
        Q1p25 = int(sQ1p25/sumArea)
        Q1p50 = int(sQ1p50/sumArea)
        Q1p75 = int(sQ1p75/sumArea)
        Q2 = int(sQ2/sumArea)
        Q5 = int(sQ5/sumArea)
        Q10 = int(sQ10/sumArea)
        Q25 = int(sQ25/sumArea)
        Q50 = int(sQ50/sumArea)
        Q100 = int(sQ100/sumArea)
        Q200 = int(sQ200/sumArea)
        Q500 = int(sQ500/sumArea)

        #******************************************************************************************************
        # Basin statistics analysis date
        #******************************************************************************************************
        now = datetime.now()
        month = now.strftime("%B")
        day = now.strftime("%d")
        year = now.strftime("%Y")

        #******************************************************************************************************
        # Text file string variables
        #******************************************************************************************************
        datastring = ""
        datastring = datastring + "GISHydro Release Version Date: %s" "\n" %(Modifieddt)
        datastring = datastring + "Project Name:                  %s" %(proj)
        datastring = datastring + "" "\n"
        datastring = datastring + "Analysis Date:                 %s %s, %s " "\n" %(month,day,year) 
        datastring = datastring + "Geographic Province(s):" "\n"
        datastring = datastring + provstring
        datastring = datastring + "" "\n"
        datastring = datastring + "Q(1.25):   %s cfs" "\n" %(Q1p25)
        datastring = datastring + "Q(1.50):   %s cfs" "\n" %(Q1p50)
        datastring = datastring + "Q(2):      %s cfs" "\n" %(Q2)
        datastring = datastring + "Q(5):      %s cfs" "\n" %(Q5)
        datastring = datastring + "Q(10):     %s cfs" "\n" %(Q10)
        datastring = datastring + "Q(25):     %s cfs" "\n" %(Q25)
        datastring = datastring + "Q(50):     %s cfs" "\n" %(Q50)
        datastring = datastring + "Q(100):    %s cfs" "\n" %(Q100)
        datastring = datastring + "Q(200):    %s cfs" "\n" %(Q200)
        datastring = datastring + "Q(500):    %s cfs" "\n" %(Q500)
        datastring = datastring + "" "\n"
        datastring = datastring + "Area Weighted Prediction Intervals (from Tasker)" "\n"
        datastring = datastring + " Return     50 PERCENT        67 PERCENT        90 PERCENT        95 PERCENT" "\n"
        datastring = datastring + " Period  lower    upper    lower    upper    lower    upper    lower    upper" "\n"
        datastring = datastring + hydro.TaskerString(1.25,q_list1)
        datastring = datastring + "" "\n"
        datastring = datastring + hydro.TaskerString(1.50,q_list2)
        datastring = datastring + "" "\n"
        datastring = datastring + hydro.TaskerString(2,q_list3)
        datastring = datastring + "" "\n"
        datastring = datastring + hydro.TaskerString(5,q_list4)
        datastring = datastring + "" "\n"
        datastring = datastring + hydro.TaskerString(10,q_list5)
        datastring = datastring + "" "\n"
        datastring = datastring + hydro.TaskerString(25,q_list6)
        datastring = datastring + "" "\n"
        datastring = datastring + hydro.TaskerString(50,q_list7)
        datastring = datastring + "" "\n"
        datastring = datastring + hydro.TaskerString(100,q_list8)
        datastring = datastring + "" "\n"
        datastring = datastring + hydro.TaskerString(200,q_list9)
        datastring = datastring + "" "\n"
        datastring = datastring + hydro.TaskerString(500,q_list10)
        datastring = datastring + "" "\n"
        datastring = datastring + "" "\n"
        datastring = datastring + "" "\n"
        datastring = datastring + "Individual Province Tasker Analyses Follow: " "\n"
        datastring = datastring + ""
        datastring = datastring + outtaskerstring

        #******************************************************************************************************
        # write strings to basin stat text file.
        #******************************************************************************************************
        defFN = optfolder + "/frdischarges.txt"
        fr = open(defFN,"w")
        fr.write(datastring)
        fr.close()

        #******************************************************************************************************
        # open "frdischarges" file in text editor
        #******************************************************************************************************

        hydro.openbrowser(defFN)

        #******************************************************************************************************
        # turn layers ON/OFF in current data frame
        #******************************************************************************************************
        mxd = arcpy.mapping.MapDocument("CURRENT")
        df = arcpy.mapping.ListDataFrames(mxd)[0]
        layers = arcpy.mapping.ListLayers(mxd, "", df)
        for lyr in layers:
            if lyr.name == "mdlayer":
                arcpy.mapping.RemoveLayer(df, lyr)
            if lyr.name == "gagefield":
                arcpy.mapping.RemoveLayer(df, lyr)
            if lyr.name == "outletpoint":
                arcpy.mapping.RemoveLayer(df, lyr)
            if lyr.name == "outletpoly":
                arcpy.mapping.RemoveLayer(df, lyr)
            if lyr.name == "limepoly":
                arcpy.mapping.RemoveLayer(df, lyr)
            if lyr.name == "outletpoint":
                arcpy.mapping.RemoveLayer(df, lyr)
            if lyr.name == "outletbuffer":
                arcpy.mapping.RemoveLayer(df, lyr)
            if lyr.name == "gagefield":
                arcpy.mapping.RemoveLayer(df, lyr)
            if lyr.name == "outletpoly":
                arcpy.mapping.RemoveLayer(df, lyr)
            if lyr.name == "mask_ints": # added on 10-22-2017: this layer is output of intersect tool
                arcpy.mapping.RemoveLayer(df, lyr)
            if lyr.name == "gauge_outlet": # added on 10-22-2017: this layer is output of join and intersect tool
                arcpy.mapping.RemoveLayer(df, lyr)

        arcpy.RefreshTOC()
        arcpy.RefreshActiveView()

        #******************************************************************************************************
        # turn "peak discharge" OFF, and "S", "Reset Sub-watershed & Add Streams ON
        #******************************************************************************************************
        button4.enabled = False
        button5_1.enabled = True
        button6.enabled = True
        tool4.enabled = True


class SegMergeDialog(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, -1, "Velocity Method Segment Generator", size=(580, 500))
        self.Bind(wx.EVT_CLOSE, self.OnClose)
        panel = wx.Panel(self, -1)

        self.SetPosition((30, 30))

        text1 = wx.StaticText(panel, -1, "Select Sub-Area", (30, 25))
        text1.SetForegroundColour((255,0,0)) # set text color

        self.subID = wx.ComboBox(panel, -1, "", (55, 45), (50, -1), arcid_list, wx.CB_DROPDOWN)
        
        wx.StaticBox(panel, -1, "Create/Update Segment", (15, 90), size=(250,340))
        wx.StaticBox(panel, -1, "Quick Merge", (30, 120), size=(220,120))
        wx.StaticText(panel, -1, "Single Overland", (100, 150))
        self.cb1 = wx.CheckBox(panel, -1, "", pos=(70,150))
        wx.StaticText(panel, -1, "Single Swale", (100, 180))
        self.cb2 = wx.CheckBox(panel, -1, "", pos=(70,180))
        wx.StaticText(panel, -1, "Single Channel", (100, 210))
        self.cb3 = wx.CheckBox(panel, -1, "", pos=(70,210))
        
        wx.StaticBox(panel, -1, "Merge Specific Segment", (30, 250), size=(220,110))
        wx.StaticText(panel, -1, "Upstream Pixel #", (40, 280))
        self.uspixel = wx.TextCtrl(panel, -1, value="", pos=(170, 275), size=(65,25))
        wx.StaticText(panel, -1, "Downstream Pixel #", (40, 315))
        self.dspixel = wx.TextCtrl(panel, -1, value="", pos=(170, 310), size=(65,25))

        wx.StaticBox(panel, -1, "Velocity Method Statistics", (280, 40), size=(260,340))
        wx.StaticText(panel, -1, "Sub-Area #", (290, 70))
        self.sanumber = wx.TextCtrl(panel, -1, value="", pos=(455, 65), size=(75,25), style = wx.TE_READONLY) # Sub-area number
        wx.StaticText(panel, -1, "Overall Travel Time (hrs):", (290, 110))
        self.Overall_Tc = wx.TextCtrl(panel, -1, value="", pos=(455, 105), size=(75,25), style = wx.TE_READONLY) # overall Tc hrs
        wx.StaticText(panel, -1, "Overland Travel Time (hrs):", (290, 150))
        self.over_Tc = wx.TextCtrl(panel, -1, value="", pos=(455, 145), size=(75,25), style = wx.TE_READONLY) # overland Tc hrs
        wx.StaticText(panel, -1, "Swale Travel Time (hrs):", (290, 190))
        self.swale_Tc = wx.TextCtrl(panel, -1, value="", pos=(455, 185), size=(75,25), style = wx.TE_READONLY) # swale Tc hrs
        wx.StaticText(panel, -1, "Channel Travel Time (hrs):", (290, 230))
        self.chan_Tc = wx.TextCtrl(panel, -1, value="", pos=(455, 225), size=(75,25), style = wx.TE_READONLY) # channel Tc hrs
        wx.StaticText(panel, -1, "# Overland Segments:", (290, 270))
        self.over_seg = wx.TextCtrl(panel, -1, value="", pos=(455, 265), size=(75,25), style = wx.TE_READONLY) # overland segments
        wx.StaticText(panel, -1, "# Swale Segments:", (290, 310))
        self.swale_seg = wx.TextCtrl(panel, -1, value="", pos=(455, 305), size=(75,25), style = wx.TE_READONLY) # swale segments
        wx.StaticText(panel, -1, "# Channel Segments:", (290, 350))
        self.chan_seg = wx.TextCtrl(panel, -1, value="", pos=(455, 345), size=(75,25), style = wx.TE_READONLY) # channel segments

        self.btnApply = wx.Button(panel, label="Recalculate Tc", pos=(90,380))
        self.Bind(wx.EVT_BUTTON, self.RecalculateTc, id=self.btnApply.GetId())

        self.btnApply = wx.Button(panel, label="Close Dialog", pos=(450, 400))
        self.Bind(wx.EVT_BUTTON, self.OnClose, id=self.btnApply.GetId())

        self.btnApply = wx.Button(panel, label="Apply", pos=(140, 45))
        self.Bind(wx.EVT_BUTTON, self.OnApply, id=self.btnApply.GetId())
        
        self.Show(True)
        
        global notable
        notable = np.ones(int(arcid))
        
    def RecalculateTc(self, event):
        arcpy.env.scratchWorkspace = scratchfolder
        arcpy.env.workspace = optfolder
        global attlist
        single_overland = 0
        single_swale = 0
        single_channel = 0
        
        if self.cb1.IsChecked():
            single_overland = 1
        if self.cb2.IsChecked():
            single_swale = 1
        if self.cb3.IsChecked():
            single_channel = 1
        
        UPPX = self.uspixel.GetValue()
        DWNPX = self.dspixel.GetValue()
        if UPPX =="" and DWNPX == "":
            UPPX = -1
            DWNPX = -1
        else:
            UPPX = int(UPPX)
            DWNPX = int(DWNPX)

        channeln = float(Tc_nc)
        overland_n = float(Tc_ns)
        w_coef = float(Tc_cwCoef)
        w_exp = float(Tc_cwExp)
        d_coef = float(Tc_cdCoef)
        d_exp = float(Tc_cdExp)
        a_coef = float(Tc_caCoef)
        a_exp = float(Tc_caExp)
        P2 = float(Tc_P)
        l_tc = float(Tc_L)

        attlist_merge = [list(elem) for elem in attlist]
        attlist = attlist_merge
        attlist1 = attlist_merge
        attlist2 = attlist_merge
        attlist3 = attlist_merge
        overland_list = [i for i in attlist1 if i[4] == "overland"]
        swale_list = [i for i in attlist2 if i[4] == "swale"]
        channel_list = [i for i in attlist3 if i[4] == "channel"]
        
        if len(overland_list) != 0 and len(swale_list) != 0 and UPPX < overland_list[-1][5] and DWNPX > swale_list[0][2] and UPPX != -1:
            pythonaddins.MessageBox("Up and Down pixel flow types are different. Please select up and down pixels of same type.","Segment Merge Error",0)
            return
        if len(channel_list) != 0 and len(swale_list) != 0 and UPPX < swale_list[-1][5] and DWNPX > channel_list[0][2] and UPPX != -1:
            pythonaddins.MessageBox("Up and Down pixel flow types are different. Please select up and down pixels of same type.","Segment Merge Error",0)
            return

        if single_overland == 1 and len(overland_list) != 0:
            shape = overland_list[0][1]
            uppxl = float(overland_list[0][2])
            Type = overland_list[0][4]
            dwpxl = float(overland_list[-1][5])
            avgarea = 0
            for col in overland_list:
                avgarea = (float(col[5])-float(col[2]))*float(col[6]) + avgarea
            avgarea = avgarea/(float(overland_list[-1][5]) - float(overland_list[0][2]))
            dsarea = np.sum(map(float,[col[7] for col in overland_list]))
            upelev = float(overland_list[0][8])
            dwnelev = float(overland_list[-1][9])
            ilength = np.sum(map(float,[col[14] for col in overland_list]))
            slope = (upelev - dwnelev)/ilength
            width = np.mean(map(float,[col[11] for col in overland_list]))
            depth = np.mean(map(float,[col[12] for col in overland_list]))
            xarea = np.mean(map(float,[col[13] for col in overland_list]))
            totlength = ilength
            if ilength > l_tc:                    
                iswale = ilength - l_tc
                vel_s = 16.1345 * (slope**0.5)
                if Tc_unpaved:
                    vel_s = 20.3282 * (slope**0.5)
                swaletinc = iswale / (vel_s * 3600)
                overtinc = 0.007 * ((overland_n * l_tc) ** 0.8) / ((P2 ** 0.5) * (slope ** 0.4))
                itime = overtinc + swaletinc
                vel = ilength / (itime * 3600)
            else:
                itime = 0.007 * ((overland_n * ilength) ** 0.8) / ((P2 ** 0.5) * (slope ** 0.4))
                vel = ilength / (itime * 3600)
            tottime = itime
            if np.isnan(vel) or vel == 0:
                vel = 0.001
            overland_list = [[[],shape,uppxl,[],Type,dwpxl,avgarea,dsarea,upelev,dwnelev,
                             slope,width,depth,xarea,ilength,totlength,vel,itime,tottime]]
        
        if single_swale == 1 and len(swale_list) != 0:
            shape = swale_list[0][1]
            uppxl = float(swale_list[0][2])
            Type = swale_list[0][4]
            dwpxl = float(swale_list[-1][5])
            avgarea = 0
            for col in swale_list:
                avgarea = (float(col[5])-float(col[2]))*float(col[6]) + avgarea
            avgarea = avgarea/(float(swale_list[-1][5]) - float(swale_list[0][2]))
            dsarea = np.sum(map(float,[col[7] for col in swale_list]))
            upelev = float(swale_list[0][8])
            dwnelev = float(swale_list[-1][9])
            ilength = np.sum(map(float,[col[14] for col in swale_list]))
            slope = (upelev - dwnelev)/ilength
            width = np.mean(map(float,[col[11] for col in swale_list]))
            depth = np.mean(map(float,[col[12] for col in swale_list]))
            xarea = np.mean(map(float,[col[13] for col in swale_list]))
            if len(overland_list) != 0:
                totlength = ilength + float(overland_list[-1][15])
            else:
                totlength = ilength
            vel = 16.1345*slope**0.5
            if Tc_unpaved:
                 vel = 20.3282 *slope**0.5
            if np.isnan(vel) or vel == 0:
                vel = 0.001
            itime = ilength/vel/3600
            if len(overland_list) != 0:
                tottime = itime + float(overland_list[-1][18])
            else:
                tottime = itime
            swale_list = [[[],shape,uppxl,[],Type,dwpxl,avgarea,dsarea,upelev,dwnelev,
                              slope,width,depth,xarea,ilength,totlength,vel,itime,tottime]]
        
        if single_swale == 0 and len(swale_list) != 0 and UPPX >= float(swale_list[0][2]) and DWNPX > UPPX and DWNPX <= float(swale_list[-1][5]):
            swale_list_1 = [i for i in swale_list if float(i[2]) < UPPX]
            swale_list_2 = [i for i in swale_list if float(i[2]) >= UPPX and float(i[5]) <= DWNPX]
            swale_list_3 = [i for i in swale_list if float(i[2]) >= DWNPX]
        
            shape = swale_list_2[0][1]
            uppxl = float(swale_list_2[0][2])
            Type = swale_list_2[0][4]
            dwpxl = float(swale_list_2[-1][5])
            avgarea = 0
            for col in swale_list_2:
                avgarea = (float(col[5])-float(col[2]))*float(col[6]) + avgarea
            avgarea = avgarea/(float(swale_list_2[-1][5]) - float(swale_list_2[0][2]))
            dsarea = np.sum(map(float,[col[7] for col in swale_list_2]))
            upelev = float(swale_list_2[0][8])
            dwnelev = float(swale_list_2[-1][9])
            ilength = np.sum(map(float,[col[14] for col in swale_list_2]))
            slope = (upelev - dwnelev)/ilength
            width = np.mean(map(float,[col[11] for col in swale_list_2]))
            depth = np.mean(map(float,[col[12] for col in swale_list_2]))
            xarea = np.mean(map(float,[col[13] for col in swale_list_2]))
            if UPPX == float(swale_list[0][2]):
                if len(overland_list) != 0:
                    totlength = ilength + float(overland_list[-1][15])
                else:
                    totlength = ilength
            else:
                totlength = ilength + float(swale_list_1[-1][15])
            vel = 16.1345 * (slope**0.5)
            if Tc_unpaved:
                 vel = 20.3282 * (slope**0.5)
            if np.isnan(vel) or vel == 0:
                vel = 0.001
            itime = ilength/vel/3600
            if UPPX == float(swale_list[0][2]):
                if len(overland_list) != 0:
                    tottime = itime + float(overland_list[-1][18])
                else:
                    tottime = itime
            else:
                tottime = itime + float(swale_list_1[-1][18])
                
            swale_list_2 = [[[],shape,uppxl,[],Type,dwpxl,avgarea,dsarea,upelev,dwnelev,
                               slope,width,depth,xarea,ilength,totlength,vel,itime,tottime]]
            
            for i in range(len(swale_list_3)):
                shape = swale_list_3[i][1]
                uppxl = float(swale_list_3[i][2])
                Type = swale_list_3[i][4]
                dwpxl = swale_list_3[i][5]
                avgarea = swale_list_3[i][6]
                dsarea = swale_list_3[i][7]
                upelev = swale_list_3[i][8]
                dwnelev = swale_list_3[i][9]
                ilength = swale_list_3[i][14]
                slope = swale_list_3[i][10]
                width =swale_list_3[i][11]
                depth =swale_list_3[i][12]
                xarea =swale_list_3[i][13]
                if i == 0:
                    totlength = float(ilength) + float(swale_list_2[-1][15])
                else:
                    totlength = float(ilength) + float(swale_list_3[i-1][15])
                vel = swale_list_3[i][16]
                if np.isnan(vel) or vel == 0:
                    vel = 0.001
                itime = swale_list_3[i][17]
                if i == 0:
                    tottime = float(itime) + float(swale_list_2[-1][18])
                else:
                    tottime = float(itime) + float(swale_list_3[i-1][18])
                swale_list_3[i] = [[],shape,uppxl,[],Type,dwpxl,avgarea,dsarea,upelev,dwnelev,
                                      slope,width,depth,xarea,ilength,totlength,vel,itime,tottime]
                
            swale_list = swale_list_1 + swale_list_2 + swale_list_3
        
        if single_channel == 1 and len(channel_list) != 0:
            shape = channel_list[0][1]
            uppxl = float(channel_list[0][2])
            Type = channel_list[0][4]
            dwpxl = float(channel_list[-1][5])
            avgarea = 0
            for col in channel_list:
                avgarea = (float(col[5])-float(col[2]))*float(col[6]) + avgarea
            avgarea = avgarea/(float(channel_list[-1][5]) - float(channel_list[0][2]))
            dsarea = np.sum(map(float,[col[7] for col in channel_list]))
            upelev = float(channel_list[0][8])
            dwnelev = float(channel_list[-1][9])
            ilength = np.sum(map(float,[col[14] for col in channel_list]))
            slope = (upelev - dwnelev)/ilength
            width = w_coef * (avgarea**w_exp)
            depth = d_coef * (avgarea**d_exp)
            xarea = a_coef * (avgarea**a_exp)
            if len(swale_list) != 0:
                totlength = ilength + float(swale_list[-1][15])
            elif len(overland_list) != 0:
                totlength = ilength + float(overland_list[-1][15])
            else:
                totlength = ilength
            vel = 1.49/channeln * (xarea/(width+2*depth))**(0.66667)*(slope**0.5)
            if np.isnan(vel) or vel == 0:
                vel = 0.001
            itime = ilength/vel/3600
            if len(swale_list) != 0:
                tottime = itime + float(swale_list[-1][18])
            elif len(overland_list) != 0:
                tottime = itime + float(overland_list[-1][18])
            else:
                tottime = itime
            
            channel_list = [[[],shape,uppxl,[],Type,dwpxl,avgarea,dsarea,upelev,dwnelev,
                             slope,width,depth,xarea,ilength,totlength,vel,itime,tottime]]

        if single_channel == 0 and len(channel_list) != 0 and UPPX >= float(channel_list[0][2]) and DWNPX > UPPX and DWNPX <= float(channel_list[-1][5]):
            channel_list_1 = [i for i in channel_list if float(i[2]) < UPPX]
            channel_list_2 = [i for i in channel_list if float(i[2]) >= UPPX and float(i[5]) <= DWNPX]
            channel_list_3 = [i for i in channel_list if float(i[2]) >= DWNPX]
        
            shape = channel_list_2[0][1]
            uppxl = float(channel_list_2[0][2])
            Type = channel_list_2[0][4]
            dwpxl = float(channel_list_2[-1][5])
            avgarea = 0
            for col in channel_list_2:
                avgarea = (float(col[5])-float(col[2]))*float(col[6]) + avgarea
            avgarea = avgarea/(float(channel_list_2[-1][5]) - float(channel_list_2[0][2]))
            dsarea = np.sum(map(float,[col[7] for col in channel_list_2]))
            upelev = float(channel_list_2[0][8])
            dwnelev = float(channel_list_2[-1][9])
            ilength = np.sum(map(float,[col[14] for col in channel_list_2]))
            slope = (upelev - dwnelev)/ilength
            width = w_coef * (avgarea**w_exp)
            depth = d_coef * (avgarea**d_exp)
            xarea = a_coef * (avgarea**a_exp)
            if UPPX == float(channel_list[0][2]):
                if len(swale_list) != 0:
                    totlength = ilength + float(swale_list[-1][15])
                elif len(overland_list) != 0:
                    totlength = ilength + float(overland_list[-1][15])
                else:
                    totlength = ilength
            else:
                totlength = ilength + float(channel_list_1[-1][15])
            vel = 1.49/channeln*(xarea/(width+2*depth))**(0.66667)*(slope**0.5)
            if np.isnan(vel) or vel == 0:
                vel = 0.001
            itime = ilength/vel/3600
            if UPPX == float(channel_list[0][2]):
                if len(swale_list) != 0:
                    tottime = itime + float(swale_list[-1][18])
                elif len(overland_list) != 0:
                    tottime = itime + float(overland_list[-1][18])
                else:
                    tottime = itime
            else:
                tottime = itime + float(channel_list_1[-1][18])
                
            channel_list_2 = [[[],shape,uppxl,[],Type,dwpxl,avgarea,dsarea,upelev,dwnelev,
                               slope,width,depth,xarea,ilength,totlength,vel,itime,tottime]]
            
            for i in range(len(channel_list_3)):
                shape = channel_list_3[i][1]
                uppxl = float(channel_list_3[i][2])
                Type = channel_list_3[i][4]
                dwpxl = channel_list_3[i][5]
                avgarea = channel_list_3[i][6]
                dsarea = channel_list_3[i][7]
                upelev = channel_list_3[i][8]
                dwnelev = channel_list_3[i][9]
                ilength = channel_list_3[i][14]
                slope = channel_list_3[i][10]
                width =channel_list_3[i][11]
                depth =channel_list_3[i][12]
                xarea =channel_list_3[i][13]
                if i == 0:
                    totlength = float(ilength) + float(channel_list_2[-1][15])
                else:
                    totlength = float(ilength) + float(channel_list_3[i-1][15])
                vel = channel_list_3[i][16]
                itime = channel_list_3[i][17]
                if i == 0:
                    tottime = float(itime) + float(channel_list_2[-1][18])
                else:
                    tottime = float(itime) + float(channel_list_3[i-1][18])
                channel_list_3[i] = [[],shape,uppxl,[],Type,dwpxl,avgarea,dsarea,upelev,dwnelev,
                                      slope,width,depth,xarea,ilength,totlength,vel,itime,tottime]
                
            channel_list = channel_list_1 + channel_list_2 + channel_list_3

        if len(overland_list) != 0 and len(swale_list) != 0:
            swale_list[0][15] = overland_list[-1][15] + swale_list[0][14]
            swale_list[0][18] = overland_list[-1][18] + swale_list[0][17]
            for i in range(len(swale_list)-1):
                swale_list[i+1][15] = swale_list[i+1][14] + swale_list[i][15]
                swale_list[i+1][18] = swale_list[i+1][17] + swale_list[i][18]

        if len(channel_list) != 0 and len(swale_list) != 0:
            channel_list[0][15] = swale_list[-1][15] + channel_list[0][14]
            channel_list[0][18] = swale_list[-1][18] + channel_list[0][17]
            for i in range(len(channel_list)-1):
                channel_list[i+1][15] = channel_list[i+1][14] + channel_list[i][15]
                channel_list[i+1][18] = channel_list[i+1][17] + channel_list[i][18]
        elif len(channel_list) != 0 and len(overland_list) != 0:
            channel_list[0][15] = overland_list[-1][15] + channel_list[0][14]
            channel_list[0][18] = overland_list[-1][18] + channel_list[0][17]
            for i in range(len(channel_list)-1):
                channel_list[i+1][15] = channel_list[i+1][14] + channel_list[i][15]
                channel_list[i+1][18] = channel_list[i+1][17] + channel_list[i][18]

        for i in range(len(overland_list)):
            overland_list[i][3] = "M" + str(i+1)
        for i in range(len(swale_list)):
            swale_list[i][3] = "S" + str(i+1)
        for i in range(len(channel_list)):
            channel_list[i][3] = "C" + str(i+1)
        
        attlist = overland_list + swale_list + channel_list
        for i in range(len(attlist)):
            attlist[i][0] = i

        # obtain variables to update segment merge dialog after merge 
        nover = len(overland_list)
        nswale = len(swale_list)
        nchannel = len(channel_list)
        total_tc = "{0:.2f}".format(float(attlist[-1][-1]))
        ov_tc = 0
        sw_tc = 0
        ch_tc = 0

        if len(overland_list) != 0:
            ov_tc = "{0:.2f}".format(np.sum(map(float,[col[17] for col in overland_list])))
        if len(swale_list) != 0:
            sw_tc = "{0:.2f}".format(np.sum(map(float,[col[17] for col in swale_list])))
        if len(channel_list) != 0:
            ch_tc = "{0:.2f}".format(np.sum(map(float,[col[17] for col in channel_list])))

        # populate segment merge dialog box with sub-area, Tc and number of segments for each of overland, swale, and channel
        self.sanumber.SetValue(str(arcid_global + 1))
        self.over_seg.SetValue(str(nover))
        self.swale_seg.SetValue(str(nswale))
        self.chan_seg.SetValue(str(nchannel))
        self.Overall_Tc.SetValue(str(total_tc))
        self.over_Tc.SetValue(str(ov_tc))
        self.swale_Tc.SetValue(str(sw_tc))
        self.chan_Tc.SetValue(str(ch_tc))

        # create tc list values using subshed Tc field
        tc_list=[]
        subshed_poly = optfolder + "/subshed.shp"
        shedtab_tc = arcpy.SearchCursor(subshed_poly,"","","Tc","")
        for t in shedtab_tc:
            get_tc = t.getValue("Tc")
            tc_list.append(get_tc)

        # update list value at index (arcid_global)
        tc_list[arcid_global] = float(attlist[-1][-1])

        # update subshed based on new Tc values
        # add "tc_list" to "subshed.shp"
        tc_lst=0
        subshed_poly = optfolder + "/subshed.shp"
        tc_update = arcpy.UpdateCursor(subshed_poly)
        for tc in tc_update:
            sheds_tc = tc_list[tc_lst]
            tc.Tc = sheds_tc
            tc_update.updateRow(tc)
            tc_lst = tc_lst + 1

        dlg7 = MergedSegTable()

        # clear up and down pixels
        self.uspixel.Clear()
        self.dspixel.Clear()

    def OnApply(self, event):
        arcpy.env.scratchWorkspace = scratchfolder
        arcpy.env.workspace = optfolder
        self.uspixel.Clear()
        self.dspixel.Clear()
       
        global subValue
        subValue = self.subID.GetValue()
        sub_num = int(subValue) - 1
        global arcid_global
        arcid_global = sub_num
        
        intxt = optfolder + "/vel_meth/velmethtable" + str(arcid_global) + ".txt"
        outcsv = optfolder + "/vel_meth/velmethtable" + str(arcid_global) + ".csv"
        
        velmethexe = []
        with open(intxt) as fin, open(outcsv, "wb") as fout:
            o=csv.writer(fout)
            for line in fin:
                o.writerow(line.split())
        with open(outcsv, "rb") as inputfile:
            reader = csv.reader(inputfile)
            next(reader, None)
            for row in csv.reader(inputfile):
                velmethexe.append([x.strip(" ") for x in row])

        # create empty lists to store variable values for attribute table display
        
        global upval,thename_lst,thetype,downval,avgarea,dsarea,upelev,downelev,theslope,thechanwidth,thechandepth,thechanarea,inclength,downlength,thevel,thetinc,thettot
        
        upval =[]
        thename_lst =[]
        thetype =[]
        downval =[]
        avgarea =[]
        dsarea =[]
        upelev =[]
        downelev =[]
        theslope =[]
        thechanwidth =[]
        thechandepth =[]
        thechanarea =[]
        inclength =[]
        downlength =[]
        thevel =[]
        thetinc =[]
        thettot =[]

        nopxo = 0
        nopxs = 0
        nopxc = 0
        tc_over = 0
        tc_swale = 0
        tc_channel = 0
        for i in range(len(velmethexe)-1):
            upval.append(int(velmethexe[i][0])-1)
            downval.append(int(velmethexe[i][0]))
            thetype.append(str(velmethexe[i][1]))
            if str(velmethexe[i][1]) == "overland":
                thename_lst.append("M"+str(nopxo+1))
                nopxo = nopxo +1
                tc_over = float(velmethexe[i][12])+tc_over
            elif str(velmethexe[i][1]) == "swale":
                thename_lst.append("S"+str(nopxs+1))
                nopxs = nopxs +1
                tc_swale = float(velmethexe[i][12])+tc_swale
            else:
                thename_lst.append("C"+str(nopxc+1))
                nopxc = nopxc +1
                tc_channel = float(velmethexe[i][12])+tc_channel
            avgarea.append(float(hydro.AverageArea(int(velmethexe[i][0])-1,int(velmethexe[i][0]),arcid_global,optfolder)[0]))
            dsarea.append(float(velmethexe[i][3]))
            upelev.append(float(velmethexe[i][4]))
            downelev.append(float(velmethexe[i+1][4]))
            theslope.append(float(velmethexe[i][5]))
            thechanwidth.append(float(velmethexe[i][6]))
            thechandepth.append(float(velmethexe[i][7]))
            thechanarea.append(float(velmethexe[i][8]))
            inclength.append(float(velmethexe[i][9]))
            downlength.append(float(velmethexe[i][10]))
            thevel.append(float(velmethexe[i][11]))
            thetinc.append(float(velmethexe[i][12]))
            thettot.append(float(velmethexe[i][13]))

        # define global variables for number of segments of overland, swale, and channel 
        global over_seg, swale_seg, channel_seg
        over_seg = nopxo
        swale_seg = nopxs
        channel_seg = nopxc

        # populate segment merge dialog box with sub-area, Tc and number of segments for each of overland, swale, and channel
        self.sanumber.SetValue(str(arcid_global + 1))
        self.over_seg.SetValue(str(over_seg))
        self.swale_seg.SetValue(str(swale_seg))
        self.chan_seg.SetValue(str(channel_seg))

        # conditions to gray out quick merge options in case of no segments
        if over_seg == 0:
            self.cb1.Disable()
        else:
            self.cb1.Enable()
        if swale_seg == 0:
            self.cb2.Disable()
        else:
            self.cb2.Enable()
        if channel_seg == 0:
            self.cb3.Disable()
        else:
            self.cb3.Enable()

        # global variables for various travel times
        global overall_tc, overland_tc, swale_tc, channel_tc
        overall_tc = "{0:.2f}".format(thettot[-1])
        overland_tc = "{0:.2f}".format(tc_over)
        swale_tc = "{0:.2f}".format(tc_swale)
        channel_tc = "{0:.2f}".format(tc_channel)

        # populate segment merge dialog box with travel time values
        self.Overall_Tc.SetValue(str(overall_tc))
        self.over_Tc.SetValue(str(overland_tc))
        self.swale_Tc.SetValue(str(swale_tc))
        self.chan_Tc.SetValue(str(channel_tc))

        # class to generate new frame for attribute table
        dlg8 = AttributeTable()

        # create tc list values using subshed Tc field
        tc_list=[]
        subshed_poly = optfolder + "/subshed.shp"
        shedtab_tc = arcpy.SearchCursor(subshed_poly,"","","Tc","")
        for t in shedtab_tc:
            get_tc = t.getValue("Tc")
            tc_list.append(get_tc)

        # update list value at index (arcid_global)
        tc_list[arcid_global] = float(attlist[-1][-1])

        # update subshed based on new Tc values
        # add "tc_list" to "subshed.shp"
        tc_lst=0
        subshed_poly = optfolder + "/subshed.shp"
        tc_update = arcpy.UpdateCursor(subshed_poly)
        for tc in tc_update:
            sheds_tc = tc_list[tc_lst]
            tc.Tc = sheds_tc
            tc_update.updateRow(tc)
            tc_lst = tc_lst + 1

        # keep segments merge window on top 
        style = self.GetWindowStyle()
        self.SetWindowStyle( style | wx.STAY_ON_TOP )

    def OnClose(self, event):
        self.Show(False)
        
class MergedSegTable(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, -1, "Segment Merge Attributes - Sub-area " + str(arcid_global + 1), size=(1240, 570)) 
        self.Bind(wx.EVT_CLOSE, self.OnClose)
        panel = wx.Panel(self, -1)
        self.index = 0

        self.SetPosition((530, 420))

        # define attribute table frame and loop over attributes
        self.list_ctrl = wx.ListCtrl(panel, size=(1220,520),style=wx.LC_REPORT |wx.LC_HRULES|wx.LC_VRULES|wx.BORDER_SUNKEN)
        self.list_ctrl.InsertColumn(1, "FID", width=70)
#        self.list_ctrl.InsertColumn(2, "Shape", width=80)
        self.list_ctrl.InsertColumn(2, "UpPixel", width=70)
        self.list_ctrl.InsertColumn(3, "SegName", width=70)
        self.list_ctrl.InsertColumn(4, "Type", width=70)
        self.list_ctrl.InsertColumn(5, "DownPixel", width=70)
        self.list_ctrl.InsertColumn(6, "Avg. Area", width=70)
        #self.list_ctrl.InsertColumn(8, "DS Area", width=80)
        self.list_ctrl.InsertColumn(7, "UpElev", width=70)
        self.list_ctrl.InsertColumn(8, "DownElev", width=70)
        self.list_ctrl.InsertColumn(9, "Slope", width=70)
        self.list_ctrl.InsertColumn(10, "Width", width=70)
        self.list_ctrl.InsertColumn(11, "Depth", width=70)
        self.list_ctrl.InsertColumn(12, "Xarea", width=70)
        self.list_ctrl.InsertColumn(13, "I_Length", width=70)
        self.list_ctrl.InsertColumn(14, "Tot_Length", width=70)
        self.list_ctrl.InsertColumn(15, "Vel.", width=70)
        self.list_ctrl.InsertColumn(16, "I_Time", width=70)
        self.list_ctrl.InsertColumn(17, "Tot_Time", width=70)

        global attlist
        attlist_rev = reversed(attlist)
        for item in attlist_rev:
            self.list_ctrl.InsertStringItem(self.index, str(int(item[0])))
#            self.list_ctrl.SetStringItem(self.index, 1, str(item[1]))
            self.list_ctrl.SetStringItem(self.index, 1, str(int(item[2])))
            self.list_ctrl.SetStringItem(self.index, 2, str(item[3]))
            self.list_ctrl.SetStringItem(self.index, 3, str(item[4]))
            self.list_ctrl.SetStringItem(self.index, 4, str(int(item[5])))
            self.list_ctrl.SetStringItem(self.index, 5, str(item[6]))
#            self.list_ctrl.SetStringItem(self.index, 7, str(item[7]))
            self.list_ctrl.SetStringItem(self.index, 6, str(item[8]))
            self.list_ctrl.SetStringItem(self.index, 7, str(item[9]))
            self.list_ctrl.SetStringItem(self.index, 8, str(item[10]))
            self.list_ctrl.SetStringItem(self.index, 9, str(item[11]))
            self.list_ctrl.SetStringItem(self.index, 10, str(item[12]))
            self.list_ctrl.SetStringItem(self.index, 11, str(item[13]))
            self.list_ctrl.SetStringItem(self.index, 12, str(item[14]))
            self.list_ctrl.SetStringItem(self.index, 13, str(item[15]))
            self.list_ctrl.SetStringItem(self.index, 14, str(item[16]))
            self.list_ctrl.SetStringItem(self.index, 15, str(item[17]))
            self.list_ctrl.SetStringItem(self.index, 16, str(item[18]))
        self.Show(True)
        
        arcpy.env.scratchWorkspace = scratchfolder
        arcpy.env.workspace = optfolder
        
        global notable
        if not os.path.exists(optfolder + "/vel_meth/attribute_tables/merged_tables"):
            os.makedirs(optfolder + "/vel_meth/attribute_tables/merged_tables")
        with open(optfolder + "/vel_meth/attribute_tables/merged_tables/" + "Segment_Merge_Attributes_Sub-area_" + str(arcid_global + 1) + "_(" + str(int(notable[arcid_global])) + ").csv","wb") as f:
            w = csv.writer(f)
            w.writerow(["FID","Shape","UpPixel","SegName","Type","DownPixel","Avg. Area","DS Area","UpElev","DownElev","Slope",
                        "Width","Depth","Xarea","I_Length","Tot_Length", "Vel.","I_Time","Tot_Time"])
            w.writerows(attlist)
        notable[arcid_global] = notable[arcid_global] + 1
        
    def OnClose(self, event):
        self.Show(False)

class PrcpFrequency(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, -1, "Precipitation Frequency & Duration Selector", size=(470, 550))
        panel = wx.Panel(self, -1)

        wx.StaticText(panel, -1, "Check desired storms:", (15, 15))
        wx.StaticText(panel, -1, "1-year", (30, 75))
        wx.StaticText(panel, -1, "6-hour", (115, 50))
        wx.StaticText(panel, -1, "12-hour", (188, 50))
        wx.StaticText(panel, -1, "24-hour", (268, 50))
        wx.StaticText(panel, -1, "48-hour", (346, 50))

        wx.StaticText(panel, -1, "2-year", (30, 105))
        wx.StaticText(panel, -1, "5-year", (30, 135))
        wx.StaticText(panel, -1, "10-year", (30, 165))
        wx.StaticText(panel, -1, "25-year", (30, 195))
        wx.StaticText(panel, -1, "50-year", (30, 225))
        wx.StaticText(panel, -1, "100-year", (30, 255))
        wx.StaticText(panel, -1, "200-year", (30, 285))
        wx.StaticText(panel, -1, "500-year", (30, 315))

        cbXYList = [(120,  75), (200,  75), (278,  75), (356,  75),
                    (120, 105), (200, 105), (278, 105), (356, 105),
                    (120, 135), (200, 135), (278, 135), (356, 135),
                    (120, 165), (200, 165), (278, 165), (356, 165),
                    (120, 195), (200, 195), (278, 195), (356, 195),
                    (120, 225), (200, 225), (278, 225), (356, 225),
                    (120, 255), (200, 255), (278, 255), (356, 255),
                    (120, 285), (200, 285), (278, 285), (356, 285),
                    (120, 315), (200, 315), (278, 315), (356, 315)]

        self.cb_list = []
        for pos in cbXYList:
            cb = wx.CheckBox(panel, -1, "", pos)
            cb.SetValue(False)
            self.cb_list.append(cb)

        wx.StaticText(panel, -1, "Output Storm Depths to File", (70, 355))
        self.cb = wx.CheckBox(panel, -1, "", (50, 355))
        self.cb.SetValue(True)

        self.btnSelect = wx.Button(panel, label="Select All", pos=(45, 395))
        self.Bind(wx.EVT_BUTTON, self.OnSelectAll, id = self.btnSelect.GetId())

        self.btnUnSelectAll = wx.Button(panel, label="Unselect All*", pos=(173, 395))
        self.Bind(wx.EVT_BUTTON, self.OnUnSelectAll, id = self.btnUnSelectAll.GetId())

        self.btnApply = wx.Button(panel, label="Apply/Close", pos=(305, 395))
        self.Bind(wx.EVT_BUTTON, self.OnApply, id = self.btnApply.GetId())

        wx.StaticText(panel, -1, "* Note: 'Unselect All' button will not unselect storms that" "\n"
                      "   have already determined", (20, 450))

        self.Show(True)
        self.Centre(True)

    def OnSelectAll(self, event):
        for cb in self.cb_list:
            cb.SetValue(True)
            
    def OnUnSelectAll(self, event):
        for cb in self.cb_list:
            cb.SetValue(False)

    def OnApply(self, event):
        arcpy.env.scratchWorkspace = scratchfolder
        arcpy.env.workspace = optfolder
        #******************************************************************************************************
        # Use selected duration and year to compute average precipitation
        #******************************************************************************************************
        global year
        year=[]
        global critdur
        critdur=[]
        global critavg
        critavg=[]
        global cb_selected
        cb_selected = []
        pr_string = ""
        for i, cb in enumerate(self.cb_list):
            if cb.GetValue():
                # "1" is added to selected boxes to start indexing from 1
                cb_selected.append(i) # "selected" index list from 1
                dem = optfolder + "/dem"
                basingrid = arcpy.Raster(dem)
                cellsize = basingrid.meanCellWidth
                arcpy.env.cellSize = str(cellsize)
                analysis_extent = basingrid.extent
                arcpy.env.extent = analysis_extent

                # following year and duration list is to create avg prec list
                yearlist = ["1", "2", "5", "10", "25", "50", "100", "200", "500"]
                durlist = ["06", "12", "24", "48"]
                yearlist = ["1", "2", "5", "10", "25", "50", "100", "200", "500"]
                durlist = ["05n","10n","15n","30n","01","02","03","06","12","24","48"]
                theyear = yearlist[i//4] # "//" will floor the value to get respective indexed year from above
                year.append(theyear)
                thecritdur = durlist[(i)%4+7]
                critdur.append(thecritdur)
                pr_path = Directory + "/data/prec/"
                PrecipFreq = hydro.GetPrecipFrequency(pr_path,durlist,theyear,thecritdur,optfolder)
                thecritavg = PrecipFreq[1]
                critavg.append(thecritavg)
                pr_string = pr_string + "     " + "%s-year, %s-hour: %0.4s inches" "\n" %(theyear,thecritdur,thecritavg) 

        #******************************************************************************************************
        # Text file string variables
        #******************************************************************************************************
        datastring = ""
        datastring = datastring + "GISHydro Release Version Date:    %s" "\n" %(Modifieddt)
        datastring = datastring + "Project Name:                     %s" %(proj)
        datastring = datastring + "" "\n"
        datastring = datastring + "Data Selected:" "\n"
        datastring = datastring + "     Outlet Easting:              %s m (MD Stateplane, NAD 1983)" "\n" %(xoutletstring)
        datastring = datastring + "     Outlet Northing:             %s m (MD Stateplane, NAD 1983)" "\n" %(youtletstring)
        datastring = datastring + "Precipitation Frequency-Duration Depths:" "\n"
        datastring = datastring + pr_string

        #******************************************************************************************************
        # write strings to precipitation depth text file.
        #******************************************************************************************************
        defFN = optfolder + "/precstat.txt"
        pr = open(defFN,"w")
        pr.write(datastring)
        pr.close()

        #******************************************************************************************************
        # open "precstat" file in text editor and close selection dialog box
        #******************************************************************************************************
        time.sleep(3) # 5-24-2017: sleep time of few seconds to finish all processes before text file can be opened
        hydro.openbrowser(defFN)
        self.Show(False)

        #******************************************************************************************************
        # turn watershed delineation OFF and basin stat ON
        #******************************************************************************************************
        button14.enabled = True
        arcpy.env.extent = "MAXOF"

class SurfaceContours(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, -1, "Contour Parameters", size=(400, 220))
        self.Bind(wx.EVT_CLOSE, self.OnClose)
        panel = wx.Panel(self, -1)
        
        wx.StaticBox(panel, -1, "Enter parameters:", (15, 15), size=(350,100))
        wx.StaticText(panel, -1, "Contour interval:", (25, 40))
        self.ContourInterval = wx.TextCtrl(panel, -1, value="10", pos=(130,40), size=(130,20))

        wx.StaticText(panel, -1, "Base contour:", (25, 70))
        self.BaseContour = wx.TextCtrl(panel, -1, value="0", pos=(130,70), size=(130,20))
        

        self.btnOK = wx.Button(panel, label="OK", pos=(50,130))
        self.Bind(wx.EVT_BUTTON, self.OnOK, id = self.btnOK.GetId())

        self.btnCancel = wx.Button(panel, label="Cancel", pos=(225,130))
        self.Bind(wx.EVT_BUTTON, self.OnClose, id = self.btnCancel.GetId())
        
        self.Show(True)
        self.Centre(True)

    def OnOK(self, event):
        arcpy.env.scratchWorkspace = scratchfolder
        arcpy.env.workspace = optfolder
        # contour and base interval
        contourInterval = float(self.ContourInterval.GetValue())
        baseContour = float(self.BaseContour.GetValue())
        # Execute Contour
        arcpy.env.addOutputsToMap = True
        demgrid = arcpy.Raster(optfolder + "/dem")
        analysis_extent = demgrid.extent
        arcpy.env.extent = analysis_extent
        arcpy.sa.Contour(optfolder + "/dem", optfolder + "/Contours", contourInterval, baseContour)
        self.Show(False)

        # change contour file name in dataframe
        mxd = arcpy.mapping.MapDocument("CURRENT")
        df = arcpy.mapping.ListDataFrames(mxd)[0]
        layers = arcpy.mapping.ListLayers(mxd, "", df)
        for lyr in layers:
            if lyr.name == "Contours":
                lyr.name = "Contours of Original DEM"
                arcpy.ApplySymbologyFromLayer_management(lyr,r"" + Directory + "/data/mdfiles/legends/contour.lyr")

        arcpy.RefreshTOC()
        arcpy.RefreshActiveView()
        arcpy.env.extent = "MAXOF"

    def OnClose(self, event):
        self.Show(False)

class TcFrame(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, -1, "Time of Concentration Calculation", size=(550, 450))
        self.Bind(wx.EVT_CLOSE, self.OnClose)
        panel = wx.Panel(self, -1)
        
        wx.StaticBox(panel, -1, "Select Tc Method:", (15, 15), size=(235,120))
        TcList = ["SCS Lag Formula", "Hydrology Panel Tc Method", "Velocity Method Tc Calculation"]
        self.Tc = wx.ComboBox(panel, -1, "Velocity Method Tc Calculation", (25, 40), (205, -1),TcList, wx.CB_DROPDOWN)

        wx.StaticBox(panel, -1, "Sheet Flow", (15, 140), size=(115,140))
        wx.StaticText(panel, -1, "ns:", (25, 175))
        self.nsValue = wx.TextCtrl(panel, -1, value="0.1", pos=(60, 170), size=(65,25))
        wx.StaticText(panel, -1, "P[in]:", (25, 210))
        self.PValue = wx.TextCtrl(panel, -1, value="3.08", pos=(60, 205), size=(65,25))
        wx.StaticText(panel, -1, "L[ft]:", (25, 245))
        self.LValue = wx.TextCtrl(panel, -1, value="100", pos=(60, 240), size=(65,25))

        wx.StaticBox(panel, -1, "Shallow Flow", (135, 140), size=(115,140))
        self.unpaved = wx.RadioButton(panel, -1, "Unpaved", (150, 175), style=wx.RB_GROUP)
        self.paved = wx.RadioButton(panel, -1, "Paved", (150, 225))

        wx.StaticBox(panel, -1, "Channel Flow", (260, 15), size=(255,265))
        self.NHD = wx.RadioButton(panel, -1, "Use NHD Streams", (265, 40), style=wx.RB_GROUP)
        self.infStreams = wx.RadioButton(panel, -1, "Use Inferred Streams", (265, 65))
        
        wx.StaticText(panel, -1, "Source Area", (425, 65))
        self.sa = wx.TextCtrl(panel, -1, value="0.0897", pos=(425, 90), size=(65,25))
        
        wx.StaticText(panel, -1, "nc", (285, 95))
        self.nc = wx.TextCtrl(panel, -1, value="0.05", pos=(305, 90), size=(65,25))
        
        wx.StaticText(panel, -1, "Channel Width:", (270, 120))
        wx.StaticText(panel, -1, "Coef.", (270, 143))
        self.cwCoef = wx.TextCtrl(panel, -1, value=str(a_w), pos=(305, 138), size=(65,25))
        wx.StaticText(panel, -1, "Exp.", (395, 140))
        self.cwExp = wx.TextCtrl(panel, -1, value=str(b_w), pos=(425, 135), size=(65,25))

        wx.StaticText(panel, -1, "Channel Depth:", (270, 170))
        wx.StaticText(panel, -1, "Coef.", (270, 193))
        self.cdCoef = wx.TextCtrl(panel, -1, value=str(c_d), pos=(305, 188), size=(65,25))
        wx.StaticText(panel, -1, "Exp.", (390, 193))
        self.cdExp = wx.TextCtrl(panel, -1, value=str(d_d), pos=(425, 188), size=(65,25))

        wx.StaticText(panel, -1, "Channel Area:", (270, 220))
        wx.StaticText(panel, -1, "Coef.", (270, 243))
        self.caCoef = wx.TextCtrl(panel, -1, value=str(e_a), pos=(305, 238), size=(65,25))
        wx.StaticText(panel, -1, "Exp.", (390, 243))
        self.caExp = wx.TextCtrl(panel, -1, value=str(f_a), pos=(425, 238), size=(65,25))

        wx.StaticBox(panel, -1, "Apply To:", (15, 295), size=(500,55))
        self.allsub = wx.RadioButton(panel, -1, "ALL Sub-Areas", (60, 320), style=wx.RB_GROUP)
        self.selsub = wx.RadioButton(panel, -1, "ONLY Selected Sub-Areas", (300, 320))
        self.selsub.Disable()

        
        self.btnApply = wx.Button(panel, label="Cancel", pos=(120, 360))
        self.Bind(wx.EVT_BUTTON, self.OnSet, id=self.btnApply.GetId())

        self.btnApply = wx.Button(panel, label="Apply", pos=(300, 360))
        self.Bind(wx.EVT_BUTTON, self.OnSet, id=self.btnApply.GetId())

        self.Show(True)
        self.Centre(True)

    def OnClose(self, event):
        self.Show(False)

    def OnSet(self, event):
        arcpy.env.scratchWorkspace = scratchfolder
        arcpy.env.workspace = optfolder
        #******************************************************************************************************
        # Get Tc method selection and parameters for velocity method calculation
        #******************************************************************************************************
        global Tc_method
        Tc_method = str(self.Tc.GetValue())
        if (Tc_method != "SCS Lag Formula" and
            Tc_method != "Hydrology Panel Tc Method" and
            Tc_method != "Velocity Method Tc Calculation"):
            pythonaddins.MessageBox("Please select Time of Concentration Method", "Tc Method Selection Warning", 0)
            style = self.GetWindowStyle()
            self.SetWindowStyle( style | wx.STAY_ON_TOP )
            
        else:
            self.Show(False)

            # define global variable for all Tc parameters
            global Tc_ns
            Tc_ns = self.nsValue.GetValue()
            global Tc_P
            Tc_P  = self.PValue.GetValue()
            global Tc_L
            Tc_L  = self.LValue.GetValue()
            global Tc_paved
            Tc_paved = self.paved.GetValue()
            global Tc_unpaved
            Tc_unpaved = self.unpaved.GetValue()
            global Tc_NHD
            Tc_NHD = self.NHD.GetValue()
            global Tc_infStreams
            Tc_infStreams = self.infStreams.GetValue()
            global Tc_sa
            Tc_sa = self.sa.GetValue()
            global Tc_nc
            Tc_nc = self.nc.GetValue()
            global Tc_cwCoef
            Tc_cwCoef = self.cwCoef.GetValue()
            global Tc_cwExp
            Tc_cwExp = self.cwExp.GetValue()
            global Tc_cdCoef
            Tc_cdCoef = self.cdCoef.GetValue()
            global Tc_cdExp
            Tc_cdExp = self.cdExp.GetValue()
            global Tc_caCoef
            Tc_caCoef = self.caCoef.GetValue()
            global Tc_caExp
            Tc_caExp = self.caExp.GetValue()
            global Tc_allsub
            Tc_allsub = self.allsub.GetValue()
            global Tc_selsub
            Tc_selsub = self.selsub.GetValue()

        # lable subwatersheds with "ARCID"
        mxd = arcpy.mapping.MapDocument("CURRENT")
        layer = arcpy.mapping.ListLayers(mxd, "subshed")[0]
        if layer.supports("LABELCLASSES"):
            for lblclass in layer.labelClasses:
                lblclass.showClassLabels = True

        lblclass.expression = "[ARCID]"
        layer.showLabels = True
        arcpy.RefreshActiveView()

        #******************************************************************************************************
        # turn watershed delineation OFF and basin stat ON
        #******************************************************************************************************
        button9.enabled = False
        button10.enabled = True

class TR20InputFile(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, -1, "TR20 Input File", size=(400, 200))
        panel = wx.Panel(self, -1)
        self.data = [(1,2), (2,3), (3,5)]
        
        wx.StaticText(panel, -1, "Overwrite TR20 Input Text File?", (50, 20))

        self.btnOK = wx.Button(panel, label="OK", pos=(150,50))
        self.Bind(wx.EVT_BUTTON, self.OnOK, id = self.btnOK.GetId())

        self.btnCancel = wx.Button(panel, label="Cancel", pos=(250,50))
        self.Bind(wx.EVT_BUTTON, self.OnClose, id = self.btnCancel.GetId())

        self.Show(True)
        self.Centre(True)

    def OnClose(self, event):
        self.Show(False)

    def OnOK(self, event):
        self.Show(False)
        dlg8 = TR20ControlPanel()

            
            
class TR20ControlPanel(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, -1, "GISHydroNXT - TR-20 Control Panel", size=(390, 540))
        panel = wx.Panel(self, -1)
        self.data = [(1,2), (2,3), (3,5)]
        
        wx.StaticBox(panel, -1, "TR-20 Input/Output File Locations", (15, 15), size=(340,55))
        wx.StaticText(panel, -1, "Input File:", (40, 35))
        InputFile = optfolder + "/TR20in.txt"
        self.InputFile = wx.TextCtrl(panel, -1, value=InputFile, pos=(110, 35), size=(220,18))
        
        wx.StaticBox(panel, -1, "Input Options", (15, 80), size=(340,55))
        wx.StaticText(panel, -1, "Hydrograph:", (40, 105))
        HydrographList = ["Standard PRF 484", "DelMarVa PRF 284"]
        self.DelMarVa = wx.ComboBox(panel, -1, "Standard PRF 484", (200,105), (130, -1),HydrographList, wx.CB_DROPDOWN)
        
        wx.StaticBox(panel, -1, "Standard Control Output Options", (15, 145), size=(340,80))
        wx.StaticText(panel, -1, "Hydrograph:", (40, 185))
        self.summary = wx.RadioButton(panel, -1, "Summary Output", (220, 170), style=wx.RB_GROUP)
        self.detail = wx.RadioButton(panel, -1, "Detailed Output", (220, 200))

        wx.StaticBox(panel, -1, "Executive Control Options", (15, 235), size=(340,70))
        wx.StaticText(panel, -1, "Main time Increment:", (40, 265))
        self.Main = wx.TextCtrl(panel, -1, value = "0.1", pos=(250,265), size=(40,20))
        wx.StaticText(panel, -1, "hrs.", (295, 265))

        wx.StaticBox(panel, -1, "Rainfall", (15,315), size=(340,100))
        wx.StaticText(panel, -1, "ARC:", (210, 355))
        ARCList = ["1","2","3"]
        self.ARC = wx.ComboBox(panel, -1, "2", (250,350), (40, -1), ARCList, wx.CB_DROPDOWN)
        wx.StaticText(panel, -1, "Perform Areal Reduction", (130, 380))
        self.ARF = wx.CheckBox(panel, -1, "", pos=(110,380))
        self.ARF.SetValue(True)

        self.btnEdit = wx.Button(panel, label="Choose Storm Depth(s)", pos=(33,350))
        self.Bind(wx.EVT_BUTTON, self.OnEdit, id = self.btnEdit.GetId())


        self.btnOK = wx.Button(panel, label="OK", pos=(50,440))
        self.Bind(wx.EVT_BUTTON, self.OnOK, id = self.btnOK.GetId())

        self.btnCancel = wx.Button(panel, label="Cancel", pos=(225,440))
        self.Bind(wx.EVT_BUTTON, self.OnClose, id = self.btnCancel.GetId())

        self.Show(True)
        self.Centre(True)
        
        global stormdepth_open
        stormdepth_open = 0

    def OnClose(self, event):
        self.Show(False)

    def OnEdit(self, event):
        global stormdepth_open
        stormdepth_open = 0
        dlg = ChooseStormDepths()

    def OnOK(self, event):
        arcpy.env.scratchWorkspace = scratchfolder
        arcpy.env.workspace = optfolder
        self.Show(False)
        global stormdepth_open
        if stormdepth_open == 0:
            pythonaddins.MessageBox("Please select storm depths","WinTR-20 Control Panel Error",0)
            return
        Main_increment = self.Main.GetValue()

        #******************************************************************************************************
        # TR20 input text files with and without subwatersheds will be generated 
        #******************************************************************************************************
        # create "FROM NODE", "TO NODE", and "GRID CODE" lists
        fn_lst=[]
        tn_lst=[]
        gc_lst=[]
        subriver = optfolder + "/subrivers.shp"
        sr = arcpy.SearchCursor(subriver, "", "", "ARCID;FROM_NODE;TO_NODE", "")
        for node in sr:
            gc = node.getValue("ARCID")
            fn = node.getValue("FROM_NODE")
            tn = node.getValue("TO_NODE")
            fn_lst.append(fn)
            tn_lst.append(tn)
            gc_lst.append(gc)

        # reach string block
        len_lst=[]
        reach_lst = [x for x in fn_lst if x in tn_lst]
        subriver_len = arcpy.SearchCursor(subriver, "", "", "GRID_CODE;Length", "")
        for i in subriver_len:
            gc = i.getValue("GRID_CODE")
            ln = i.getValue("Length")
            for r in reach_lst:
                if gc == r:
                    len_lst.append(ln)

        reach = "Reach"
        tn_lst = map(str,tn_lst)
        tn_lst = [reach+i for i in tn_lst]

        auxdict = {}
        for key in tn_lst:
            if key in auxdict:
                auxdict[key] = True # means: duplicates
            else:
                auxdict[key] = False # means: no duplicates
        for key in auxdict:
            if auxdict[key] == False:
                tn_lst = [item.replace(key, "Outlet") for item in tn_lst]
        del auxdict, key, item
        
        r = dict([(x, []) for x in tn_lst])        
        for k, v in zip(tn_lst, fn_lst):
            r[k] += [v,]

        # create "slope", "area (mi^2)", "CN", and "Tc" lists using sub watersheds shapefile
        sp_lst = []
        da_lst = []
        cn_lst = []
        tc_lst = []
        subshed = optfolder + "/subshed.shp"
        ss = arcpy.SearchCursor(subshed, "", "", "CurveNum;Slope;Tc;AreaMi2", "")
        for att in ss:
            sp = att.getValue("Slope")
            da = att.getValue("AreaMi2")
            cn = att.getValue("CurveNum")
            tc = att.getValue("Tc")
            sp_lst.append(sp)
            da_lst.append(da)
            cn_lst.append(cn)
            tc_lst.append(tc)

        # create "GAGE" and YY lists with matching length as gridcode in sub area
        GAGE=[]
        NN_sub = []
        YY_sub = []
        for n in enumerate(fn_lst):
            GAGE.append("GAGE")
            NN_sub.append("NN")
            YY_sub.append("YY")

        # convert all integer/float lists into list of strings for justified text writing
        sp_lst = ["%0.2f" %x for x in sp_lst]
        da_lst = ["%0.2f" %x for x in da_lst]
        cn_lst = ["%0.1f" %x for x in cn_lst]
        tc_lst = ["%0.2f" %x for x in tc_lst]
        gc_lst = map(str,gc_lst)
        sp_lst = map(str,sp_lst)
        da_lst = map(str,da_lst)
        cn_lst = map(str,cn_lst)
        tc_lst = map(str,tc_lst)

        # write sub-area strings
        sub = ""
        if self.detail.GetValue() == True:
            for a,b,c,d,e,f,g in zip(gc_lst, tn_lst, GAGE, da_lst, cn_lst, tc_lst, YY_sub):
                sub += "          " + a.ljust(10) + b.ljust(10) + c.ljust(11) + d.ljust(9) + e.ljust(10) + f.ljust(10)+ g + "\n"

        else:
            for a,b,c,d,e,f,g in zip(gc_lst, tn_lst, GAGE, da_lst, cn_lst, tc_lst, NN_sub):
                sub += "          " + a.ljust(10) + b.ljust(10) + c.ljust(11) + d.ljust(9) + e.ljust(10) + f.ljust(10)+ g + "\n"

        # write reach strings
        NN_reach = []
        for n in enumerate(len_lst):
            NN_reach.append("NN")

        # changed "reachstring" to "reachstring_1" to create formatted string in two steps
        # (due to unequal length of lists: reach_blk and len_lst)
        reachstring = "" 
        reach = "Reach"
        reach_str = map(str,reach_lst)
        reach_blk = [reach+i for i in reach_str]
        reach_blk.insert(len(reach_blk)+1,"Outlet") # reach_blk = reach block


        len_lst = ["%0.1f" %x for x in len_lst]

        for h,k,l in zip(zip(reach_blk,reach_blk[1:]),reach_lst,len_lst):
            r1 = h[0]
            r2 = h[1]
            xs = "XS" + str(k)
            reachstring += r1.rjust(16) + r2.rjust(10) + xs.rjust(7) + str(l).rjust(17 + len(str(l))) + "NN".rjust(22 - len(str(l))) + "\n" # changed log logic to length logic

        stormstring = ""
        ARC = str(self.ARC.GetValue())
        if self.ARF.GetValue() == True:
            RF_precip = hydro.ArealRF(year_uSpecified,prec_uSpecified,areami2)
        else:
            RF_precip = prec_uSpecified
            
        storm_number = len(prec_uSpecified)
        designstorm = ""
        designstorm = designstorm + "%s" "\n" %(storm_number)
        designstorm = designstorm + "%s" "\n" %(str(self.ARC.GetValue()))
        
        precdist = []
        prec_selected = [float(i) for i in prec_uSpecified]
        for i,p in zip(year_uSpecified,prec_selected):
            if i in cb_selected:
                durlist = ["05n","10n","15n","30n","01","02","03","06","12","24","48"]
                yearlist = ["1", "2", "5", "10", "25", "50", "100", "200", "500"]
                year = yearlist[i//4]
                critdur = durlist[(i)%4+7]
                designstorm = designstorm + "p%s-%s" "\n" %(year,critdur)
                designstorm = designstorm + "%s" "\n" %(critdur)

                for d in durlist:
                    thefilename = Directory + "/data/prec/p" + str(year) + "-" + str(d) + "m"
                    precavg = arcpy.GetRasterProperties_management(thefilename, "MEAN")
                    precavg = float(precavg.getOutput(0))
                    theavg = precavg/1000
                    precdist.append(theavg)
                    designstorm = designstorm + "%s\n" %(theavg)
            else:
                durlist = ["05n","10n","15n","30n","01","02","03","06","12","24","48"]
                yearlist = ["1", "2", "5", "10", "25", "50", "100", "200", "500"]
                nodata_list = [-999] * 11
                year = yearlist[i//4]
                critdur = durlist[(i)%4+7]
                if critdur == "06":
                    nodata_list[7] = p
                if critdur == "12":
                    nodata_list[8] = p
                if critdur == "24":
                    nodata_list[9] = p
                if critdur == "48":
                    nodata_list[10] = p

                designstorm = designstorm + "p%s-%s" "\n" %(year,critdur)
                designstorm = designstorm + "%s" "\n" %(critdur)
                for n in nodata_list:
                    designstorm = designstorm + "%s\n" %(n)

        if os.path.exists(optfolder + "/design_storm"):
            path = optfolder + "/design_storm"
            os.chdir(path)
            stormFN = optfolder + "/design_storm/stormdata.txt"
            stormfile = open(stormFN,"w")
            stormfile.write(designstorm)
            stormfile.close()
            os.system(path + "/design_storm_v2.exe")
            time.sleep(4)
        else:
            path = optfolder + "/design_storm"
            os.mkdir(path, 0755)
            src = r"" + Directory + "/data/design_storm/design_storm_v2.exe"
            shutil.copy2(src, path)
            os.chdir(path)
            stormFN = optfolder + "/design_storm/stormdata.txt"
            stormfile = open(stormFN,"w")
            stormfile.write(designstorm)
            stormfile.close()
            os.system(path + "/design_storm_v2.exe")
            time.sleep(4)

        stormanalysis = optfolder + "/design_storm/stormanalysis.txt"
        storm_type = []
        with open(stormanalysis) as f:
            next(f)
            for lines in f:
                line = lines.split()
                storm = line[4]
                storm_type.append(storm)

        year = []
        prcp = []
        duration = []        
        for i,p,s in zip(year_uSpecified,RF_precip,storm_type):
            yearlist = ["1", "2", "5", "10", "25", "50", "100", "200", "500"]
            durlist = ["05n","10n","15n","30n","01","02","03","06","12","24","48"]
            theyear = yearlist[i//4]
            year.append(theyear)
            thecritdur = durlist[(i)%4+7]
            duration.append(thecritdur)
            precavg = p
            prcp.append(precavg)
            if (theyear == "1") or (theyear == "2") or (theyear == "5"):
                if float(precavg) <= 9.99:
                    if s == "Type":
                        stormstring = stormstring + "p".rjust(11) + theyear.rjust(1) + "-".rjust(1) + thecritdur.rjust(1) + "GAGE".rjust(9) + precavg.rjust(20) + "Type II".rjust(13) + ARC.rjust(4) + "\n"
                    else:
                        stormstring = stormstring + "p".rjust(11) + theyear.rjust(1) + "-".rjust(1) + thecritdur.rjust(1) + "GAGE".rjust(9) + precavg.rjust(20) + "rtp".rjust(9) + theyear.rjust(1) + "-".rjust(1) + thecritdur.rjust(1)+ ARC.rjust(4) + "\n"
                else:
                    if s == "Type":
                        stormstring = stormstring + "p".rjust(11) + theyear.rjust(1) + "-".rjust(1) + thecritdur.rjust(1) + "GAGE".rjust(9) + precavg.rjust(21) + "Type II".rjust(12) + ARC.rjust(4) + "\n"
                    else:
                        stormstring = stormstring + "p".rjust(11) + theyear.rjust(1) + "-".rjust(1) + thecritdur.rjust(1) + "GAGE".rjust(9) + precavg.rjust(21) + "rtp".rjust(8) + theyear.rjust(1) + "-".rjust(1) + thecritdur.rjust(1)+ ARC.rjust(4) + "\n"

            elif (theyear == "10") or (theyear == "25") or (theyear == "50"):
                if float(precavg) <= 9.99:
                    if s == "Type":
                        stormstring = stormstring + "p".rjust(11) + theyear.rjust(1) + "-".rjust(1) + thecritdur.rjust(1) + "GAGE".rjust(8) + precavg.rjust(20) + "Type II".rjust(13) + ARC.rjust(4) + "\n"
                    else:
                        stormstring = stormstring + "p".rjust(11) + theyear.rjust(1) + "-".rjust(1) + thecritdur.rjust(1) + "GAGE".rjust(8) + precavg.rjust(20) + "rtp".rjust(9) + theyear.rjust(1) + "-".rjust(1) + thecritdur.rjust(1)+ ARC.rjust(3) + "\n"
                else:
                    if s == "Type":
                        stormstring = stormstring + "p".rjust(11) + theyear.rjust(1) + "-".rjust(1) + thecritdur.rjust(1) + "GAGE".rjust(8) + precavg.rjust(21) + "Type II".rjust(12) + ARC.rjust(4) + "\n"
                    else:
                        stormstring = stormstring + "p".rjust(11) + theyear.rjust(1) + "-".rjust(1) + thecritdur.rjust(1) + "GAGE".rjust(8) + precavg.rjust(21) + "rtp".rjust(8) + theyear.rjust(1) + "-".rjust(1) + thecritdur.rjust(1)+ ARC.rjust(3) + "\n"
    
            else:
                if float(precavg) <= 9.99:
                    if s == "Type":
                        stormstring = stormstring + "p".rjust(11) + theyear.rjust(1) + "-".rjust(1) + thecritdur.rjust(1) + "GAGE".rjust(7) + precavg.rjust(20) + "Type II".rjust(13) + ARC.rjust(4) + "\n"
                    else:
                        stormstring = stormstring + "p".rjust(11) + theyear.rjust(1) + "-".rjust(1) + thecritdur.rjust(1) + "GAGE".rjust(7) + precavg.rjust(20) + "rtp".rjust(9) + theyear.rjust(1) + "-".rjust(1) + thecritdur.rjust(1)+ ARC.rjust(2) + "\n"
                else:
                    if s == "Type":
                        stormstring = stormstring + "p".rjust(11) + theyear.rjust(1) + "-".rjust(1) + thecritdur.rjust(1) + "GAGE".rjust(7) + precavg.rjust(21) + "Type II".rjust(12) + ARC.rjust(4) + "\n"
                    else:
                        stormstring = stormstring + "p".rjust(11) + theyear.rjust(1) + "-".rjust(1) + thecritdur.rjust(1) + "GAGE".rjust(7) + precavg.rjust(21) + "rtp".rjust(8) + theyear.rjust(1) + "-".rjust(1) + thecritdur.rjust(1)+ ARC.rjust(2) + "\n"
        # write rainfall distribution from designstorm text file
        rainfall_string = ""
        storm_infilename = optfolder + "/design_storm/designstorm.txt"
        with open(storm_infilename) as dist:
            next(dist)
            for lines in dist:
                rainfall_string = rainfall_string + lines 

        # write stream cross-section block from rating table folder
        rattabstring = ""
        for i in reach_lst:
            infilename = optfolder + "/rating_table/rattabout_reach" + str(i) + ".txt"
            infile = open(infilename,"r").readlines()

            header_line = infile[0].split()
            reach_drop = header_line[0]
            reach_elev = header_line[1]
            reach_no   = header_line[2]

            rattab_header = reach_drop.rjust(13) + "       " + reach_elev.ljust(25) + reach_no.rjust(11) # modified: reach_no.rjust(10)
            rattabstring = rattabstring + rattab_header + "\n"

            with open(infilename) as f:
                next(f)
                for lines in f:
                    line = lines.split()

                    # added to format new rattab.exe output
                    rattab = line[0].rjust(26) + "    " + line[1].ljust(10) + line[2].ljust(10) + line[3].ljust(10) + line[4].ljust(10) + "\n" 
                    rattabstring = rattabstring + rattab

        # Write TR20 Input file
        inputstring = ""
        inputstring = inputstring + "WinTR-20: Version 3.10" + "{:>18}{:>1}{:>9}{:>1}{:>9}{:>1}{:>7}{:>1}".format("","0","","0","","10.","","0")
        inputstring = inputstring + "" "\n"
        inputstring = inputstring + "GISHydroNXT - [folder:%s]" "\n" %optfolder
        inputstring = inputstring + "" "\n"
        inputstring = inputstring + "SUB-AREA:" "\n"
        inputstring = inputstring + sub
        inputstring = inputstring + "" "\n"
        inputstring = inputstring + "" "\n"
        # DelMarVa Hydrograph
        if self.DelMarVa.GetValue() == "DelMarVa PRF 284":
            table_dmv = open(r"" + Directory + "/data/mdfiles/lookup/Table_DMV.txt")
            dmv_head = table_dmv.read()
            dmv_hyd  = dmv_head[39:]
            inputstring = inputstring + dmv_hyd
            inputstring = inputstring + "" "\n"
            
        if os.path.exists(optfolder + "/rating_table"):
            inputstring = inputstring + "STREAM REACH:" "\n"
            inputstring = inputstring + reachstring
            inputstring = inputstring + "" "\n"
            inputstring = inputstring + "" "\n"

        inputstring = inputstring + "STORM ANALYSIS:" "\n"
        inputstring = inputstring + stormstring
        inputstring = inputstring + "" "\n"
        inputstring = inputstring + "" "\n"
        inputstring = inputstring + "RAINFALL DISTRIBUTION:" "\n"
        inputstring = inputstring + rainfall_string
        inputstring = inputstring + "" "\n"
        inputstring = inputstring + "" "\n"

        if os.path.exists(optfolder + "/rating_table"):
            inputstring = inputstring + "STREAM CROSS SECTION:" "\n"
            inputstring = inputstring + rattabstring
            inputstring = inputstring + "" "\n"
            inputstring = inputstring + "" "\n"
            inputstring = inputstring + "" "\n"

        inputstring = inputstring + "" "\n"
        inputstring = inputstring + "GLOBAL OUTPUT:" "\n"
        if self.summary.GetValue() == True:
            inputstring = inputstring + "{:>20}{:>1}{:>8}{:>1}{:>7}{:>1}{:>5}{:>1}".format("","1.","",float(Main_increment),"","YNNNN","","YNNNNN")
        else:
            inputstring = inputstring + "{:>20}{:>1}{:>8}{:>1}{:>7}{:>1}{:>5}{:>1}".format("","1.","",float(Main_increment),"","YYNNN","","YNNNNN")

        defFN = optfolder + "/TR20in.txt"
        f = open(defFN,"w")
        f.write(inputstring)
        f.close()
        
        # open "TR20in" file in text editor
        #*****************************************************************************
        time.sleep(3) # 5-24-2017: sleep time of few seconds to finish all processes before text file can be opened
        hydro.openbrowser(defFN)
        self.Show(False)

        # turn ON Win-TR20 button
        #*****************************************************************************
        button15.enabled = True

class ChooseStormDepths(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, -1, "IDF Precipitation Values", size=(490, 450))
        panel = wx.Panel(self, -1)

        Depths_font = wx.StaticText(panel, -1, "All depths are in Inches", (160, 5))
        font_size = wx.Font(11, wx.DEFAULT, wx.NORMAL, wx.NORMAL)
        Depths_font.SetFont(font_size)

        wx.StaticText(panel, -1, "1-yr", (25, 57))
        wx.StaticText(panel, -1, "6-hour", (80, 30))
        wx.StaticText(panel, -1, "12-hour", (178, 30))
        wx.StaticText(panel, -1, "24-hour", (278, 30))
        wx.StaticText(panel, -1, "48-hour", (377, 30))

        wx.StaticText(panel, -1, "2-yr", (25, 87))
        wx.StaticText(panel, -1, "5-yr", (25, 117))
        wx.StaticText(panel, -1, "10-yr", (25, 147))
        wx.StaticText(panel, -1, "25-yr", (25, 177))
        wx.StaticText(panel, -1, "50-yr", (25, 207))
        wx.StaticText(panel, -1, "100-yr", (25, 237))
        wx.StaticText(panel, -1, "200-yr", (25, 267))
        wx.StaticText(panel, -1, "500-yr", (25, 297))

        # create lists to hold default (-999), index (locations where to replace avg preci), and average precip depths
        default = []
        for i in range(0,36):
            val = "-"
            default.append(val)

        precip_avg = [round(elem,2) for elem in critavg]
        a,b,c = [default,cb_selected,precip_avg]
        d     = dict(zip(b,c))
        depths = [d.get(i,j) for i,j in enumerate(a)]

        depthList = [(90, 55), (190, 55), (290, 55), (390, 55),
                     (90, 85), (190, 85), (290, 85), (390, 85),
                     (90, 115), (190, 115), (290, 115), (390, 115),
                     (90, 145), (190, 145), (290, 145), (390, 145),
                     (90, 175), (190, 175), (290, 175), (390, 175),
                     (90, 205), (190, 205), (290, 205), (390, 205),
                     (90, 235), (190, 235), (290, 235), (390, 235),
                     (90, 265), (190, 265), (290, 265), (390, 265),
                     (90, 295), (190, 295), (290, 295), (390, 295)]

        self.controls = []
        for pos,precip in zip(depthList,depths):
            control = wx.TextCtrl(panel, -1, value=str(precip), pos=pos, size=(60,25))
            if precip == "-":
                control.Enable(False)
            self.controls.append(control)

        cbXYList = [(70, 60), (170, 60), (270, 60), (370, 60),
                    (70, 90), (170, 90), (270, 90), (370, 90),
                    (70, 120), (170, 120), (270, 120), (370, 120),
                    (70, 150), (170, 150), (270, 150), (370, 150),
                    (70, 180), (170, 180), (270, 180), (370, 180),
                    (70, 210), (170, 210), (270, 210), (370, 210),
                    (70, 240), (170, 240), (270, 240), (370, 240),
                    (70, 270), (170, 270), (270, 270), (370, 270),
                    (70, 300), (170, 300), (270, 300), (370, 300)]

        self.cb_list = []
        for pos,precip in zip(cbXYList,depths):
            cb = wx.CheckBox(panel, -1, "", pos)
            cb.SetValue(False)
            if precip == "-":
                cb.Enable(False)
            else:
                cb.SetValue(True)
            self.cb_list.append(cb)

        self.btnOK = wx.Button(panel, label="OK", pos=(190, 355))
        self.Bind(wx.EVT_BUTTON, self.OnOK, id = self.btnOK.GetId())

        self.Show()
        self.Centre()

    def OnOK(self, event):
        arcpy.env.scratchWorkspace = scratchfolder
        arcpy.env.workspace = optfolder
        #******************************************************************************************************
        # Use specified duration and depth for index adjustment
        #******************************************************************************************************
        global stormdepth_open
        stormdepth_open = 1
        
        all_values = []
        for control in self.controls:
            all_values.append(control.GetValue())

        global IDF
        IDF = [str(item) for item in all_values]

        # user specified (or edited) duration and precipitation depths
        py = hydro.PrcpandYear(self.cb_list,IDF)
        global year_uSpecified
        year_uSpecified = py[0]

        global prec_uSpecified
        prec_uSpecified = py[1]

        self.Show(False)

class AttributeTable(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, -1, "Segment Attributes - Sub-area " + str(arcid_global + 1), size=(1240, 570)) 
        self.Bind(wx.EVT_CLOSE, self.OnClose)
        panel = wx.Panel(self, -1)
        self.index = 0
        self.SetPosition((530, 420))

        global upval,thename_lst,thetype,downval,avgarea,dsarea,upelev,downelev,theslope,thechanwidth,thechandepth,thechanarea,inclength,downlength,thevel,thetinc,thettot
        # define attribute table frame and loop over attributes
        self.list_ctrl = wx.ListCtrl(panel, size=(1220,520),
                                     style=wx.LC_REPORT |wx.LC_HRULES|wx.LC_VRULES|wx.BORDER_SUNKEN)
        self.list_ctrl.InsertColumn(0, "FID", width=70)
#        self.list_ctrl.InsertColumn(1, "Shape", width=80)
        self.list_ctrl.InsertColumn(1, "UpPixel", width=70)
        self.list_ctrl.InsertColumn(2, "SegName", width=70)
        self.list_ctrl.InsertColumn(3, "Type", width=70)
        self.list_ctrl.InsertColumn(4, "DownPixel", width=70)
        self.list_ctrl.InsertColumn(5, "Avg. Area", width=70)
#        self.list_ctrl.InsertColumn(7, "DS Area", width=80)
        self.list_ctrl.InsertColumn(6, "UpElev", width=70)
        self.list_ctrl.InsertColumn(7, "DownElev", width=70)
        self.list_ctrl.InsertColumn(8, "Slope", width=70)
        self.list_ctrl.InsertColumn(9, "Width", width=70)
        self.list_ctrl.InsertColumn(10, "Depth", width=70)
        self.list_ctrl.InsertColumn(11, "Xarea", width=70)
        self.list_ctrl.InsertColumn(12, "I_Length", width=70)
        self.list_ctrl.InsertColumn(13, "Tot_Length", width=70)
        self.list_ctrl.InsertColumn(14, "Vel.", width=70)
        self.list_ctrl.InsertColumn(15, "I_Time", width=70)
        self.list_ctrl.InsertColumn(16, "Tot_Time", width=70)
        
        arcpy.env.scratchWorkspace = scratchfolder
        arcpy.env.workspace = optfolder
        
        shape = ["polyline"] * len(upval) # since all shape types are "polyline" so simply multiplied it with length of records
        rowin = np.arange(0,len(upval),dtype=int)
        
        for a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q in reversed(zip(rowin,upval,thename_lst,thetype,downval,avgarea,upelev,downelev,theslope,thechanwidth,
                                                                    thechandepth,thechanarea,inclength,downlength,thevel,thetinc,thettot)):
            self.list_ctrl.InsertStringItem(self.index, str(a))
#            self.list_ctrl.SetStringItem(self.index, 1, str(b))
            self.list_ctrl.SetStringItem(self.index, 1, str(b))
            self.list_ctrl.SetStringItem(self.index, 2, str(c))
            self.list_ctrl.SetStringItem(self.index, 3, str(d))
            self.list_ctrl.SetStringItem(self.index, 4, str(e))
            self.list_ctrl.SetStringItem(self.index, 5, str(f))
#            self.list_ctrl.SetStringItem(self.index, 7, str(h))
            self.list_ctrl.SetStringItem(self.index, 6, str(g))
            self.list_ctrl.SetStringItem(self.index, 7, str(h))
            self.list_ctrl.SetStringItem(self.index, 8, str(i))
            self.list_ctrl.SetStringItem(self.index, 9, str(j))
            self.list_ctrl.SetStringItem(self.index, 10, str(k))
            self.list_ctrl.SetStringItem(self.index, 11, str(l))
            self.list_ctrl.SetStringItem(self.index, 12, str(m))
            self.list_ctrl.SetStringItem(self.index, 13, str(n))
            self.list_ctrl.SetStringItem(self.index, 14, str(o))
            self.list_ctrl.SetStringItem(self.index, 15, str(p))
            self.list_ctrl.SetStringItem(self.index, 16, str(q))

        self.Show(True)
        
        global attlist
        if not os.path.exists(optfolder + "/vel_meth/attribute_tables"):
            os.makedirs(optfolder + "/vel_meth/attribute_tables")
        with open(optfolder + "/vel_meth/attribute_tables/" + "Segment_Attributes_Sub-area_" + str(arcid_global + 1) + ".csv","wb") as f:
            w = csv.writer(f)
            attlist = list(zip(rowin,shape,upval,thename_lst,thetype,downval,avgarea,dsarea,upelev,downelev,theslope,thechanwidth,
                               thechandepth,thechanarea,inclength,downlength,thevel,thetinc,thettot))
            w.writerow(["FID","Shape","UpPixel","SegName","Type","DownPixel","Avg. Area","DS Area","UpElev","DownElev","Slope",
                        "Width","Depth","Xarea","I_Length","Tot_Length", "Vel.","I_Time","Tot_Time"])
            w.writerows(attlist)

    def OnClose(self, event):
        self.Show(False)

        
Updated: 02 October 2016