# Exporting bitmasks

This tutorial shows how to generate bit masks from ENVISAT flags information as “raw” image using PyEPR.

The example code (`examples/write_bitmask.py`) is a direct translation of the C sample program write_bitmask.c bundled with the EPR API distribution.

The program is invoked as follows:

    $ python write_bitmask.py <envisat-product> <bitmask-expression> \
    <output-file>

The `examples/write_bitmask.py` code consists in a single function that also includes command line arguments handling:

    #!/usr/bin/env python3

    # This program is a direct translation of the sample program
    # "write_bitmask.c" bundled with the EPR-API distribution.
    #
    # Source code of the C program is available at:
    # https://github.com/bcdev/epr-api/blob/master/src/examples/write_bitmask.c

    """Generates bit mask from ENVISAT flags information as "raw" image
    for (e.g.) Photoshop

    Call::

        $ python3 write_bitmask.py <envisat-product> <bitmask-expression>
        <output-file>

    Example to call the main function::

        $ python3 write_bitmask.py MER_RR__2P_TEST.N1 \
        'l2_flags.LAND and !l2_flags.BRIGHT' my_flags.raw

    """

    import sys
    import epr

    def main(*argv):
        if not argv:
            argv = sys.argv

        if len(argv) != 4:
            print("Usage: write_bitmask <envisat-product> <bitmask-expression> "
                  "<output-file>")
            print("  where envisat-product is the input filename")
            print("  and bitmask-expression is a string containing the bitmask "
                  "logic")
            print("  and output-file is the output filename.")
            print("Example:")
            print("  MER_RR__2P_TEST.N1 'l2_flags.LAND and not l2_flags.BRIGHT' "
                  "my_flags.raw")
            print
            sys.exit(1)

        product_file_path = argv[1]
        bm_expr = argv[2]
        image_file_path = argv[3]

        # Open the product; an argument is a path to product data file
        with epr.open(product_file_path) as product:
            offset_x = 0
            offset_y = 0
            source_width = product.get_scene_width()
            source_height = product.get_scene_height()
            source_step_x = 1
            source_step_y = 1

            bm_raster = epr.create_bitmask_raster(source_width, source_height,
                                                  source_step_x, source_step_y)

            product.read_bitmask_raster(bm_expr, offset_x, offset_y, bm_raster)

            with open(image_file_path, "wb") as out_stream:
                bm_raster.data.tofile(out_stream)

        print(f"Raw image data successfully written to {image_file_path!r}.")
        print(f"Data type is 'byte', size is {source_width} x {source_height} "
              f"pixels.")

    if __name__ == "__main__":
        main()

In order to use the Python EPR API the `epr` module is imported:

    import epr

As usual the ENVISAT product is opened using the `epr.open()` function that returns an `epr.Product` instance. In this case the `epr.open()` is used together with a `with` statement so that the `epr.Product` instance is closed automatically when the program exits the `with` block.

        # Open the product; an argument is a path to product data file
        with epr.open(product_file_path) as product:

Scene size parameters are retrieved form the `epr.Product` object using the `epr.Product.get_scene_width()` and `epr.Product.get_scene_height()` methods:

            source_width = product.get_scene_width()
            source_height = product.get_scene_height()

The EPR API allows to manage data by means of `epr.Raster` objects, so the function `epr.create_bitmask_raster()`, specific for bitmasks, is used to create a `epr.Raster` instance.

See also

`epr.create_raster()`

Data are actually read using the `epr.Product.read_bitmask_raster()` method of the `epr.Product` class:

            product.read_bitmask_raster(bm_expr, offset_x, offset_y, bm_raster)

The `epr.Product.read_bitmask_raster()` method receives in input the bm_expr parameter that is set via command line:

        bm_expr = argv[2]

bm_expr is a string that define the logical expression for the definition of the bit-mask. In a bit-mask expression, any number of the flag-names (found in the DDDB) can be composed with “(”, ”)”, “NOT”, “AND”, “OR”.

Valid bit-mask expression are for example:

    flags.LAND OR flags.CLOUD

or:

    NOT flags.WATER AND flags.TURBID_S

Finally data are written to disk as a flat binary file using the `numpy.ndarray.tofile()` method of the `epr.Raster.data` attribute of the `epr.Raster` objects that exposes data via the `numpy.ndarray` interface:

            with open(image_file_path, "wb") as out_stream:
                bm_raster.data.tofile(out_stream)