Open-Source-Spatial-Clean-Cooking-Tool / OnStove

This repository contain the general code for the Open Source Spatial Clean Cooking Tool OnStove
MIT License
7 stars 9 forks source link

Check tiers for assessing electricity use #10

Open camiloramirezgo opened 3 years ago

camiloramirezgo commented 3 years ago

The idea is to produce a Tiers of electricity consumption map that would help assess the potential areas where electric cooking can be implemented. The initial idea is to use Falchetta et al. approach developed for Subsaharan Africa: https://doi.org/10.1038/s41597-019-0122-6

camiloramirezgo commented 3 years ago

The Approach by Falchetta et al. did not work in the context of Nepal, as the nighttime lights dataset only covered around 50% of the population in the country. National statistics say that the electrified people is around 95%, thus this creates a big mismatch as the above approach relies on nighttime light coverage.

The steps followed were:

  1. Create clusters to assess urban/rural split:
    
    # Read population dataset and extract metadata
    pop_path = 'data/population_npl_2018-10-01_3857_100x100.tif'
    with rasterio.open(pop_path) as src:
    population = src.read(1)
    population_meta = src.meta

Get coordinates of cells where population is over 0

rows, cols = np.where(population>0) x, y = rasterio.transform.xy(population_meta['transform'], rows, cols, offset='center') coords = np.column_stack((x, y))

Create clusters sing the DBSCAN object of sklearn.cluster.

A radius of 500 m and a min_samples of 50 where used to create a good separation between clusters

labels = DBSCAN(eps=500, min_samples=50).fit_predict(coords) clusters = population.copy() clusters[rows, cols] = labels

![image](https://user-images.githubusercontent.com/12953752/122174896-72621400-ce83-11eb-9847-94d49f2180c7.png)

2. Then run the urban/rural split method from OnSSET
```python
# Create dataframe with the clusters and population
df = gpd.GeoDataFrame({'Population': population[rows, cols], 'Cluster': clusters[rows, cols], 
                                         'geometry': gpd.points_from_xy(x, y)})

# Make the unclustered points (-1) to be a standalone cluster each
max_cluster = df['Cluster'].max()
cluster_number = df.loc[df['Cluster']==-1, 'Cluster'].count()

# Calculate area of each cluster
df.loc[df['Cluster']==-1, 'Cluster'] = [max_cluster + i for i in range(1, cluster_number + 1)]
df['Area'] = population_meta['transform'][0] * abs(population_meta['transform'][4]) / (1000 ** 2)
df_clusters = df.groupby('Cluster')[['Population', 'Area']].sum().reset_index()

# Get urban/rural split
calibrate_urban(df_clusters, 0.197, '')
dff = df.merge(df_clusters[['Cluster', 'IsUrban']], on='Cluster', how='left')
isurban = population.copy()
isurban[rows, cols] = dff['IsUrban']

image

  1. Classify demand Tiers
    # Call the get_tiers() functionusing the rural, periurban and urban datasets created with the previous step
    tiers_urban = get_tiers('data/ntl_urban.tif', ntl_urban, df_district)
    tiers_periurban = get_tiers('data/ntl_periurban.tif', ntl_periurban, df_district)
    tiers_rural = get_tiers('data/ntl_rural.tif', ntl_rural, df_district)

    This calculates the nighttime lights lower and upper bounds for each Tier for the rural, periurban and rural settlements. It uses the median of the percentiles distribution of nighttime lights among districts in Nepal. image

This result is not good as about 50% of the population is classified as Tier 0 due to the lack of nighttime lights. This is not consistent with the national statistics.

camiloramirezgo commented 3 years ago

Another approach is to use GDP, wealth index and population density to estimate Tiers of demand, based on a simple MCA. This could be used as well in combination with MTF data to calibrate the Tiers to province levels.