def read_canal_data(self):

        #-------------------------------------------------------------------
        # Notes:  Assume that canal_file contains key-value pairs,
        #         starting with "n_canals:" and followed by "n_canals"
        #         blocks of the form:
        #            canal_in_ID:  (pixel ID as long integer)
        #            canal_out_ID: (pixel ID as long integer)
        #            Q_fraction:   (fraction to take from in_ID in [0,1])
        #            travel_time:  (canal travel time, in minutes)
        #
        #         nt_canals is computed as ceil(travel_time / cp.dt)
        #-------------------------------------------------------------------
        # Note:  Q_canals is same at upstream and downstream ends, but the
        #        downstream end lags the upstream end by the travel time
        #        from in_ID to out_ID.  As a result, the duration and Q
        #        vector for the downstream end are computed from those of
        #        the upstream end, and the travel time, td, as:
        #            Q_out   = [0,  Q_in]
        #            dur_out = [td, dur_in]
        #            dur_sum_out = [0, dur_sum_in] + td
        #
        #        Rather than create the dur_sum_canals_out and
        #        Q_canals_out vectors, can construct them in Update_Canals.
        #-------------------------------------------------------------------
        if (self.comp_status == 'Disabled'): return
        if not(self.use_canals): return
    
        #---------------------------
        # Can canal_file be found ?
        #---------------------------
        FOUND = tf_utils.file_exists( self.canal_file )
        if not(FOUND):
            self.use_canals = False
            return

        #------------------------
        # Open the "canal_file"
        #------------------------
        file_unit = open(self.canal_file, 'r')

        #------------------------
        # Read number of canals
        #------------------------
        n_canals      = cfg.read_value(file_unit, dtype='Int32')
        self.n_canals = n_canals

        #--------------------
        # Initialize arrays
        #--------------------
        self.canal_in_IDs      = np.zeros([n_canals], dtype='Int32')
        self.canal_out_IDs     = np.zeros([n_canals], dtype='Int32')
        self.canal_Q_fractions = np.zeros([n_canals], dtype='Float64')
        self.canal_times       = np.zeros([n_canals], dtype='Float64')
        
        #----------------------------------
        # Read information for each canal
        #----------------------------------
        for k in xrange(n_canals):
            canal_in_ID  = cfg.read_value(file_unit, dtype='Int32')
            canal_out_ID = cfg.read_value(file_unit, dtype='Int32')
            Q_fraction   = cfg.read_value(file_unit, dtype='Float64')
            travel_time  = cfg.read_value(file_unit, dtype='Float64')
            #----------------------------------------------------------
            self.canal_in_IDs[k]      = canal_in_ID
            self.canal_out_IDs[k]     = canal_out_ID
            self.canal_Q_fractions[k] = Q_fraction
            self.canal_times[k]       = travel_time

        #--------------------------------------------------------
        # Compute "nt_canals", which is the number of timesteps
        # it takes for flow to travel from end to end.
        #--------------------------------------------------------
        # This depends on "self.dt", which is now read from the
        # Diversion component CFG file.  ## (9/22/14)
        #--------------------------------------------------------
        self.nt_canals = np.ceil(self.canal_times / self.dt)
        
        #-----------------------
        # Close the input file
        #-----------------------
        file_unit.close()

        #-----------------------------------------------------
        # Compute xy coordinates for canal entrance and exit
        #-----------------------------------------------------
        canal_in_rows    = (self.canal_in_IDs / self.nx)
        canal_in_cols    = (self.canal_in_IDs % self.nx)
        self.canals_in_x = (canal_in_cols * self.dx)
        self.canals_in_y = (canal_in_rows * self.dy)       
        #-----------------------------------------------------
        canal_out_rows    = (self.canal_out_IDs / self.nx)
        canal_out_cols    = (self.canal_out_IDs % self.nx)
        self.canals_out_x = (canal_out_cols * self.dx)
        self.canals_out_y = (canal_out_rows * self.dy)         
                        
        #-----------------------------------------------------
        # Create a 2D array to store the discharge values as
        # they are moving toward downstream end of canal.
        #-----------------------------------------------------
        # update_canals() will "roll" this array downstream
        # by one array element each time step
        #-----------------------------------------------------
        nt_max       = np.int(self.nt_canals.max())
        nt_min       = np.int(self.nt_canals.min())
        self.canal_Q = np.zeros([n_canals, nt_max], dtype='Float64')
        self.nt_max  = nt_max
        print 'Diversions component: Min steps per canal =', nt_min
        print 'Diversions component: Max steps per canal =', nt_max
    def read_sink_data(self):
        
        #------------------------------------------------------------
        # Notes:  Assume that source_file contains key-value pairs,
        #         starting with "n_sinks:", "nt_max" and "dt:",
        #         followed by "n_sinks" blocks of the form:
        #
        #         sink_ID: (sink pixel ID as long integer)
        #         nt:      (number of discharge (Q) values)
        #         Q:       (vector of discharges in m^3/s)
        #------------------------------------------------------------
        if (self.comp_status == 'Disabled'): return
        if not(self.use_sinks): return
    
        #---------------------------
        # Can sink_file be found ?
        #---------------------------
        FOUND = tf_utils.file_exists( self.sink_file )
        if not(FOUND):
            self.use_sinks = False
            return

        #-----------------------
        # Open the "sink_file"
        #-----------------------
        file_unit = open(self.sink_file, 'r')

        #------------------------------------------------
        # Read number of sinks, max number of timesteps
        # for any sink and the common timestep, dt
        #------------------------------------------------
        n_sinks = cfg.read_value(file_unit, dtype='Int32')
        nt_max  = cfg.read_value(file_unit, dtype='Int32')
        sink_dt = cfg.read_value(file_unit, dtype='Float64')
        self.sink_dt = sink_dt
        
        #--------------------
        # Initialize arrays
        #--------------------
        self.sink_IDs     = np.zeros([n_sinks], dtype='Int32')
        self.nt_sinks     = np.zeros([n_sinks], dtype='Int32')
        self.Q_sinks_all  = np.zeros([n_sinks, nt_max], dtype='Float64')
        self.n_sinks      = n_sinks
        self.nt_max_sinks = nt_max
        
        #---------------------------------
        # Read information for each sink
        #---------------------------------
        for k in xrange(n_sinks):
            sink_ID  = cfg.read_value(file_unit, dtype='Int32')
            nt       = cfg.read_value(file_unit, dtype='Int32')
            Q_values = cfg.read_list_after_key(file_unit, dtype='Float64')
            #---------------------------------------------------------------
            nQ        = size(Q_values)
            print 'Diversions component: Read', nQ, 'Q_values for sink.'
            #--------------------------------------------------------------- 
            self.sink_IDs[k]     = sink_ID
            self.nt_sinks[k]     = nt
            self.Q_sinks_all[k,0:nt] = Q_values

        #-----------------------
        # Close the input file
        #-----------------------
        file_unit.close()              

        #-----------------------------------
        # Compute xy coordinates for sinks
        #-----------------------------------
        sink_rows    = (self.sink_IDs / self.nx)
        sink_cols    = (self.sink_IDs % self.nx)
        self.sinks_x = (sink_cols * self.dx)
        self.sinks_y = (sink_rows * self.dy)  
    def read_canal_data(self):

        #-------------------------------------------------------------------
        # Notes:  Assume that canal_file contains key-value pairs,
        #         starting with "n_canals:" and followed by "n_canals"
        #         blocks of the form:
        #            canal_in_ID:  (pixel ID as long integer)
        #            canal_out_ID: (pixel ID as long integer)
        #            Q_fraction:   (fraction to take from in_ID in [0,1])
        #            travel_time:  (canal travel time, in minutes)
        #
        #         nt_canals is computed as ceil(travel_time / cp.dt)
        #-------------------------------------------------------------------
        # Note:  Q_canals is same at upstream and downstream ends, but the
        #        downstream end lags the upstream end by the travel time
        #        from in_ID to out_ID.  As a result, the duration and Q
        #        vector for the downstream end are computed from those of
        #        the upstream end, and the travel time, td, as:
        #            Q_out   = [0,  Q_in]
        #            dur_out = [td, dur_in]
        #            dur_sum_out = [0, dur_sum_in] + td
        #
        #        Rather than create the dur_sum_canals_out and
        #        Q_canals_out vectors, can construct them in Update_Canals.
        #-------------------------------------------------------------------
        if (self.comp_status == 'Disabled'): return
        if not (self.use_canals): return

        #---------------------------
        # Can canal_file be found ?
        #---------------------------
        FOUND = tf_utils.file_exists(self.canal_file)
        if not (FOUND):
            self.use_canals = False
            return

        #------------------------
        # Open the "canal_file"
        #------------------------
        file_unit = open(self.canal_file, 'r')

        #------------------------
        # Read number of canals
        #------------------------
        n_canals = cfg.read_value(file_unit, dtype='Int32')
        self.n_canals = n_canals

        #--------------------
        # Initialize arrays
        #--------------------
        self.canal_in_IDs = np.zeros([n_canals], dtype='Int32')
        self.canal_out_IDs = np.zeros([n_canals], dtype='Int32')
        self.canal_Q_fractions = np.zeros([n_canals], dtype='Float64')
        self.canal_times = np.zeros([n_canals], dtype='Float64')

        #----------------------------------
        # Read information for each canal
        #----------------------------------
        for k in xrange(n_canals):
            canal_in_ID = cfg.read_value(file_unit, dtype='Int32')
            canal_out_ID = cfg.read_value(file_unit, dtype='Int32')
            Q_fraction = cfg.read_value(file_unit, dtype='Float64')
            travel_time = cfg.read_value(file_unit, dtype='Float64')
            #----------------------------------------------------------
            self.canal_in_IDs[k] = canal_in_ID
            self.canal_out_IDs[k] = canal_out_ID
            self.canal_Q_fractions[k] = Q_fraction
            self.canal_times[k] = travel_time

        #--------------------------------------------------------
        # Compute "nt_canals", which is the number of timesteps
        # it takes for flow to travel from end to end.
        #--------------------------------------------------------
        # This depends on "self.dt", which is now read from the
        # Diversion component CFG file.  ## (9/22/14)
        #--------------------------------------------------------
        self.nt_canals = np.ceil(self.canal_times / self.dt)

        #-----------------------
        # Close the input file
        #-----------------------
        file_unit.close()

        #-----------------------------------------------------
        # Compute xy coordinates for canal entrance and exit
        #-----------------------------------------------------
        canal_in_rows = (self.canal_in_IDs / self.nx)
        canal_in_cols = (self.canal_in_IDs % self.nx)
        self.canals_in_x = (canal_in_cols * self.dx)
        self.canals_in_y = (canal_in_rows * self.dy)
        #-----------------------------------------------------
        canal_out_rows = (self.canal_out_IDs / self.nx)
        canal_out_cols = (self.canal_out_IDs % self.nx)
        self.canals_out_x = (canal_out_cols * self.dx)
        self.canals_out_y = (canal_out_rows * self.dy)

        #-----------------------------------------------------
        # Create a 2D array to store the discharge values as
        # they are moving toward downstream end of canal.
        #-----------------------------------------------------
        # update_canals() will "roll" this array downstream
        # by one array element each time step
        #-----------------------------------------------------
        nt_max = np.int(self.nt_canals.max())
        nt_min = np.int(self.nt_canals.min())
        self.canal_Q = np.zeros([n_canals, nt_max], dtype='Float64')
        self.nt_max = nt_max
        print 'Diversions component: Min steps per canal =', nt_min
        print 'Diversions component: Max steps per canal =', nt_max
    def read_sink_data(self):

        #------------------------------------------------------------
        # Notes:  Assume that source_file contains key-value pairs,
        #         starting with "n_sinks:", "nt_max" and "dt:",
        #         followed by "n_sinks" blocks of the form:
        #
        #         sink_ID: (sink pixel ID as long integer)
        #         nt:      (number of discharge (Q) values)
        #         Q:       (vector of discharges in m^3/s)
        #------------------------------------------------------------
        if (self.comp_status == 'Disabled'): return
        if not (self.use_sinks): return

        #---------------------------
        # Can sink_file be found ?
        #---------------------------
        FOUND = tf_utils.file_exists(self.sink_file)
        if not (FOUND):
            self.use_sinks = False
            return

        #-----------------------
        # Open the "sink_file"
        #-----------------------
        file_unit = open(self.sink_file, 'r')

        #------------------------------------------------
        # Read number of sinks, max number of timesteps
        # for any sink and the common timestep, dt
        #------------------------------------------------
        n_sinks = cfg.read_value(file_unit, dtype='Int32')
        nt_max = cfg.read_value(file_unit, dtype='Int32')
        sink_dt = cfg.read_value(file_unit, dtype='Float64')
        self.sink_dt = sink_dt

        #--------------------
        # Initialize arrays
        #--------------------
        self.sink_IDs = np.zeros([n_sinks], dtype='Int32')
        self.nt_sinks = np.zeros([n_sinks], dtype='Int32')
        self.Q_sinks_all = np.zeros([n_sinks, nt_max], dtype='Float64')
        self.n_sinks = n_sinks
        self.nt_max_sinks = nt_max

        #---------------------------------
        # Read information for each sink
        #---------------------------------
        for k in xrange(n_sinks):
            sink_ID = cfg.read_value(file_unit, dtype='Int32')
            nt = cfg.read_value(file_unit, dtype='Int32')
            Q_values = cfg.read_list_after_key(file_unit, dtype='Float64')
            #---------------------------------------------------------------
            nQ = size(Q_values)
            print 'Diversions component: Read', nQ, 'Q_values for sink.'
            #---------------------------------------------------------------
            self.sink_IDs[k] = sink_ID
            self.nt_sinks[k] = nt
            self.Q_sinks_all[k, 0:nt] = Q_values

        #-----------------------
        # Close the input file
        #-----------------------
        file_unit.close()

        #-----------------------------------
        # Compute xy coordinates for sinks
        #-----------------------------------
        sink_rows = (self.sink_IDs / self.nx)
        sink_cols = (self.sink_IDs % self.nx)
        self.sinks_x = (sink_cols * self.dx)
        self.sinks_y = (sink_rows * self.dy)
    def read_source_data(self):

        #------------------------------------------------------------
        # Notes:  Assume that source_file contains key-value pairs,
        #         starting with "n_sources:", "nt_max" and "dt:",
        #         followed by "n_sources" blocks of the form:
        #
        #         source_ID: (source pixel ID as long integer)
        #         nt:        (number of discharge (Q) values)
        #         Q:         (vector of discharges in m^3/s)
        #------------------------------------------------------------
        if (self.comp_status == 'Disabled'): return
        if not (self.use_sources): return

        #-----------------------------
        # Can source_file be found ?
        #-----------------------------
        FOUND = tf_utils.file_exists(self.source_file)
        if not (FOUND):
            self.use_sources = False
            return

        #-------------------------
        # Open the "source_file"
        #-------------------------
        file_unit = open(self.source_file, 'r')

        #--------------------------------------------------
        # Read number of sources, max number of timesteps
        # for any source and the common timestep, dt
        #--------------------------------------------------
        n_sources = cfg.read_value(file_unit, dtype='Int32')
        nt_max = cfg.read_value(file_unit, dtype='Int32')
        dt = cfg.read_value(file_unit, dtype='Float64')

        ########################################################
        # (2/3/13) Get "dt" from sink_file vs. channels comp.
        ########################################################
        self.dt = dt

        #--------------------
        # Initialize arrays
        #--------------------
        self.source_IDs = np.zeros([n_sources], dtype='Int32')
        self.nt_sources = np.zeros([n_sources], dtype='Int32')
        self.Q_sources_all = np.zeros([n_sources, nt_max], dtype='Float64')
        self.n_sources = n_sources

        self.nt_max_sources = nt_max

        #-----------------------------------
        # Read information for each source
        #-----------------------------------
        for k in range(n_sources):
            source_ID = cfg.read_value(file_unit, dtype='Int32')
            nt = cfg.read_value(file_unit, dtype='Int32')
            Q_values = cfg.read_list_after_key(file_unit, dtype='Float64')
            #---------------------------------------------------------------
            nQ = np.size(Q_values)
            print('Diversions component: Read', nQ, 'Q_values for source.')
            #---------------------------------------------------------------
            self.source_IDs[k] = source_ID
            self.nt_sources[k] = nt
            self.Q_sources_all[k, 0:nt] = Q_values

        #-----------------------
        # Close the input file
        #-----------------------
        file_unit.close()
    def read_source_data(self):

        #------------------------------------------------------------
        # Notes:  Assume that source_file contains key-value pairs,
        #         starting with "n_sources:", "nt_max" and "dt:",
        #         followed by "n_sources" blocks of the form:
        #
        #         source_ID: (source pixel ID as long integer)
        #         nt:        (number of discharge (Q) values)
        #         Q:         (vector of discharges in m^3/s)
        #------------------------------------------------------------
        if (self.comp_status == 'Disabled'): return
        if not(self.use_sources): return
        
        #-----------------------------
        # Can source_file be found ?
        #-----------------------------
        FOUND = tf_utils.file_exists( self.source_file )
        if not(FOUND):
            self.use_sources = False
            return

        #-------------------------
        # Open the "source_file"
        #-------------------------
        file_unit = open(self.source_file, 'r')

        #--------------------------------------------------
        # Read number of sources, max number of timesteps
        # for any source and the common timestep, dt
        #--------------------------------------------------
        n_sources = cfg.read_value(file_unit, dtype='Int32')
        nt_max    = cfg.read_value(file_unit, dtype='Int32')
        dt        = cfg.read_value(file_unit, dtype='Float64')

        ########################################################
        # (2/3/13) Get "dt" from sink_file vs. channels comp.
        ########################################################
        self.dt = dt
        
        #--------------------
        # Initialize arrays
        #--------------------
        self.source_IDs    = np.zeros([n_sources], dtype='Int32')
        self.nt_sources    = np.zeros([n_sources], dtype='Int32')
        self.Q_sources_all = np.zeros([n_sources, nt_max], dtype='Float64')
        self.n_sources     = n_sources

        self.nt_max_sources = nt_max
        
        #-----------------------------------
        # Read information for each source
        #-----------------------------------
        for k in xrange(n_sources):
            source_ID = cfg.read_value(file_unit, dtype='Int32')
            nt        = cfg.read_value(file_unit, dtype='Int32')
            Q_values  = cfg.read_list_after_key(file_unit, dtype='Float64')
            #---------------------------------------------------------------
            nQ        = np.size(Q_values)
            print 'Diversions component: Read', nQ, 'Q_values for source.'
            #---------------------------------------------------------------            
            self.source_IDs[k]     = source_ID
            self.nt_sources[k]     = nt
            self.Q_sources_all[k,0:nt] = Q_values
 
        #-----------------------
        # Close the input file
        #-----------------------
        file_unit.close()