コード例 #1
0
ファイル: test_plot_utils.py プロジェクト: corsima/anuga_core
    def test_Make_Geotif_with_knn(self):
        # VERY BASIC TEST using knn+inverse distance interpolation to make the grid
        #
        # Simply create some data and grid it
        #
        # If nothing fails, that's good
        #
        # Pick a domain that makes sense in EPSG:32756
        x = np.linspace(307000., 308000., 100)
        y = np.linspace(6193000., 6194000., 100)
        myCellSize = 5.0
        xG, yG = np.meshgrid(x, y)
        xG = xG.flatten()
        yG = yG.flatten()
        # Surface is z=x+y
        fakeZ = xG - min(xG) + yG - min(yG)
        dataToGrid = np.vstack([xG, yG, fakeZ]).transpose()
        util.Make_Geotif(dataToGrid,
                         output_quantities=['TestData'],
                         EPSG_CODE=32756,
                         output_dir='.',
                         CellSize=myCellSize,
                         k_nearest_neighbours=4)

        # Use gdal to check that at least the data extent is ok
        import osgeo.gdal as gdal
        raster = gdal.Open('PointData_TestData.tif')
        rasterGeoTrans = raster.GetGeoTransform()
        assert (np.allclose(x.min() - myCellSize / 2.0, rasterGeoTrans[0]))
        assert (np.allclose(y.max() + myCellSize / 2.0, rasterGeoTrans[3]))
        #release data file
        raster = None
        # Delete tif made with Make_Geotif
        os.remove('PointData_TestData.tif')
コード例 #2
0
    def test_quantity_from_Pt_Pol_Data_and_Raster(self):
        #
        #
        #
        domain = self.create_domain(1.0, 0.0)

        # Evolve the model
        # for t in domain.evolve(yieldstep=0.2, finaltime=1.0):
        #    pass

        # 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]]
        trenchPts = numpy.array([minX + 50., minY + 50., -1000.])
        #
        PtPolData = [[trenchPoly, trenchPts]]
        F = qs.quantity_from_Pt_Pol_Data_and_Raster(PtPolData,
                                                    'PointData_ElevTest.tif',
                                                    domain)

        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 (numpy.allclose(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.))

        # Clean up file
        os.remove('PointData_ElevTest.tif')

        return
コード例 #3
0
 def make_me_a_tif(self):
     # We need to make a .tif to test some functions
     # This does the job
     #
     from anuga.utilities import plot_utils as util
     #
     # Do it with Make_Geotif
     # Pick a domain that makes sense in EPSG:32756
     x = numpy.linspace(307000., 307100., 101)
     y = numpy.linspace(6193000., 6193100., 101)
     xG, yG = numpy.meshgrid(x, y)
     xG = xG.flatten()
     yG = yG.flatten()
     # Surface is z=x+y
     fakeZ = xG-min(xG)+yG - min(yG)
     dataToGrid = numpy.vstack([xG, yG, fakeZ]).transpose()
     #
     util.Make_Geotif(dataToGrid, output_quantities=['TestData'],
                      EPSG_CODE=32756, output_dir='.', CellSize=1.0)
コード例 #4
0
pyplot.savefig('Modelled_vs_Observed_peakStage.png')

pyplot.clf()
pyplot.hist(floodLevels[:,3]-modelled_level)
pyplot.xlabel('Observed minus Modelled flood level')
pyplot.title('Difference in Modelled and Observed flood levels, Towradgi 1998')
pyplot.savefig('Error_peakstage.png')


# Make a bunch of GIS outputs
try:
    tif_outdir='OUTPUT_TIFS'
    CellSize=5.0
    print 'Making tifs'
    util.Make_Geotif(swwdir+swwname,
                      ['depth','velocity','depthIntegratedVelocity','elevation', 'friction'],'max',
                      CellSize=CellSize,EPSG_CODE=32756,output_dir=tif_outdir)
    print 'Made tifs'
except:
    print 'Cannot make GIS plot -- perhaps GDAL etc are not installed?'

    
# Plot depth raster with discrepency between model and data
depthFile=tif_outdir+'/Towradgi_historic_flood_depth_max.tif'
#myDepth=scipy.misc.imread(depthFile)
raster = gdal.Open(depthFile)
myDepth = scipy.array(raster.ReadAsArray())


