def quick_set_quantity(
        quantity_name,
        quantity_data,
        domain,
        quantity_clip_range,
        quantity_mean,
        quantity_additions,
        location="vertices",
        mean_type="mean",
    ):
        """Convenience function to set the quantities
            and reduce boilerplate code.
            Sets the quantity + takes care of quantity additions
        """

        # Make the function
        quantity_function = qs.composite_quantity_setting_function(
            quantity_data, domain, quantity_clip_range, nan_treatment="fall_through", default_k_nearest_neighbours=2
        )
        # Spatially average the function if required
        if quantity_mean is not None:
            grid_spacing = [quantity_mean, quantity_mean]
            quantity_function = make_spatially_averaged_function(
                quantity_function, domain, approx_grid_spacing=grid_spacing, averaging=mean_type
            )

        # Set the quantity
        domain.set_quantity(quantity_name, quantity_function, location=location)

        # Treat additions
        quantity_addition_function = qs.composite_quantity_setting_function(
            quantity_additions, domain, nan_treatment="fall_through"
        )
        domain.add_quantity(quantity_name, quantity_addition_function, location=location)
Esempio n. 2
0
    def quick_set_quantity(quantity_name, quantity_data, domain,
                           quantity_clip_range, quantity_mean,
                           quantity_additions, location='vertices',
                           mean_type='mean'):
        """Convenience function to set the quantities
            and reduce boilerplate code.
            Sets the quantity + takes care of quantity additions
        """

        # Make the function
        quantity_function = \
            qs.composite_quantity_setting_function(
                quantity_data,
                domain,
                quantity_clip_range,
                nan_treatment='fall_through',
                default_k_nearest_neighbours=2)
        # Spatially average the function if required
        if quantity_mean is not None:
            grid_spacing = [quantity_mean, quantity_mean]
            quantity_function = make_spatially_averaged_function(
                quantity_function, domain, approx_grid_spacing=grid_spacing,
                averaging=mean_type)

        # Set the quantity
        domain.set_quantity(quantity_name, quantity_function,
                            location=location)

        # Treat additions
        quantity_addition_function = \
            qs.composite_quantity_setting_function(
                quantity_additions, domain, nan_treatment='fall_through')
        domain.add_quantity(quantity_name, quantity_addition_function, 
            location=location)
Esempio n. 3
0
 def should_fail_1():
     F = qs.composite_quantity_setting_function(
         [[trenchPoly, f0], ['All', 'PointData_ElevTest.tif']],
         domain,
         clip_range=[[-500., -1000.], [-1.0e+100, 1.0e+100]],
         verbose=False)
     return
 def should_fail_1():
     F=qs.composite_quantity_setting_function(
         [[trenchPoly, f0], ['All', 'PointData_ElevTest.tif']],
         domain,
         clip_range = [[ -500., -1000.], [-1.0e+100, 1.0e+100]],
         verbose=False) 
     return
Esempio n. 5
0
 def should_fail():
     F = qs.composite_quantity_setting_function(
         [['All', f0], ['All', 'PointData_ElevTest.tif']],
         domain,
         verbose=False)
     # Need to call it to get the error
     F(numpy.array([3.]), numpy.array([3.]))
     return
 def should_fail():
     F=qs.composite_quantity_setting_function(
         [['All', f0], ['All', 'PointData_ElevTest.tif']],
         domain,
         verbose=False)
     # Need to call it to get the error
     F(numpy.array([3.]), numpy.array([3.]))
     return
