<jupyter_start><jupyter_text>Exercise: Vegetation change detection  Overview In this exercise, we will create a notebook to detect vegetation change. To compare change, we need to have data from two different times: an older dataset, and a newer dataset.The notebook will include the following steps:* Load Landsat 8 data* Calculate a vegetation index for the loaded data* Split the vegetation index data into half, based on when the data was collected &mdash; an older half and a newer half* Compute the mean composite for each half; and* Compare the older and newer averages to check for vegetation change. At the conclusion of this exercise, you will have performed a vegetation analysis which can be used to report on changes in the selected area.  Set up notebook In your **Training** folder, create a new Python 3 notebook. Name it `Vegetation_exercise.ipynb`. For more instructions on creating a new notebook, see the [instructions from Session 2](../session_2/04_load_data_exercise.ipynbMake-a-new-notebook).  Load packages and functions In the first cell, type the following code and then run the cell to import necessary Python dependencies.     import matplotlib.pyplot as plt    %matplotlib inline    import datacube        from deafrica_tools.datahandling import load_ard    from deafrica_tools.plotting import display_map    from deafrica_tools.bandindices import calculate_indices<jupyter_code>.. note::
    As of June 2021, the ``deafrica_tools`` package has replaced the deprecated ``sys.path.append('../Scripts')`` file import. For more information on ``deafrica_tools``, visit the `DE Africa Tools module documentation <https://docs.digitalearthafrica.org/en/latest/sandbox/api.html>`_.<jupyter_output><empty_output><jupyter_text>In this exercise, we import one new function, `calculate_indices`.Instead of calculating band indices such as NDVI by defining a formula, we can call upon preset index calculations in the Sandbox. `calculate_indices` contains definitions for over a dozen different indices, from NDVI to the Bare Soil Index (BSI) to Tasselled Cap Wetness (TCW), and can apply them to your dataset. Using this function to select the index we want might seem like a lot of effort. However, there are some benefits to using the `calculate_indices` function, as we will see in this exercise.* Reduce chances of error in typing out the formula, as they are already defined in the `calculate_indices` script &mdash; this is great for more complicated formulae * Compare different index results without manually defining many different formulae* Reduce the number of definitions you have to type &mdash; for instance, there is no need for `red=` or `nir=` as we used in Session 4We will use `calculate_indices` after we load the dataset.  Connect to the datacube Enter the following code and run the cell to create our `dc` object, which provides access to the datacube.     dc = datacube.Datacube(app="Vegetation_exercise")  Select area of interest We need to select an area of interest. Some areas to check for vegetation changes include mining sites, where there might be devegetation, or crops, where seasonal changes in vegetation greenness occur.Previously, we have provided a longitude range and a latitude range. However, it is more common to define a central point, and provide a buffer around it.  *We previously used the* `x=(lon1, lon2), y=(lat1, lat2)` *method (left) to define our area of interest. In this exercise, we will use the buffer zone method (right). The advantage is that you can define one buffer to use in all four directions, and it is much easier to explore different areas by changing the central point and/or the buffer width.* We will be selecting an area around a centre point. Enter the following code and run the cell to select an area and time range of interest. The parameters are:* `latitude`: The latitude at the centre of your area of interest.* `longitude`: The longitude at the centre of your area of interest.* `buffer`: The number of degrees to load around the central latitude and longitude.* `time`: The date range to analyse. For reasonable results, the range should span at least two years to prevent detecting seasonal changes.* `time_baseline`: The date at which to split the total dataset into two non-overlapping samples. For this exercise, we choose a date halfway in our time range. Its value here, `'2015-12-31'`, is halfway between `'2013-01-01'` and `'2018-12-31'` - the time range in `time`. So our two time periods will be 2013 to 2015, and 2016 to 2018.In the next cell, enter the following code, and then run it to select an area.      Define the area of interest    latitude = 0.02    longitude = 35.425    buffer = 0.1     Combine central lat,lon with buffer to get area of interest    lat_range = (latitude-buffer, latitude+buffer)    lon_range = (longitude-buffer, longitude+buffer)     Set the range of dates for the complete sample    time = ('2013-01-01', '2018-12-01')     Set the date to separate the data into two samples for comparison    time_baseline = '2015-12-31' In the next cell, enter the following code, and then run it to show the area on a map. Since we have defined our area using the variables `lon_range` and `lat_range`, we can use those instead of typing out `(latitude-buffer, latitude+buffer)` and `(longitude-buffer, longitude+buffer)` again.     display_map(x=lon_range, y=lat_range)  Load data Since we want to look at a longer time range, Landsat 8 data is suitable. In the new cell below, enter the following code, and then run it to load Landsat 8 data.Notice `lat_range`, `lon_range` and `time` were all defined in the previous cell, so we can use them as variables here.<jupyter_code>.. note::
    If you are unsure where we defined ``lat_range``, ``lon_range`` and ``time``, scroll up to the previous cell and look for the lines starting with ``lat_range = ...``, ``lon_range = ...`` and ``time = ...``.<jupyter_output><empty_output><jupyter_text>landsat_ds = load_ard(        dc=dc,         products=["ls8_sr"],         lat=lat_range,         lon=lon_range,        time=time,         output_crs="EPSG:6933",        resolution=(-30, 30),        align=(15, 15),        group_by='solar_day',        measurements=['nir', 'red', 'blue'],        min_gooddata=0.7) The output from running the `load_ard()` function should include a statement that says `Loading 46 time steps`.<jupyter_code>.. note::
    As of June 2021, DE Africa Landsat data has been upgraded to Collection 2. Datacube names have been updated to ``ls5_sr``, ``ls7_sr`` and ``ls8_sr``. Deprecated naming conventions such as ``ls8_usgs_sr_scene`` will no longer work. For more information on Landsat Collection 2, visit the `DE Africa Landsat documentation <https://docs.digitalearthafrica.org/en/latest/data_specs/Landsat_C2_SR_specs.html>`_.<jupyter_output><empty_output><jupyter_text>Calculate indices Now we need to calculate a vegetation index.Until now, we have used NDVI, which uses the ratio of the red and near-infrared (NIR) bands to identify live green vegetation. The formula is:$$\begin{aligned}\text{NDVI} = \frac{\text{NIR} - \text{Red}}{\text{NIR} + \text{Red}}\end{aligned}$$This time we will use the Enhanced Vegetation Index (EVI). EVI uses the red, near-infrared (NIR) and blue bands to identify vegetation, and is particularly sensitive to high biomass regions, which is why it can be superior to NDVI. The formula for EVI is more complicated than NDVI as it uses three different bands and some empirical scaling constants.$$\begin{aligned}\text{EVI} = \frac{2.5 \times (\text{NIR} - \text{Red})}{\text{NIR} + 6 \times \text{Red} - 7.5 \times \text{Blue} + 1}\end{aligned}$$ Instead of typing out that whole formula, we can use the `calculate_indices` function to calculate EVI. `calculate_indices` requires three inputs:* The dataset name, e.g. `landsat_ds`* The name of the index to calculate, e.g. `index='EVI'`* The Landsat collection number, e.g. `collection='c2'``c2` stands for 'Collection 2', which is the currently-available Landsat collection of data as named by its publishers, US Geological Survey.In the next cell, enter the following code, and then run it to calculate the EVI vegetation index for this data.     landsat_ds = calculate_indices(landsat_ds, index='EVI', collection='c2') This adds a variable called `EVI` to our `landsat_ds` dataset.  Detect changes We want to determine what changed in vegetation between the older and newer halves of the data. First, we will split the vegetation index data into the older half and newer half. Data that was collected in the first half of our time range (2013 to 2015) will go in the older half, and data collected in the second half (2016 to 2018) will be in the newer half.The split is done using `sel()` and `slice()`.* `sel()` stands for 'selection' and tells us we are taking a selection of the dataset. We have to define which coordinate we are selecting by. In this case, we will use the `time` coordinate.* `slice()` specifies which part of the coordinate we are taking. In this case, we want to slice `time` between 2013 &ndash; 2015, and then again 2016 &ndash; 2018. Recall we named the halfway point `time_baseline`.We use `sel()` and `slice()` to create two new datasets:* `baseline_sample`: EVI from 2013 to 2015* `postbaseline_sample`: EVI from 2016 to 2018To do this, enter the following code in the next cell.     baseline_sample = landsat_ds.EVI.sel(time=slice(time[0], time_baseline))    postbaseline_sample = landsat_ds.EVI.sel(time=slice(time_baseline, time[1])) Here, using `time[0]` will give us the first date that we stored in the `time` variable (`'2013-01-01'`), and `time[1]` will give us the second date we stored in the `time` variable (`'2018-12-0'`). By using the `time` variable directly, we ensure that the code will work if those dates are changed and the notebook is rerun.<jupyter_code>.. note::
    Carefully check all your ``.``, ``,``, ``()`` pairs, and ``' '`` pairs in the above code to avoid generating errors.<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.08048149621965778, 'fraction_numerical': 0.019498607242339833, 'mean_word_length': 4.544953116381688, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 19, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '4', 'dir': 'jupyter-structured-clean-dedup', 'id': '155922', 'license': 'Apache-2.0', 'n_tokens_mistral': 2877, 'n_tokens_neox': 2617, 'n_words': 1405, 'path': 'docs/session_5/02_vegetation_exercise.ipynb', 'repo_name': 'digitalearthafrica/notebooks-training', 'size': '10052'}