#! /usr/bin/env python

'''
Python Interface to SAGA Tools Library
----------
- Category : Terrain Analysis
- Name     : Channels
- ID       : ta_channels

Description
----------
Tools for (grid based) digital terrain analysis.
'''

from PySAGA.helper import Tool_Wrapper

def Run_Channel_Network(ELEVATION=None, INIT_GRID=None, SINKROUTE=None, DIV_GRID=None, TRACE_WEIGHT=None, CHNLNTWRK=None, CHNLROUTE=None, SHAPES=None, INIT_METHOD=None, INIT_VALUE=None, DIV_CELLS=None, MINLEN=None, Verbose=2):
    '''
    Channel Network
    ----------
    [ta_channels.0]\n
    This tool derives a channel network based on gridded digital elevation data.\n
    Use the initiation options to determine under which conditions channels shall start.\n
    Arguments
    ----------
    - ELEVATION [`input grid`] : Elevation. A grid that contains elevation data.
    - INIT_GRID [`input grid`] : Initiation Grid. Dependent on the chosen 'Initiation Type' and 'Initiation Threshold' the values of this grid control where a channel is initiated.
    - SINKROUTE [`optional input grid`] : Flow Direction. An optional grid that provides information about flow directions. 
Values between 1 to 8 force the flow of a cell to be given to one its adjacent neighbor cells (1->NE, 2->E, 3->SE, 4->S, 5->SW, 6->W, 7->NW, 8->N). In case of other values the algorithm will use its own routing scheme. 
This option is in particular useful to supply the algorithm with routes that lead the flow through closed depression. 
    - DIV_GRID [`optional input grid`] : Divergence. Tracing: Convergence
    - TRACE_WEIGHT [`optional input grid`] : Tracing: Weight. Tracing: Weight
    - CHNLNTWRK [`output grid`] : Channel Network. If a cell is part of a channel its value equals the channel order. Otherwise the cell is marked as no-data.
    - CHNLROUTE [`output grid`] : Channel Direction. If a cell is part of a channel then its value shows the flow direction of the channel (1->NE, 2->E, 3->SE, 4->S, 5->SW, 6->W, 7->NW, 8->N). Otherwise the cell is marked as no-data.
    - SHAPES [`output shapes`] : Channel Network. This shapes layer will contain the resulting channel network in vector format (lines).
    - INIT_METHOD [`choice`] : Initiation Type. Available Choices: [0] Less than [1] Equals [2] Greater than Default: 2 Options:
 - Less than
 - Equals
 - Greater than
Controls under which condition a channel is initiated.
    - INIT_VALUE [`floating point number`] : Initiation Threshold. Default: 0.000000 Dependent on the chosen 'Initiation Grid' and 'Initiation Type' this value controls under which condition a channel is initiated.
    - DIV_CELLS [`integer number`] : Tracing: Max. Divergence. Minimum: 1 Default: 5 Tracing: Stop after x cells with divergent flow
    - MINLEN [`integer number`] : Min. Segment Length. Default: 10 Minimum Segment Length (Cells)

    - Verbose [`integer number`] : Verbosity level, 0=silent, 1=tool name and success notification, 2=complete tool output.\n
    Returns
    ----------
    `boolean` : `True` on success, `False` on failure.
    '''
    Tool = Tool_Wrapper('ta_channels', '0', 'Channel Network')
    if Tool.is_Okay():
        Tool.Set_Input ('ELEVATION', ELEVATION)
        Tool.Set_Input ('INIT_GRID', INIT_GRID)
        Tool.Set_Input ('SINKROUTE', SINKROUTE)
        Tool.Set_Input ('DIV_GRID', DIV_GRID)
        Tool.Set_Input ('TRACE_WEIGHT', TRACE_WEIGHT)
        Tool.Set_Output('CHNLNTWRK', CHNLNTWRK)
        Tool.Set_Output('CHNLROUTE', CHNLROUTE)
        Tool.Set_Output('SHAPES', SHAPES)
        Tool.Set_Option('INIT_METHOD', INIT_METHOD)
        Tool.Set_Option('INIT_VALUE', INIT_VALUE)
        Tool.Set_Option('DIV_CELLS', DIV_CELLS)
        Tool.Set_Option('MINLEN', MINLEN)
        return Tool.Execute(Verbose)
    return False