Esempio n. 7
0
    #------------------------------------------------------------------------------
    # Setup initial conditions
    #------------------------------------------------------------------------------
    domain.set_quantity('stage', 0.0)

    # Friction -- 2 options
    variable_friction = True
    if not variable_friction:
        # Constant friction
        domain.set_quantity('friction', 0.02)

    else:
        # Set friction to 0.02 on roads, 0.04 elsewhere
        road_polygon = anuga.read_polygon('Road/RoadPolygon.csv')
        friction_function = qs.composite_quantity_setting_function(
            [ [road_polygon, 0.02], ['All', 0.04] ], 
            domain)
        domain.set_quantity('friction', friction_function)

    # Elevation
    if houses_as_holes:
        domain.set_quantity('elevation', filename='topography1.pts',
                              use_cache=use_cache,
                                  verbose=verbose)

    else:
        domain.set_quantity('elevation', filename='topography1.pts',
                              use_cache=use_cache,
                              verbose=verbose, location='vertices')
        # Add house_height inside houses    
        house_addition_function = qs.composite_quantity_setting_function(
Esempio n. 8
0
    #------------------------------------------------------------------------------
    # Setup initial conditions
    #------------------------------------------------------------------------------
    domain.set_quantity('stage', 0.0)

    # Friction -- 2 options
    variable_friction = True
    if not variable_friction:
        # Constant friction
        domain.set_quantity('friction', 0.02)

    else:
        # Set friction to 0.02 on roads, 0.04 elsewhere
        road_polygon = anuga.read_polygon('Road/RoadPolygon.csv')
        friction_function = qs.composite_quantity_setting_function(
            [[road_polygon, 0.02], ['All', 0.04]], domain)
        domain.set_quantity('friction', friction_function)

    # Elevation
    if houses_as_holes:
        domain.set_quantity('elevation',
                            filename='topography1.pts',
                            use_cache=use_cache,
                            verbose=verbose)

    else:
        domain.set_quantity('elevation',
                            filename='topography1.pts',
                            use_cache=use_cache,
                            verbose=verbose,
                            location='vertices')
Esempio n. 9
0
    def test_composite_quantity_setting_function(self):
        # Test the composite_quantity_setting_function

        domain = self.create_domain(1.0, 0.0)

        # Make a raster from the elevation data
        from anuga.utilities import plot_utils as util
        xs = domain.centroid_coordinates[:, 0] + domain.geo_reference.xllcorner
        ys = domain.centroid_coordinates[:, 1] + domain.geo_reference.yllcorner
        elev = domain.quantities['elevation'].centroid_values

        allDat = numpy.vstack([xs, ys, elev]).transpose()
        util.Make_Geotif(allDat,
                         output_quantities=['ElevTest'],
                         EPSG_CODE=32756,
                         output_dir='.',
                         CellSize=1.,
                         k_nearest_neighbours=1)

        # Make a polygon-point pair which we use to set elevation in a 'channel'
        trenchPoly = [[minX + 40., minY], [minX + 40., minY + 100.],
                      [minX + 60., minY + 100.], [minX + 60., minY]]

        #################################################################

        # This example uses a constant, and a raster, to set the quantity
        F = qs.composite_quantity_setting_function(
            [[trenchPoly, -1000.], ['Extent', 'PointData_ElevTest.tif']],
            domain,
            verbose=False)

        # Points where we test the function
        testPts_X = numpy.array([50., 3.])
        testPts_Y = numpy.array([1., 20.])
        fitted = F(testPts_X, testPts_Y)

        # The fitted value in the trench should be -1000.
        assert (fitted[0] == -1000.)

        # Find the nearest domain point to the second test point
        # This will have been used in constructing the elevation raster
        nearest = ((domain.centroid_coordinates[:, 0] - 3.)**2 +
                   (domain.centroid_coordinates[:, 1] - 20.)**2).argmin()
        nearest_x = domain.centroid_coordinates[nearest, 0]
        assert (numpy.allclose(fitted[1], -nearest_x / 150.))

        #################################################################

        # This example uses a constant, and a raster, to set the quantity, and
        # applies the min/max bound
        F = qs.composite_quantity_setting_function(
            [[trenchPoly, -1000.], ['Extent', 'PointData_ElevTest.tif']],
            domain,
            clip_range=[[-500., 1.0e+100], [-1.0e+100, 1.0e+100]],
            verbose=False)

        # Points where we test the function
        testPts_X = numpy.array([50., 3.])
        testPts_Y = numpy.array([1., 20.])
        fitted = F(testPts_X, testPts_Y)

        # The fitted value in the trench should be -500, because of clipping
        assert (fitted[0] == -500.)

        # Find the nearest domain point to the second test point
        # This will have been used in constructing the elevation raster
        nearest = ((domain.centroid_coordinates[:, 0] - 3.)**2 +
                   (domain.centroid_coordinates[:, 1] - 20.)**2).argmin()
        nearest_x = domain.centroid_coordinates[nearest, 0]

        assert (numpy.allclose(fitted[1], -nearest_x / 150.))

        #########################################################################

        # This example uses a function, and a raster, to set the quantity
        def f0(x, y):
            return x / 10.

        F = qs.composite_quantity_setting_function(
            [[trenchPoly, f0], ['Extent', 'PointData_ElevTest.tif']],
            domain,
            verbose=False)
        fitted = F(testPts_X, testPts_Y)
        # Now the fitted value in the trench should be determined by f0
        assert (numpy.allclose(fitted[0], 50. / 10.))
        # The second test point should be as before
        nearest = ((domain.centroid_coordinates[:, 0] - 3.)**2 +
                   (domain.centroid_coordinates[:, 1] - 20.)**2).argmin()
        nearest_x = domain.centroid_coordinates[nearest, 0]
        assert (numpy.allclose(fitted[1], -nearest_x / 150.))

        ##########################################################################

        # This example uses 'All' as a polygon
        F = qs.composite_quantity_setting_function(
            [['All', f0], [None, 'PointData_ElevTest.tif']],
            domain,
            verbose=False)
        fitted = F(testPts_X, testPts_Y)
        # Now the fitted value in the trench should be determined by f0
        assert (numpy.allclose(fitted[0], 50. / 10.))
        assert (numpy.allclose(fitted[1], 3. / 10.))

        ###########################################################################
        # This example should fail
        def should_fail():
            F = qs.composite_quantity_setting_function(
                [['All', f0], ['All', 'PointData_ElevTest.tif']],
                domain,
                verbose=False)
            # Need to call it to get the error
            F(numpy.array([3.]), numpy.array([3.]))
            return

        self.assertRaises(Exception, lambda: should_fail())

        ###########################################################################
        # This example should fail (since the clip_range minimum >= maximum)
        def should_fail_1():
            F = qs.composite_quantity_setting_function(
                [[trenchPoly, f0], ['All', 'PointData_ElevTest.tif']],
                domain,
                clip_range=[[-500., -1000.], [-1.0e+100, 1.0e+100]],
                verbose=False)
            return

        self.assertRaises(Exception, lambda: should_fail_1())

        ###########################################################################
        # This example features a function with some nan return values, and uses
        # the nan_interpolation_region_polygon to try to fix it
        def f0(x, y):
            output = x / 10.
            output[0] = numpy.nan
            return output

        F = qs.composite_quantity_setting_function(
            [[trenchPoly, f0], ['Extent', 'PointData_ElevTest.tif']],
            domain,
            nan_treatment='fall_through',
            nan_interpolation_region_polygon=[trenchPoly],
            default_k_nearest_neighbours=3,
            default_raster_interpolation='bilinear',
            verbose=False)

        # Points where we test the function. We deliberately use many points with x=50,
        # which happens to ensure that the nan value is replaced with the same
        # value it would have had anyway
        testPts_X = numpy.array([50., 50.00, 50., 50., 97., 51., 3.])
        testPts_Y = numpy.array([1., 2., 3., 4, 20., 50., 60.])
        fitted = F(testPts_X, testPts_Y)

        # We should have no nan values
        assert (sum(fitted != fitted) == 0)

        # Now the fitted value in the trench should be determined by f0 because
        # the re-interpolation of nan values was designed to ensure it
        assert (numpy.allclose(fitted[0], 50. / 10.))

        ###########################################################################
        # This example features a function with some nan return values, and uses
        # the nan_interpolation_region_polygon to try to fix it

        # Make a polygon-point pair which we use to set elevation in a 'channel'
        innerTrenchPoly = [[minX + 45., minY + 45.], [minX + 45., minY + 55.],
                           [minX + 55., minY + 55.], [minX + 55., minY + 45.]]

        def f_nan(x, y):
            output = x * 0 + numpy.nan
            return (output)

        F = qs.composite_quantity_setting_function(
            [[innerTrenchPoly, f_nan], [trenchPoly, f0],
             ['Extent', 'PointData_ElevTest.tif']],
            domain,
            nan_treatment='fall_through',
            nan_interpolation_region_polygon=[trenchPoly],
            default_k_nearest_neighbours=3,
            default_raster_interpolation='bilinear',
            verbose=False)

        # Points where we test the function. We deliberately use many points with x=50,
        # which happens to ensure that the nan value is replaced with the same
        # value it would have had anyway
        testPts_X = numpy.array([50., 50.00, 50., 50., 97., 51., 3.])
        testPts_Y = numpy.array([1., 2., 3., 4, 20., 50., 60.])
        fitted = F(testPts_X, testPts_Y)

        # We should have no nan values
        assert (sum(fitted != fitted) == 0)

        # Now the fitted value in the trench should be determined by f0 because
        # the re-interpolation of nan values was designed to ensure it
        assert (numpy.allclose(fitted[0], 50. / 10.))

        return
Esempio n. 10
0
def start_sim(run_id, Runs, scenario_name, Scenario, session, **kwargs):
    yieldstep = kwargs['yieldstep']
    finaltime = kwargs['finaltime']
    logger = logging.getLogger(run_id)
    max_triangle_area = kwargs['max_triangle_area']
    logger.info('Starting hydrata_project')

    if run_id == 'local_run':
        base_dir = os.getcwd()
    else:
        base_dir = os.getcwd() + '/base_dir/%s/' % run_id

    outname = run_id
    meshname = base_dir + 'outputs/' + run_id + '.msh'

    def get_filename(data_type, file_type):
        files = os.listdir('%sinputs/%s' % (base_dir, data_type))
        filename = '%sinputs/%s/%s' % (
            base_dir, data_type, [f for f in files if f[-4:] == file_type][0])
        return filename

    boundary_data_filename = get_filename('boundary_data', '.shp')
    elevation_data_filename = get_filename('elevation_data', '.tif')
    try:
        structures_filename = get_filename('structures', '.shp')
    except OSError as e:
        structures_filename = None
    try:
        rain_data_filename = get_filename('rain_data', '.shp')
    except OSError as e:
        rain_data_filename = None
    try:
        inflow_data_filename = get_filename('inflow_data', '.shp')
    except OSError as e:
        inflow_data_filename = None
    try:
        friction_data_filename = get_filename('friction_data', '.shp')
    except OSError as e:
        friction_data_filename = None

    logger.info('boundary_data_filename: %s' % boundary_data_filename)
    logger.info('structures_filename: %s' % structures_filename)
    logger.info('rain_data_filename: %s' % rain_data_filename)
    logger.info('inflow_data_filename: %s' % inflow_data_filename)
    logger.info('friction_data_filename: %s' % friction_data_filename)
    logger.info('elevation_data_filename: %s' % elevation_data_filename)

    # create a list of project files
    vector_filenames = [
        boundary_data_filename, structures_filename, rain_data_filename,
        inflow_data_filename, friction_data_filename
    ]

    # set the projection system for ANUGA calculations from the geotiff elevation data
    elevation_data_gdal = gdal.Open(elevation_data_filename)
    project_spatial_ref = osr.SpatialReference()
    project_spatial_ref.ImportFromWkt(elevation_data_gdal.GetProjectionRef())
    project_spatial_ref_epsg_code = int(
        project_spatial_ref.GetAttrValue("AUTHORITY", 1))

    # check the spatial reference system of the project files matches that of the calculation
    for filename in vector_filenames:
        if filename:
            prj_text = open(filename[:-4] + '.prj').read()
            srs = osr.SpatialReference()
            srs.ImportFromESRI([prj_text])
            srs.AutoIdentifyEPSG()
            logger.info('filename is: %s' % filename)
            logger.info('EPSG is: %s' % srs.GetAuthorityCode(None))
            if str(srs.GetAuthorityCode(None)) != str(
                    project_spatial_ref_epsg_code):
                logger.warning('warning spatial refs are not maching: %s, %s' %
                               (srs.GetAuthorityCode(None),
                                project_spatial_ref_epsg_code))

    logger.info('Setting up structures...')
    if structures_filename:
        structures = []
        logger.info('processing structures from :%s' % structures_filename)
        ogr_shapefile = ogr.Open(structures_filename)
        ogr_layer = ogr_shapefile.GetLayer(0)
        ogr_layer_feature = ogr_layer.GetNextFeature()
        while ogr_layer_feature:
            structure = json.loads(ogr_layer_feature.GetGeometryRef().
                                   ExportToJson())['coordinates'][0]
            structures.append(structure)
            ogr_layer_feature = None
            ogr_layer_feature = ogr_layer.GetNextFeature()

        logger.info('structures: %s' % structures)
    else:
        logger.warning('warning: no structures found.')
        structures = None

    logger.info('Setting up friction...')
    frictions = []
    if friction_data_filename:
        logger.info('processing frictions from :%s' % friction_data_filename)
        ogr_shapefile = ogr.Open(friction_data_filename)
        ogr_layer = ogr_shapefile.GetLayer(0)
        ogr_layer_feature = ogr_layer.GetNextFeature()
        while ogr_layer_feature:
            friction_poly = json.loads(ogr_layer_feature.GetGeometryRef().
                                       ExportToJson())['coordinates'][0]
            friction_value = float(ogr_layer_feature.GetField('mannings'))
            friction_couple = [friction_poly, friction_value]
            frictions.append(friction_couple)
            ogr_layer_feature = None
            ogr_layer_feature = ogr_layer.GetNextFeature()

        frictions.append(['All', 0.04])
        logger.info('frictions: %s' % frictions)
    else:
        frictions.append(['All', 0.04])
        logger.info('warning: no frictions found.')

    logger.info('Setting up boundary conditions...')
    ogr_shapefile = ogr.Open(boundary_data_filename)
    ogr_layer = ogr_shapefile.GetLayer(0)
    ogr_layer_definition = ogr_layer.GetLayerDefn()
    logger.info('ogr_layer_definition.GetGeomType: %s' %
                ogr_layer_definition.GetGeomType())
    boundary_tag_index = 0
    bdy_tags = {}
    bdy = {}

    ogr_layer_feature = ogr_layer.GetNextFeature()
    while ogr_layer_feature:
        boundary_tag_key = ogr_layer_feature.GetField('bdy_tag_k')
        boundary_tag_value = ogr_layer_feature.GetField('bdy_tag_v')
        bdy_tags[boundary_tag_key] = [
            boundary_tag_index * 2, boundary_tag_index * 2 + 1
        ]
        bdy[boundary_tag_key] = boundary_tag_value
        geom = ogr_layer_feature.GetGeometryRef().GetPoints()
        ogr_layer_feature = None
        ogr_layer_feature = ogr_layer.GetNextFeature()
        boundary_tag_index = boundary_tag_index + 1
        logger.info('bdy_tags: %s' % bdy_tags)
    logger.info('bdy: %s' % bdy)

    boundary_data = su.read_polygon(boundary_data_filename)

    create_mesh_from_regions(boundary_data,
                             boundary_tags=bdy_tags,
                             maximum_triangle_area=max_triangle_area,
                             interior_regions=None,
                             interior_holes=structures,
                             filename=meshname,
                             use_cache=False,
                             verbose=True)

    domain = Domain(meshname, use_cache=False, verbose=True)
    domain.set_name(outname)
    domain.set_datadir(base_dir + '/outputs')
    logger.info(domain.statistics())
    poly_fun_pairs = [['Extent', elevation_data_filename.encode("utf-8")]]
    topography_function = qs.composite_quantity_setting_function(
        poly_fun_pairs,
        domain,
        nan_treatment='exception',
    )
    friction_function = qs.composite_quantity_setting_function(
        frictions, domain)
    domain.set_quantity('friction', friction_function, verbose=True)
    domain.set_quantity('stage', 0.0)
    domain.set_quantity('elevation',
                        topography_function,
                        verbose=True,
                        alpha=0.99)
    domain.set_minimum_storable_height(0.005)

    logger.info('Applying rainfall...')
    if rain_data_filename:
        ogr_shapefile = ogr.Open(rain_data_filename)
        ogr_layer = ogr_shapefile.GetLayer(0)
        rainfall = 0
        ogr_layer_feature = ogr_layer.GetNextFeature()
        while ogr_layer_feature:
            rainfall = float(ogr_layer_feature.GetField('rate_mm_hr'))
            polygon = su.read_polygon(rain_data_filename)
            logger.info("applying Polygonal_rate_operator with rate, polygon:")
            logger.info(rainfall)
            logger.info(polygon)
            Polygonal_rate_operator(domain,
                                    rate=rainfall,
                                    factor=1.0e-6,
                                    polygon=polygon,
                                    default_rate=0.0)
            ogr_layer_feature = None
            ogr_layer_feature = ogr_layer.GetNextFeature()

    logger.info('Applying surface inflows...')
    if inflow_data_filename:
        ogr_shapefile = ogr.Open(inflow_data_filename)
        ogr_layer = ogr_shapefile.GetLayer(0)
        ogr_layer_definition = ogr_layer.GetLayerDefn()
        ogr_layer_feature = ogr_layer.GetNextFeature()
        while ogr_layer_feature:
            in_fixed = float(ogr_layer_feature.GetField('in_fixed'))
            line = ogr_layer_feature.GetGeometryRef().GetPoints()
            logger.info("applying Inlet_operator with line, in_fixed:")
            logger.info(line)
            logger.info(in_fixed)
            Inlet_operator(domain, line, in_fixed, verbose=False)
            ogr_layer_feature = None
            ogr_layer_feature = ogr_layer.GetNextFeature()

    logger.info('Applying Boundary Conditions...')
    logger.info('Available boundary tags: %s' % domain.get_boundary_tags())

    Br = anuga.Reflective_boundary(domain)
    Bd = anuga.Dirichlet_boundary([0.0, 0.0, 0.0])
    Bt = anuga.Transmissive_boundary(domain)

    for key, value in bdy.iteritems():
        if value == 'Br':
            bdy[key] = Br
        elif value == 'Bd':
            bdy[key] = Bd
        elif value == 'Bt':
            bdy[key] = Bt
        else:
            logger.info(
                'No matching boundary condition exists - please check your shapefile attributes in: %s'
                % boundary_data_filename)

    # set a default value for exterior & interior boundary if it is not already set
    try:
        bdy['exterior']
    except KeyError:
        bdy['exterior'] = Br
    try:
        bdy['interior']
    except KeyError:
        bdy['interior'] = Br

    logger.info('bdy: %s' % bdy)

    domain.set_boundary(bdy)

    domain = distribute(domain)
    logger.info('Beginning evolve phase...')
    for t in domain.evolve(yieldstep, finaltime):
        domain.write_time()
        print domain.timestepping_statistics()
        logger.info(domain.timestepping_statistics(track_speeds=True))
        percentage_complete = round(domain.time / domain.finaltime, 3) * 100
        logger.info('%s percent complete' % percentage_complete)
        if run_id != 'local_run':
            write_percentage_complete(run_id, Runs, scenario_name, Scenario,
                                      session, percentage_complete)
    domain.sww_merge(delete_old=True)
    barrier()
    finalize()
    sww_file = base_dir + '/outputs/' + run_id + '.sww'
    sww_file = sww_file.encode(
        'utf-8',
        'ignore')  # sometimes run_id gets turned to a unicode object by celery
    util.Make_Geotif(swwFile=sww_file,
                     output_quantities=['depth', 'velocity'],
                     myTimeStep='max',
                     CellSize=max_triangle_area,
                     lower_left=None,
                     upper_right=None,
                     EPSG_CODE=project_spatial_ref_epsg_code,
                     proj4string=None,
                     velocity_extrapolation=True,
                     min_allowed_height=1.0e-05,
                     output_dir=(base_dir + '/outputs/'),
                     bounding_polygon=boundary_data,
                     internal_holes=structures,
                     verbose=False,
                     k_nearest_neighbours=3,
                     creation_options=[])
    logger.info("Done. Nice work.")
Esempio n. 11
0
def run_chennai(sim_id):
    project_root = os.path.abspath(os.path.dirname(__file__))
    if not os.path.exists(project_root):
        os.makedirs(project_root)
    print "project_root = " + project_root

    inputs_dir = '%s/inputs/' % project_root
    if not os.path.exists(inputs_dir):
        os.makedirs(inputs_dir)
    print "inputs_dir = " + inputs_dir

    working_dir = '%s/working/%s/' % (project_root, sim_id)
    if not os.path.exists(working_dir):
        os.makedirs(working_dir)
    print "working_dir = " + working_dir

    outputs_dir = '%s/outputs/%s' % (project_root, sim_id)
    if not os.path.exists(outputs_dir):
        os.makedirs(outputs_dir)
    print "outputs_dir = " + outputs_dir

    # get data
    print "downloading data..."
    urllib.urlretrieve(
        'http://chennaifloodmanagement.org/uploaded/layers/utm44_1arc_v3.tif',
        inputs_dir + 'utm44_1arc_v3.tif'
    )

    print os.listdir(inputs_dir)

    # configure logging TODO: get this working!
    log_location = project_root + '/' + sim_id + '.log'
    open(log_location, 'a').close()
    log.console_logging_level = log.INFO
    log.log_logging_level = log.DEBUG
    log.log_filename = log_location
    print "# log.log_filename is: " + log.log_filename
    print "# log_location is: " + log_location
    log.debug('A message at DEBUG level')
    log.info('Another message, INFO level')

    print "# starting"
    bounding_polygon_01 = [
        [303382.14647903712, 1488780.8996663219],
        [351451.89152459265, 1499834.3704521982],
        [378957.03975921532, 1493150.8764886451],
        [422656.80798244767, 1504204.3472745214],
        [433196.16384805075, 1471300.9923770288],
        [421885.63560203766, 1413463.0638462803],
        [408261.59021479468, 1372590.9276845511],
        [371245.31595511554, 1427344.16669366],
        [316492.0769460068, 1417833.0406686035],
        [303382.14647903712, 1488780.8996663219]
    ]
    boundary_tags_01 = {
        'inland': [0, 1, 2, 6, 7, 8],
        'ocean': [3, 4, 5]
    }
    print "# Create domain:"
    print "# mesh_filename = " + working_dir + 'mesh_01.msh'
    domain = anuga.create_domain_from_regions(bounding_polygon=bounding_polygon_01,
                                              boundary_tags=boundary_tags_01,
                                              mesh_filename=working_dir + 'mesh_01.msh',
                                              maximum_triangle_area=100000,
                                              verbose=True)
    domain.set_name(sim_id)
    domain.set_datadir(outputs_dir)
    poly_fun_pairs = [
            [
                'Extent',
                inputs_dir + 'utm44_1arc_v3.tif'
            ]
    ]
    print "# create topography_function"
    print "input raster = " + inputs_dir + 'utm44_1arc_v3.tif'
    topography_function = qs.composite_quantity_setting_function(
        poly_fun_pairs,
        domain,
        nan_treatment='exception',
    )
    print topography_function
    print "# set_quantity elevation"
    domain.set_quantity('elevation', topography_function)  # Use function for elevation
    domain.set_quantity('friction', 0.03)  # Constant friction
    domain.set_quantity('stage', 1)  # Constant initial stage

    print "# all quantities set"

    print "# Setup boundary conditions"
    Br = anuga.Reflective_boundary(domain)  # Solid reflective wall
    Bt = anuga.Transmissive_boundary(domain)  # Continue all values on boundary
    Bd = anuga.Dirichlet_boundary([-20, 0., 0.])  # Constant boundary values
    Bi = anuga.Dirichlet_boundary([10.0, 0, 0])  # Inflow
    Bw = anuga.Time_boundary(
        domain=domain,  # Time dependent boundary
        function=lambda t: [(10 * sin(t * 2 * pi) - 0.3) * exp(-t), 0.0, 0.0]
    )

    print "# Associate boundary tags with boundary objects"
    domain.set_boundary({'inland': Br, 'ocean': Bd})
    print domain.get_boundary_tags()

    catchmentrainfall = Rainfall(
        domain=domain,
        rate=0.2
    )
    # # Note need path to File in String.
    # # Else assumed in same directory
    domain.forcing_terms.append(catchmentrainfall)

    print "# Evolve system through time"
    counter_timestep = 0
    for t in domain.evolve(yieldstep=300, finaltime=6000):
        counter_timestep += 1
        print counter_timestep
        print domain.timestepping_statistics()

    asc_out_momentum = outputs_dir + '/' + sim_id + '_momentum.asc'
    asc_out_depth = outputs_dir + '/' + sim_id + '_depth.asc'

    anuga.sww2dem(outputs_dir + '/' + sim_id + '.sww',
                  asc_out_momentum,
                  quantity='momentum',
                  number_of_decimal_places=3,
                  cellsize=30,
                  reduction=max,
                  verbose=True)
    anuga.sww2dem(outputs_dir + '/' + sim_id + '.sww',
                  asc_out_depth,
                  quantity='depth',
                  number_of_decimal_places=3,
                  cellsize=30,
                  reduction=max,
                  verbose=True)

    outputs =[asc_out_depth, asc_out_momentum]

    for output in outputs:
        print "# Convert ASCII grid to GeoTiff so geonode can import it"
        src_ds = gdal.Open(output)
        dst_filename = (output[:-3] + 'tif')

        print "# Create gtif instance"
        driver = gdal.GetDriverByName("GTiff")

        print "# Output to geotiff"
        dst_ds = driver.CreateCopy(dst_filename, src_ds, 0)

        print "# Properly close the datasets to flush the disk"
        dst_filename = None
        src_ds = None

    print "Done. Nice work."
    def test_composite_quantity_setting_function(self):
        # Test the composite_quantity_setting_function
        
        domain=self.create_domain(1.0, 0.0)
        
        # Make a raster from the elevation data
        from anuga.utilities import plot_utils as util
        xs=domain.centroid_coordinates[:,0]+domain.geo_reference.xllcorner
        ys=domain.centroid_coordinates[:,1]+domain.geo_reference.yllcorner
        elev=domain.quantities['elevation'].centroid_values

        allDat=numpy.vstack([xs,ys,elev]).transpose()
        util.Make_Geotif(allDat, output_quantities=['ElevTest'], EPSG_CODE=32756, 
                        output_dir='.', CellSize=1.,k_nearest_neighbours=1)

        # Make a polygon-point pair which we use to set elevation in a 'channel'
        trenchPoly = [[minX+40., minY], [minX+40., minY+100.], 
            [minX+60., minY+100.], [minX+60., minY]]

        #################################################################
 
        # This example uses a constant, and a raster, to set the quantity           
        F=qs.composite_quantity_setting_function(
            [[trenchPoly, -1000.], ['Extent', 'PointData_ElevTest.tif']],
            domain,
            verbose=False)

        # Points where we test the function
        testPts_X=numpy.array([50., 3.])
        testPts_Y=numpy.array([1., 20.])
        fitted=F(testPts_X,testPts_Y)

        # The fitted value in the trench should be -1000.
        assert(fitted[0]==-1000.)

        # Find the nearest domain point to the second test point
        # This will have been used in constructing the elevation raster
        nearest=((domain.centroid_coordinates[:,0]-3.)**2 + 
                 (domain.centroid_coordinates[:,1]-20.)**2).argmin()
        nearest_x=domain.centroid_coordinates[nearest,0]
        assert(numpy.allclose(fitted[1],-nearest_x/150.))

        #################################################################
 
        # This example uses a constant, and a raster, to set the quantity, and
        # applies the min/max bound           
        F=qs.composite_quantity_setting_function(
            [[trenchPoly, -1000.], ['Extent', 'PointData_ElevTest.tif']],
            domain,
            clip_range = [[-500., 1.0e+100], [-1.0e+100, 1.0e+100]],
            verbose=False) 

        # Points where we test the function
        testPts_X=numpy.array([50., 3.])
        testPts_Y=numpy.array([1., 20.])
        fitted=F(testPts_X,testPts_Y)

        # The fitted value in the trench should be -500, because of clipping
        assert(fitted[0]==-500.)

        # Find the nearest domain point to the second test point
        # This will have been used in constructing the elevation raster
        nearest = ((domain.centroid_coordinates[:,0]-3.)**2 + 
                   (domain.centroid_coordinates[:,1]-20.)**2).argmin()
        nearest_x = domain.centroid_coordinates[nearest,0]

        assert(numpy.allclose(fitted[1],-nearest_x/150.))

        #########################################################################

        # This example uses a function, and a raster, to set the quantity           
        def f0(x,y):
            return x/10.
        F = qs.composite_quantity_setting_function(
            [[trenchPoly, f0], ['Extent', 'PointData_ElevTest.tif']],
            domain,
            verbose=False) 
        fitted = F(testPts_X,testPts_Y)
        # Now the fitted value in the trench should be determined by f0
        assert(numpy.allclose(fitted[0],50./10.))
        # The second test point should be as before
        nearest = ((domain.centroid_coordinates[:,0]-3.)**2 + 
                   (domain.centroid_coordinates[:,1]-20.)**2).argmin()
        nearest_x = domain.centroid_coordinates[nearest,0]
        assert(numpy.allclose(fitted[1],-nearest_x/150.))

        ##########################################################################

        # This example uses 'All' as a polygon
        F = qs.composite_quantity_setting_function(
            [['All', f0 ], [None, 'PointData_ElevTest.tif']],
            domain,
            verbose=False) 
        fitted=F(testPts_X,testPts_Y)
        # Now the fitted value in the trench should be determined by f0
        assert(numpy.allclose(fitted[0],50./10.))
        assert(numpy.allclose(fitted[1],3./10.))

        ###########################################################################
        # This example should fail
        def should_fail():
            F=qs.composite_quantity_setting_function(
                [['All', f0], ['All', 'PointData_ElevTest.tif']],
                domain,
                verbose=False)
            # Need to call it to get the error
            F(numpy.array([3.]), numpy.array([3.]))
            return
        self.assertRaises(Exception, lambda: should_fail())

        ###########################################################################
        # This example should fail (since the clip_range minimum >= maximum)
        def should_fail_1():
            F=qs.composite_quantity_setting_function(
                [[trenchPoly, f0], ['All', 'PointData_ElevTest.tif']],
                domain,
                clip_range = [[ -500., -1000.], [-1.0e+100, 1.0e+100]],
                verbose=False) 
            return
        self.assertRaises(Exception, lambda: should_fail_1())

        ###########################################################################
        # This example features a function with some nan return values, and uses
        # the nan_interpolation_region_polygon to try to fix it
        def f0(x,y):
            output = x/10.
            output[0] = numpy.nan
            return output 

        F = qs.composite_quantity_setting_function(
            [[trenchPoly, f0], ['Extent', 'PointData_ElevTest.tif']],
            domain,
            nan_treatment = 'fall_through',
            nan_interpolation_region_polygon = [trenchPoly],
            default_k_nearest_neighbours = 3,
            default_raster_interpolation = 'bilinear',
            verbose=False) 

        # Points where we test the function. We deliberately use many points with x=50,
        # which happens to ensure that the nan value is replaced with the same
        # value it would have had anyway
        testPts_X = numpy.array([50.,50.00, 50., 50., 97., 51., 3.])
        testPts_Y = numpy.array([1.,    2., 3. , 4  , 20., 50., 60.])
        fitted = F(testPts_X,testPts_Y)
       
        # We should have no nan values
        assert(sum(fitted!=fitted) == 0)

        # Now the fitted value in the trench should be determined by f0 because
        # the re-interpolation of nan values was designed to ensure it
        assert(numpy.allclose(fitted[0],50./10.))

        ###########################################################################
        # This example features a function with some nan return values, and uses
        # the nan_interpolation_region_polygon to try to fix it

        # Make a polygon-point pair which we use to set elevation in a 'channel'
        innerTrenchPoly = [[minX+45., minY+45.], [minX+45., minY+55.], 
            [minX+55., minY+55.], [minX+55., minY+45.]]

        def f_nan(x,y):
            output = x*0 + numpy.nan
            return(output)

        F = qs.composite_quantity_setting_function(
            [[innerTrenchPoly, f_nan], [trenchPoly, f0], ['Extent', 'PointData_ElevTest.tif']],
            domain,
            nan_treatment = 'fall_through',
            nan_interpolation_region_polygon = [trenchPoly],
            default_k_nearest_neighbours = 3,
            default_raster_interpolation = 'bilinear',
            verbose=False) 

        # Points where we test the function. We deliberately use many points with x=50,
        # which happens to ensure that the nan value is replaced with the same
        # value it would have had anyway
        testPts_X = numpy.array([50.,50.00, 50., 50., 97., 51., 3.])
        testPts_Y = numpy.array([1.,    2., 3. , 4  , 20., 50., 60.])
        fitted = F(testPts_X,testPts_Y)
       
        # We should have no nan values
        assert(sum(fitted!=fitted) == 0)

        # Now the fitted value in the trench should be determined by f0 because
        # the re-interpolation of nan values was designed to ensure it
        assert(numpy.allclose(fitted[0],50./10.))

        return