Search code examples
rparallel-processinggisraster

Parallel process list of rasters with focal function and parLapply in R


I am attempting to parallel process a list of rasters and execute a focal function using parLapply. I think I am misunderstanding something crucial. The code runs, but looks like it doesn't write the focal function out properly on my drive. As well it looks like it executed Density_Function on the first raster in the list twice.... new to the parallel processing world and was wondering if there are any suggestions on how to handle this? Just a side note, when I run my Density_Function and list using lapply it works. How do I parallel process this?

`# Density function
Density_Function <- function (raster_layer){
                    weight <- focalWeight(raster_layer,90,type = "circle")                        
                    raster_name <- names(raster_layer)
                    short_name <- substr(raster_name,1,4)
                    half_output <- "X:/Path"
                    full_output <- paste0(half_output,short_name,"_90m.tif")
                    focal(raster_layer, weight, fun=sum, full_output, na.rm=TRUE, pad=TRUE, NAonly=FALSE, overwrite=TRUE)         
                    }

#Bring in raster data and create list
roads_raster <-raster('X:/roads.tif')
pipe_raster <-raster('X:/pipes.tif')
raster_list <- list(roads_raster,pipe_raster) ` 

#Activate cluster
no_cores <- detectCores() - 1
cl <- makeCluster(no_cores)

#Apply function
parLapply(cl = cl, x = raster_list, fun = Density_Function)

#Close cluster
stopCluster(cl)

Solution

  • I took a different approach but ended up getting what I intended. Instead of using the parLapply, I use a foreach to loop through my list of rasters and execute my density function in parallel.

    This blog was really helpful: http://www.gis-blog.com/increasing-the-speed-of-raster-processing-with-r-part-23-parallelisation/

    library(doParallel)   
    library(foreach)
    
    #Density function, 1km circular radius
    Density_Function_1000 <- function (raster_layer){
      raster_name <- names(raster_layer)
      short_name <- substr(raster_name,1,4)
      weight <- focalWeight(raster_layer,1000,type = "circle")
      half_output <- "X:/Path"
      full_output <- paste0(half_output,short_name,"_1km.tif")
      focal(raster_layer, weight, fun=sum, full_output, na.rm=TRUE, pad=TRUE, NAonly=FALSE, overwrite=TRUE)
      }
    
    #Define how many cores you want to use
    UseCores <- detectCores() -1
    #Register CoreCluster
    cl <- makeCluster(UseCores)
    registerDoParallel(cl)
    
    #Create my list of rasters
    raster_list <- list(roads_raster, cuts_raster, wells_raster, seis_raster, pipes_raster, fires_raster)
    
    #Use foreach loop and %dopar% command to execute my density function in parallel 
    foreach(i = raster_list) %dopar% {
      library(raster)
      Density_Function_1000(i)
      }
    
    #end cluster
    stopCluster(cl)