Source code for forestatrisk.predict.predict_raster_binomial_iCAR

#!/usr/bin/env python
# -*- coding: utf-8 -*-

# ==============================================================================
# author          :Ghislain Vieilledent
# email           :ghislain.vieilledent@cirad.fr, ghislainv@gmail.com
# web             :https://ecology.ghislainv.fr
# python_version  :>=2.7
# license         :GPLv3
# ==============================================================================

# Import
from __future__ import division, print_function  # Python 3 compatibility
from glob import glob
import os
import sys

# Third party imports
import numpy as np
from osgeo import gdal
import pandas as pd
from patsy.build import build_design_matrices

# Local application imports
from ..misc import invlogit, rescale
from ..misc import progress_bar, makeblock


# predict_binomial_iCAR
[docs] def predict_binomial_iCAR(model, new_data, rhos): """Function to return the predictions of a model_binomial_iCAR model. Function to return the predictions of a model_binomial_iCAR model for a new data-set. In this function, rho values for spatial cells are directly provided and not obtained from the model. :param model: The model_binomial_iCAR model to predict from. :param new_data: Pandas DataFrame including explicative variables. :param rhos: Spatial random effects for each observation (row) in new_data. :return: Predictions (probabilities). """ (x_new,) = build_design_matrices([model._x_design_info], new_data) X_new = x_new[:, :-1] return invlogit(np.dot(X_new, model.betas) + rhos)
# predict
[docs] def predict_raster_binomial_iCAR( model, var_dir="data", input_cell_raster="output/rho.tif", input_forest_raster="data/forest.tif", output_file="output/pred_binomial_iCAR.tif", blk_rows=128, verbose=True, ): """Predict the spatial probability of deforestation from a model. This function predicts the spatial probability of deforestation from a model_binomial_iCAR model. Computation are done by block and can be performed on large geographical areas. :param model: The model_binomial_iCAR model to predict from. :param var_dir: Directory with rasters (.tif) of explicative variables. :param input_cell_raster: Path to raster of rho values for spatial cells. :param input_forest_raster: Path to forest raster (1 for forest). :param output_file: Name of the raster file to output the probability map. :param blk_rows: If > 0, number of rows for computation by block. :param verbose: Logical. Whether to print messages or not. Default to ``True``. """ # Mask on forest fmaskR = gdal.Open(input_forest_raster) fmaskB = fmaskR.GetRasterBand(1) # Landscape variables from forest raster gt = fmaskR.GetGeoTransform() ncol = fmaskR.RasterXSize nrow = fmaskR.RasterYSize Xmin = gt[0] Xmax = gt[0] + gt[1] * ncol Ymin = gt[3] + gt[5] * nrow Ymax = gt[3] # Raster list var_tif = var_dir + "/*.tif" raster_list = glob(var_tif) raster_list.sort() # Sort names raster_list.append(input_cell_raster) raster_names = [] for i in range(len(raster_list)): fname = os.path.basename(raster_list[i]) index_dot = fname.index(".") raster_names.append(fname[:index_dot]) raster_names.append("fmask") # Make vrt with gdalbuildvrt print("Make virtual raster with variables as raster bands") param = gdal.BuildVRTOptions( resolution="user", outputBounds=(Xmin, Ymin, Xmax, Ymax), xRes=gt[1], yRes=-gt[5], separate=True, ) gdal.BuildVRT("/vsimem/var.vrt", raster_list, options=param) stack = gdal.Open("/vsimem/var.vrt") nband = stack.RasterCount proj = stack.GetProjection() # List of nodata values bandND = np.zeros(nband) for k in range(nband): band = stack.GetRasterBand(k + 1) bandND[k] = band.GetNoDataValue() if (bandND[k] is None) or (bandND[k] is np.nan): print("NoData value is not specified for" " input raster file {}".format(k)) sys.exit(1) bandND = bandND.astype(np.float32) # Make blocks blockinfo = makeblock("/vsimem/var.vrt", blk_rows=blk_rows) nblock = blockinfo[0] nblock_x = blockinfo[1] x = blockinfo[3] y = blockinfo[4] nx = blockinfo[5] ny = blockinfo[6] print("Divide region in {} blocks".format(nblock)) # Raster of predictions print("Create a raster file on disk for projections") driver = gdal.GetDriverByName("GTiff") Pdrv = driver.Create( output_file, ncol, nrow, 1, gdal.GDT_UInt16, ["COMPRESS=LZW", "PREDICTOR=2", "BIGTIFF=YES"], ) Pdrv.SetGeoTransform(gt) Pdrv.SetProjection(proj) Pband = Pdrv.GetRasterBand(1) Pband.SetNoDataValue(0) # Predict by block # Message print("Predict deforestation probability by block") # Loop on blocks of data for b in range(nblock): # Progress bar if verbose: progress_bar(nblock, b + 1) # Position in 1D-arrays px = b % nblock_x py = b // nblock_x # Number of pixels npix = nx[px] * ny[py] # Data for one block of the stack (shape = (nband,nrow,ncol)) data = stack.ReadAsArray(x[px], y[py], nx[px], ny[py]) # Replace ND values with -9999 for i in range(nband): data[i][np.nonzero(data[i] == bandND[i])] = -9999 # Forest mask fmaskA = fmaskB.ReadAsArray(x[px], y[py], nx[px], ny[py]) fmaskA = fmaskA.astype(np.float32) # From uint to float fmaskA[np.nonzero(fmaskA != 1)] = -9999 fmaskA = fmaskA[np.newaxis, :, :] # Concatenate forest mask with stack data = np.concatenate((data, fmaskA), axis=0) # Transpose and reshape to 2D array data = data.transpose(1, 2, 0) data = data.reshape(npix, nband + 1) # Observations without NA w = np.nonzero(~(data == -9999).any(axis=1)) # Remove observations with NA data = data[w] # Transform into a pandas DataFrame df = pd.DataFrame(data) df.columns = raster_names # Add fake "cell" column df["cell"] = 0 # Predict with binomial iCAR model pred = np.zeros(npix) # Initialize with nodata value (0) if len(w[0]) > 0: # Get predictions into an array p = predict_binomial_iCAR(model, new_data=df, rhos=data[:, -2]) # Rescale and return to pred pred[w] = rescale(p) # Assign prediction to raster pred = pred.reshape(ny[py], nx[px]) Pband.WriteArray(pred, x[px], y[py]) # Compute statistics print("Compute statistics") Pband.FlushCache() # Write cache data to disk Pband.ComputeStatistics(False) # # Build overviews # print("Build overviews") # Pdrv.BuildOverviews("nearest", [4, 8, 16, 32]) # Dereference driver Pband = None del Pdrv
# End