Advertisement
Guest User

Untitled

a guest
Jun 30th, 2016
49
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.45 KB | None | 0 0
  1. ###########################################################################################
  2. # Script to compute SPEI (Thornthwaite)rasters using PRISM 800m
  3. # Using precipitation and temperature from PRISM800m rasters to calculate
  4. # Thornthwaite-based SPEI
  5. # @USDA-ARS-Tucson, AZ
  6. # @Date: 04-20-2016
  7. ###########################################################################################
  8.  
  9. library(raster)
  10. library(data.table)
  11.  
  12. ### PRECIPITATION DATA
  13. setwd('~/smbdir/PRISM800m/MONTHLY/ppt/')
  14. # Get a vector with all daiy files
  15. all.files <- list.files(pattern='\\.tif$')
  16. # Get a stack and convert it into a matrix -> data.table
  17. ptm<-proc.time()
  18. ppt.stack <- stack(all.files)
  19. mt <- as.matrix(ppt.stack)
  20. DT <- as.data.table(mt)
  21. proc.time() - ptm
  22. print("Done...")
  23.  
  24. # Get x,y from converting raster template to points
  25.  
  26. rTemp <- raster('cai_ppt_us_us_30s_201312.tif')
  27. rTemp[1:ncell(rTemp)] <- 1
  28.  
  29. rTemp <- rasterToPoints(rTemp)
  30. rTemp <- as.data.table(rTemp)
  31.  
  32. # Add LATITUDE and LONGITUDE columns to DT
  33. DT[,LATITUDE:=rTemp$y]
  34. DT[,LONGITUDE:=rTemp$x]
  35. dt.names <- c(names(DT)[1369:1370],names(DT)[1:1368])
  36. setcolorder(DT,dt.names)
  37.  
  38. # Add PIXELID column and re-arrange columns
  39. DT[,PIXELID:=seq(1:nrow(DT))]
  40. dt.names <-c(names(DT)[nrow(DT)], names(DT)[1:1371])
  41. setcolorder(DT,dt.names)
  42.  
  43. # Change names of dates
  44. setnames(DT,names(DT)[4:ncol(DT)],paste0("D_",substr(names(DT)[4:ncol(DT)],19,22),substr(names(DT)[4:ncol(DT)],23,24),"01"))
  45.  
  46. saveRDS(DT,'~/DATA/DATA_TABLES/dt.prism.ppt.1900.2013.rds')
  47.  
  48. ### TEMPERATURE DATA##########################
  49. #############################################
  50.  
  51. setwd('~/smbdir/PRISM800m/MONTHLY/tmean/')
  52. # Get a vector with all daiy files
  53. all.files <- list.files(pattern='\\.tif$')
  54. # Get a stack and convert it into a matrix -> data.table
  55. ptm<-proc.time()
  56. temp.stack <- stack(all.files)
  57. mt <- as.matrix(temp.stack)
  58. DT <- as.data.table(mt)
  59. proc.time() - ptm
  60. print("Done...")
  61.  
  62. # Get x,y from converting raster template to points
  63.  
  64. rTemp <- raster('cai_tmean_us_us_30s_201312.tif')
  65. rTemp[1:ncell(rTemp)] <- 1
  66.  
  67. rTemp <- rasterToPoints(rTemp)
  68. rTemp <- as.data.table(rTemp)
  69.  
  70. # Add LATITUDE and LONGITUDE columns to DT
  71. DT[,LATITUDE:=rTemp$y]
  72. DT[,LONGITUDE:=rTemp$x]
  73. dt.names <- c(names(DT)[1369:1370],names(DT)[1:1368])
  74. setcolorder(DT,dt.names)
  75.  
  76. # Add PIXELID column and re-arrange columns
  77. DT[,PIXELID:=seq(1:nrow(DT))]
  78. dt.names <-c(names(DT)[ncol(DT)], names(DT)[1:1370])
  79. setcolorder(DT,dt.names)
  80.  
  81. # Change names of dates
  82. setnames(DT,names(DT)[4:ncol(DT)],paste0("D_",substr(names(DT)[4:ncol(DT)],21,24),substr(names(DT)[4:ncol(DT)],25,26),"01"))
  83.  
  84. saveRDS(DT,'~/DATA/DATA_TABLES/dt.tmean.1900.2013.rds')
  85.  
  86.  
  87. DT <- readRDS('~/DATA/DATA_TABLES/dt.tmean.1900.2013.rds')
  88.  
  89. ### GET PET ###
  90. setkey(DT,PIXELID)
  91. DT.temp <- DT[!is.na(D_19000101),]
  92. # Set water year from oct-sep
  93. #DT.temp[,c(4:12):=NULL, with=FALSE]
  94. #DT.temp[,c(1360:1362):=NULL, with=FALSE]
  95. # Create ref. template
  96. DT.ref <- DT[,list(PIXELID,LATITUDE,LONGITUDE)]
  97. setkey(DT.ref, PIXELID)
  98. rm(DT)
  99.  
  100. # GET numeric vector to use with ts
  101. vcols <- names(DT.temp)[c(2,4:ncol(DT.temp))]
  102.  
  103. # Join monthly data into a column-list, each cell contains the monthly time series for each pixel
  104. ptm<-proc.time()
  105. DT.temp[,TS_COL:=list(list(list(as.numeric(.SD)))),.SDcols=vcols,by=PIXELID] # 1871.694 seconds
  106. proc.time() - ptm
  107. DT.temp <- DT.temp[,list(PIXELID,LATITUDE,TS_COL)]
  108. gc()
  109. #
  110. #saveRDS(DT.temp,'~/DATA/DATA_TABLES/dt.temp.TS_COL.rds')
  111. #DT.temp <- readRDS('~/DATA/DATA_TABLES/dt.temp.TS_COL.rds')
  112.  
  113. # Parallel setup
  114. library(parallel)
  115.  
  116. vCluster <- makeCluster(65)
  117.  
  118. GetTempTS <- function(x) {
  119. l <- unlist(x)
  120. list.final <- list(lat=l[1], tst=ts(l[2:length(l)], frequency=12, start=c(1900,1)))
  121. }
  122. GetPET <- function(x) {
  123. thornthwaite(x$tst, x$lat, na.rm=TRUE)
  124. }
  125.  
  126. GetDTpet <- function (x) {
  127. #transpose(setDT(list(x)))
  128. as.numeric(t(as.matrix(unlist(x))))
  129. }
  130.  
  131. GetWB <- function(x) {
  132. list(wb=ts(unlist(x), frequency=12, start=c(1900,1)))
  133. }
  134. GetSPEI <- function(x) {
  135. spei(x$wb, 12)$fitted
  136. }
  137.  
  138. # Make libraries and functions available to cluster
  139. clusterEvalQ(vCluster, c(library(data.table), library(SPEI)))
  140. clusterExport(vCluster, c('GetTempTS', 'GetPET', 'GetDTpet', 'GetSPEI','GetWB'))
  141.  
  142. # Prepare Timeseries of temperature to use as input for thornthwaite
  143. ptm<-proc.time()
  144. list.ts <- parLapply(vCluster, DT.temp$TS_COL, GetTempTS) # 3183 seconds
  145. proc.time() - ptm
  146.  
  147.  
  148. stopCluster(vCluster)
  149. rm(vCluster)
  150. rm(DT.temp)
  151.  
  152.  
  153. # Get PET
  154. ptm<-proc.time()
  155. list.pet <- parLapply(vCluster, list.ts, GetPET) # 4787.603 seconds
  156. proc.time() - ptm
  157.  
  158. #saveRDS(list.pet, '~/smbdir/DATA_TABLES/list.pet.rds') # This is 100 GB file, taking quite of time saving.
  159. ptm <- proc.time()
  160. list.pet2 <- readRDS('~/smbdir/DATA_TABLES/list.pet.rds') # 1087 seconds
  161. proc.time() - ptm
  162. #
  163. ptm<-proc.time()
  164. list.pet.dt <- parLapply(vCluster, list.pet, GetDTpet) # 2450 seconds with 68 cores
  165. proc.time() - ptm
  166. #
  167. # GetDTpet - Convert list of vectors with PET into data.table
  168. # Maybe it's a good idea to stop the cluster and remove list.pet to release memory
  169. stopCluster(vCluster)
  170. rm(list.pet)
  171. gc()
  172. ptm<-proc.time()
  173. dt.pet <-as.data.table(t(as.data.table(list.pet.dt))) # 3482 seconds
  174. proc.time() - ptm
  175. #
  176.  
  177. # Open precipitation data to substract dt.pet
  178. dt.ppt <- readRDS('~/DATA/DATA_TABLES/dt.ppt.1900.2013.rds')
  179. # Remove NA's
  180. dt.ppt <- dt.ppt[!is.na(D_19000101),]
  181. dt.ppt.cols <- dt.ppt[,4:ncol(dt.ppt),with=FALSE]
  182. # Get waterbalance (PPT - PET)
  183. dt.wb <- dt.ppt.cols - dt.pet
  184. dt.wb[,c('PIXELID','LATITUDE','LONGITUDE'):=dt.ppt[,list(PIXELID,LATITUDE,LONGITUDE)]]
  185.  
  186. vcols <- names(dt.wb)[1:1368]
  187. vcols <- c('PIXELID','LATITUDE','LONGITUDE',vcols)
  188. setcolorder(dt.wb,vcols)
  189. setkey(dt.wb, PIXELID)
  190.  
  191. saveRDS('~/DATA/DATA_TABLES/dt.wb.prism.1900.2013.rds')
  192.  
  193. ## set WB time series
  194. vcols <- names(dt.wb)[c(1,4:ncol(dt.wb))]
  195. ptm<-proc.time()
  196. dt.wb[,TS_COL:=list(list(list(as.numeric(.SD)))),.SDcols=vcols,by=PIXELID] # 2806 seconds
  197. proc.time() - ptm
  198. dt.wb <- dt.wb[,list(PIXELID,TS_COL)]
  199.  
  200. # Setup Water balance time series
  201. ptm<-proc.time()
  202. list.wb.ts <- parLapply(vCluster, dt.wb$TS_COL, GetWB) # 3183 seconds
  203. proc.time() - ptm
  204.  
  205. # Get SPEI time series
  206. ptm<-proc.time()
  207. list.spei.ts <- parLapply(vCluster, list.wb.ts, GetSPEI) # 11613 seconds (3.2 hours)
  208. proc.time() - ptm
  209. #
  210. stopCluster(vCluster)
  211. rm(vCluster)
  212. gc()
  213.  
  214. vCluster <- makeCluster(65)
  215. # Get a data table with SPEI
  216. ptm<-proc.time()
  217. list.spei.dt <- parLapply(vCluster, list.spei.ts, GetDTpet) #1116.363
  218. proc.time() - ptm
  219. #
  220. ptm<-proc.time()
  221. dt.spei <-as.data.table(t(as.data.table(list.spei.dt))) # 3482 seconds
  222. proc.time() - ptm
  223. #
  224. ptm<-proc.time()
  225. saveRDS(dt.spei,'~/DATA/DATA_TABLES/dt.spei.conus.1901_2013.rds')
  226. proc.time() - ptm
  227. # Saving time: 5.9 hrs
  228.  
  229. # Get PIXELID, LAT,LNG
  230. DT <- readRDS('~/DATA/DATA_TABLES/dt.tmean.1900.2013.rds')[,list(PIXELID,LATITUDE,LONGITUDE,D_19000101)]
  231.  
  232. ### GET PET ###
  233. setkey(DT,PIXELID)
  234. DT.temp <- DT[!is.na(D_19000101),]
  235.  
  236.  
  237. dt.spei[,c("PIXELID","LATITUDE","LONGITUDE"):=DT.temp[,list(PIXELID,LATITUDE,LONGITUDE)]]
  238.  
  239. setkey(dt.spei,'PIXELID')
  240.  
  241. # Join to make maps
  242. dt.spei.all <- DT[dt.spei]
  243. dt.spei.all[,LATITUDE:=i.LATITUDE]
  244. dt.spei.all[,LONGITUDE:=i.LONGITUDE]
  245. dt.spei.all[,c('V1','V2','V3','V4','V5','V6','V7','V8','V9','V10','V11','V12'):=NULL]
  246.  
  247.  
  248.  
  249. MapPixels <- function (DT_Pixels, vraster.template, vext) {
  250. # Generates a raster based on x,y pixels.
  251. #
  252. # Args:
  253. # DT_Pixels: A data tables with x,y coordinates and the values to assign each cell
  254. # vraster.template: A string value with the filename of a raster, this
  255. # raster is used to get the CRS information
  256. # vext: This should contain the "extent" of the analysis area
  257. # Returns:
  258. # A raster of the input pixels
  259.  
  260. if (nchar(vraster.template) <= 1) {
  261. #vraster.template <- tk_choose.files(caption="Select raster template...")
  262. vraster.template <- raster(vraster.template)
  263. vraster.template <- crop (vraster.template, vext)
  264. } else {
  265. vraster.template <- raster(vraster.template)
  266. #vraster.template <- crop(vraster.template, vext)
  267. }
  268. coordinates(DT_Pixels) <- ~ x + y
  269. gridded(DT_Pixels)<- TRUE
  270. vRasterOut <- raster(DT_Pixels)
  271. crs(vRasterOut) <- crs(vraster.template)
  272.  
  273. return (vRasterOut)
  274. }
  275.  
  276. vRaster <- '~/smbdir/PRISM800m/MONTHLY/ppt/cai_ppt_us_us_30s_193712.tif'
  277. vext <- extent(raster(vRaster))
  278.  
  279. ptm<-proc.time()
  280. st <-seq(as.Date("1901/1/1"),as.Date("2013-12-01"), by = "month")
  281. for (j in seq_len(ncol(dt.spei.all)-3)) {
  282. #seq_len(ncol(dt))) {
  283. map <- MapPixels(dt.spei.all[,list(x=LONGITUDE,y=LATITUDE,spei=dt.spei.all[[j]])], vRaster, vext)
  284. vname <- paste0("SPEI_CONUS_",as.character(st[j]),".tif")
  285. writeRaster(map,vname,format='GTiff', datatype = 'FLT4S', NAflag=-9999)
  286. }
  287. proc.time() - ptm
  288. #
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement