Ошибка памяти при растровой обработке в R - PullRequest
0 голосов
/ 09 ноября 2019

Я написал скрипт для автоматизации обработки моих растровых данных, но он не работает после половины его завершения. Цикл ищет в каталоге unzipped подкаталоги, которые содержат .tif файлы, и объединяет их с некоторыми базовыми картами в /base_layers. Ошибка:

Ошибка в матрице (unlist (ini), ncol = 2, byrow = TRUE): «данные» должны иметь векторный тип, было «NULL»

и

В writeBin (v, x @ file @ con, size = x @ file @ dsize): проблема записи в соединение

и

Ошибка в .local (.Object, ...): Ошибка GDAL 3: Свободное дисковое пространство составляет 875151360 байт, тогда как 2473962400 как минимум необходимы. Вы можете отключить эту проверку, задав для параметра конфигурации CHECK_DISK_FREE_SPACE значение FALSE.

ИСПРАВЛЕНО Мне кажется, см. Ответы Выполнено в модуле kubernetes с Ubuntu, 24гигабайты оперативной памяти, и 50 гигабайт хранилища, и 4 виртуальных ЦП, а также в экземпляре виртуальной машины под управлением Ubuntu 18.04 с 2 виртуальными ЦП, 8 гигабайтами оперативной памяти и 50 гигабайтами хранилища. Части провалились частично из-за проблем с памятью, и виртуальная машина также не завершила работу. Код обычно терпит неудачу, когда достигает стадии растра маски, но только после прохождения нескольких итераций цикла (так что все работает в начале).

Если кто-то может указать, может ли фрагментация памяти произойти вэтот скрипт, или способы очистки памяти ОС, я был бы всегда благодарен!

Скрипт:

library(raster)
library(rgdal)
input = "/mnt/nfs/data/unzipped"
output = "/mnt/nfs/data/training" #path to where the data should go

#get paths to basemaps
DEM = raster("/mnt/nfs/data/base_layers/Clipped_filled_dem.tif")
flow_accum = raster("/mnt/nfs/data/base_layers/accumulation.tif")
slope = raster("/mnt/nfs/data/base_layers/Clipped_slope.tif")
aspect = raster("/mnt/nfs/data/base_layers/Clipped_filled_aspect.tif") 
ruggedness = raster("/mnt/nfs/data/base_layers/Clipped_TRI.tif")

#get directories that have data that needs to be processed
directory = list.dirs(path = input, recursive = FALSE)
for(direct in directory) {
    subdirect = list.dirs(path = direct,recursive = FALSE)
    for(sub in subdirect){

        files_for_raster <- list.files(path = sub, pattern = "*.tif$", full.names = TRUE)
        rasterstack = stack(files_for_raster)

        # name of datapull
        name = gsub(paste(direct,"/",sep=""),"",sub)
        print(c("working in",name))

        # crop DEM to the extent of the satellite image
        DEMcrop = crop(DEM,rasterstack) #extent can be a raster
        flow_accumcrop = crop(flow_accum,rasterstack)
        slopecrop = crop(slope,rasterstack)
        aspectcrop = crop(aspect,rasterstack)
        ruggednesscrop = crop(ruggedness,rasterstack)
        print(c("cropped"))
        print(object.size(DEMcrop))
        print(object.size(rasterstack))

        # resample rasters, this will take a bit
        DEMcrop = resample(DEMcrop,rasterstack) 
        flow_accumcrop = resample(flow_accumcrop,rasterstack)
        slopecrop = resample(slopecrop,rasterstack)
        aspectcrop = resample(aspectcrop,rasterstack)
        ruggednesscrop = resample(ruggednesscrop,rasterstack)
        print(c("resampled"))
        print(object.size(DEMcrop))
        print(object.size(rasterstack))

        # mask layers 
        DEMcrop = mask(DEMcrop,raster::subset(rasterstack,1)) 
        flow_accumcrop = mask(flow_accumcrop,raster::subset(rasterstack,1))
        slopecrop = mask(slopecrop,raster::subset(rasterstack,1))
        aspectcrop = mask(aspectcrop,raster::subset(rasterstack,1))
        ruggednesscrop = mask(ruggednesscrop,raster::subset(rasterstack,1))
        print(c("masked"))
        print(object.size(DEMcrop))
        print(object.size(rasterstack))

        # add baselayers to the raster stack
        finalstack = addLayer(rasterstack,DEMcrop,flow_accumcrop,slopecrop,aspectcrop,ruggednesscrop)
        print(names(finalstack))
        print(nlayers(finalstack))
        bands<-c("band1","band2","band3","band4","band5","band6","band7")
        type<-c("quality","sr_ndvi","DEM","flow_accum","slope","aspect","TRI")
        band_info<-data.frame(bands,type)

        print("finalstack")

        # create new output directory and save raster there
        output_subdirect = gsub(paste(input,"/",sep=""),"",sub)
        dir.create(file.path(output,output_subdirect), recursive = TRUE)
        Sys.chmod(file.path(output,output_subdirect), mode = "777", use_umask = FALSE)
        print("created directory")
        write = file.path(output,output_subdirect)
        writeRaster(finalstack, format="GTiff", filename=file.path(write,name,fsep="/"), options=c("INTERLEAVE=BAND","COMPRESS=NONE"), overwrite=TRUE)
        write.csv(band_info, file = paste(file.path(write,name,fsep="/"),".csv",sep=""))
        print("done processing")
        rm(rasterstack,DEMcrop,flow_accumcrop,slopecrop,aspectcrop,ruggednesscrop)
        gc()
        print(gc())
        system("sudo sysctl -w vm.drop_caches=3")
    }
}

# useful functions
#mystack = stack("path/to/multilayer.tif") # multilayer.tif is an existing raster stack
#band1 = subset(mystack,subset=1) # subsets bands from raster stack
#removeTmpFiles(h=0) # removes temp files, can be used after writing raster stackes to delete all temp raster files
#rasterbrick<-brick(rasterstack) #can make a raster brick from a raster stack

Я включил print(object.size()), чтобы попытаться увидеть, растут ли мои объектыв размере во время выполнения кода.

1 Ответ

0 голосов
/ 10 ноября 2019

Файл записывал большие растры на диск в папке /tmp, более 20 ГБ при каждом запуске. Заполнил диск довольно быстро. Все еще беспокоился, почему он записывал растры в существующие файлы, а не очищал их. Может очистить каталог tmp во время сценария.

Это было довольно хорошее объяснение проблем с памятью в растровом пакете. https://discuss.ropensci.org/t/how-to-avoid-space-hogging-raster-tempfiles/864

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...