def Run_Watershed_Basins(ELEVATION=None, CHANNELS=None, SINKROUTE=None, BASINS=None, MINSIZE=None, Verbose=2):
    '''
    Watershed Basins
    ----------
    [ta_channels.1]\n
    Watershed Basins\n
    Arguments
    ----------
    - ELEVATION [`input grid`] : Elevation
    - CHANNELS [`input grid`] : Channel Network
    - SINKROUTE [`optional input grid`] : Sink Route
    - BASINS [`output grid`] : Watershed Basins
    - MINSIZE [`integer number`] : Min. Size. Default: 0 Minimum size of basin (cells)

    - Verbose [`integer number`] : Verbosity level, 0=silent, 1=tool name and success notification, 2=complete tool output.\n
    Returns
    ----------
    `boolean` : `True` on success, `False` on failure.
    '''
    Tool = Tool_Wrapper('ta_channels', '1', 'Watershed Basins')
    if Tool.is_Okay():
        Tool.Set_Input ('ELEVATION', ELEVATION)
        Tool.Set_Input ('CHANNELS', CHANNELS)
        Tool.Set_Input ('SINKROUTE', SINKROUTE)
        Tool.Set_Output('BASINS', BASINS)
        Tool.Set_Option('MINSIZE', MINSIZE)
        return Tool.Execute(Verbose)
    return False

def Run_Watershed_Basins_Extended(DEM=None, CHANNELS=None, BASINS=None, SUBBASINS=None, V_BASINS=None, V_SUBBASINS=None, HEADS=None, MOUTHS=None, DISTANCE=None, Verbose=2):
    '''
    Watershed Basins (Extended)
    ----------
    [ta_channels.2]\n
    Extended watershed basin analysis.\n
    Arguments
    ----------
    - DEM [`input grid`] : DEM
    - CHANNELS [`input grid`] : Drainage Network
    - BASINS [`output grid`] : Basins
    - SUBBASINS [`output grid`] : Subbasins
    - V_BASINS [`output shapes`] : Basins
    - V_SUBBASINS [`output shapes`] : Subbasins
    - HEADS [`output shapes`] : River Heads
    - MOUTHS [`output shapes`] : River Mouths
    - DISTANCE [`boolean`] : Flow Distances. Default: 0

    - Verbose [`integer number`] : Verbosity level, 0=silent, 1=tool name and success notification, 2=complete tool output.\n
    Returns
    ----------
    `boolean` : `True` on success, `False` on failure.
    '''
    Tool = Tool_Wrapper('ta_channels', '2', 'Watershed Basins (Extended)')
    if Tool.is_Okay():
        Tool.Set_Input ('DEM', DEM)
        Tool.Set_Input ('CHANNELS', CHANNELS)
        Tool.Set_Output('BASINS', BASINS)
        Tool.Set_Output('SUBBASINS', SUBBASINS)
        Tool.Set_Output('V_BASINS', V_BASINS)
        Tool.Set_Output('V_SUBBASINS', V_SUBBASINS)
        Tool.Set_Output('HEADS', HEADS)
        Tool.Set_Output('MOUTHS', MOUTHS)
        Tool.Set_Option('DISTANCE', DISTANCE)
        return Tool.Execute(Verbose)
    return False

