Changeset 1919


Ignore:
Timestamp:
Oct 14, 2005, 11:26:21 AM (18 years ago)
Author:
ole
Message:

Implemented arbitrary expressions for sww2dem using code from changeset:1916

Location:
inundation/pyvolution
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • inundation/pyvolution/data_manager.py

    r1911 r1919  
    12481248
    12491249
    1250     if quantity is given, out values from quantity otherwise default to
    1251     elevation
     1250    The parameter quantity must be the name of an existing quantity or
     1251    an expression involving existing quantities. The default is
     1252    'elevation'.
    12521253
    12531254    if timestep (an index) is given, output quantity at that timestep
     
    12621263    from Numeric import array, Float, concatenate, NewAxis, zeros, reshape, sometrue
    12631264    from utilities.polygon import inside_polygon
     1265    from util import apply_expression_to_dictionary
    12641266   
    12651267    msg = 'Format must be either asc or ers'
     
    13151317
    13161318    #Get quantity and reduce if applicable
    1317     if verbose: print 'Reading quantity %s' %quantity
    1318 
    1319     if quantity.lower() == 'depth':
    1320         q = fid.variables['stage'][:] - fid.variables['elevation'][:]
    1321     else:
    1322         q = fid.variables[quantity][:]
     1319    if verbose: print 'Processing quantity %s' %quantity
     1320
     1321    #Turn NetCDF objects into Numeric arrays
     1322    quantity_dict = {}
     1323    for name in fid.variables.keys():
     1324
     1325        if name not in ['x', 'y', 'volumes', 'time']:
     1326            quantity_dict[name] = fid.variables[name][:]
     1327
     1328    #print quantity_dict     
     1329   
     1330
     1331    q = apply_expression_to_dictionary(quantity, quantity_dict)
    13231332
    13241333
  • inundation/pyvolution/domain.py

    r1916 r1919  
    745745    """
    746746
    747     #Replace quantity names with actual quantities
    748     quantities = domain.quantities
    749     for quantity_name in quantities.keys():
    750         expression = expression.replace(quantity_name,
    751                                         'quantities["%s"]' %quantity_name)
    752 
    753     #Evaluate and return
    754     return eval(expression)   
     747    from util import apply_expression_to_dictionary
     748    return apply_expression_to_dictionary(expression, domain.quantities)
    755749   
    756750
  • inundation/pyvolution/test_data_manager.py

    r1902 r1919  
    13511351
    13521352
     1353    def test_sww2dem_asc_derived_quantity(self):
     1354        """Test that sww information can be converted correctly to asc/prj
     1355        format readable by e.g. ArcView
     1356
     1357        This tests the use of derived quantities
     1358        """
     1359
     1360        import time, os
     1361        from Numeric import array, zeros, allclose, Float, concatenate
     1362        from Scientific.IO.NetCDF import NetCDFFile
     1363
     1364        #Setup
     1365        self.domain.filename = 'datatest'
     1366
     1367        prjfile = self.domain.filename + '_depth.prj'
     1368        ascfile = self.domain.filename + '_depth.asc'
     1369        swwfile = self.domain.filename + '.sww'
     1370
     1371        self.domain.set_datadir('.')
     1372        self.domain.format = 'sww'
     1373        self.domain.smooth = True
     1374        self.domain.set_quantity('elevation', lambda x,y: -x-y)
     1375        self.domain.set_quantity('stage', 0.0)
     1376
     1377        self.domain.geo_reference = Geo_reference(56,308500,6189000)
     1378
     1379
     1380        sww = get_dataobject(self.domain)
     1381        sww.store_connectivity()
     1382        sww.store_timestep('stage')
     1383
     1384        self.domain.evolve_to_end(finaltime = 0.01)
     1385        sww.store_timestep('stage')
     1386
     1387        cellsize = 0.25
     1388        #Check contents
     1389        #Get NetCDF
     1390
     1391        fid = NetCDFFile(sww.filename, 'r')
     1392
     1393        # Get the variables
     1394        x = fid.variables['x'][:]
     1395        y = fid.variables['y'][:]
     1396        z = fid.variables['elevation'][:]
     1397        time = fid.variables['time'][:]
     1398        stage = fid.variables['stage'][:]
     1399
     1400
     1401        #Export to ascii/prj files
     1402        sww2dem(self.domain.filename,
     1403                basename_out = 'datatest_depth',
     1404                quantity = 'stage - elevation',
     1405                cellsize = cellsize,
     1406                reduction = min,
     1407                format = 'asc',
     1408                verbose = False)
     1409
     1410
     1411        #Check asc file
     1412        ascid = open(ascfile)
     1413        lines = ascid.readlines()
     1414        ascid.close()
     1415
     1416        L = lines[0].strip().split()
     1417        assert L[0].strip().lower() == 'ncols'
     1418        assert L[1].strip().lower() == '5'
     1419
     1420        L = lines[1].strip().split()
     1421        assert L[0].strip().lower() == 'nrows'
     1422        assert L[1].strip().lower() == '5'
     1423
     1424        L = lines[2].strip().split()
     1425        assert L[0].strip().lower() == 'xllcorner'
     1426        assert allclose(float(L[1].strip().lower()), 308500)
     1427
     1428        L = lines[3].strip().split()
     1429        assert L[0].strip().lower() == 'yllcorner'
     1430        assert allclose(float(L[1].strip().lower()), 6189000)
     1431
     1432        L = lines[4].strip().split()
     1433        assert L[0].strip().lower() == 'cellsize'
     1434        assert allclose(float(L[1].strip().lower()), cellsize)
     1435
     1436        L = lines[5].strip().split()
     1437        assert L[0].strip() == 'NODATA_value'
     1438        assert L[1].strip().lower() == '-9999'
     1439
     1440
     1441        #Check grid values (where applicable)
     1442        for j in range(5):
     1443            if j%2 == 0:
     1444                L = lines[6+j].strip().split()
     1445                jj = 4-j
     1446                for i in range(5):
     1447                    if i%2 == 0:
     1448                        index = jj/2 + i/2*3
     1449                        val0 = stage[0,index] - z[index]
     1450                        val1 = stage[1,index] - z[index]
     1451
     1452                        #print i, j, index, ':', L[i], val0, val1
     1453                        assert allclose(float(L[i]), min(val0, val1))
     1454
     1455
     1456        fid.close()
     1457
     1458        #Cleanup
     1459        os.remove(prjfile)
     1460        os.remove(ascfile)
     1461        #os.remove(swwfile)
     1462
     1463
     1464
     1465
    13531466
    13541467    def test_sww2dem_asc_missing_points(self):
  • inundation/pyvolution/test_util.py

    r1911 r1919  
    972972
    973973
    974 
     974    def test_apply_expression_to_dictionary(self):
     975
     976        foo = array([[1,2,3],
     977                     [4,5,6]])
     978
     979        bar = array([[-1,0,5],
     980                     [6,1,1]])                 
     981
     982        D = {'X': foo, 'Y': bar}
     983
     984        Z = apply_expression_to_dictionary('X+Y', D)       
     985        assert allclose(Z, foo+bar)
     986
     987        Z = apply_expression_to_dictionary('X*Y', D)       
     988        assert allclose(Z, foo*bar)       
     989
     990        Z = apply_expression_to_dictionary('4*X+Y', D)       
     991        assert allclose(Z, 4*foo+bar)       
     992
     993        #Check exceptions
     994        try:
     995            #Wrong name
     996            Z = apply_expression_to_dictionary('4*X+A', D)       
     997        except NameError:
     998            pass
     999        else:
     1000            msg = 'Should have raised a NameError Exception'
     1001            raise msg
     1002
     1003
     1004        try:
     1005            #Wrong order
     1006            Z = apply_expression_to_dictionary(D, '4*X+A')       
     1007        except AssertionError:
     1008            pass
     1009        else:
     1010            msg = 'Should have raised a AssertionError Exception'
     1011            raise msg       
     1012       
    9751013
    9761014
  • inundation/pyvolution/util.py

    r1911 r1919  
    457457    sww.store_timestep('stage')
    458458
     459
     460
     461
     462
     463
     464
     465def apply_expression_to_dictionary(expression, _):
     466    """Apply arbitrary expression to values of dictionary _
     467
     468    expression: Arbitrary, e.g. arithmetric, expression relating keys
     469                from dictionary _. A key must not be the single character '_'
     470
     471    _: Dictionary of variable names used in expression and their
     472       corresponding values. The dictinary name is chosen as the
     473       inconspicuous symbol _ in order to avoid single letter variable
     474       to inabvertently substitute parts of the dictionary name
     475   
     476
     477    Given an expression in terms of the keys, replace key by the
     478    corresponding values and evaluate.
     479
     480    Values in dictionary must support operators given in expression
     481    e.g. by overloading
     482    """
     483
     484    #FIXME: Varibles may substitute into other variables e.g. x into xmomentum.
     485   
     486    import types
     487
     488    assert isinstance(expression, basestring)
     489    assert type(_) == types.DictType
     490
     491    #Replace key names with values
     492    for key in _.keys():
     493        msg = 'Key must not be the single character "_"'
     494        assert key != '_', msg
     495        expression = expression.replace(key,
     496                                        '_["%s"]' %key)
     497
     498
     499    #Evaluate and return
     500    try:
     501        return eval(expression)
     502    except NameError, e:
     503        msg = 'Expression "%s" could not be evaluated: %s' %(expression, e)
     504        raise NameError, msg
     505   
     506
     507
     508
     509
     510
     511
     512
    459513####################################################################
    460514#Python versions of function that are also implemented in util_gateway.c
Note: See TracChangeset for help on using the changeset viewer.