X=scipy.arange(p.xllcorner, p.xllcorner+myDepth.shape[1]*CellSize, CellSize)
Y=scipy.arange(p.yllcorner, p.yllcorner+myDepth.shape[0]*CellSize, CellSize)
コード例 #5
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
コード例 #6
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.")
コード例 #7
0
def make_me_some_tifs(
    sww_file,
    bounding_polygon,
    proj4string,
    my_time_step='collected_max',
    tif_output_subdir='/TIFS/',
    cell_size=5.0,
    k_nearest_neighbours=1,
    make_highres_drape_plot=False,
    elevation_raster=None,
    depth_threshold=None,
    clip_polygon=None,
    clip_polygon_layer=None,
    creation_options=['COMPRESS=DEFLATE'],
):
    """

    ### INPUT DATA
    - swwFile -- Full path name of sww to read outputs from
    - bounding_polygon -- ANUGA's bounding polygon, or another polygon to clip
      the rasters to, [in ANUGA's polygon format].
    - proj4string defining the coordinate system
    - my_time_step -- option from util.Make_Geotif
      use 'max' to plot the maxima
      use [0, 5, 10] to plot the first, sixth and eleventh output time step
      use 'collected_max' to read the csv outputs from
        collect_max_quantities_operator
    - tif_outputdir -- Write outputs to this folder inside the swwFile's
      directory (MUST INCLUDE TRAILING SLASH /)
    - cell_size -- Desired raster cellSize (m)
    - k_nearest_neighbours -- use inverse distance weighted interpolation with this many neighbours
    - make_highres_drape_plot -- True/False, Make a high-res drape plot?
    - elevation_raster -- Filename of elevation raster for 'high-res-drape'
      depth plot [from subtracting stage from high res topography]
    - depth_threshold -- Depth threshold for high-res-drape' plot (m). If
      ANUGA's triangle has depth
      < depth_threshold, then depth=0 in all high-res cells in that triangle
    - clipPolygon -- Polygon to clip 'high-res-drape' plot. Must be
      provided if make_highres_drape_plot==True (can use bounding polygon or
      another choice)
    - clipPolygonLayer -- Layer for above as used by gdal (usually shapefile
      name without .shp)
    - creation_options -- list of gdal tif creation options

    ## OUTPUT
    Nothing is returned, but tifs are made in tif_output_subdir inside the
    swwFile directory

    """

    # Convert utm_zone to proj4string
    # p=Proj(proj='utm', south=(utm_zone<0.),
    #        zone=abs(utm_zone), ellps='WGS84')
    # proj4string = p.srs

    tif_output_dir = os.path.dirname(sww_file) + tif_output_subdir

    # Make the geotifs

    if my_time_step == 'collected_max':

        # Read max quantity output files inputs

        max_qfiles = glob.glob(os.path.dirname(sww_file) + '/*_UH_MAX.csv')
        if len(max_qfiles) == 0:
            raise Exception(
                'Cannot find any files containing collected maxima')
        for i in range(len(max_qfiles)):
            if i == 0:
                max_qs = numpy.genfromtxt(max_qfiles[i], delimiter=',')
            else:
                extra_data = numpy.genfromtxt(max_qfiles[i], delimiter=',')
                max_qs = \
                    numpy.vstack([max_qs, extra_data])

        # Make the geotiff's

        for (i, quant) in enumerate(
            ['stage', 'depth', 'velocity', 'depthIntegratedVelocity']):

            # FIXME: The interpolation function is remade for every quantity,
            # since only a 3 column array can be passed to Make_Geotif Could
            # make it fast (do it only once) by changing Make_Geotif

            tmp_arr = max_qs[:, [0, 1, i + 2]]

            util.Make_Geotif(
                tmp_arr,
                output_quantities=[quant + '_MAX'],
                CellSize=cell_size,
                proj4string=proj4string,
                verbose=True,
                bounding_polygon=bounding_polygon,
                output_dir=tif_output_dir,
                creation_options=creation_options,
                k_nearest_neighbours=k_nearest_neighbours,
            )

        # Also plot elevation + friction
        # Try to reduce memory demands by only extracting first timestep
        fid = NetCDFFile(sww_file)

        # Make xy coordinates (note -- max_quantity_collector outputs might
        # have repeated x,y at parallel ghost cells)
        x_v = fid.variables['x'][:] + fid.xllcorner
        y_v = fid.variables['y'][:] + fid.yllcorner
        vols = fid.variables['volumes'][:]
        xc = (1. / 3.) * (x_v[vols[:, 0]] + x_v[vols[:, 1]] + x_v[vols[:, 2]])
        yc = (1. / 3.) * (y_v[vols[:, 0]] + y_v[vols[:, 1]] + y_v[vols[:, 2]])

        for (i, quant) in enumerate(['elevation_c', 'friction_c']):

            # Get the quantity if it exists
            if fid.variables.has_key(quant):
                quant_values = fid.variables[quant]
                # If multi time-steps, only get first timestep
                if (len(quant_values.shape) > 1):
                    quant_values = quant_values[0, :]
            else:
                # Set quantity to nan if it is not stored
                quant_values = xc * 0. + numpy.nan

            tmp_arr = numpy.vstack([xc, yc, quant_values]).transpose()

            util.Make_Geotif(
                tmp_arr,
                output_quantities=[quant + '_INITIAL'],
                CellSize=cell_size,
                proj4string=proj4string,
                verbose=True,
                bounding_polygon=bounding_polygon,
                output_dir=tif_output_dir,
                creation_options=creation_options,
                k_nearest_neighbours=k_nearest_neighbours,
            )

    else:
        util.Make_Geotif(
            sww_file,
            myTimeStep=my_time_step,
            output_quantities=[
                'depth',
                'stage',
                'elevation',
                'velocity',
                'depthIntegratedVelocity',
                'friction',
            ],
            CellSize=cell_size,
            proj4string=proj4string,
            verbose=True,
            bounding_polygon=bounding_polygon,
            output_dir=tif_output_dir,
            creation_options=creation_options,
            k_nearest_neighbours=k_nearest_neighbours,
        )

    # Early finish

    if not make_highres_drape_plot:
        return

    # Get extent of geotifs

    sample_rast = glob.glob(tif_output_dir + '*.tif')[0]
    raster_extent = su.getRasterExtent(sample_rast)

    # Make the resampled elevation data

    make_resampled_elevation(
        elevation_raster,
        raster_extent,
        cell_size,
        clip_polygon,
        clip_polygon_layer,
        proj4string,
        tif_output_dir,
    )

    elevation = glob.glob(tif_output_dir + 'LIDAR_resampled*')[0]
    mask = glob.glob(tif_output_dir + 'Mask_resampled*')[0]
    if my_time_step == 'collected_max':
        depth = glob.glob(tif_output_dir + 'PointData_depth_*')[0]
        stage = glob.glob(tif_output_dir + 'PointData_stage_*')[0]
    else:
        depth = glob.glob(tif_output_dir + '*_depth_max.tif')[0]
        stage = glob.glob(tif_output_dir + '*_stage_max.tif')[0]

    # Call gdal_calc

    gdal_calc_command(stage, depth, elevation, mask, depth_threshold)

    return