def Run_Vertical_Distance_to_Channel_Network(ELEVATION=None, CHANNELS=None, DISTANCE=None, BASELEVEL=None, THRESHOLD=None, MAXITER=None, NOUNDERGROUND=None, Verbose=2):
    '''
    Vertical Distance to Channel Network
    ----------
    [ta_channels.3]\n
    This tool calculates the vertical distance to a channel network base level. The algorithm consists of two major steps:\n
    1. Interpolation of a channel network base level elevation\n
    2. Subtraction of this base level from the original elevations\n
    Arguments
    ----------
    - ELEVATION [`input grid`] : Elevation. A grid that contains elevation data.
    - CHANNELS [`input grid`] : Channel Network. A grid providing information about the channel network. It is assumed that no-data cells are not part of the channel network. Vice versa all others cells are recognised as channel network members.
    - DISTANCE [`output grid`] : Vertical Distance to Channel Network. The resulting grid gives the altitude above the channel network in the same units as the elevation data.
    - BASELEVEL [`output grid`] : Channel Network Base Level. This optional grid output contains the interpolated channel network base level elevations.
    - THRESHOLD [`floating point number`] : Tension Threshold. Minimum: 0.000000 Default: 1.000000 Maximum change in elevation units (e.g. meter), iteration is stopped once maximum change reaches this threshold.
    - MAXITER [`integer number`] : Maximum Iterations. Minimum: 0 Default: 0 Maximum number of iterations, ignored if set to zero
    - NOUNDERGROUND [`boolean`] : Keep Base Level below Surface. Default: 1

    - Verbose [`integer number`] : Verbosity level, 0=silent, 1=tool name and success notification, 2=complete tool output.\n
    Returns
    ----------
    `boolean` : `True` on success, `False` on failure.
    '''
    Tool = Tool_Wrapper('ta_channels', '3', 'Vertical Distance to Channel Network')
    if Tool.is_Okay():
        Tool.Set_Input ('ELEVATION', ELEVATION)
        Tool.Set_Input ('CHANNELS', CHANNELS)
        Tool.Set_Output('DISTANCE', DISTANCE)
        Tool.Set_Output('BASELEVEL', BASELEVEL)
        Tool.Set_Option('THRESHOLD', THRESHOLD)
        Tool.Set_Option('MAXITER', MAXITER)
        Tool.Set_Option('NOUNDERGROUND', NOUNDERGROUND)
        return Tool.Execute(Verbose)
    return False

