Changeset 6556 for anuga_core


Ignore:
Timestamp:
Mar 19, 2009, 4:08:50 PM (16 years ago)
Author:
rwilson
Message:

Changes to sww2dem() to minimize memory footprint.

Location:
anuga_core/source/anuga
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • anuga_core/source/anuga/shallow_water/data_manager.py

    r6310 r6556  
    8989from anuga.load_mesh.loadASCII import export_mesh_file
    9090from anuga.utilities.polygon import intersection
    91 
     91from anuga.utilities.system_tools import get_vars_in_expression
     92
     93
     94# Default block size for sww2dem()
     95DEFAULT_BLOCK_SIZE = 10000
    9296
    9397######
     
    21042108            origin=None,
    21052109            datum='WGS84',
    2106             format='ers'):
     2110            format='ers',
     2111            block_size=None):
    21072112    """Read SWW file and convert to Digitial Elevation model format
    21082113    (.asc or .ers)
     
    21472152
    21482153    format can be either 'asc' or 'ers'
     2154
     2155    block_size - sets the number of slices along the non-time axis to
     2156                 process in one block.
    21492157    """
    21502158
     
    21772185        number_of_decimal_places = 3
    21782186
     2187    if block_size is None:
     2188        block_size = DEFAULT_BLOCK_SIZE
     2189
     2190    # Read SWW file
    21792191    swwfile = basename_in + '.sww'
    21802192    demfile = basename_out + '.' + format
    2181     # Note the use of a .ers extension is optional (write_ermapper_grid will
    2182     # deal with either option
    21832193
    21842194    # Read sww file
     
    22532263            if verbose: print '    %s in [%f, %f]' %(name, min(q), max(q))
    22542264
    2255     # Get quantity and reduce if applicable
    2256     if verbose: print 'Processing quantity %s' %quantity
    2257 
    2258     # Turn NetCDF objects into Numeric arrays
    2259     try:
    2260         q = fid.variables[quantity][:]
    2261     except:
    2262         quantity_dict = {}
    2263         for name in fid.variables.keys():
    2264             quantity_dict[name] = fid.variables[name][:]
    2265         #Convert quantity expression to quantities found in sww file
    2266         q = apply_expression_to_dictionary(quantity, quantity_dict)
    2267 
    2268     if len(q.shape) == 2:
    2269         #q has a time component, must be reduced alongthe temporal dimension
    2270         if verbose: print 'Reducing quantity %s' %quantity
    2271         q_reduced = num.zeros(number_of_points, num.Float)
    2272 
    2273         if timestep is not None:
    2274             for k in range(number_of_points):
    2275                 q_reduced[k] = q[timestep,k]
    2276         else:
    2277             for k in range(number_of_points):
    2278                 q_reduced[k] = reduction( q[:,k] )
    2279 
    2280         q = q_reduced
    2281 
     2265    # Get the variables in the supplied expression.
     2266    # This may throw a SyntaxError exception.
     2267    var_list = get_vars_in_expression(quantity)
     2268
     2269    # Check that we have the required variables in the SWW file.
     2270    missing_vars = []
     2271    for name in var_list:
     2272        try:
     2273            _ = fid.variables[name]
     2274        except:
     2275            missing_vars.append(name)
     2276    if missing_vars:
     2277        msg = ("In expression '%s', variables %s are not in the SWW file '%s'"
     2278               % (quantity, swwfile))
     2279        raise Exception, msg
     2280
     2281    # Create result array and start filling, block by block.
     2282    result = num.zeros(number_of_points, num.Float)
     2283
     2284    for start_slice in xrange(0, number_of_points, block_size):
     2285        # limit slice size to array end if at last block
     2286        end_slice = min(start_slice + block_size, number_of_points)
     2287       
     2288        # get slices of all required variables
     2289        q_dict = {}
     2290        for name in var_list:
     2291            # check if variable has time axis
     2292            if len(fid.variables[name].shape) == 2:
     2293                q_dict[name] = fid.variables[name][:,start_slice:end_slice]
     2294            else:       # no time axis
     2295                q_dict[name] = fid.variables[name][start_slice:end_slice]
     2296
     2297        # Evaluate expression with quantities found in SWW file
     2298        res = apply_expression_to_dictionary(quantity, q_dict)
     2299
     2300        if len(res.shape) == 2:
     2301            new_res = num.zeros(res.shape[1], num.Float)
     2302            for k in xrange(res.shape[1]):
     2303                new_res[k] = reduction(res[:,k])
     2304            res = new_res
     2305
     2306        result[start_slice:end_slice] = res
     2307                                   
    22822308    #Post condition: Now q has dimension: number_of_points
    2283     assert len(q.shape) == 1
    2284     assert q.shape[0] == number_of_points
     2309    assert len(result.shape) == 1
     2310    assert result.shape[0] == number_of_points
    22852311
    22862312    if verbose:
    22872313        print 'Processed values for %s are in [%f, %f]' % \
    2288               (quantity, min(q), max(q))
     2314              (quantity, min(result), max(result))
    22892315
    22902316    #Create grid and update xll/yll corner and x,y
     
    23592385    #Interpolate using quantity values
    23602386    if verbose: print 'Interpolating'
    2361     grid_values = interp.interpolate(q, grid_points).flat
     2387    grid_values = interp.interpolate(result, grid_points).flat
    23622388
    23632389    if verbose:
  • anuga_core/source/anuga/shallow_water/test_data_manager.py

    r6522 r6556  
    20002000                number_of_decimal_places = 9,
    20012001                verbose = self.verbose,
    2002                 format = 'asc')
     2002                format = 'asc',
     2003                block_size=2)
    20032004
    20042005
  • anuga_core/source/anuga/utilities/system_tools.py

    r5921 r6556  
    247247       
    248248           
    249 
    250 
     249##
     250# @brief Get list of variable names in an expression string.
     251# @param source A string containing a python expression.
     252# @return A list of variable name strings.
     253# @note Throws SyntaxError exception if not a valid expression.
     254def get_vars_in_expression(source):
     255    '''Get list of variable names in a python expression.'''
     256
     257    import compiler
     258    from compiler.ast import Node
     259
     260    ##
     261    # @brief Internal recursive function.
     262    # @param node An AST parse Node.
     263    # @param var_list Input list of variables.
     264    # @return An updated list of variables.
     265    def get_vars_body(node, var_list=[]):
     266        if isinstance(node, Node):
     267            if node.__class__.__name__ == 'Name':
     268                for child in node.getChildren():
     269                    if child not in var_list:
     270                        var_list.append(child)
     271            if any(isinstance(child, Node) for child in node.getChildren()):
     272                for child in node.getChildren():
     273                    var_list = get_vars_body(child, var_list)
     274
     275        return var_list
     276
     277    return get_vars_body(compiler.parse(source))
  • anuga_core/source/anuga/utilities/test_system_tools.py

    r6158 r6556  
    134134        #print checksum
    135135       
    136        
     136
     137    def test_get_vars_in_expression(self):
     138        '''Test the 'get vars from expression' code.'''
     139
     140        def test_it(source, expected):
     141            result = get_vars_in_expression(source)
     142            result.sort()
     143            expected.sort()
     144            msg = ("Source: '%s'\nResult: %s\nExpected: %s"
     145                   % (source, str(result), str(expected)))
     146            self.failUnlessEqual(result, expected, msg)
     147               
     148        source = 'fred'
     149        expected = ['fred']
     150        test_it(source, expected)
     151
     152        source = 'tom + dick'
     153        expected = ['tom', 'dick']
     154        test_it(source, expected)
     155
     156        source = 'tom * (dick + harry)'
     157        expected = ['tom', 'dick', 'harry']
     158        test_it(source, expected)
     159
     160        source = 'tom + dick**0.5 / (harry - tom)'
     161        expected = ['tom', 'dick', 'harry']
     162        test_it(source, expected)
     163
    137164#-------------------------------------------------------------
    138165if __name__ == "__main__":
Note: See TracChangeset for help on using the changeset viewer.