def Run_Overland_Flow_Distance_to_Channel_Network(ELEVATION=None, CHANNELS=None, ROUTE=None, FIELDS=None, FLOW_K=None, FLOW_R=None, DISTANCE=None, DISTVERT=None, DISTHORZ=None, TIME=None, SDR=None, PASSES=None, METHOD=None, BOUNDARY=None, FLOW_B=None, FLOW_K_DEFAULT=None, FLOW_R_DEFAULT=None, Verbose=2):
    '''
    Overland Flow Distance to Channel Network
    ----------
    [ta_channels.4]\n
    This tool calculates overland flow distances to a channel network based on gridded digital elevation data and channel network information. The flow algorithm may be either Deterministic 8 (O'Callaghan & Mark 1984) or Multiple Flow Direction (Freeman 1991). Sediment Delivery Rates (SDR) according to Ali & De Boer (2010) can be computed optionally.\n
    Arguments
    ----------
    - ELEVATION [`input grid`] : Elevation. A grid that contains elevation data.
    - CHANNELS [`input grid`] : Channel Network. A grid providing information about the channel network. It is assumed that no-data cells are not part of the channel network. Vice versa all others cells are recognised as channel network members.
    - ROUTE [`optional input grid`] : Preferred Routing. Downhill flow is bound to preferred routing cells, where these are not no-data. Helps to model e.g. small ditches, that are not well represented in the elevation data.
    - FIELDS [`optional input grid`] : Fields. If set, output is given about the number of fields a flow path visits downhill. For D8 only.
    - FLOW_K [`optional input grid`] : Manning-Strickler Coefficient. Manning-Strickler coefficient for flow travel time estimation (reciprocal of Manning's Roughness Coefficient)
    - FLOW_R [`optional input grid`] : Flow Depth. flow depth [m] for flow travel time estimation
    - DISTANCE [`output grid`] : Overland Flow Distance. The overland flow distance in map units. It is assumed that the (vertical) elevation data use the same units as the (horizontal) grid coordinates.
    - DISTVERT [`output grid`] : Vertical Overland Flow Distance. This is the vertical component of the overland flow
    - DISTHORZ [`output grid`] : Horizontal Overland Flow Distance. This is the horizontal component of the overland flow
    - TIME [`output grid`] : Flow Travel Time. flow travel time to channel expressed in hours based on Manning's Equation
    - SDR [`output grid`] : Sediment Yield Delivery Ratio. This is the horizontal component of the overland flow
    - PASSES [`output grid`] : Fields Visited. Number of fields a flow path visits downhill starting at a cell. For D8 only.
    - METHOD [`choice`] : Flow Algorithm. Available Choices: [0] D8 [1] MFD Default: 1 Choose a flow routing algorithm that shall be used for the overland flow distance calculation:
- D8
- MFD
    - BOUNDARY [`boolean`] : Boundary Cells. Default: 0 Take cells at the boundary of the DEM as channel.
    - FLOW_B [`floating point number`] : Beta. Minimum: 0.000000 Default: 1.000000 catchment specific parameter for sediment delivery ratio calculation
    - FLOW_K_DEFAULT [`floating point number`] : Default. Minimum: 0.000000 Default: 20.000000 default value if no grid has been selected
    - FLOW_R_DEFAULT [`floating point number`] : Default. Minimum: 0.000000 Default: 0.050000 default value if no grid has been selected

    - Verbose [`integer number`] : Verbosity level, 0=silent, 1=tool name and success notification, 2=complete tool output.\n
    Returns
    ----------
    `boolean` : `True` on success, `False` on failure.
    '''
    Tool = Tool_Wrapper('ta_channels', '4', 'Overland Flow Distance to Channel Network')
    if Tool.is_Okay():
        Tool.Set_Input ('ELEVATION', ELEVATION)
        Tool.Set_Input ('CHANNELS', CHANNELS)
        Tool.Set_Input ('ROUTE', ROUTE)
        Tool.Set_Input ('FIELDS', FIELDS)
        Tool.Set_Input ('FLOW_K', FLOW_K)
        Tool.Set_Input ('FLOW_R', FLOW_R)
        Tool.Set_Output('DISTANCE', DISTANCE)
        Tool.Set_Output('DISTVERT', DISTVERT)
        Tool.Set_Output('DISTHORZ', DISTHORZ)
        Tool.Set_Output('TIME', TIME)
        Tool.Set_Output('SDR', SDR)
        Tool.Set_Output('PASSES', PASSES)
        Tool.Set_Option('METHOD', METHOD)
        Tool.Set_Option('BOUNDARY', BOUNDARY)
        Tool.Set_Option('FLOW_B', FLOW_B)
        Tool.Set_Option('FLOW_K_DEFAULT', FLOW_K_DEFAULT)
        Tool.Set_Option('FLOW_R_DEFAULT', FLOW_R_DEFAULT)
        return Tool.Execute(Verbose)
    return False

def Run_Channel_Network_and_Drainage_Basins(DEM=None, DIRECTION=None, CONNECTION=None, ORDER=None, BASIN=None, SEGMENTS=None, BASINS=None, NODES=None, THRESHOLD=None, SUBBASINS=None, Verbose=2):
    '''
    Channel Network and Drainage Basins
    ----------
    [ta_channels.5]\n
    Deterministic 8 based flow network analysis.\n
    Arguments
    ----------
    - DEM [`input grid`] : Elevation
    - DIRECTION [`output grid`] : Flow Direction
    - CONNECTION [`output grid`] : Flow Connectivity
    - ORDER [`output grid`] : Strahler Order
    - BASIN [`output grid`] : Drainage Basins
    - SEGMENTS [`output shapes`] : Channels
    - BASINS [`output shapes`] : Drainage Basins
    - NODES [`output shapes`] : Junctions
    - THRESHOLD [`integer number`] : Threshold. Minimum: 1 Default: 5 Strahler order to begin a channel.
    - SUBBASINS [`boolean`] : Subbasins. Default: 1

    - Verbose [`integer number`] : Verbosity level, 0=silent, 1=tool name and success notification, 2=complete tool output.\n
    Returns
    ----------
    `boolean` : `True` on success, `False` on failure.
    '''
    Tool = Tool_Wrapper('ta_channels', '5', 'Channel Network and Drainage Basins')
    if Tool.is_Okay():
        Tool.Set_Input ('DEM', DEM)
        Tool.Set_Output('DIRECTION', DIRECTION)
        Tool.Set_Output('CONNECTION', CONNECTION)
        Tool.Set_Output('ORDER', ORDER)
        Tool.Set_Output('BASIN', BASIN)
        Tool.Set_Output('SEGMENTS', SEGMENTS)
        Tool.Set_Output('BASINS', BASINS)
        Tool.Set_Output('NODES', NODES)
        Tool.Set_Option('THRESHOLD', THRESHOLD)
        Tool.Set_Option('SUBBASINS', SUBBASINS)
        return Tool.Execute(Verbose)
    return False

def Run_Strahler_Order(DEM=None, STRAHLER=None, Verbose=2):
    '''
    Strahler Order
    ----------
    [ta_channels.6]\n
    This tool allows one to calculate the Strahler stream order on basis of a DEM and the steepest descent (D8) algorithm.\n
    Arguments
    ----------
    - DEM [`input grid`] : Elevation. The input elevation data set.
    - STRAHLER [`output grid`] : Strahler Order. The output data set with encoded Strahler stream order.

    - Verbose [`integer number`] : Verbosity level, 0=silent, 1=tool name and success notification, 2=complete tool output.\n
    Returns
    ----------
    `boolean` : `True` on success, `False` on failure.
    '''
    Tool = Tool_Wrapper('ta_channels', '6', 'Strahler Order')
    if Tool.is_Okay():
        Tool.Set_Input ('DEM', DEM)
        Tool.Set_Output('STRAHLER', STRAHLER)
        return Tool.Execute(Verbose)
    return False

def Run_Valley_Depth(ELEVATION=None, VALLEY_DEPTH=None, RIDGE_LEVEL=None, THRESHOLD=None, MAXITER=None, NOUNDERGROUND=None, ORDER=None, Verbose=2):
    '''
    Valley Depth
    ----------
    [ta_channels.7]\n
    Valley depth is calculated as difference between the elevation and an interpolated ridge level. Ridge level interpolation uses the algorithm implemented in the 'Vertical Distance to Channel Network' tool. It performs the following steps:\n
    - Definition of ridge cells (using Strahler order on the inverted DEM).\n
    - Interpolation of the ridge level.\n
    - Subtraction of the original elevations from the ridge level.\n
    Arguments
    ----------
    - ELEVATION [`input grid`] : Elevation
    - VALLEY_DEPTH [`output grid`] : Valley Depth
    - RIDGE_LEVEL [`output grid`] : Ridge Level
    - THRESHOLD [`floating point number`] : Tension Threshold. Minimum: 0.000000 Default: 1.000000 Maximum change in elevation units (e.g. meter), iteration is stopped once maximum change reaches this threshold.
    - MAXITER [`integer number`] : Maximum Iterations. Minimum: 0 Default: 0 Maximum number of iterations, ignored if set to zero
    - NOUNDERGROUND [`boolean`] : Keep Ridge Level above Surface. Default: 1
    - ORDER [`integer number`] : Ridge Detection Threshold. Minimum: 1 Maximum: 7 Default: 4

    - Verbose [`integer number`] : Verbosity level, 0=silent, 1=tool name and success notification, 2=complete tool output.\n
    Returns
    ----------
    `boolean` : `True` on success, `False` on failure.
    '''
    Tool = Tool_Wrapper('ta_channels', '7', 'Valley Depth')
    if Tool.is_Okay():
        Tool.Set_Input ('ELEVATION', ELEVATION)
        Tool.Set_Output('VALLEY_DEPTH', VALLEY_DEPTH)
        Tool.Set_Output('RIDGE_LEVEL', RIDGE_LEVEL)
        Tool.Set_Option('THRESHOLD', THRESHOLD)
        Tool.Set_Option('MAXITER', MAXITER)
        Tool.Set_Option('NOUNDERGROUND', NOUNDERGROUND)
        Tool.Set_Option('ORDER', ORDER)
        return Tool.Execute(Verbose)
    return False

