init project

This commit is contained in:
xuehaiming 2024-10-23 16:30:58 +08:00
commit 59af39637a
507 changed files with 219969 additions and 0 deletions

BIN
.RData Normal file

Binary file not shown.

7
.gitignore vendored Normal file
View File

@ -0,0 +1,7 @@
GO.Rout
data/*
confirmData/*
txt/*
tmp/*
zip/*

BIN
Deploy/._.DS_Store Normal file

Binary file not shown.

BIN
Deploy/shud/._.DS_Store Normal file

Binary file not shown.

BIN
Deploy/shud/._GetReady.R Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

72
Deploy/shud/GetReady.R Normal file
View File

@ -0,0 +1,72 @@
#' ===============================================================
#' Author: Lele Shu <shulele@lzb.ac.cn>
#' Date: 2023.02.03
#' Function: The AutoSHUD function
#'
#' ===============================================================
#'
wdir = file.path(CV$dirs$deploy)
source(file.path(CV$dirs$deploy, 'Step1_RawDataProcessng.R'))
source(file.path(CV$dirs$deploy, 'Step2_DataSubset.R'))
source(file.path(CV$dirs$deploy, 'Step3_BuidModel.R'))
source(file.path(CV$dirs$deploy, 'Rfunction/ReadProject.R'))
GetReady.AutoSHUD <- function(CV){
xfg <- read.prj(CV)
if( !is.null(xfg$fsp.lake) ){
LAKEON = TRUE
}else{
LAKEON = FALSE
}
pre.sp = list(
dem = 'dem.tif',
wbd = 'wbd.shp',
wbd.buf = 'wbd_buf.shp',
stm = 'stm.shp',
lake = 'lake.shp',
soil.r = 'soil.tif',
soil.idx = 'soil_idx.tif',
geol.r = 'geol.tif',
geol.idx = 'geol_idx.tif',
soil.v = 'soil.shp',
geol.v = 'geol.shp',
lu.r = 'landuse.tif',
lu.idx = 'landuse_idx.tif',
lu.v = 'landuse.shp',
meteo = 'meteo.shp',
meteoCov = 'meteoCov.shp')
dir.pd.pcs = file.path(xfg$dir$predata,'PCS')
dir.pd.gcs = file.path(xfg$dir$predata,'GCS')
dir.create(dir.pd.pcs, showWarnings = FALSE, recursive = TRUE)
dir.create(dir.pd.gcs, showWarnings = FALSE, recursive = TRUE)
pd.pcs = lapply(1:length(pre.sp), function(x){ file.path(dir.pd.pcs, pre.sp[[x]])} )
names(pd.pcs) = names(pre.sp)
pd.gcs = lapply(1:length(pre.sp), function(x){ file.path(dir.pd.gcs, pre.sp[[x]])} )
names(pd.gcs) = names(pre.sp)
pd.att <- list(
geol = file.path(xfg$dir$predata,'GEOL.csv'),
soil = file.path(xfg$dir$predata,'SOIL.csv'),
landuse = file.path(xfg$dir$predata,'LANDUSE.csv')
)
xfg$LAKEON=LAKEON
xfg$pd.att=pd.att
xfg$pd.pcs=pd.pcs
xfg$pd.gcs=pd.gcs
cv = CV
cv$deploy = utils::modifyList(CV$deploy, xfg)
return(cv)
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,121 @@
readnc.time <- function(ncid) {
# modified after https://stackoverflow.com/questions/46001573/convert-a-netcdf-time-variable-to-an-r-date-object
require(lubridate)
ncdims <- names(ncid$dim) #get netcdf dimensions
timevar <- ncdims[which(ncdims %in% c("time", "Time", "datetime", "Datetime", "date", "Date"))[1]] #find time variable
times <- ncvar_get(ncid, timevar)
if (length(timevar)==0) stop("ERROR! Could not identify the correct time variable")
timeatt <- ncatt_get(ncid, timevar) #get attributes
timedef <- strsplit(timeatt$units, " ")[[1]]
timeunit <- timedef[1]
if(length(timedef) < 5){
# cat("Warning:", tz, "not a valid timezone. Assuming UTC\n")
tz <- "UTC"
}else{
tz <- timedef[5]
}
timestart <- strsplit(timedef[4], ":")[[1]]
if (length(timestart) != 3 || timestart[1] > 24 || timestart[2] > 60 || timestart[3] > 60 || any(timestart < 0)) {
cat("Warning:", timestart, "not a valid start time. Assuming 00:00:00\n")
warning(paste("Warning:", timestart, "not a valid start time. Assuming 00:00:00\n"))
timedef[4] <- "00:00:00"
}
timestart <- ymd_hms(paste(timedef[3], timedef[4]), tz=tz)
f <- switch(tolower(timeunit), #Find the correct lubridate time function based on the unit
seconds=seconds, second=seconds, sec=seconds,
minutes=minutes, minute=minutes, min=minutes,
hours=hours, hour=hours, h=hours,
days=days, day=days, d=days,
months=months, month=months, m=months,
years=years, year=years, yr=years,
NA
)
suppressWarnings(if (is.na(f)) stop("Could not understand the time unit format"))
timestart + f(times)
}
readnc<-function(ncid= nc_open(fn),
xyid=c(1,1), vns=NULL){
if(is.null(vns)){
vns = names(ncid$var)
vns = vns[!(vns %in% 'time_bnds')] # don't need the time_bnds
}
nv = length(vns)
x.mat = matrix(0, ncol=nv, nrow=ns)
for(i in 1:nv){ #reading file
vn=vns[i]
mat=ncvar_get(ncid, vn)
x.v = mat[xyid]
x.mat[,i] = x.v
}
colnames(x.mat) = vns
x.mat
}
nc.sub <-function(fn, ncid=ncdf4::nc_open(fn),
ext){
ncid=nc_open(fns[1])
#nc_close(ncid)
lon=round(ncvar_get(ncid, 'longitude'), 3)
lat=round(ncvar_get(ncid, 'latitude'), 3)
nlon=length(lon)
nlat = length(lat)
#==================
loc.confirm <- function(){
ext = c(-20, 50, -38, 40)
xid=which(lon >= ext[1] & lon <= ext[2])
yid=which(lat >= ext[3] & lat <= ext[4])
xy.grid = expand.grid(lon[xid], lat[yid])
dat = ncvar_get(ncid, 'precip',
count = c(length(xid), length(yid), 1),
start = c( which(lon == min(lon[xid]) ), which(lat==min(lat[yid]) ), 1) )
xyz=cbind(xy.grid, as.numeric(dat) )
r=rasterFromXYZ(xyz)
png(filename = file.path(odir, paste0('LocationConfirm.png')), height = 11, width = 8, units = 'in', res=100)
rplot(r); rplot(wbd, add=T, border=2)
grid()
dev.off()
}
nc_close(ncid)
}
read.nc2Raster <- function(fn, ncid=ncdf4::nc_open(fn),
plot=TRUE,
varid=2, xname=NULL, yname=NULL){
nv = ncid$nvars
if(is.character(varid)){
varid = varid
}else{
vns = names(ncid$var)
if(nv>0){
varid = vns[varid]
}else{
varid = vns[1]
}
}
if(is.null(xname) | is.null(yname)){
dn = names(ncid$dim)
yname = dn[grepl('^lat|^x', tolower(dn) )]
xname = dn[grepl('^lon|^y', tolower(dn) )]
}
x = ncdf4::ncvar_get(ncid, xname)
y = ncdf4::ncvar_get(ncid, yname)
nx=length(x); ny=length(y);
dx=mean(diff(x)); dy=mean(diff(y))
r = raster::raster(ncols=nx, nrows=ny)
raster::extent(r) = c(min(x), max(x), min(y), max(y)) + c(-dx, dx, -dy, dy)/2
val = ncdf4::ncvar_get(ncid, varid)
nc_close(ncid)
# dim(val)
r = raster::setValues(r, t(val[, ny:1 ]) )
if(plot){
raster::plot(r, main=varid)
}
r
}
# vn=vns[4]
# ncvar_get(ncid, varid = vn, start=)

View File

@ -0,0 +1,77 @@
# read the orginal fldas data and save to .RDS file.
source('AutoSHUD/Rfunction/LDAS_UnitConvert.R')
source('AutoSHUD/Rfunction/raster2Polygon.R')
source('AutoSHUD/Rfunction/CMFD_readnc.R')
fun.CMFD.NC2RDS <- function(xfg){
varnames = c("Pres", "LRad", "Prec", "SHum", "SRad", "Temp", "Wind")
varnames = c("Prec", "Temp", "SHum", "SRad", "Wind", "Pres")
nv=length(varnames)
nyr = length(xfg$years)
fn=list.files(xfg$dir.ldas, pattern = glob2rx(paste0(varnames[1], '*CMFD*.nc') ),
recursive = TRUE, ignore.case = TRUE, full.names = TRUE)[1]
# cmd = paste('find',xfg$dir.lddas, ' -name "*CMFD*.nc" > filelist.txt')
# system(cmd)
# fn=readLines(file.path(xfg$dir.ldas, 'filelist.txt'))[1]
xp = initalGrids(fn=fn, vn=tolower(varnames[1]), pd.gcs = pd.gcs, pd.pcs = pd.pcs)
id = xp$id
print(length(id))
sitenames=xp$sitenames
ext=xp$ext
nsite = length(id)
# print(id)
# library(foreach)
# library(doMC)
# library(doParallel)
# registerDoMC(12)
# foreach (idd = 1:ndir) %dopar%{
msg <-function(i, n, str, ntab=0){
message(paste(rep('\t', ntab), collapse = ''),
i, '/', n, '\t', str)
}
for (iyr in 1:nyr) {
yr <- xfg$years[iyr]
message(iyr, '/', nyr, '\t', yr)
fn.rds = file.path(xfg$dir$predata, paste0('CMFD_', yr, '.RDS'))
if(file.exists(fn.rds)){
next;
}
arr = array(dim = c(nsite, nv, 366*(24/3))) #(N_SITE, N_VARNAME, N_TIME)
for(ivn in 1:nv){
vn = varnames[ivn]
message('\t', ivn, '/', nv, '\t', vn)
path = file.path(xfg$dir.ldas, vn)
fns = list.files(path, pattern = glob2rx(paste0(tolower(vn), '_CMFD_*', yr, '*.nc')), full.names = F)
ffns = list.files(path, pattern = glob2rx(paste0(tolower(vn), '_CMFD_*', yr, '*.nc')), full.names = T)
nf = length(fns)
pnt = 0;
for(i in 1:nf){ # vn in the whole year
msg(i, nf, fns[i], ntab=3)
ncid = nc_open(ffns[i])
# debug(readnc)
dat=readnc.CMFD(ncid, varid = tolower(vn), ext = ext)
nc_close(ncid)
nd = dim(dat$arr)
if(length(nd)==3){
mat = matrix(dat$arr, nrow=nd[1]*nd[2], ncol=nd[3])[id, ]
}else{
mat= dat$arr
}
if(i==1){
xtime=dat$time
}else{
xtime = c(xtime, dat$time)
}
timelen = length(dat$time)
arr[ , ivn, 1:timelen + pnt] = mat
pnt = pnt+timelen
}
}
arr=arr[,, 1:pnt ]
x.t = strftime(xtime, origin=as.POSIXct('1900-01-01'), usetz = FALSE, tz='UTC')
dimnames(arr) = list(sitenames, varnames, x.t)
saveRDS(arr, file=fn.rds)
}
}

View File

@ -0,0 +1,54 @@
# read the RDS above, to save as .csv file.
# source('GetReady.R')
fun.CMFD.RDS2csv <- function(xfg){
source('AutoSHUD/Rfunction/LDAS_UnitConvert.R')
years = xfg$years
fns = file.path(xfg$dir$predata, paste0('CMFD_',years, '.RDS'))
fns
cns = c("Prec", "Temp", "SHum", "SRad", "Wind", "Pres")
forcnames = c( "Prcp_mm.d", "Temp_C", "RH_%", "Wind_m.s", "RN_w.m2" )
nf=length(fns)
for(i in 1:nf){
x=readRDS(fns[i])
message(i,'/', nf, '\t', basename(fns[i]))
y=x[,cns,]
if(i==1){
dat = y
}else{
dat=abind::abind(dat, y, along=3)
}
}
dn = dimnames(dat)
nd = dim(dat)
xl = list()
time = as.POSIXct(dimnames(dat)[[3]], tz='UTC')
for(i in 1:nd[1]){
message(i,'/', nd[1], '\t', dn[[1]][i] )
x = t( dat[i,,] )
y=unitConvert.CMFD(x)
xl[[i]]=as.xts(y, order.by=time)
}
nx=length(xl)
sitename = dn[[1]]
sitename
fns=paste0(sitename, '.csv')
for(i in 1:nx){
fn=fns[i]
message(i,'/', nx, '\t', fn)
write.tsd(xl[[i]], file.path(xfg$dir$forc, fn))
if(i==1){
xmean = xl[[i]]
}else{
xmean = xmean + xl[[i]]
}
}
png(fn=file.path(xfg$dir$fig, paste0(xfg$prefix, '_Rawdata','_CMFD_TS.png') ), type='cairo',
height=6, width=7, res=200, units = 'in')
plot.zoo(xmean/nx, main='CMFD')
dev.off()
}

View File

@ -0,0 +1,142 @@
readnc.CMFD<-function(ncid, varid=NULL, ext = NULL){
msg= 'readnc:: '
vars = names(ncid$var)
nvars = length(vars)
if(is.null(varid)){ # read all
varid = varid[!(vars %in% 'time_bnds')] # don't need the time_bnds
}else if(is.character(varid)){ # read VARID (character) by user
if(!all(varid %in% vars)){ # validate the input chars.
message(msg, 'ERROR:: some varid is missing in the dataset.\n')
print(varid[! (varid %in% vars)])
stop('Stop with error.')
}
varid = varid
}else if(is.numeric(varid)) { # read VARID (index) by user
if(max(varid)>nvars || min(varid) < 1){
message(msg, 'ERROR:: Wrong value in varid.\n')
stop('Stop with error.')
}
message('Reading VARID = ', vars[varid])
varid = vars[varid]
}else{ # ERROR
message(msg, 'ERROR:: Wrong format of varid.\n')
stop('Stop with error.')
}
ncdims = names(ncid$dim)
var.lon <- ncdims[which(grepl('lon', tolower(ncdims)))]
var.lat <- ncdims[which(grepl('lat', tolower(ncdims)))]
lon <- ncdf4::ncvar_get(ncid, varid = var.lon)
lat <- ncdf4::ncvar_get(ncid, varid = var.lat)
dx = mean(diff(lon)); dy = mean(diff(lat))
xmin = min(lon - dx/2); xmax = max(lon + dx/2)
ymin = min(lat - dy/2); ymax = max(lat + dy/2)
if(is.null(ext)){
ext= c(min(lon), max(lon), min(lat), max(lat))
}
if(ext[1] < xmin | ext[2] > xmax | ext[3] < ymin | ext[4] > ymax){
warning(paste('Extent required is larger than the boundbox of dataset'))
message(paste(ext, collaps=','))
message(paste(c(xmin,xmax,ymin, ymax), collaps=','))
}
xid = min(which(abs(lon - ext[1]) <= dx/2)):max(which(abs(lon - ext[2]) <= dx/2))
yid = min(which(abs(lat - ext[3]) <= dy/2)):max(which(abs(lat - ext[4]) <= dy/2))
nx = length(xid); ny = length(yid)
x.cord = lon[xid]; y.cord = lat[yid]
tx = readnc.time(ncid = ncid)
ntime = length(tx)
arr = array(0, dim=c(nx, ny, ntime),
dimnames= list(x.cord, y.cord, tx))
ndims = ncid$ndims
start = c(min(xid), min(yid), 1)
count = c(nx, ny, ntime)
vn=varid[1]
arr=ncdf4::ncvar_get(ncid, vn, start = start, count = count)
rt = list('x' = x.cord, 'y' = y.cord, 'arr' = arr, 'time' = tx)
return(rt)
}
#
# ncid = nc_open(ffns[i])
# x0=readnc.CMFD(ncid, varid = tolower(vn))
# x=readnc.CMFD(ncid, varid = tolower(vn), ext = ext)
# nc_close(ncid)
# r0 = xyz2Raster(x0)
# r=xyz2Raster(x)
# plot(r0[[1]])
# plot(r[[1]], add=T)
# x$arr
initalGrids <- function(fn, vn, pd.gcs, pd.pcs, sp.ldas=NULL){
buf.g = readOGR(pd.gcs$wbd.buf)
ext = extent(buf.g)
fid = nc_open(fn)
nc.all = rSHUD::readnc(fid, varid = vn)
nc.sub = rSHUD::readnc(fid, varid = vn, ext = ext)
nc_close(fid)
nc.all$x = round(nc.all$x, 3); nc.all$y = round(nc.all$y, 3)
nc.sub$x = round(nc.sub$x, 3); nc.sub$y = round(nc.sub$y, 3)
# undebug(xyz2Raster)
r = xyz2Raster(x = nc.all)
# debug(xyz2Raster)
r.sub = xyz2Raster(x = nc.sub)
if(is.null(sp.ldas)){
sp.ldas = raster2Polygon(rx = r.sub)
# sp.center = gCentroid(sp.ldas, byid=TRUE)
# =========PLOT===========================
png.control(fn=paste0(prefix, '_LDAS_location.png'), path = xfg$dir$fig, ratio=1)
plot(r * 0, col='gray', legend=FALSE)
plot(r.sub * 0, col='red', legend=FALSE, add=TRUE)
plot(buf.g, add=T)
dev.off()
# =========Get the data===========================
sp0.gcs = spTransform(sp.ldas, xfg$crs.gcs)
sp0.pcs = spTransform(sp.ldas, xfg$crs.pcs)
}
id=which(gIntersects(sp0.gcs, buf.g, byid = T))
writeshape(sp0.gcs[id, ], file = pd.gcs$meteoCov)
writeshape(sp0.pcs[id, ], file = pd.pcs$meteoCov)
sitenames = paste0('X', sp0.gcs@data$xcenter, 'Y', sp0.gcs@data$ycenter)
sitenames=sitenames[id]
# plot(sp0.gcs)
# plot(buf.g, add=TRUE, border=2)
# plot(sp0.gcs[id, ],add=T, col=3)
retval = list(id=id, sitenames=sitenames, ext=ext)
return(retval)
}
# xp = initalGrids(fn=fn, vn=tolower(varnames[1]), pd.gcs = pd.gcs, pd.pcs = pd.pcs)
# xp = initalGrids(fn=fn, vn=tolower(varnames[1]), pd.gcs = pd.gcs, pd.pcs = pd.pcs)
# library(ncdf4)
# source('Rfunction/nc2fishnet.R')
# fn = '/Volumes/Forcing/CMFD/Data_forcing_03hr_010deg/Prec/prec_CMFD_V0106_B-01_03hr_010deg_197901.nc'
# fid = ncdf4::nc_open(fn)
# x=readnc.CMFD(ncid=fid, varid = 'prec')
# ncdf4::nc_close(fid)
# spx = nc.fishnet(x)
# crs(spx) = sp::CRS('+init=epsg:4326')
# writeshape(spx, '/Volumes/Forcing/CMFD_fishnet')
# raster::plot(spx)
# xp = initalGrids(fn=fn, vn=tolower(varnames[1]), pd.gcs = pd.gcs, pd.pcs = pd.pcs)
# x=dat
# x$arr=x$arr[,,1]
# nd=dim(x$arr)
# for(i in 1:nd[3]){
# x$arr[id+nd[1]*nd[2]*(i-1)]=1000
# }
# r=xyz2Raster(x)
# animate(r)
# plot(r.sub);
# plot(add=T, buf.g)

View File

@ -0,0 +1,90 @@
# read the orginal fldas data and save to .RDS file.
# good for PALEOFLOOD project in Arizona. 2021-04-04
require(ncdf4)
source('Rfunction/LDAS_UnitConvert.R')
source('Rfunction/raster2Polygon.R')
source('Rfunction/CMIP6_readnc.R')
varnames = c('pr','tas', 'huss', 'rsds', 'sfcWind')
nv=length(varnames)
nyr = length(xfg$years)
i=1
ffns = list.files(xfg$dir.ldas, pattern = glob2rx(paste0('*', varnames[i], '*future*.nc')),
recursive = TRUE, ignore.case = TRUE, full.names = TRUE)
# fn ='/Volumes/Download/CMIP6-data/青海湖项目/pr/2015-2051/pr_day_FGOALS-f3-H_highres-future_r1i1p1f1_gr_20510101-20510125.nc'
# ncid = nc_open(fn)
# ncid$filename
# ncvar_get(ncid, varid = cimp.vn[i])
fn=ffns[1]
xp = initalGrids(fn=fn, vn=tolower(varnames[1]), pd.gcs = pd.gcs, pd.pcs = pd.pcs)
id = xp$id
print(length(id))
sitenames=xp$sitenames
ext=xp$ext
nsite = length(id)
# print(id)
# library(foreach)
# library(doMC)
# library(doParallel)
# registerDoMC(12)
# foreach (idd = 1:ndir) %dopar%{
msg <-function(i, n, str, ntab=0){
message(paste(rep('\t', ntab), collapse = ''),
i, '/', n, '\t', str)
}
for (iyr in 1:nyr) {
yr <- xfg$years[iyr]
message(iyr, '/', nyr, '\t', yr)
fn.rds = file.path(xfg$dir$predata, paste0('CMIP6_', yr, '.RDS'))
if(file.exists(fn.rds)){
next;
}
arr = array(dim = c(nsite, nv, 366*(24/3))) #(N_SITE, N_VARNAME, N_TIME)
for(ivn in 1:nv){
vn = varnames[ivn]
message('\t', ivn, '/', nv, '\t', vn)
path = file.path(xfg$dir.ldas, vn)
ffns = list.files(path, pattern = glob2rx(paste0('*', tolower(vn),
'*future*_gr_', yr, '*.nc')),ignore.case = TRUE,
full.names = T, recursive = TRUE)
# ffns
fns=basename(ffns)
nf = length(fns)
pnt = 0;
if(('ta'== vn) | ('hur'==vn)){
if(nf != 12){
message('FILE(s) are missing')
print(nf)
print(ffns)
stop()
}
}
for(i in 1:nf){ # vn in the whole year
msg(i, nf, fns[i], ntab=3)
ncid = nc_open(ffns[i])
# debug(readnc)
dat=ReadNC(ncid, varid = vn, ext = ext, t.len=NULL)
nc_close(ncid)
nd = dim(dat$arr)
mat = matrix(dat$arr, nrow=nd[1]*nd[2], ncol=nd[3])[id, ]
if(i==1){
xtime=dat$time
}else{
xtime = c(xtime, dat$time)
}
timelen = length(dat$time)
arr[ , ivn, 1:timelen + pnt] = mat
pnt = pnt+timelen
}
}
arr=arr[,, 1:pnt ]
x.t = strftime(xtime, origin=as.POSIXct('1900-01-01'), usetz = FALSE, tz='UTC')
dimnames(arr) = list(sitenames, varnames, x.t)
saveRDS(arr, file=fn.rds)
}

View File

@ -0,0 +1,68 @@
# read the RDS above, to save as .csv file.
source('GetReady.R')
source('AtuSHUD/Rfunction/LDAS_UnitConvert.R')
years = xfg$years
# years=2015:2016
fns = file.path(xfg$dir$predata, paste0('CMIP6_',years, '.RDS'))
fns
cns = c('pr','tas', 'huss', 'rsds', 'sfcWind')
forcnames = c( "Prcp_mm.d", "Temp_C", "RH_%", "Wind_m.s", "RN_w.m2" )
nf=length(fns)
for(i in 1:nf){
x=readRDS(fns[i])
message(i,'/', nf, '\t', basename(fns[i]))
y=x[,cns,]
if(i==1){
dat = y
}else{
dat=abind::abind(dat, y, along=3)
}
}
dn = dimnames(dat)
nd = dim(dat)
xl = list()
time = as.POSIXct(dimnames(dat)[[3]], tz='UTC')
for(i in 1:nd[1]){
message(i,'/', nd[1], '\t', dn[[1]][i] )
x = t( dat[i,,] )
y=unitConvert.CMIP6(x)
print(apply(y, 2, range))
xl[[i]]=as.xts(y, order.by=time)
}
nx=length(xl)
sitename = dn[[1]]
sitename
fns=paste0(sitename, '.csv')
fixdata <- function(x){
idx=1:365
x[idx + 365] = x[idx]
x
}
pp=NULL
for(i in 1:nx){
fn=fns[i]
message(i,'/', nx, '\t', fn)
xl[[i]] = fixdata(xl[[i]])
write.tsd(xl[[i]], file.path(xfg$dir$forc, fn))
if(i==1){
xmean = xl[[i]]
pp=xl[[i]]$Precip_mm.d
}else{
xmean = xmean + xl[[i]]
pp=cbind(pp, xl[[i]]$Precip_mm.d)
}
}
plot(pp)
xm = xmean/nx
saveRDS(xm, file.path(xfg$dir$forc, 'forc.mean.RDS'))
png.control(fn=paste0('Rawdata','_CMIP6_TS.png'),
path = file.path(xfg$dir$fig), ratio=1)
plot.zoo(xm, main='CMIP6')
dev.off()
plot.zoo(xm, main='CMIP6')

View File

@ -0,0 +1,227 @@
readnc.CMIP6<-function(ncid, varid=NULL, ext = NULL){
msg= 'readnc:: '
vars = names(ncid$var)
nvars = length(vars)
if(is.null(varid)){ # read all
varid = varid[!(vars %in% 'time_bnds')] # don't need the time_bnds
}else if(is.character(varid)){ # read VARID (character) by user
if(!all(varid %in% vars)){ # validate the input chars.
message(msg, 'ERROR:: some varid is missing in the dataset.\n')
print(varid[! (varid %in% vars)])
stop('Stop with error.')
}
varid = varid
}else if(is.numeric(varid)) { # read VARID (index) by user
if(max(varid)>nvars || min(varid) < 1){
message(msg, 'ERROR:: Wrong value in varid.\n')
stop('Stop with error.')
}
message('Reading VARID = ', vars[varid])
varid = vars[varid]
}else{ # ERROR
message(msg, 'ERROR:: Wrong format of varid.\n')
stop('Stop with error.')
}
ncdims = names(ncid$dim)
var.lon <- ncdims[which(grepl('lon', tolower(ncdims)))]
var.lat <- ncdims[which(grepl('lat', tolower(ncdims)))]
lon <- ncdf4::ncvar_get(ncid, varid = var.lon)
lat <- ncdf4::ncvar_get(ncid, varid = var.lat)
dx = mean(diff(lon)); dy = mean(diff(lat))
xmin = min(lon - dx/2); xmax = max(lon + dx/2)
ymin = min(lat - dy/2); ymax = max(lat + dy/2)
if(is.null(ext)){
ext= c(min(lon), max(lon), min(lat), max(lat))
}
if(ext[1] < xmin | ext[2] > xmax | ext[3] < ymin | ext[4] > ymax){
warning(paste('Extent required is larger than the boundbox of dataset'))
message(paste(ext, collaps=','))
message(paste(c(xmin,xmax,ymin, ymax), collaps=','))
}
xid = min(which(abs(lon - ext[1]) <= dx/2)):max(which(abs(lon - ext[2]) <= dx/2))
yid = min(which(abs(lat - ext[3]) <= dy/2)):max(which(abs(lat - ext[4]) <= dy/2))
nx = length(xid); ny = length(yid)
x.cord = lon[xid]; y.cord = lat[yid]
tx = readnc.time(ncid = ncid)
ntime = length(tx)
arr = array(0, dim=c(nx, ny, ntime),
dimnames= list(x.cord, y.cord, tx))
ndims = ncid$ndims
start = c(min(xid), min(yid), 1)
count = c(nx, ny, ntime)
vn=varid[1]
arr=ncdf4::ncvar_get(ncid, vn, start = start, count = count)
rt = list('x' = x.cord, 'y' = y.cord, 'arr' = arr, 'time' = tx)
return(rt)
}
#
# ncid = nc_open(ffns[i])
# x0=readnc.CMFD(ncid, varid = tolower(vn))
# x=readnc.CMFD(ncid, varid = tolower(vn), ext = ext)
# nc_close(ncid)
# r0 = xyz2Raster(x0)
# r=xyz2Raster(x)
# plot(r0[[1]])
# plot(r[[1]], add=T)
# x$arr
ReadNC<-function(ncid, varid=NULL, ext = NULL, t.len=NULL){
msg= 'readnc:: '
vars = names(ncid$var)
nvars = length(vars)
if(is.null(varid)){ # read all
varid = varid[!(vars %in% 'time_bnds')] # don't need the time_bnds
}else if(is.character(varid)){ # read VARID (character) by user
if(!all(varid %in% vars)){ # validate the input chars.
message(msg, 'ERROR:: some varid is missing in the dataset.\n')
print(varid[! (varid %in% vars)])
stop('Stop with error.')
}
varid = varid
}else if(is.numeric(varid)) { # read VARID (index) by user
if(max(varid)>nvars || min(varid) < 1){
message(msg, 'ERROR:: Wrong value in varid.\n')
stop('Stop with error.')
}
message('Reading VARID = ', vars[varid])
varid = vars[varid]
}else{ # ERROR
message(msg, 'ERROR:: Wrong format of varid.\n')
stop('Stop with error.')
}
ncdims = names(ncid$dim)
var.lon <- ncdims[which(grepl('lon', tolower(ncdims)))]
var.lat <- ncdims[which(grepl('lat', tolower(ncdims)))]
lon <- ncdf4::ncvar_get(ncid, varid = var.lon)
lat <- ncdf4::ncvar_get(ncid, varid = var.lat)
dx = mean(diff(lon)); dy = mean(diff(lat))
xmin = min(lon - dx/2); xmax = max(lon + dx/2)
ymin = min(lat - dy/2); ymax = max(lat + dy/2)
if(is.null(ext)){
ext= c(min(lon), max(lon), min(lat), max(lat))
}
if(ext[1] < xmin | ext[2] > xmax | ext[3] < ymin | ext[4] > ymax){
warning(paste('Extent required is larger than the boundbox of dataset'))
message(paste(ext, collaps=','))
message(paste(c(xmin,xmax,ymin, ymax), collaps=','))
}
xid = min(which(abs(lon - ext[1]) <= dx/2)):max(which(abs(lon - ext[2]) <= dx/2))
yid = min(which(abs(lat - ext[3]) <= dy/2)):max(which(abs(lat - ext[4]) <= dy/2))
nx = length(xid); ny = length(yid)
x.cord = lon[xid]; y.cord = lat[yid]
if(is.null(t.len)){
t.len = ncid$dim$time$len
}
arr = array(0, dim=c(nx, ny, t.len ),
dimnames= list(x.cord, y.cord, 1:t.len))
ndims = ncid$ndims
if(('ta'== varid) | ('hur'== varid)){
start = c(min(xid), min(yid), 1, 1)
count = c(nx, ny, 8, t.len) # level 5, from bottom to upper.
}else{
start = c(min(xid), min(yid), 1)
count = c(nx, ny, t.len)
}
nch = nchar(ncid$filename)
tatt = ncatt_get(ncid, 'time')
tx = seq.Date(
as.Date(substr(ncid$filename, nch-19, nch-12), '%Y%m%d'),
as.Date(substr(ncid$filename, nch-10, nch-3), '%Y%m%d'),
by='days')
arr= ncdf4::ncvar_get(ncid, varid, start = start, count = count)
if(('ta'== varid) | ('hur'== varid)){
arr=apply(arr, c(1, 2, 4), max, na.rm=TRUE)
}else{
arr=arr
}
idx = which(grepl('0229', format(tx, "%m%d")) )
if(length(idx)>0){
tx = tx[-idx]
}
rt = list('x' = x.cord, 'y' = y.cord, 'arr' = arr, 'time' = tx)
return(rt)
}
initalGrids <- function(fn, vn, pd.gcs, pd.pcs, sp.ldas=NULL){
buf.g = readOGR(pd.gcs$wbd.buf)
ext = extent(buf.g)
fid = nc_open(fn)
nc.all = ReadNC(fid, varid = vn, t.len = 2)
nc.sub = ReadNC(fid, varid = vn, ext = ext, t.len = 2)
nc_close(fid)
nc.all$x = round(nc.all$x, 3); nc.all$y = round(nc.all$y, 3)
nc.sub$x = round(nc.sub$x, 3); nc.sub$y = round(nc.sub$y, 3)
r = xyz2Raster(x = nc.all)
r.sub = xyz2Raster(x = nc.sub)
if(is.null(sp.ldas)){
sp.ldas = raster2Polygon(rx = r.sub)
# sp.center = gCentroid(sp.ldas, byid=TRUE)
# =========PLOT===========================
png.control(fn=paste0(prefix, '_LDAS_location.png'), path = xfg$dir$fig, ratio=1)
plot(r * 0, col='gray', legend=FALSE)
plot(r.sub * 0, col='red', legend=FALSE, add=TRUE)
plot(buf.g, add=T)
dev.off()
# =========Get the data===========================
sp0.gcs = spTransform(sp.ldas, xfg$crs.gcs)
sp0.pcs = spTransform(sp.ldas, xfg$crs.pcs)
}
id=which(gIntersects(sp0.gcs, buf.g, byid = T))
writeshape(sp0.gcs[id, ], file = pd.gcs$meteoCov)
writeshape(sp0.pcs[id, ], file = pd.pcs$meteoCov)
sitenames = paste0('X', sp0.gcs@data$xcenter, 'Y', sp0.gcs@data$ycenter)
sitenames=sitenames[id]
# plot(sp0.gcs)
# plot(buf.g, add=TRUE, border=2)
# plot(sp0.gcs[id, ],add=T, col=3)
retval = list(id=id, sitenames=sitenames, ext=ext)
return(retval)
}
# xp = initalGrids(fn=fn, vn=tolower(varnames[1]), pd.gcs = pd.gcs, pd.pcs = pd.pcs)
# xp = initalGrids(fn=fn, vn=tolower(varnames[1]), pd.gcs = pd.gcs, pd.pcs = pd.pcs)
# library(ncdf4)
# source('Rfunction/nc2fishnet.R')
# fn = '/Volumes/Forcing/CMFD/Data_forcing_03hr_010deg/Prec/prec_CMFD_V0106_B-01_03hr_010deg_197901.nc'
# fid = ncdf4::nc_open(fn)
# x=readnc.CMFD(ncid=fid, varid = 'prec')
# ncdf4::nc_close(fid)
# spx = nc.fishnet(x)
# crs(spx) = sp::CRS('+init=epsg:4326')
# writeshape(spx, '/Volumes/Forcing/CMFD_fishnet')
# raster::plot(spx)
# xp = initalGrids(fn=fn, vn=tolower(varnames[1]), pd.gcs = pd.gcs, pd.pcs = pd.pcs)
# x=dat
# x$arr=x$arr[,,1]
# nd=dim(x$arr)
# for(i in 1:nd[3]){
# x$arr[id+nd[1]*nd[2]*(i-1)]=1000
# }
# r=xyz2Raster(x)
# animate(r)
# plot(r.sub);
# plot(add=T, buf.g)

View File

@ -0,0 +1,69 @@
# read the RDS above, to save as .csv file.
unitConvert <- function(x){
t0=273.15
prcp = x[,'Rainf_f_tavg']
temp = x[,'Tair_f_tavg']
SH = x[,'Qair_f_tavg']
winds = x[,'Wind_f_tavg']
solar= x[,'Swnet_tavg']
press = x[,'Psurf_f_tavg']
rh = 0.263*press*SH/exp(17.67 * (temp - t0) /(temp - 29.65) ) # specific hum to relative hum
forcnames = c( "Precip", "Temp", "RH", "Wind", "RN" )
ret = cbind(prcp * 86400 /1000 , #mm/m2/s(FLDAS) to m/day (PIHM)
temp - t0 , # C
rh/100 , # PERCENTAGE
abs(winds) * 86400 , #m/s to m/day
solar *24 *3600 )
colnames(ret) = forcnames
ret = round(ret, 4)
ret
}
fns = file.path(dir.predata, paste0(prjname,'-', years, '.RDS'))
cns = c('Rainf_f_tavg', 'Tair_f_tavg','Qair_f_tavg',
'Wind_f_tavg', 'Swnet_tavg','Lwnet_tavg',
'Psurf_f_tavg')
forcnames = c( "Prcp_mm.hr", "Temp_C", "RH_%", "Wind_m.s", "RN_w.m2" )
nf=length(fns)
for(i in 1:nf){
x=readRDS(fns[i])
message(i,'/', nf, '\t', basename(fns[i]))
y=x[,cns,]
if(i==1){
dat = y
}else{
dat=abind::abind(dat, y, along=3)
}
}
dn = dimnames(dat)
nd = dim(dat)
xl = list()
time = as.Date(dimnames(dat)[[3]],'%Y%m%d')
for(i in 1:nd[1]){
message(i,'/', nd[1], '\t', dn[[1]][i] )
x = t( dat[i,,] )
y=unitConvert(x)
xl[[i]]=as.xts(y, order.by=time)
}
nx=length(xl)
sitename = dn[[1]]
sitename
fns=paste0(sitename, '.csv')
for(i in 1:nx){
fn=fns[i]
write.tsd(xl[[i]], file.path(dir.forc, fn))
if(i==1){
xmean = xl[[i]]
}else{
xmean = xmean + xl[[i]]
}
}
png.control(fn=paste0('Rawdata','_FLDAS_TS.png'), path = file.path(dir.png), ratio=1)
plot.zoo(xmean/nx, main='FLDAS')
dev.off()

View File

@ -0,0 +1,67 @@
# read the orginal fldas data and save to .RDS file.
#install.packages('ncdf4')
require(ncdf4)
source('GetReady.R')
source('Rfunction/Fun.readnc.R')
fl=readOGR(file.path(dir.predata, 'FLDAS_GCS.shp'))@data
head(fl)
# years=2017:2018
dirs = file.path(dir.fldas, years)
ndir = length(dirs)
fn=list.files(dir.fldas, pattern=glob2rx('*.nc'), recursive = T, full.names = T)[1]
fid=nc_open(fn)
xloc = round(fid$dim$X$vals,2)
yloc = round(fid$dim$Y$vals, 2)
nx=length(xloc)
ny = length(yloc)
#===================================================
xc = fl[,'xcenter']
yc = fl[,'ycenter']
xid = match(round(xc, 2), xloc)
yid = match(round(yc,2), yloc)
xyid=cbind(xid,yid)
sn = paste0('X',xc*100, 'Y', yc*100)
ns = length(sn)
vns = names(fid$var)
vns = vns[!(vns %in% 'time_bnds')] # don't need the time_bnds
mat=ncvar_get(fid, vns[2])
mat=mat*0+1
png.control(fn=paste0('Rawdata','_FLDAS_location.png'), path = file.path(dir.png), ratio=1)
image(xloc, yloc, mat, xlab='Lon', ylab='Lat', main='Coverage of FLDAS') ; grid()
points(xloc[xid], yloc[yid], col=3)
plot(wbd.gcs, add=T)
dev.off()
nv=length(vns)
for(idd in 1:ndir){ # for each year dir
# library(foreach)
# library(doMC)
# library(doParallel)
# registerDoMC(4)
# foreach (idd = 1:ndir) %dopar%{
cdir <- dirs[idd]
fns = list.files(cdir, pattern=glob2rx('*.nc'), recursive = T, full.names = T)
nf = length(fns)
x.arr = array(0, dim=c(ns, nv, nf) )
x.t= character(nf)
for(j in 1:nf){ # files in each year
fn=fns[j]
t=substr(basename(fn), 22, 29)
message(j, '/', nf, '\t', t)
x.mat = readnc(fn, xyid=xyid, vns=vns)
x.t[j] = t
x.arr[,,j ] = x.mat
}
dimnames(x.arr) = list(sn, vns, x.t)
fn.rds = file.path(dir.predata, paste0(prjname,'-', basename(cdir), '.RDS'))
saveRDS(x.arr, file=fn.rds)
}

View File

@ -0,0 +1,83 @@
fun.Soil_Geol <- function(xfg, TOP=TRUE, col_ID = 2:5){
if(TOP){
fn.r = xfg$fn.soil
fn.tab = xfg$fa.soil
outdir = xfg$dir$predata
}else{
fn.r = xfg$fn.geol
fn.tab = xfg$fa.geol
outdir = xfg$dir$predata
}
msg = 'fun.Soil_Geol:: '
if(!file.exists(fn.r)){
message(msg, 'Raster file is missing: ', fn.r)
stop('STOP WITH ERROR.')
}
if(!file.exists(fn.tab)){
message(msg, 'Attribute file is missing: ', fn.tab)
stop('STOP WITH ERROR.')
}
if(file.exists(fn.r)){
r=raster(fn.r)
}else{
messge(msg, 'File does not exist or empty: ', fn.r)
stop(paste(msg, 'Exit with error in '))
}
# plot(r)
# x=foreign::read.dbf(fn.tab)
x=read.df(file=fn.tab)[[1]]
ur =sort(unique(r))
nr=length(ur)
r1 = reclassify(r, cbind(ur, 1:nr))
idx = which(x[, 1] %in% ur)
fx <- function(x){
y = matrix(as.numeric( as.matrix(x)), ncol=4)
for(i in 1:4){
cc = y[, i]
if(i==4){
cc[cc<1.1] = NA
}
y[is.na(cc), i] = round(mean(cc, na.rm=TRUE), 3)
}
return(y)
}
cn = c('ID', 'SILT', 'CLAY', 'OM', 'BD')
texture = fx(x[idx, col_ID]) # ONLY the texture values, FOUR colums.
texture = cbind(1:nr, texture)
colnames(texture) = cn
if(TOP){
# write.df(texture, file=file.path(outdir, 'SOIL.csv'))
# para = PTF.soil(x=texture, rm.outlier = T)
fp = xfg$pd.pcs$soil.r
fg = xfg$pd.gcs$soil.r
fatt=xfg$pd.att$soil
}else{
# texture = fx(x[idx, col_ID])
write.df(texture, file=file.path(outdir, 'GEOL.csv'))
# para = PTF.geol(x=texture, rm.outlier = T)
# raster::writeRaster(r1, filename = file.path(outdir, 'GEOL.tif'), overwrite=TRUE)
fp = xfg$pd.pcs$geol.r
fg = xfg$pd.gcs$geol.r
fatt = xfg$pd.att$geol
}
write.df(texture, file=fatt)
r2 = raster::projectRaster(r1, crs=xfg$crs.pcs)
raster::writeRaster(r1, filename = fp, overwrite=TRUE)
raster::writeRaster(r2, filename = fg, overwrite=TRUE)
texture[is.na(texture) | is.nan(texture)] = -9999
message(msg, 'Texture: ')
print(apply(texture, 2, summary))
# message(msg, 'Hydrologic parameters: ')
# print(apply(para, 2, summary))
rl = list('raster' = r1,
'texture' = texture)
return (rl)
}

View File

@ -0,0 +1,90 @@
# read the RDS above, to save as .csv file.
source('AutoSHUD/Rfunction/LDAS_UnitConvert.R')
write.tsd.custom <- function (x, file, append = F, quite = F, header = NULL)
{
mat = as.matrix(rbind(x))
nr = nrow(x)
nc = ncol(x)
if (!quite) {
message("Writing ", file)
}
tt = stats::time(x)
tday = as.numeric(difftime(tt, tt[1], units = "days"))
if (is.null(header)) {
t0 = format(time(x)[1], "%Y%m%d")
header = c(nr, nc + 1, t0)
}
dd = data.frame(Time_Day = tday, mat)
write(header, file = file, ncolumns = length(header), append = append,
sep = "\t")
write(colnames(dd), file = file, ncolumns = nc + 1, append = T,
sep = "\t")
write(t(dd), file = file, ncolumns = nc + 1, append = T,
sep = "\t")
}
fun.GLDAS.RDS2csv <- function(xfg){
fns = file.path(xfg$dir$predata, paste0(xfg$prjname,'-', xfg$years, '.RDS'))
cns = c('Rainf_f_tavg', 'Tair_f_inst','Qair_f_inst',
'Wind_f_inst', 'Swnet_tavg','Lwnet_tavg',
'Psurf_f_inst')
forcnames = c( "Prcp_mm.d", "Temp_C", "RH_%", "Wind_m.s", "RN_w.m2" )
nf=length(fns)
for(i in 1:nf){
x=readRDS(fns[i])
message(i,'/', nf, '\t', basename(fns[i]))
y=x[,cns,]
if(i==1){
dat = y
}else{
dat=abind::abind(dat, y, along=3)
}
}
dn = dimnames(dat)
nd = dim(dat)
xl = list()
# TODDO: modify the time to extract correct time
time.tag = dimnames(dat)[[3]]
idx = which(!grepl(' ', time.tag))
time.tag[idx] = paste0(time.tag[idx], '00:00:00')
time = lubridate::ymd_hms(time.tag)
# time = as.POSIXct(dimnames(dat)[[3]], format= "%Y%m%d%H")
diff_seconds = as.numeric(difftime(time[[2]], time[[1]], units="hours")) * 3600
diff_seconds
for(i in 1:nd[1]){
message(i,'/', nd[1], '\t', dn[[1]][i] )
x = t( dat[i,,] )
y=unitConvert.GLDAS(x, diff_seconds)
xl[[i]]=as.xts(y, order.by=time)
}
nx=length(xl)
sitename = dn[[1]]
sitename
fns=paste0(sitename, '.csv')
xmean = NULL
for(i in 1:nx){
fn=fns[i]
# write this in correct format
# write.tsd.custom(xl[[i]], file.path(xfg$dir$forc, fn))
write.tsd(xl[[i]], file.path(xfg$dir$forc, fn))
if(all(is.na(xl[[i]]))){
}else{
if(is.null(xmean)){
xmean = xl[[i]]
}else{
xmean = xmean + xl[[i]]
}
}
}
xmean = xmean / nx
xmean[is.na(xmean)] <- -999
if(all(is.na(xmean))){}else{
png(file = file.path(xfg$dir$fig, paste0(xfg$prefix, '_GLDAS_TS.png')), height=7, width=11, res=200, unit='in')
plot.zoo(xmean, main='GLDAS')
dev.off()
}
}

View File

@ -0,0 +1,111 @@
# read the orginal fldas data and save to .RDS file.
#install.packages('ncdf4')
require(ncdf4)
# library(rSHUD)
# source('GetReady.R')
# =========Forcing Coverage===========================
# sp0 = readOGR(xfg$fsp.forc)
# ========= Get the GRID===========================
# spx = readOGR(xfg$pd.gcs$meteoCov)
# fl=spx@data
fun.GLDAS.nc2RDS <- function(xfg, res=0.25){
buf.g = readOGR(xfg$pd.gcs$wbd.buf)
ext = extent(buf.g)
dir.years = file.path(xfg$dir.ldas, xfg$years)
ndir = length(dir.years)
xfg$dir.ldas
writelog(msg=paste0('forcing dir:', xfg$dir.ldas), caller = caller)
fns=list.files(file.path(xfg$dir.ldas, '2002/100'), pattern=glob2rx('*.nc4'), recursive = T, full.names = T)[1]
# cmd = paste('find',xfg$dir.lddas, ' -name "*.nc4" > filelist.txt')
# system(cmd)
# fns=readLines(file.path(xfg$dir.ldas, 'filelist.txt'))
fid=nc_open(fns[1]) #打开一个NC文件
nc.all = rSHUD::readnc(fid, varid = 2)
nc.sub = rSHUD::readnc(fid, varid = 2, ext = ext)
nc_close(fid)
r = xyz2Raster(x = nc.all)
r.sub = xyz2Raster(x = nc.sub, res=res)
# plot(r.sub);
# plot(add=T, buf.g)
vns = names(fid$var)
vns = vns[! grepl('time', tolower(vns))] # don't need the time_bnds
# =========PLOT===========================
go.plot <- function(prefix){
png(file.path(xfg$dir$fig, paste0(prefix, '_LDAS_location.png')), height=8, width=15, units = 'in', res=200)
plot(r * 0, col='gray', legend=FALSE)
plot(r.sub * 0, col='red', legend=FALSE, add=TRUE)
plot(buf.g, add=T)
grid();
mtext(side=3, 'GLDAS coverage (0.25 deg)')
dev.off()
}; go.plot(xfg$prefix)
# =========Get the data===========================
xfg$res = 0.25
yx = expand.grid(nc.sub$y, nc.sub$x)
rn = paste0('X', yx[, 2], 'Y',yx[,1])
ext.fn = c(range(yx[, 2]), range(yx[, 1]) ) + c(-1, 1, -1, 1) *0.5 * xfg$res
ext.fn
sp.forc = fishnet(xx=seq(ext.fn[1], ext.fn[2], xfg$res ),
yy=seq(ext.fn[3], ext.fn[4], xfg$res), crs=xfg$crs.gcs)
go.plot <- function(prefix){
png(file.path(xfg$dir$fig, paste0(prefix, '_LDAS_Coverage.png')), height=8, width=8, units = 'in', res=200)
plot(sp.forc, axes=TRUE);
plot(buf.g, border='red', add=T); grid()
text(yx[, 2], yx[, 1]+xfg$res/5, paste0('X', yx[, 2]))
text(yx[, 2], yx[, 1]-xfg$res/5, paste0('Y', yx[, 1]))
mtext(side=3, 'GLDAS coverage (0.25 deg)')
dev.off()
}; go.plot(xfg$prefix)
sp0.gcs = spTransform(sp.forc, xfg$crs.gcs)
sp0.pcs = spTransform(sp.forc, xfg$crs.pcs)
writeshape(sp0.gcs, file = xfg$pd.gcs$meteoCov)
writeshape(sp0.pcs, file = xfg$pd.pcs$meteoCov)
ns = length(rn)
nv=length(vns)
# library(foreach)
# library(doMC)
# library(doParallel)
# registerDoMC(12)
# foreach (idd = 1:ndir) %dopar%{
for (idd in 1:ndir) {
cdir <- dir.years[idd]
message(idd, '/', ndir, '\t', basename(cdir))
fn.rds = file.path(xfg$dir$predata, paste0(xfg$prjname,'-', basename(cdir), '.RDS'))
if(!file.exists(fn.rds)){
fns = list.files(cdir, pattern=glob2rx('*.nc4'), recursive = T, full.names = T)
nf = length(fns)
x.t= character(nf)
for(j in 1:nf){ # files in each year
fn=fns[j]
message('\t', j, '/', nf, '\t', basename(fn))
ncid = nc_open(fn)
# debug(readnc)
x.nc = readnc(ncid, varid=vns, ext=ext)
nc_close(ncid)
if(j == 1){
d3 = dim(x.nc$arr)
x.arr = array(0, dim=c(d3[1] * d3[2], nv, nf) )
}
x.t[j] = strftime(x.nc$time, usetz = FALSE, tz='UTC')
x.arr[ , , j] = matrix(x.nc$arr, ncol=nv)
}
dimnames(x.arr) = list(rn, vns, x.t)
saveRDS(x.arr, file=fn.rds)
}else{
}
}
}
# xfg = CV$xfg
# xfg$prefix = 'AutoSHUD_S2'
# fun.GLDAS.nc2RDS(xfg)
# fun.GLDAS.RDS2csv(xfg)

View File

@ -0,0 +1,94 @@
unitConvert.NLDAS <- function(x, diff_seconds){
t0=273.15
prcp = x[,'APCP']
temp = x[,'TMP']
SH = x[,'SPFH']
winds = x[,'UGRD']
solar= x[,'DSWRF']
press = x[,'PRES']
rh = 0.263*press*SH/exp(17.67 * (temp - t0) /(temp - 29.65) ) # specific hum to relative hum
forcnames = c( "Precip_mm.d", "Temp_C", "RH_1", "Wind_m.s", "RN_w.m2" )
ret = cbind(prcp * 86400 / diff_seconds, # mm/hr(NLDAS) to mm/day (SHUD)
temp - t0 , # C
rh , # Ratio 0-1
abs(winds), #m/s
solar # w/m2
)
colnames(ret) = forcnames
ret = round(ret, 4)
ret
}
unitConvert.CMIP6 <- function(x, diff_seconds){
# "pr" "tas" "huss" "rsds" "sfcWind"
t0=273.15
prcp = x[,'pr']
temp = x[,'tas']
temp[temp < 200] = t0
SH = x[,'huss']
winds = x[,'sfcWind']
solar= x[,'rsds']
press = 80000
rh = 0.263*press*SH/exp(17.67 * (temp - t0) /(temp - 29.65) ) # specific hum to relative hum
# plot(rh)
forcnames = c( "Precip_mm.d", "Temp_C", "RH_1", "Wind_m.s", "RN_w.m2" )
ret = cbind(prcp * 86400 , # "kg m-2 s-1" (GLDAS ) to "mm day" (SHUD)
temp - t0 , # C
rh / 100 , # Ratio 0-1
abs(winds), #m/s
solar # w/m2
)
colnames(ret) = forcnames
ret = round(ret, 4)
ret
}
# tsd = as.xts(x, order.by=as.Date(rownames(x)))
# plot(tsd[, 1])
# y=unitConvert.CMIP6(x)
unitConvert.GLDAS <- function(x, diff_seconds){
t0=273.15
prcp = x[,'Rainf_f_tavg']
temp = x[,'Tair_f_inst']
SH = x[,'Qair_f_inst']
winds = x[,'Wind_f_inst']
solar= x[,'Swnet_tavg']
press = x[,'Psurf_f_inst']
rh = 0.263*press*SH/exp(17.67 * (temp - t0) /(temp - 29.65) ) # specific hum to relative hum
forcnames = c( "Precip_mm.d", "Temp_C", "RH_1", "Wind_m.s", "RN_w.m2" )
ret = cbind(prcp * 86400 , # "kg m-2 s-1" (GLDAS ncid$var$Rainf_tavg$units) to "mm m-2 day" (SHUD)
temp - t0 , # C
rh , # Ratio 0-1
abs(winds), #m/s
solar # w/m2
)
colnames(ret) = forcnames
ret = round(ret, 4)
ret
}
unitConvert.CMFD <- function(x){
t0=273.15
prcp = x[,'Prec']
temp = x[,'Temp']
SH = x[,'SHum']
winds = x[,'Wind']
solar= x[,'SRad']
press = x[,'Pres']
rh = 0.263*press*SH/exp(17.67 * (temp - t0) /(temp - 29.65) ) # specific hum to relative hum
forcnames = c( "Precip_mm.d", "Temp_C", "RH_1", "Wind_m.s", "RN_w.m2" )
p_mm.day = prcp * 24
p_mm.day[p_mm.day < 1e-4 ] = 0.0 # prcp < 0.1 mm/day, No rain then.
ret = cbind(prcp*24 , #mm/hr(CMFD) to mm/day (SHUD 2021.12)
temp - t0 , # C
rh/100 , # Ratio 0-1
abs(winds) , #m/s to m/s
solar ) # w/m2
ret = round(ret, 4)
colnames(ret) = forcnames
ret
}

View File

@ -0,0 +1,75 @@
#' PIHM Analysis project.
#' Developed by Lele Shu( lele.shu at gmail.com lzs157 at psu.edu )
#' Created by Thu Apr 16 10:53:00 EDT 2015
#' <- ============================================
#' Current version is for PIHM 2.0 and above;
#'
NLCD2lc <- function (years=1979:2016){
att=readatt()
lc= att[,4];
message('LC = ')
ulc=sort(unique(att[,4]))
print( ulc)
if (length( which (ulc <10 | ulc >100) ) ){
stop('Current LC code is not NLCD')
}
# VEGPRMT.TBL
veg = fun.vegtable(lc =ulc )
if (PIHMVER ==2.4){
writeveg(path=inpath,fn=paste0(PRJNAME,'.lc'), x=veg)
}else{
writeveg(path=dirname(inpath), x=veg)
}
# att file
for (i in 1:length(ulc)){
key = ulc[i];
lc[which(lc == key) ]= i
}
att[,'LC']= lc
#att[,'LAI']=lc
writeatt(att)
#.lai FILE.
lr = fun.lairl(lc=ulc,years=years)
writelai(x=lr)
}
lc.OID2NLCD <- function(lc){
att <- readatt();
#lc=sort(unique( att[,'LC'] ) );
oid <- att[,'LC'] ;
ids <- numeric(length(lc));
len <- length(lc);
for( i in 1:len) {
att[oid==i,'LC']=lc[i];
}
ret <- att;
writeatt(att);
}
lc.NLCD2OID <- function(){
att <- readatt();
lc=sort(unique( att[,'LC'] ) );
if (min(lc) < 11 | max(lc) > 95){
print(lc)
stop('Check the value of LC in att, they may not be the NLCD code')
}
oid <- att[,'LC'] ;
len <- length(lc);
write.table(file=paste0(PRJNAME,'.NLCD.csv'),
cbind('OID'=1:len, 'NLCD'=lc),
quote=FALSE, row.names=FALSE)
for( i in 1:len) {
att[oid==lc[i],'LC']=i;
}
ret <- att;
writeatt(att);
}

View File

@ -0,0 +1,96 @@
#' PIHM Analysis project.
#' Developed by Lele Shu( lele.shu at gmail.com lzs157 at psu.edu )
#' Fri Sep 2 15:32:54 EDT 2016
#' =============================================
#' @param x, which is the integer number defined in NLCD 2001,2006, and 2011. Any value out of (0,100) will be assigned as black.
#' @keywords NLCD, Landuse, colormap
#' @return HEX color strings
#' @examples
#' lc=c(11,21,22,23,24,31,41,42,43,52,71,81,82,90,95)
#' nx=length(x)
#' x = numeric(nx)+1
#' names(x)= lc
#' barplot(lc, x, col=NLCD.colors(lc) )
#' @source See the link of NLCD: \url{http://www.mrlc.gov/nlcd11_leg.php}
NLCD.colors <- function(x,def.col = '#EEEEEE'){
# 2001, 2006, 2011 version
#reference http://www.mrlc.gov/nlcd11_leg.php
lccol = matrix(def.col, nrow=100)
lccol[1]= "#00fa00"
lccol[11]= "#476ba1"
lccol[12]= "#d1defa"
lccol[21]= "#decaca"
lccol[22]= "#d99482"
lccol[23]= "#ee0000"
lccol[24]= "#ab0000"
lccol[31]= "#b3aea3"
lccol[32]= "#fafafa"
lccol[41]= "#68ab63"
lccol[42]= "#1c6330"
lccol[43]= "#b5ca8f"
lccol[51]= "#a68c30"
lccol[52]= "#ccba7d"
lccol[71]= "#e3e3c2"
lccol[72]= "#caca78"
lccol[73]= "#99c247"
lccol[74]= "#78ae94"
lccol[81]= "#dcd93d"
lccol[82]= "#ab7028"
lccol[90]= "#bad9eb"
lccol[91]= "#b5d4e6"
lccol[92]= "#b5d4e6"
lccol[93]= "#b5d4e6"
lccol[94]= "#b5d4e6"
lccol[95]= "#70a3ba"
x=round(x)
#x=sort(round(x), decreasing=FALSE);
ret = rep(def.col, length(x));
id = which( x %in% 1:100)
ret[id] = lccol[x[id]]
return(ret)
}
NLCD.names <- function(x,def.name = 'n/a'){
# 2001, 2006, 2011 version
#reference http://www.mrlc.gov/nlcd11_leg.php
nlcd.names = matrix(def.name, nrow=100)
nlcd.names[1]= "n/a"
nlcd.names[11]= "Open Water"
nlcd.names[12]= "Perennial Ice/Snow"
nlcd.names[21]= "Developed, Open Space"
nlcd.names[22]= "Developed, Low Intensity"
nlcd.names[23]= "Developed, Medium Intensity"
nlcd.names[24]= "Developed, High Intensity"
nlcd.names[31]= "Barren Land (Rock/Sand/Clay)"
nlcd.names[32]= "n/a"
nlcd.names[41]= "Deciduous Forest"
nlcd.names[42]= "Evergreen Forest"
nlcd.names[43]= "Mixed Forest"
nlcd.names[51]= "Dwarf Scrub"
nlcd.names[52]= "Shrub/Scrub"
nlcd.names[71]= "Grassland/Herbaceous"
nlcd.names[72]= "Sedge/Herbaceous"
nlcd.names[73]= "Lichens"
nlcd.names[74]= "Moss"
nlcd.names[81]= "Pasture/Hay"
nlcd.names[82]= "Cultivated Crops"
nlcd.names[90]= "Woody Wetlands"
nlcd.names[91]= "n/a"
nlcd.names[92]= "n/a"
nlcd.names[93]= "n/a"
nlcd.names[94]= "n/a"
nlcd.names[95]= "Emergent Herbaceous Wetlands"
x=round(x);
ret = rep(def.name, length(x));
id = which( x %in% 1:100)
ret[id] = nlcd.names[x[id]]
return(ret)
}

View File

@ -0,0 +1,40 @@
unitConvert <- function(x, diff_seconds){
t0=273.15
prcp = x[,'APCP']
temp = x[,'TMP']
SH = x[,'SPFH']
winds = x[,'UGRD']
solar= x[,'DSWRF']
press = x[,'PRES']
rh = 0.263*press*SH/exp(17.67 * (temp - t0) /(temp - 29.65) ) # specific hum to relative hum
forcnames = c( "Precip", "Temp", "RH", "Wind", "RN" )
ret = cbind(prcp * 86400 / diff_seconds, # mm/hr(NLDAS) to mm/day (SHUD)
temp - t0 , # C
rh , # PERCENTAGE
abs(winds), #m/s
solar # w/m2
)
# ret = cbind(prcp * diff_seconds /1000 , #mm/m2/s(FLDAS) to m/day (SHUD)
# temp - t0 , # C
# rh/100 , # PERCENTAGE
# abs(winds) * diff_seconds , #m/s to m/day
# solar *diff_seconds )
colnames(ret) = forcnames
ret
}
#
for(i in 1:n3){
fn.csv = filename[i]
message(i, '/', n3, '\t', basename(fn.csv))
xt = as.xts(t(aa[, , i]), order.by = ts)
yt = unitConvert(xt, 3600)
print(mean(apply.yearly(yt$Precip, sum)/24))
}
# xt = as.xts(t(aa[, , i]), order.by = ts)
# pd = apply.daily(xt$APCP, sum)
# apply.yearly(pd, sum)

View File

@ -0,0 +1,136 @@
# read the orginal fldas data and save to .RDS file.
# good for PALEOFLOOD project in Arizona. 2021-04-04
require(ncdf4)
source('Rfunction/LDAS_UnitConvert.R')
sp.ldas = readOGR(pd.gcs$meteoCov)
fl = sp.ldas@data
buf.g = readOGR(pd.gcs$wbd.buf)
ext = extent(buf.g)
ext.nldas = c(-125, -67, 25, 53)
res = xfg$res
xx = seq(ext.nldas[1] + res / 2, ext.nldas[2] - res / 2, by=res)
yy = seq(ext.nldas[3] + res / 2, ext.nldas[4] - res / 2, by=res)
sp.fnpt =fishnet(xx = xx, yy=yy, crs =crs(sp.ldas), type='point')
# writeshape(sp.fnpt, 'fnpt')
# idx.fn = rgeos::gContains(sp.ldas, sp.fnpt, byid = TRUE)
# idx.fn = gIntersects(sp.ldas, sp.fnpt, byid = TRUE)
# idx = unlist(apply(idx.fn, 2, which))
# pt.xy = sp.fnpt@data
nlon = length(xx)
nlat = length(yy)
px = sp.ldas@data$xcenter
py = sp.ldas@data$ycenter
idx.cr=cbind( match(px, xx), match(py, yy)) # match column and row.
dir.years = file.path(xfg$dir.ldas, xfg$years)
ndir = length(dir.years)
fn=list.files(xfg$dir.ldas, pattern=glob2rx('*.RDS'), recursive = T, full.names = T)[1]
fn
x=readRDS(fn)
# vns = dimnames(x$data)[[3]]
fun.toRaster <- function(x){
r = raster();
extent(r) = ext.nldas;
res(r) = xfg$res
r=setValues(r, as.numeric(x))
r
}
r = fun.toRaster( x$data[, nlat:1 , 1, 1] )
tmp = x$data[, , 1, 1]*0
tmp[idx.cr[, 1], idx.cr[, 2]]= 1 #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
r1 = fun.toRaster(x=tmp[, nlat:1])
png.control(fn=paste0(prefix, '_LDAS_location.png'), path = xfg$dir$fig, ratio=1, ht=9, wd=12, res=300)
# plot(r, col='gray',legend=FALSE)
plot(r1,legend=FALSE)
plot(sp.ldas, add=TRUE, border=4)
plot(buf.g, add=T)
dev.off()
# stop()
filename = paste0('X', px, 'Y', py)
vns = c("TMP", "SPFH", "PRES", "UGRD", "VGRD", "PEVAP", "APCP", "DSWRF" )
i.dir=1
ns=length(sp.ldas)
nv=length(vns)
# library(foreach)
# library(doMC)
# library(doParallel)
# registerDoMC(12)
# foreach (idd = 1:ndir) %dopar%{
for (i.dir in 1:ndir) {
cdir <- dir.years[i.dir]
fns = list.files(cdir, pattern=glob2rx('*.RDS'), recursive = T, full.names = T)
nf = length(fns)
# message('Number of RDS files: ', nf)
message(i.dir, '/', ndir, '\t', basename(cdir), '\t', nf)
x.arr = array(NA, dim=c(nv, nf*24, ns) )
nlen = 0
str.time = character(nf*24)
fn.rds = file.path(xfg$dir$predata, paste0(xfg$prjname,'-', basename(cdir), '.RDS'))
if(!file.exists(fn.rds)){
x.year = NULL
for(i.file in 1:nf){ # files in each year
fn=fns[i.file]
message('\t', i.file, '/', nf, '\t', basename(fn))
x=readRDS(fn)
x.day = array(dim = c(length(vns), dim(x$data)[4], ns))
for( i.site in 1:ns){
x.day[, , i.site] = x$data[idx.cr[i.site, 1],idx.cr[i.site, 2], vns , ]
}
xt.i = dimnames(x$data)[[4]]
nt = length(xt.i)
x.arr[, nlen + (1:nt) , ] = x.day
str.time[nlen + (1:nt) ] = xt.i
nlen = nlen+nt;
}
print(nlen)
# x.arr = array(NA, dim=c(nv, nf*24, ns) )
x.arr = x.arr[1:nv, 1:nlen, 1:ns]
str.time=str.time[1:nlen]
dns = list(vns, str.time, filename)
dimnames(x.arr) = dns
saveRDS(x.arr, file=fn.rds)
# xt.i = as.POSIXct(dimnames(x.day)[[2]], format='%Y-%m-%d.%H.%M.%S', usetz = FALSE, tz='UTC')
}else{
x.arr = readRDS(fn.rds)
dns = dimnames(x.arr)
}
n2=dim(x.arr)[2]
if(i.dir == 1){
nmove = 0
NN2 = c(nv, 24*366*ndir, ns)
aa = array(dim = NN2)
dds = rep('NA', NN2[2])
}else{
}
dds[nmove + 1:n2] = dimnames(x.arr)[[2]]
aa[ , nmove + 1:n2, ] = x.arr[vns, ,]
nmove = nmove + n2
}
aa=aa[, 1:nmove, ]
stime = dds[1:nmove]
dimnames(aa) = list(dns[[1]], stime, dns[[3]])
n3 = dim(aa)[3]
ts = as.POSIXct(stime, format='%Y-%m-%d.%H.%M.%S', tz='UTC')
filename = file.path(xfg$dir$forc, paste0(dimnames(aa)[[3]], '.csv') )
for(i in 1:n3){
fn.csv = filename[i]
message(i, '/', n3, '\t', basename(fn.csv))
xt = as.xts(t(aa[, , i]), order.by = ts)
yt = unitConvert.NLDAS(xt, 3600)
# barplot(apply.daily(yt$Precip, max)[1:150])
# readline(paste0(i))
# print(mean(apply.yearly(yt$Precip, sum)/24))
write.tsd(yt, file = fn.csv)
}

View File

@ -0,0 +1,10 @@
GaussKruger <- function(){
x = fishnet(ext=c(-180, 180, -90, 90), dx = 6, dy=180)
plot(x, axes=T)
x
}

View File

@ -0,0 +1,190 @@
read.prj <- function(CV){
fn.prj = CV$deploy$config
crs.gcs = CV$para$gcs
dir.predata = CV$dirs$model
message('Reading project file ', fn.prj)
getVAL <- function(x, valname, real=FALSE, defVal = NULL){
names(x) = toupper(names(x))
valname = toupper(valname)
y = x[[valname]]
if(is.null(y)) {
# if(is.null(defVal)){
# message('Error: value ', valname, ' is missing')
# stop('GetVal')
# }else{
r = NULL
# }
}else{
r = y
}
if(real){
r = as.numeric(r)
}
return(r)
}
if(file.exists(fn.prj)){
# tmp=read.table(fn.prj, header = F, row.names = 1)
t1 = readLines(fn.prj, skipNul = TRUE)
idx = which( grepl('^#', t1) | grepl('^ *$', t1) )
if(length(idx)>0){
t2 = t1[-1 * idx]
}else{
t2 = t1
}
tmp=read.table(text=t2, header = F, row.names = 1)
xcfg = data.frame(t(tmp), stringsAsFactors = FALSE)
# print(xcfg)
}else{
stop('File missing: ', fn.prj)
}
isoil = getVAL(xcfg, 'Soil', TRUE)
ilanduse = getVAL(xcfg, 'landuse', TRUE)
iforcing = getVAL(xcfg, 'forcing', TRUE)
if(isoil >= 1){
# local soil data.
fn.soil = getVAL(xcfg, 'fn.soil')
fn.geol = getVAL(xcfg, 'fn.geol')
tab.soil = getVAL(xcfg, 'tab.soil')
tab.geol = getVAL(xcfg, 'tab.geol')
}else{
# global soil data.
dir.soil = getVAL(xcfg, 'dir.soil')
}
dir.ldas = getVAL(xcfg, 'dir.ldas')
dir.out = getVAL(xcfg, 'dir.out')
dout.forc = getVAL(xcfg, 'dout.forc')
prjname=getVAL(xcfg, 'prjname')
years=getVAL(xcfg, 'startyear', TRUE): getVAL(xcfg, 'endyear', TRUE)
fsp.wbd = getVAL(xcfg, 'fsp.wbd')
fsp.stm = getVAL(xcfg, 'fsp.stm')
fsp.forc = getVAL(xcfg, 'fsp.forc')
fsp.lake = getVAL(xcfg, 'fsp.lake')
fr.dem = getVAL(xcfg, 'fr.dem')
fn.landuse = getVAL(xcfg, 'fn.landuse')
tab.landuse = getVAL(xcfg, 'tab.landuse')
MaxArea = getVAL(xcfg, 'MaxArea', TRUE, defVal = 1) * 1e6
NumCells = getVAL(xcfg, 'NumCells', TRUE, 1000)
AqDepth = getVAL(xcfg, 'AqDepth', TRUE, 10)
flowpath = getVAL(xcfg, 'flowpath', TRUE, 0)
MinAngle = getVAL(xcfg, 'MinAngle', TRUE, 31)
MAX_SOLVER_STEP = getVAL(xcfg, 'MAX_SOLVER_STEP', TRUE, 2)
CRYOSPHERE = getVAL(xcfg, 'CRYOSPHERE', TRUE, 2)
STARTDAY = getVAL(xcfg, 'STARTDAY', TRUE, 0)
ENDDAY = getVAL(xcfg, 'ENDDAY', TRUE, 365)
DistBuffer = getVAL(xcfg, 'DistBuffer', TRUE, CV$para$distBuff)
if(is.null(CV$para$pcs)){
crs.fn <- getVAL(xcfg, 'fsp.crs')
if( !is.null(crs.fn)){
if(file.exists(crs.fn)){
message('CRS file:', crs.fn)
crs.pcs <- raster::crs(rgdal::readOGR(crs.fn))
}else{
message('CRS file is missing. So Albers projection is used')
crs.pcs <- rSHUD::crs.Albers(rgdal::readOGR(fsp.wbd))
message(crs.pcs)
}
}else{
message('CRS file is missing. So Albers projection is used')
crs.pcs <- rSHUD::crs.Albers(rgdal::readOGR(fsp.wbd))
message(crs.pcs)
}
}else{
crs.pcs = CV$para$pcs
}
# ===============================
tol.wb = getVAL(xcfg, 'tol.wb', TRUE, NULL)
tol.rivlen = getVAL(xcfg, 'tol.rivlen', TRUE, NULL)
RivWidth = getVAL(xcfg, 'RivWidth', TRUE, NULL)
RivDepth = getVAL(xcfg, 'RivDepth', TRUE, NULL)
QuickMode = (getVAL(xcfg, 'QuickMode') > 0)
dir.png =file.path(dir.out, 'Figure')
dir.modelin <- file.path(dir.out, 'input', prjname)
dir.modelout <- file.path(dir.out, 'output', paste0(prjname, '.out') )
dir.forc=getVAL(xcfg, 'fc.out', real=FALSE, file.path(dir.out, 'forcing'))
dirlist = list(out=dir.out,
fig=dir.png,
predata=dir.predata,
modelin=dir.modelin,
modelout=dir.modelout,
forc = dir.forc)
if(isoil < 1){
dirlist = c(dirlist, soil=dir.soil)
}
tmp=lapply(dirlist, dir.create, showWarnings=F, recursive=T)
# Some Constant values in the working environments.
cfg = list('prjname' = prjname,
'years' = years,
'crs.pcs'=crs.pcs,
'crs.gcs'=crs.gcs,
'fsp.wbd'=fsp.wbd,
'fsp.stm'=fsp.stm,
'fsp.lake' = fsp.lake,
'fr.dem'=fr.dem,
'dir'=dirlist,
'iforcing' = iforcing,
'fsp.forc'=fsp.forc,
'dout.forctsd' = dout.forc,
'ilanduse' = ilanduse,
'fn.landuse'=fn.landuse,
'tab.landuse'=tab.landuse,
'isoil' = isoil,
'para' = list(
'NumCells'=NumCells,
'AqDepth'=AqDepth,
'MaxArea'=MaxArea,
'QuickMode'=QuickMode,
'tol.wb'=tol.wb,
'tol.rivlen'=tol.rivlen,
'RivWidth'=RivWidth,
'RivDepth'=RivDepth,
'DistBuffer'=DistBuffer,
'flowpath' = flowpath,
'MinAngle'=MinAngle,
'MAX_SOLVER_STEP' = MAX_SOLVER_STEP,
'CRYOSPHERE'=CRYOSPHERE,
'STARTDAY'=STARTDAY,
'ENDDAY'=ENDDAY
)
)
if(isoil>=1){
cfg = c(cfg,
'isoil' = isoil,
'fn.soil'=fn.soil,
'fn.geol'=fn.geol,
'tab.soil'=tab.soil,
'tab.geol'=tab.geol)
}else{
# void
}
if(iforcing < 1){
# res = getVAL(xcfg, 'res', real = TRUE)
cfg = c(cfg, dir.ldas = dir.ldas)
}else{
# void
}
return(cfg)
}
#
# xfg <- read.prj(CV)

View File

@ -0,0 +1,27 @@
AA = seq(1e3, AA1, length.out = 10)[-1]
AA = 10 ^ (0:6 ) * 1e6
a = 3.2
ord=rbind(1:5)
b= max(ord) * .05
# W = a*log(AA)^(b*ord)
fx.W <- function(x) {return( (log(AA) / 1) ^ (1.2^x) )}
fx.W <- function(x, a, b) {return( log10(AA/1000) ^ a /(1 + exp(- b * 2^x)) )}
fx.D <- function(w){return( log(w) ^ (1+b) ) }
# fx.W <- function(x) {return(log(AA) * log(AA) ^ (b * x) )}
#
# fx.W <- function(x) {return( a + b ^ (1/ log(AA) ^ (b * x) ) )}
w = round(t(apply(ord, 2, fx.W, a=a, b=b)), 0)
d = round(fx.D(w), 1)
dim(w)
par(mfrow=c(2,1))
matplot(w, type='l', log=''); grid()
matplot(d, type='l', log=''); grid()
print(round(AA/1e6))
apply(d, 1, summary)
apply(w, 1, summary)

View File

@ -0,0 +1,15 @@
SoilGeol <- function(spm, rdsfile){
# rdsfile=file.path(dir.pihmgis, 'Soil_sl1.tif')
xy = coordinates(spm)
# plot(xy, asp=1)
xl=readRDS(rdsfile)
nx=length(xl)
mat=matrix(0, nrow=nrow(xy), ncol=4)
for(i in 1:nx){
r=xl[[i]]
mat[,i]=raster::extract(xl[[i]], xy)
}
colnames(mat) = names(xl)
return(mat)
}

View File

@ -0,0 +1,123 @@
# cfun <- function (x,tab, type=1) {
# #Source: http://www.pihm.psu.edu/EstimationofVegitationParameters.htm
# dlai=rbind(c( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
# c( 8.76, 9.16, 9.827, 10.093, 10.36, 10.76, 10.493, 10.227, 10.093, 9.827, 9.16, 8.76),
# c( 5.117, 5.117, 5.117, 5.117, 5.117, 5.117, 5.117, 5.117, 5.117, 5.117, 5.117, 5.117),
# c( 8.76, 9.16, 9.827, 10.093, 10.36, 10.76, 10.493, 10.227, 10.093, 9.827, 9.16, 8.76),
# c( 0.52, 0.52, 0.867, 2.107, 4.507, 6.773, 7.173, 6.507, 5.04, 2.173, 0.867, 0.52),
# c( 4.64, 4.84, 5.347, 6.1, 7.4335, 8.7665, 8.833, 8.367, 7.5665, 6, 5.0135, 4.64),
# c( 5.276088, 5.528588, 6.006132, 6.4425972, 7.2448806, 8.3639474, 8.540044, 8.126544, 7.2533006, 6.3291908, 5.6258086, 5.300508),
# c( 2.3331824, 2.4821116, 2.7266101, 3.0330155, 3.8849492, 5.5212224, 6.2395131, 5.7733017, 4.1556703, 3.1274641, 2.6180116, 2.4039116 ),
# c( 0.580555, 0.6290065, 0.628558, 0.628546, 0.919255, 1.7685454, 2.5506969, 2.5535975, 1.7286418, 0.9703975, 0.726358, 0.6290065 ),
# c( 0.3999679, 0.4043968, 0.3138257, 0.2232945, 0.2498679, 0.3300675, 0.4323964, 0.7999234, 1.1668827, 0.7977234, 0.5038257, 0.4043968),
# c( 0.782, 0.893, 1.004, 1.116, 1.782, 3.671, 4.782, 4.227, 2.004, 1.227, 1.004, 0.893),
# c( 0.782, 0.893, 1.004, 1.116, 1.782, 3.671, 4.782, 4.227, 2.004, 1.227, 1.004, 0.893),
# c( 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001 ),
# c( 1.2867143, 1.3945997, 1.5506977, 1.7727263, 2.5190228, 4.1367678, 5.0212291, 4.5795799, 2.8484358, 1.8856229, 1.5178736, 1.3656797)
# );
# drl=rbind(c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
# c( 1.112, 1.103, 1.088, 1.082, 1.076, 1.068, 1.073, 1.079, 1.082, 1.088, 1.103, 1.112),
# c( 2.653, 2.653, 2.653, 2.653, 2.653, 2.653, 2.653, 2.653, 2.653, 2.653, 2.653, 2.653),
# c( 1.112, 1.103, 1.088, 1.082, 1.076, 1.068, 1.073, 1.079, 1.082, 1.088, 1.103, 1.112),
# c( 0.52, 0.52, 0.666, 0.91, 1.031, 1.044, 1.042, 1.037, 1.036, 0.917, 0.666, 0.52),
# c( 0.816, 0.8115, 0.877, 0.996, 1.0535, 1.056, 1.0575, 1.058, 1.059, 1.0025, 0.8845, 0.816),
# c( 0.7602524, 0.7551426, 0.7772204, 0.8250124, 0.846955, 0.8449668, 0.8471342, 0.8496604, 0.8514252, 0.8299022, 0.7857734, 0.7602744),
# c( 0.35090494, 0.34920916, 0.36891486, 0.40567288, 0.42336056, 0.42338372, 0.42328378, 0.42485112, 0.42631836, 0.40881268, 0.37218526, 0.35096866),
# c( 0.05641527, 0.05645892, 0.05557872, 0.05430207, 0.05425842, 0.05399002, 0.05361482, 0.0572041, 0.05892068, 0.05821407, 0.05709462, 0.05645892),
# c( 0.03699235, 0.03699634, 0.03528634, 0.03272533, 0.03272134, 0.03270066, 0.03268178, 0.03907616, 0.04149324, 0.04032533, 0.03823134, 0.03699634),
# c( 0.0777, 0.0778, 0.0778, 0.0779, 0.0778, 0.0771, 0.0759, 0.0766, 0.0778, 0.0779, 0.0778, 0.0778),
# c( 0.0777, 0.0778, 0.0778, 0.0779, 0.0778, 0.0771, 0.0759, 0.0766, 0.0778, 0.0779, 0.0778, 0.0778),
# c( 0.0112, 0.0112, 0.0112, 0.0112, 0.0112, 0.0112, 0.0112, 0.0112, 0.0112, 0.0112, 0.0112, 0.0112),
# c( 0.1947138, 0.19413424, 0.20831414, 0.23348558, 0.24574614, 0.24605016, 0.24538258, 0.24630454, 0.247455, 0.23527388, 0.20963734, 0.19478494)
# );
# if(missing('tab') ){ #undefined table, use the default table.
# tab=switch(type,'lai'=dlai, 'rl'=drl)
# }
# ret = tab[x,]
# }
#
#
# rep.row<-function(x,n){
# for(i in 1:n){
# if(i==1){
# ret = x;
# }else{
# ret=rbind(ret, x)
# }
# }
# return(ret)
# }
#
# rep.col<-function(x,n){
# for(i in 1:n){
# if(i==1){
# ret = x;
# }else{
# ret=cbind(ret, x)
# }
# }
# return(ret)
# }
# GLC.LaiRf <- function(lc,years=2000+1:2, if.daily=FALSE){
# #years=2000:(2010+1);
# years=sort(c(years,max(years)+1))
# yrlim=range(years);
# ny = length(years)
# t1=as.Date(paste(yrlim[1],'-01-01',sep=''))
# t2=as.Date(paste(yrlim[2],'-12-31',sep=''))
# tdaily = seq.Date(t1,t2,by=1)
# DataDaily=xts::as.xts(numeric(length(tdaily)),order.by=tdaily)
# DataMon=xts::apply.monthly(DataDaily,FUN=sum)
# tmon =as.Date( format(time(DataMon), "%Y-%m-01"))
# #tmon = time(DataMon)- days_in_month(time(DataMon))+1
# nlc=length(lc)
# l = matrix(0, nrow=12, ncol=nlc)
# r = matrix(0, nrow=12, ncol=nlc)
# for (i in 1:nlc){
# l[,i] = cfun(lc[i], type=1)
# r[,i] = cfun(lc[i], type=2)
# }
# lmat = xts::as.xts(rep.row(l, ny), order.by=tmon)
# rmat = xts::as.xts(rep.row(r, ny), order.by=tmon)
# colnames(lmat)=lc
# colnames(rmat)=lc
# ret=list('LAI'=lmat, 'RL'=rmat)
# if(if.daily){
# ld = NA*rep.col(DataDaily, nlc);
# rd = NA*rep.col(DataDaily, nlc);
# ld[time(lmat),]=lmat
# rd[time(rmat),]=rmat
# ld=na.approx(ld)
# rd=na.approx(ld)
# colnames(ld)=lc
# colnames(rd)=lc
# ret=list('LAI'=ld, 'RL'=rd)
# }
# return(ret)
# }
fun.MeltFactor <- function(years=2000+1:2){
mf=c(0.001308019, 0.001633298, 0.002131198, 0.002632776, 0.003031171, 0.003197325, 0.003095839, 0.00274524, 0.002260213, 0.001759481, 0.001373646, 0.001202083);
years=sort(c(years,max(years)+1))
yrlim=range(years);
ny = length(years)
t1=as.Date(paste(yrlim[1],'-01-01',sep=''))
t2=as.Date(paste(yrlim[2],'-12-31',sep=''))
tdaily = seq.Date(t1,t2,by=1)
DataDaily=as.xts(numeric(length(tdaily)),order.by=tdaily)
DataMon=apply.monthly(DataDaily,FUN=sum)
#tmon = time(DataMon)- days_in_month(time(DataMon))+1
tmon =as.Date( format(time(DataMon), "%Y-%m-01"))
ret = as.xts(rep(mf, ny), order.by=tmon)
ret
}
fun.vegtable <- function (lc, file){
x=read.csv(file=file.path('table','lc_table.csv'), header = T)
y = x[lc,1:8]
nr = nrow(y)
write(nr, file=file, append = F)
write.table(y, file=file, append=T, row.names = F, col.names = F, quote = F)
y
}

View File

@ -0,0 +1,4 @@
# sp.meteoSite=readOGR(fn)

View File

@ -0,0 +1,39 @@
#############################################################
# Notes
#
#
# See Notes for packages needed
#############################################################
getSoilData <- function(MUKEY, vars = c('silttotal_r', 'claytotal_r', 'om_r', 'dbthirdbar_r'),
na.rm=TRUE
# ,fn = 'gSSURGO_texture.csv'
){
# cnames = c('sandtotal_r', 'silttotal_r', 'claytotal_r', 'om_r',
# "ksat_l","ksat_r", "ksat_h",
# "awc_l", "awc_r", "awc_h")
library('soilDB')
in.statement <- format_SQL_in_statement(MUKEY)
#in.statement = paste(MUKEY);
q <- paste("SELECT component.mukey, ", paste(vars, collapse=',') ,
"FROM component ",
"JOIN chorizon " ,
"ON component.cokey = chorizon.cokey AND mukey ",
"IN ", in.statement,
"ORDER BY mukey ", sep=" ")
ret <- SDA_query(q)
q <- paste("SELECT component.mukey, ", paste(vars, collapse=',') ,
"FROM component ",
"JOIN chorizon " ,
"ON component.cokey = chorizon.cokey AND mukey ",
"IN ", in.statement,
"ORDER BY mukey ", sep=" ")
ret <- SDA_query(q)
tmp = apply(ret, 1, mean, na.rm=FALSE)
ret = ret[!is.na(tmp),]
# write.csv(ret, file=fn)
return(ret)
}

View File

@ -0,0 +1,11 @@
nc.fishnet <- function(x){
# fid = ncdf4::nc_open(fn)
# x=readnc.CMFD(ncid=fid, varid = varid)
# ncdf4::nc_close(fid)
res = mean(round(diff(x$x), 4))
xlim = range(x$x) + c(-1, 1)*res*0.5
ylim = range(x$y) + c(-1, 1)*res*0.5
spx = rSHUD::fishnet(xx=seq(xlim[1], xlim[2], by=res), yy=seq(ylim[1], ylim[2], by=res))
return(spx)
}

View File

@ -0,0 +1,9 @@
raster2Polygon <- function(rx){
ext= raster::extent(rx)
res =raster::res(rx)
xx = seq(ext[1], ext[2], res[1])
yy = seq(ext[3], ext[4], res[2])
spx = rSHUD::fishnet(xx=xx, yy=yy, crs=raster::crs(rx))
return(spx)
}

View File

View File

View File

@ -0,0 +1,108 @@
AutoSHUD_Step1 <- function(CV){
caller = as.character( deparse(sys.call()) )
writelog(msg=caller, caller = caller)
writemessage(paste0('Running the AutoSHUD_Step1(CV) '), caller = caller, CV$task.log)
prefix = 'AutoSHUD_S1'
xfg = CV$deploy
if(is.null(xfg)){ writelog(msg="Error: xfg is missing in CV", caller = caller) }
# ================= Boundary =================
wbd0 = readOGR(xfg$fsp.wbd) # Read data
wbd0 = gBuffer(wbd0, width=0) # Remove error from irregular polygon.
# ---- disolve ----
wbd.dis = removeholes(gUnaryUnion(wbd0))
# wbd in pcs
wb.p = spTransform(wbd0, xfg$crs.pcs)
writeshape(wb.p, xfg$pd.pcs$wbd)
# buffer of wbd in pcs
buf.p = gBuffer(wb.p, width = xfg$para$DistBuffer)
writeshape(buf.p, xfg$pd.pcs$wbd.buf)
buf.g = spTransform(buf.p, xfg$crs.gcs)
writeshape(buf.g, xfg$pd.gcs$wbd.buf)
wb.g=spTransform(wb.p, CRSobj = xfg$crs.gcs )
writeshape(wb.g, xfg$pd.gcs$wbd)
# ================= DEM =================
dem0=raster(xfg$fr.dem)
# -------CROP DEM -----------------
# Crop the dem AND conver the dem to PCS.
writelog(msg=paste0('Cuting DEM ...'), caller = caller)
fun.gdalwarp(f1=xfg$fr.dem,
f2=xfg$pd.pcs$dem,
t_srs = xfg$crs.pcs,
s_srs = crs(dem0),
opt = paste0('-cutline ', xfg$pd.pcs$wbd.buf) )
# # Crop the dem, output is in GCS
fun.gdalwarp(f1=xfg$fr.dem,
f2=xfg$pd.gcs$dem,
t_srs = xfg$crs.gcs,
s_srs = crs(dem0),
opt = paste0('-cutline ', xfg$pd.pcs$wbd.buf) )
# =========Stream Network===========================
writelog(msg=paste0('Stream network ...'), caller = caller)
stm0 = readOGR(xfg$fsp.stm) # data 0: raw data
stm1 = spTransform(stm0, xfg$crs.pcs) # data 1: PCS
fun.simplifyRiver <- function(rmDUP=TRUE){
riv.xy = extractCoords(stm1)
npoint = nrow(riv.xy)
mlen = gLength(stm1) / npoint
r.dem = raster(xfg$pd.pcs$dem)
dx = mean(res(r.dem))
if( mlen < dx){
stm1 = gSimplify(stm1, tol = dx)
}
if(rmDUP){
res = rmDuplicatedLines(stm1)
}else{
res = stm1
}
res
}
# debug(sp.RiverDown)
if(xfg$para$flowpath){
stm1 = fun.simplifyRiver(rmDUP = FALSE)
stm.p= sp.RiverPath(stm1, tol.simplify = 30)$sp # clean data with flowpath.
stm.p = stm1
}else{
stm.p = stm1
}
writelog(msg=paste0('writing stream out: ', xfg$pd.pcs$stm), caller = caller)
writeshape(stm.p, file=xfg$pd.pcs$stm)
#' ==========================================
if(xfg$LAKEON){
writemessage(paste0('Lake module is ENABLED '), caller = caller, CV$task.log)
writelog(msg=paste0('Lake is ON.'), caller = caller)
spl0 = readOGR(xfg$fsp.lake) # data 0: raw data
spl1 = removeholes(spl0)
spl.gcs = spTransform(spl1, CRSobj = xfg$crs.gcs)
writeshape(spl.gcs, xfg$pd.gcs$lake)
spl.pcs = spTransform(spl.gcs, CRSobj = xfg$crs.pcs) # data 1: PCS
writeshape(spl.pcs, xfg$pd.pcs$lake)
}
#' ==== PLOT FIGURE ================
writelog(msg=paste0('Ploting'), caller = caller)
dem.p = raster(xfg$pd.pcs$dem)
png(file.path(xfg$dir$fig, paste0(prefix, '_Rawdata_Elevation.png')), type='cairo',height=8, width=8, units = 'in', res=200)
par(mar=c(2, 2, 1, 1) )
plot(dem.p)
plot(wb.p, add=T, border=2)
plot(stm.p, add=T, col=4);
if(xfg$LAKEON){
plot(spl.pcs, add=TRUE, border='darkblue', lwd=1.5)
}
grid()
dev.off()
writelog(paste0('Finished'), caller=caller)
}
# AutoSHUD_Step1(CV)

View File

@ -0,0 +1,95 @@
AutoSHUD_Step2 <- function(CV){
caller = as.character( deparse(sys.call()) )
writelog(msg=caller, caller = caller)
writemessage(paste0('Running the AutoSHUD_Step2(CV) '), caller = caller, CV$task.log)
raster.reclass <- function(fn.r, fn.tab, fn.ridx){
rx = raster(fn.r)
att = read.df(fn.tab)[[1]]
rcl = cbind(att[, 1], 1:nrow(att))
ry = raster::reclassify(rx, rcl)
writeRaster(ry, filename = fn.ridx, overwrite=TRUE)
# return(ry)
}
plotfun <-function(fn.r, key){
r = raster(fn.r)
png(filename = file.path(xfg$dir$fig, paste0(xfg$prefix,'_', key, '.png')), type='cairo',
height = 7, width=7, unit='in', res=300)
par(mar=c(2, 2, 1, 1))
plot(r)
plot(wb.p, add=T, border='red', lwd=1)
plot(stm.p, add=T, col='blue', lwd=1)
grid();
mtext(side=3, line=-1, paste0(key, '(Class)') )
dev.off()
}
xfg = CV$deploy
xfg$prefix = 'AutoSHUD_S2'
stm.p = readOGR(xfg$pd.pcs$stm)
wb.p = readOGR(xfg$pd.pcs$wbd)
if(is.null(xfg)){
writelog(msg="Error: xfg is missing in CV", caller = caller)
}
# =======Soil=================================================================
# =======Soil=================================================================
# source(file.path(CV$dirs$deploy, 'Rfunction/Fun.Soil_Geol.R') )
writemessage(paste0('Processing SOIL/Geol data... '), caller = caller, CV$task.log)
# this script for soil/geol data with SpatialData and Attribute Table.
message('Processing SOIL/Geol data...')
message('fn.soil: ', xfg$fn.soil)
message('fa.soil: ', xfg$fa.soil)
message('fn.geol: ', xfg$fn.geol)
message('fa.geol: ', xfg$fa.geol)
fun.gdalcut(f.in = xfg$fn.soil, f.mask = xfg$pd.pcs$wbd.buf,
f.out= xfg$pd.pcs$soil.r, t_srs = xfg$crs.pcs, s_srs = xfg$crs.gcs)
fun.gdalcut(f.in = xfg$fn.geol, f.mask = xfg$pd.pcs$wbd.buf,
f.out= xfg$pd.pcs$geol.r, t_srs = xfg$crs.pcs, s_srs = xfg$crs.gcs)
raster.reclass(fn.r = xfg$pd.pcs$soil.r, fn.tab = xfg$fa.soil, fn.ridx = xfg$pd.pcs$soil.idx)
raster.reclass(fn.r = xfg$pd.pcs$geol.r, fn.tab = xfg$fa.geol, fn.ridx = xfg$pd.pcs$geol.idx)
dat.soil = fun.Soil_Geol(xfg, TOP = TRUE)
dat.geol = fun.Soil_Geol(xfg, TOP = FALSE)
plotfun(fn.r = xfg$pd.pcs$geol.idx, key = 'Geol')
plotfun(fn.r = xfg$pd.pcs$soil.idx, key = 'Soil')
#
# =======Land Cover ====================================================
# =======Land Cover ====================================================
writemessage(paste0('Processing landuse data... '), caller = caller, CV$task.log)
if( xfg$ilanduse >= 1){
# local landuse map and attribute table.
fun.gdalcut(f.in = xfg$fn.landuse,
f.mask = xfg$pd.pcs$wbd.buf,
f.out= xfg$pd.pcs$lu.r,
t_srs = xfg$crs.pcs,
s_srs = xfg$crs.gcs)
raster.reclass(fn.r = xfg$pd.pcs$lu.r, fn.tab = xfg$tab.landuse, fn.ridx = xfg$pd.pcs$lu.idx)
plotfun(fn.r = xfg$pd.pcs$lu.idx, key = 'Landuse')
}
# # =======Forcing =================================================================
# # =======Forcing =================================================================
writemessage(paste0('Processing reanalysis coverage data... '), caller = caller, CV$task.log)
if(xfg$iforcing >= 1){
# local map
att=read.df(xfg$fc.att)[[1]]
sp.forc = xy2shp(xy = cbind(att$LON, att$LAT), crs=xfg$crs.gcs, shape = 'point', df = att)
# plot(sp.forc)
writeshape(sp.forc, file = xfg$pd.gcs$meteo)
sp.forc.pcs = sp::spTransform(sp.forc, xfg$crs.pcs)
writeshape(sp.forc.pcs, file = xfg$pd.pcs$meteo)
png(filename = file.path(xfg$dir$fig, paste0(xfg$prefix,'_', 'Metero', '.png')), type='cairo',height = 7, width=7, unit='in', res=300)
par(mar=c(2, 2, 1, 1))
plot(sp.forc.pcs, axes=TRUE, col='darkgreen')
plot(wb.p, add=T, border='red', lwd=1)
plot(stm.p, add=T, col='blue', lwd=1)
grid();
mtext(side=3, line=-1, paste0('Meterology sites',' (N=', nrow(sp.forc.pcs), ')') )
dev.off()
}else{
stop(paste('WRONG LDAS CODE: ', xfg$iforcing))
}
writelog(paste0('Finished'), caller=caller)
# return(xfg)
}
# AutoSHUD_Step2(CV)

View File

@ -0,0 +1,287 @@
AutoSHUD_Step3 <- function(CV){
caller = as.character( deparse(sys.call()) )
writelog(msg=caller, caller = caller)
writemessage(paste0('Running the AutoSHUD_Step3(CV) '), caller = caller, CV$task.log)
prefix = 'AutoSHUD_S3'
xfg = CV$deploy
if(is.null(xfg)){
writelog(msg="Error: xfg is missing in CV", caller = caller)
}
fin <- shud.filein(xfg$prjname, inpath = xfg$dir$modelin, outpath= xfg$dir$modelout)
wbd=readOGR(xfg$pd.pcs$wbd)
dem=raster(xfg$pd.pcs$dem)
buf.g = readOGR(xfg$pd.pcs$wbd.buf)
# ==============================================
AA1=gArea(wbd)
a.max = min(AA1/xfg$para$NumCells, xfg$para$MaxArea)
NCELL.MAX = round(AA1 / a.max * 1.5)
q.min = xfg$para$MinAngle
tol.wb = xfg$para$tol.wb
tol.rivlen = xfg$para$tol.rivlen
years = xfg$years
if(is.null(tol.wb) | is.infinite(tol.wb)){ tol.wb = min(sqrt(a.max), 3000) }
if(is.null(tol.rivlen) | is.infinite(tol.rivlen) ){ tol.rivlen = min(sqrt(a.max), 5000) }
#
# tol.wb = min(sqrt(a.max)/2, 300)
# tol.rivlen = min(sqrt(a.max)*3, 5000)
bm.para = data.frame(a.max/1e6, tol.wb, tol.rivlen)
names(bm.para)=c('MaxArea_km2', 'tol.wb', 'MaxRivLen')
print(bm.para)
ny=length(years)
nday = 365*ny + round(ny/4) - 1
writemessage(paste0('Area = ', AA1), caller = caller, CV$task.log)
writemessage(paste0('Max cell area = ', a.max), caller = caller, CV$task.log)
writemessage(paste0('NCELL.MAX = ', NCELL.MAX), caller = caller, CV$task.log)
writemessage(paste0('Minimum Angle = ', q.min), caller = caller, CV$task.log)
writemessage(paste0('Simplity tolerance for boundary = ', tol.wb), caller = caller, CV$task.log)
writemessage(paste0('Simplity tolerance for river length = ', tol.rivlen), caller = caller, CV$task.log)
writemessage(paste0('Years ', min(years), '~', max(years)), caller = caller, CV$task.log)
writemessage(paste0('No of Days = ', nday), caller = caller, CV$task.log)
#' ==============================================
#' BUFFER
wb.dis = rgeos::gUnionCascaded(wbd)
wb.s1 = rgeos::gSimplify(wb.dis, tol=tol.wb, topologyPreserve = T)
# wb.s2 = sp.simplifyLen(wb.s1, tol.wb)
wb.s2 = gSimplify(wb.s1, tol = tol.wb)
wb.simp = wb.s2
#' ====================================================
#'
if(xfg$LAKEON){
source(file.path(CV$dirs$deploy, 'SubScript/Sub3_lake.R') )
}else{
sp.lake=NULL
}
tri = shud.triangle(wb=wb.simp,q=q.min, a=a.max, S=NCELL.MAX)
# =========Mesh generation=====================================
pm = shud.mesh(tri, dem=dem, AqDepth = xfg$para$AqDepth)
spm = sp.mesh2Shape(pm, crs = crs(wbd))
writeshape(spm, crs(wbd), file=file.path(fin['inpath'], 'gis', 'domain'))
print(nrow(spm@data))
ia=getArea(pm)
nCells = length(spm)
writemessage(paste0('No of tirangular cells = ', nCells), caller = caller, CV$task.log)
writemessage(paste0('Mean area of tirangular cells = ', mean(ia)), caller = caller, CV$task.log)
# ==============================================
riv0=readOGR(xfg$pd.pcs$stm)
if(xfg$para$flowpath){
# debug(sp.RiverPath)
riv1=sp.RiverPath(riv0)$sp #Build the River Path --- Dissolve the lines.
riv1=riv0
riv2=rmDuplicatedLines(riv1)
}else{
riv1 = riv0
riv2=riv1
}
lens=gLength(riv2, byid=TRUE)
summary(lens)
spr = sp.CutSptialLines(sl=riv2, tol=tol.rivlen)
# writeshape(spr, file=file.path(xfg$dir$predata, 'spr'))
go.png <- function(){
png(file = file.path(xfg$dir$fig, paste0(prefix, '.1_datain.png')), type='cairo', height=7, width=7, res=300, unit='in')
par(mar=c(2, 2, 1, 1) )
plot(dem);
plot(wbd, add=T, border='red', lwd=1); plot(riv2, add=T, lwd=1, col='blue');
mtext(line=-1,side=3, cex=1,'DEM-WBD-Riv'); grid()
dev.off()
}; go.png()
# ======FORCING FILE======================
sp.meteoSite = rgdal::readOGR(xfg$pd.pcs$meteo)
sp.meteoSite@data$ID = paste0(CV$json$meteorological_data, '_', sp.meteoSite@data$FILENAME)
sp.forc = rSHUD::ForcingCoverage(sp.meteoSite = sp.meteoSite,
pcs=xfg$crs.pcs, gcs=xfg$crs.gcs,
dem=dem, wbd=wbd)
# head(sp.forc@data)
write.forc(sp.forc@data, path = '../ETV/TSD',
startdate = paste0(min(years), '0101'),
file=fin['md.forc'])
go.png <-function(){
png(file.path(xfg$dir$fig, paste0(prefix, '.2_buf_riv_forc.png')), type='cairo', height=7, width=7, units = 'in', res=300)
par(mar=c(2, 2, 1, 1) )
plot(dem);grid()
plot(buf.g, add=T, axes=T, lwd=1)
plot(wbd, add=T, border='red', lwd=1)
plot(riv2, add=T, col='blue', lwd=1)
plot(sp.meteoSite, add=T, col='darkgreen', cex=0.3)
plot(sp.forc, add=T, lwd=0.5, lty=2)
grid(); mtext(line=-1,side=3, cex=1, 'DEM-WBD-Riv-Meteo'); dev.off()
}; go.png();
# xfg$dir$fig = file.path(xfg$dir$modelin, 'fig')
gisout = file.path(xfg$dir$modelin, 'gis')
dir.create(xfg$dir$modelin, showWarnings = F, recursive = T)
dir.create(xfg$dir$fig, showWarnings = F, recursive = T)
dir.create(gisout, showWarnings = F, recursive = T)
go.png <-function(){
png(file.path(xfg$dir$fig, paste0(prefix, '.3_domain.png')), type='cairo', height=7, width=7, units = 'in', res=300)
par(mar=c(2, 2, 1, 1) )
plot_sp(spm, 'Zmax', axes=TRUE, lwd=0.3, border='gray')
plot(spr, add=T, col=rgb(0.8, 0.8, 0.8, alpha = 0.5), lwd=2)
plot(spr, add=T, col='blue', lwd=1)
mtext(line=-1,side=3, cex=1, paste0('SHUD triangular mesh (Ncell = ', nCells, ')' ))
grid(); title(''); dev.off()
}; go.png()
# ======LANDUSE======================
rlc.idx = raster(xfg$pd.pcs$lu.idx)
para.lc = read.df(xfg$tab.landuse)[[1]]
para.lc = para.lc[, -1*ncol(para.lc)]
para.lc[, 1] = 1:nrow(para.lc)
# ====== generate .att ======================
r.soil.idx = raster(xfg$pd.pcs$soil.idx)
r.geol.idx = raster(xfg$pd.pcs$geol.idx)
pa=shud.att(tri,
r.soil = r.soil.idx, r.geol = r.geol.idx, r.lc = rlc.idx,
r.forc = sp.forc, r.BC = 0, sp.lake = sp.lake)
fx <- function(x){ x[is.na(x)] = median(x, na.rm = TRUE); return(x) }
pa = apply(pa, 2, fx)
spm@data = cbind(spm@data, pa)
writeshape(spm, crs(wbd), file=file.path(fin['inpath'], 'gis', 'domain'))
# ====== generate .riv ======================
pr=shud.river(spr, dem)
pr@rivertype$Width= pr@rivertype$Width * xfg$para$RivWidth
pr@rivertype$Depth= xfg$para$RivDepth + (1:nrow(pr@rivertype) - 1 )*0.5
pr@rivertype$BankSlope = 1
spr@data = data.frame(pr@river, pr@rivertype[pr@river$Type,])
writeshape(spr, crs(wbd), file=file.path(gisout, 'river'))
# Cut the rivers with triangles
sp.seg=sp.RiverSeg(spm, spr)
writeshape(sp.seg, crs(wbd), file=file.path(gisout, 'seg'))
# Generate the River segments table
prs = shud.rivseg(sp.seg)
# Generate initial condition
# debug(shud.ic)
if(xfg$LAKEON){
lakestage = 30;
}else{
lakestage = NULL
}
pic = shud.ic(ncell = nrow(pm@mesh), nriv = nrow(pr@river), lakestage=lakestage,
AqD = xfg$para$AqDepth)
# Generate shapefile of mesh domain
cfg.para = shud.para(nday = nday)
cfg.para['INIT_MODE']=3
# calibration
cfg.calib = shud.calib()
#soil/geol/landcover
if(xfg$para$QuickMode){
message('\n !!! QUICK MODE in SOIL/GEOL parameters!!!\n')
para.soil = PTF.soil()
para.geol = PTF.geol()
}else{
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
# !!!!! the column of soil/geol file must be 5 colume: ID SILT CLAY OM BD
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
asoil = as.matrix(read.df(xfg$pd.att$soil)[[1]])[, -1]
ageol = as.matrix(read.df(xfg$pd.att$geol)[[1]])[, -1]
asoil=rbind(asoil)
ageol=rbind(ageol)
asoil[asoil[, 3] > 5, 3] = NA # Organic Matter must less 5.
ageol[ageol[, 3] > 5, 3] = NA
fx <- function(x){ x[is.na(x) | is.nan(x)] = mean(x, na.rm=TRUE); return(x) }
asoil = rbind(apply(asoil, 2, fx))
ageol = rbind(apply(ageol, 2, fx))
para.soil = data.frame(PTF.soil(asoil))
para.geol = data.frame(PTF.geol(ageol))
# plot(ageol[, 3], para.geol[, 2], xlab='OM', ylab='KsatV(m_d)', log='x')
fun.plot <- function(dat, ylab=''){
nd = length(dat)
x = (1:nd)/nd
y=sort(dat)
plot(x, y, xlab='', ylab='', pch=20, col='blue',type='b');
mtext(side = 1, line=2, 'Exceedance');
mtext(side = 2, line=2, ylab);
grid()
}
go.png <-function(){
png(file.path(xfg$dir$fig, paste0(prefix, '.4_soilgeol_para.png')), type='cairo', height=7, width=7, units = 'in', res=300)
par(mar=c(3, 3, 1, 1), mfrow=c(2,2) )
fun.plot(para.soil$KsatV.m_d., ylab='Soil KsatV (m/day)')
fun.plot(para.soil$Beta, ylab='Soil Beta (-)')
fun.plot(para.geol$KsatV.m_d., ylab='Geol KsatV (m/day)')
fun.plot(para.geol$ThetaS.m3_m3., ylab='Geol Porosity (m3/m3)')
dev.off()
}; go.png()
}
# ====== LAI ======================
ts.lai = read.tsd(CV$etv$landuse.lai)[[1]]
write.tsd(ts.lai, file = fin['md.lai'])
#MeltFactor
# mf =read.tsd(CV$etv$meltfactor)
mf = MeltFactor(years = years)
write.tsd(mf, file=fin['md.mf'])
# write SHUD input files.
write.mesh( pm, file = fin['md.mesh'])
write.riv(pr, file=fin['md.riv'])
write.ic(pic, file=fin['md.ic'])
write.df(pa, file=fin['md.att'])
write.df(prs, file=fin['md.rivseg'])
write.df(para.lc, file=fin['md.lc'])
write.df(para.soil, file=fin['md.soil'])
write.df(para.geol, file=fin['md.geol'])
cfg.para$START=xfg$para$STARTDAY
cfg.para$END=xfg$para$ENDDAY
cfg.para$CRYOSPHERE = xfg$para$CRYOSPHERE
cfg.para$MAX_SOLVER_STEP = xfg$para$MAX_SOLVER_STEP
write.config(cfg.para, fin['md.para'])
write.config(cfg.calib, fin['md.calib'])
if( any( is.na(pm@mesh) ) | any( is.na(pm@point) ) ){
message('NA in .SP.MESH file')
}
if(any( is.na(pr@river)) ){
message('NA in .SP.RIV file')
}
if(any( is.na(pa)) ){
message('NA in .SP.ATT file')
}
pp = shud.env(prjname = xfg$prjname, inpath = xfg$dir$modelin, outpath = xfg$dir$modelout)
ia= getArea()
ma = MeshAtt()
go.plot <- function(){
png(file.path(xfg$dir$fig, paste0(prefix, '.5_HistArea.png')), type='cairo', height=7, width=7, units = 'in', res=300)
par(mfrow=c(2, 1))
hist(ia/1e6, xlab='', ylab='', main='Histgram of triangle area', freq=TRUE);
mtext(side=1, line=2,'Area (km2)')
mtext(side=2, line=2,'Count')
hist(sqrt(ia)/1e3, xlab='', ylab='', main='Histgram of equivalent resolution', freq=TRUE);
mtext(side=1, line=2,'Length (km)')
mtext(side=2, line=2,'Count')
par(mfrow=c(1, 1))
dev.off()
}; go.plot()
# ModelInfo()
message('Ncell = ', nrow(pm@mesh))
message('Nriv = ', nrow(pr@river))
writelog(paste0('Finished'), caller=caller)
return(nCells)
}
# AutoSHUD_Step3(CV)

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,78 @@
# THIS IS FOR ISRIC_SoilGrids SOIL DATA ONLY
soil.str = c('CLYPPT_M_sl',
'SNDPPT_M_sl',
'SLTPPT_M_sl',
'ORCDRC_M_sl',
'BLDFIE_M_sl')
tmp=expand.grid(soil.str, c(1,7) )
fns=paste0(tmp[,1], tmp[,2], "_250m.tif")
fns1=paste0(tmp[,1], tmp[,2], "_250m_PCS.tif")
d0 = dir.soil
d1 = file.path(dir.predata, 'soil')
dir.create(d1, showWarnings = F, recursive = T)
cmds=paste('gdalwarp -overwrite -q -cutline',
file.path(dir.predata, 'wbd_buf.shp'), '-crop_to_cutline -of GTiff ',
file.path(d0, fns), file.path(d1, fns) )
cmds1=paste('gdalwarp -overwrite -dstnodata -9 -q',
'-s_srs', paste0("'", crs.gcs, "'"),
'-t_srs', paste0("'", crs(wbd), "'"),
file.path(d1, fns), file.path(d1, fns1) )
cmds
nc=length(cmds)
for(i in 1:nc){ # gdalwarp cut the data with wbd_buf
cm=cmds[i]
message(i, '/', nc, '\t', fns[i])
system(cm)
system(cmds1[i])
}
# stop()
ffns = file.path(d1, fns1)
nf=length(ffns)
for(i in 1:nf){
cm=cmds[i]
message(i, '/', nc, '\t', fns1[i])
r=raster(ffns[i])
png.control(fn=paste0(fns1[i],'.png'), path = file.path(dir.png,'Rawdata_Soil'), ratio=1)
plot(r)
plot(wbd.buf, add=T, axes=T, lwd=2)
plot(wbd, add=T, border=3, lwd=2)
plot(stm, add=T, col=2, lwd=2)
title(fns[i])
dev.off()
}
# =========Save to RDS =============
do.SoilGeology <- function(lyr, indir, vns= c('SLT', 'CLY', 'ORCDRC', 'BLD')){
# lyr='sl1'
# vns= c('SLT', 'CLY', 'ORCDRC', 'BLD')
# lyr = 'sl1'
# nv = dim(rl)[3]
nv=length(vns)
rl=list()
for(i in 1:nv){
message(i,'/', nv, '\t', vns[i])
pattern=glob2rx(paste0(vns[i], '*', lyr, '*PCS.tif'))
r = raster(list.files(indir, pattern = pattern,full.names = TRUE) )
if(i==1){
rc = r
res(rc)=res(r)*5
extent(rc)=extent(r)
rc[]=1
}
if(i==3){#Pribyl, D. W. (2010). A critical review of the conventional SOC to SOM conversion factor. GCSderma, 156(34), 7583. https://doi.org/10.1016/j.GCSderma.2010.02.003
r = r /10/0.58;
}
if(i==4){ # kg/m3 = g/cm3
r = r / 1000
}
rr=resample(r, rc)
rl[[i]] =rr
}
names(rl) = vns
saveRDS(rl, file.path(dir.predata, paste0('Soil_', lyr, '.RDS')))
}
do.SoilGeology(lyr='sl1', indir=file.path(dir.predata, 'soil'))
do.SoilGeology(lyr='sl7', indir=file.path(dir.predata, 'soil'))

View File

@ -0,0 +1,53 @@
#'
#' THIS IS FOR US gSSURGO SOIL DATA ONLY
#'
source('Rfunction/fun.SSURGO.R')
#' ==========Soil Raster =============
fn0.soil = file.path(xfg$dir$soil, 'gSSURGO-mukey.tif')
r0 = raster(fn0.soil)
tmpsoil = file.path(dir.pd.pcs, 'soil_mukey.tif')
fun.gdalcut( f.in = fn0.soil,
f.mask = pd.pcs$wbd.buf,
f.out = tmpsoil,
s_srs = crs(r0), t_srs = xfg$crs.pcs)
r1 = raster(tmpsoil)
uk = sort(unique(r1))
rcl = cbind(uk, 1:length(uk))
r.cl = reclassify(r1, rcl=rcl)
plot(r.cl)
writeRaster(r.cl, filename = pd.pcs$soil.r, overwrite=TRUE)
#' ========Soil texture ==============
# cnames = c('sandtotal_r', 'silttotal_r', 'claytotal_r', 'om_r', 'dbthirdbar_r',
# "ksat_l","ksat_r", "ksat_h",
# "awc_l", "awc_r", "awc_h")
vars = c('sandtotal_r',
'silttotal_r',
'claytotal_r',
'om_r',
'dbthirdbar_r',
"ksat_r", "awc_r")
df0 = getSoilData(MUKEY = uk, vars = vars, na.rm=TRUE)
nu = length(uk)
att = matrix(0, nrow=nu, ncol=4)
i=1
cnames = c('silttotal_r',
'claytotal_r',
'om_r',
'dbthirdbar_r')
print(cnames)
for(i in 1:nu){
ikey = uk[i]
message(i, '/', nu, '\t', ikey)
idx = which(df0$mukey %in% ikey)
x=apply(df0[idx, cnames], 2, mean, na.rm=TRUE)
att[i, ] = x
}
plot(r.cl)
colnames(att) = cnames
write.df(att, file=pd.att$geol)
write.df(att, file=pd.att$soil)

View File

@ -0,0 +1,97 @@
fun.lc.GLC <- function(xfg){
fun.gdalcut(f.in = xfg$fn.landuse,
f.mask = xfg$pd.pcs$wbd.buf,
f.out= xfg$pd.pcs$lu.r,
t_srs = xfg$crs.pcs,
s_srs = xfg$crs.gcs)
r.lu = raster(xfg$pd.pcs$lu.r)
wb.p = readOGR(xfg$pd.pcs$wbd)
# stm.p = readOGR(xfg$pd.pcs$stm)
go.plot <- function(prefix){
tab = read.df('AutoSHUD/Table/USGS_GLC.csv', sep='\t')[[1]]
clr = read.table('AutoSHUD/Table/LCType_color.clr', sep='\t')
tocol = function(x){rgb(x[, 1], x[, 2],x[, 3], min(1, x[, 4]) )
}
col = tocol(clr[, 2:5]/255)
ulc = cellStats(r.lu, unique, na.rm=TRUE)
brk = 0:17
txt = rep('', 17); txt[ulc] = '(x)'
labs = paste0(tab$remark, txt)
png(filename = file.path(xfg$dir$fig, paste0(prefix,'_Landuse.png')), height = 7, width=9, unit='in', res=200)
par(mar=c(3, 3, 3, 15))
plot(r.lu, legend=FALSE, col=col, breaks=brk)
# plot(r.lu, legend.only=TRUE, col=col, breaks=brks, label=labs)
plot(r.lu, legend.only=TRUE, breaks=brk, col=col,
smallplot=c(0.67,0.70, 0.1,0.9),
legend.width=2, legend.shrink=.5, cex=2, horizontal=FALSE,
axis.args=list(at=0:16+.5, labels=labs, cex.axis=.75),
legend.args=list(text='',side=3, font=2, cex=0.8))
plot(wb.p, add=T, border='red', lwd=2)
# plot(stm.p, add=T, col='blue', lwd=1)
grid()
title('Landuse: USGS Global Land Cover')
dev.off()
};
go.plot(xfg$prefix)
# lc1 = 0:16 # GLCC classifications
# lc2 = 0:12 # LSM classifications
# rcl = rbind(c(0,0),
# c(1,1),
# c(2,2),
# c(3,3),
# c(4,4),
# c(5,5),
# c(6,6),
# c(7,7),
# c(8,8),
# c(9,9),
# c(10,10),
# c(11,0),
# c(12,11),
# c(13,13),
# c(14,11),
# c(15,0),
# c(16,12))
# rcl[,2]=rcl[,2]+1 #classes start from 1, instead of 0;
#
# r.lsm = raster::reclassify(r.lu, rcl)
# ulc = unique(r.lsm)
#
# writeRaster(r.lsm, filename = file.path(xfg$dir$predata, 'pcs', 'Landuse_idx.tif'), overwrite=T)
# # saveraster(r.lsm, fn=file.path(outpath, 'Landuse_PCS') )
#
# # ===========================
# cn=c('INDEX','LAIMAX','RS','RGL','ALBMAX','SHDFAC','ROUGH','DROOT','SoilDgrd','ImpArea')
# # vtab = t(matrix(c(1,0.00000,100.00000,30.00000,0.13500, 0.00000,0.10000,0.60000,0.00000,0,
# # 2,10.76000,125.00000,30.00000,0.18200, 0.80000,0.32000,0.60000,0.00000,0,
# # 3,5.11700,150.00000,96.07728,0.21300, 0.90000,0.32000,0.60000,0.00000,0,
# # 4,10.76000,150.00000,30.00000,0.18200, 0.80000,0.36000,0.60000,0.00000,0,
# # 5,7.17300,100.00000,72.00234,0.23600, 0.80000,0.36000,0.60000,0.00000,0,
# # 6,8.83300,125.00000,52.56440,0.20250, 0.79500,0.40000,0.60000,0.00000,0,
# # 7,8.54004,173.51021,55.99480,0.21129, 0.79986,0.35000,0.60000,0.00000,0,
# # 8,3.66000,300.00000,82.93310,0.25245, 0.80184,0.40000,0.40000,0.00000,0,
# # 9,3.66000,300.00000,126.09371,0.24959, 0.62501,0.30000,0.40000,0.00000,0,
# # 10,2.60000,170.00000,142.33158,0.26652, 0.21818,0.25000,0.40000,0.00000,0,
# # 11,2.90000,40.00000,100.00000,0.28802, 0.72552,0.10000,0.40000,0.05000,0,
# # 12,4.78200,40.00000,100.00000,0.24992, 0.83537,0.20000,0.40000,0.50000,0,
# # 13,0.00100,174.99974,155.98361,0.38000, 0.07489,0.02000,0.05000,0.30000,0,
# # 14,0.00100,200.00000,97.19872,0.24650, 0.10000,0.02000,0.05000,0.90000,0.5
# # ), nrow=length(cn)))
# #
# # colnames(vtab)=cn
# # vtab[, 'ROUGH']=(vtab[, 'ROUGH']/10+0.08)
# # debug(read.df)
# vtab = read.df('Table/USGS_GLC.csv')
#
# write.df(vtab, file=file.path(xfg$dir$predata,'LANDUSE.csv') )
# write.table(vtab, file.path(xfg$dir$predata,'LanduseTable.csv'), quote=F,
# col.names = T, row.names = F)
return(xfg)
}

View File

@ -0,0 +1,25 @@
fun.lc.NLCD <- function(xfg){
r = raster::raster(xfg$fn.landuse)
fun.gdalcut(f.in = xfg$fn.landuse,
f.mask = pd.pcs$wbd.buf,
f.out = pd.pcs$lu.r,
s_srs = crs(r),
t_srs = xfg$crs.pcs
)
r1 = raster(pd.pcs$lu.r)
plot(r1)
alc = sort(unique(r1))
att=read.table('AutoSHUD/Table/nlcd.csv', header = TRUE)
att = att[att$INDEX %in% alc, ] # find the value only exist in the nlcd file.
natt = nrow(att)
rcl = cbind(att[, 1], 1:natt)
lc.att = data.frame('ID'=1:natt, att[, -1])
write.df(lc.att, file = pd.att$landuse)
r2 = raster::reclassify(r1, rcl)
writeRaster(r2, filename = pd.pcs$lu.idx, overwrite=TRUE)
}

View File

@ -0,0 +1,55 @@
buf.g = readOGR(pd.gcs$wbd.buf)
wb.g = readOGR(pd.gcs$wbd)
if(xfg$iforcing == 0.3){ res = 0.25 }
if(xfg$iforcing == 0.4){ res = 0.125 }
ext = extent(buf.g)
ext.fn = c(floor(ext[1]), ceiling(ext[2]), floor(ext[3]), ceiling(ext[4]) )
sp.fn =fishnet(xx = seq(ext.fn[1], ext.fn[2], by=res),
yy = seq(ext.fn[3], ext.fn[4], by=res),
crs =crs(buf.g), type='polygon')
id=which(gIntersects(sp.fn, buf.g, byid = T))
sp.ldas = sp.fn[id,]
plot(sp.ldas); plot(add=T, buf.g, border=3); plot(add=T, wb.g, border=2)
# writeshape(sp.ldas, file=file.path(dir.predata, 'LDAS_GCS'))
writeshape(sp.ldas, file=pd.gcs$meteoCov)
sp.ldas.pcs = spTransform(sp.ldas, xfg$crs.pcs)
writeshape(sp.ldas.pcs, file=pd.pcs$meteoCov)
# writeshape(sp.ldas.pcs, file=file.path(dir.predata, 'LDAS'))
png.control(fn=paste0(prefix, '_LDAS.png'), path = xfg$dir$fig, ratio=1)
plot(sp.fn, axes=T); grid()
plot(sp.ldas, add=T, col=3)
plot(wb.g, add=T, border=2)
plot(buf.g, add=T, border=4)
title('LDAS')
dev.off()
# Forcing:
# 0 LDAS mode: 0.1 CLDAS, 0.2 FLDAS, 0.3 GLDAS 0.4 NLDAS
# 1 Local data: 1.1 Points of metereo-station 1.2 Polygon of coverage
if ( xfg$iforcing == 0.1 ) { # FLDAS
message('USING FLDAS FORCING DATA')
source('Rfunction/CLDAS_nc2RDS.R') # read the orginal fldas data and save to .RDS file.
source('Rfunction/CLDAS_RDS2csv.R') # read the RDS above, to save as .csv file.
}else if ( xfg$iforcing == 0.2 ) { # FLDAS
message('USING FLDAS FORCING DATA')
source('Rfunction/FLDAS_nc2RDS.R') # read the orginal fldas data and save to .RDS file.
source('Rfunction/FLDAS_RDS2csv.R') # read the RDS above, to save as .csv file.
}else if( xfg$iforcing == 0.3 ){ # GLDAS
message('USING GLDA FORCING DATA')
source('Rfunction/GLDAS_nc2RDS.R') # read the orginal fldas data and save to .RDS file.
source('Rfunction/GLDAS_RDS2csv.R') # read the RDS above, to save as .csv file.
}else if( xfg$iforcing == 0.4 ){ # nldas
message('USING NLDAS FORCING DATA')
source('Rfunction/NLDAS_nc2RDS.R') # read the orginal fldas data and save to .RDS file.
source('Rfunction/NLDAS_RDS2csv.R') # read the RDS above, to save as .csv file.
}else{
stop(paste('WRONG LDAS CODE: ', xfg$iforcing))
}

View File

@ -0,0 +1,69 @@
#' INPUT:
#' pd.gcs
#' xfg
#'
#' OUTPUT:
#' sp.ldas, write file: DataPre/pcs/meteoCov.shp
#'
#'
#'
#'
buf.g = readOGR(pd.gcs$wbd.buf)
wb.g = readOGR(pd.gcs$wbd)
if(xfg$iforcing == 0.3){ res = 0.25 } #GLDAS
if(xfg$iforcing == 0.4){ res = 0.125 } #NLDAS
ext = extent(buf.g)
ext.fn = c(floor(ext[1]), ceiling(ext[2]), floor(ext[3]), ceiling(ext[4]) )
sp.fn =fishnet(xx = seq(ext.fn[1], ext.fn[2], by=res),
yy = seq(ext.fn[3], ext.fn[4], by=res),
crs =crs(buf.g), type='polygon')
id=which(gIntersects(sp.fn, buf.g, byid = T))
sp.ldas = sp.fn[id,]
plot(sp.ldas); plot(add=T, buf.g, border=3); plot(add=T, wb.g, border=2)
# writeshape(sp.ldas, file=file.path(dir.predata, 'LDAS_GCS'))
writeshape(sp.ldas, file=pd.gcs$meteoCov)
sp.ldas.pcs = spTransform(sp.ldas, xfg$crs.pcs)
writeshape(sp.ldas.pcs, file=pd.pcs$meteoCov)
# writeshape(sp.ldas.pcs, file=file.path(dir.predata, 'LDAS'))
png.control(fn=paste0(prefix, '_LDAS.png'), path = xfg$dir$fig, ratio=1)
plot(sp.fn, axes=T); grid()
plot(sp.ldas, add=T, col=3)
plot(wb.g, add=T, border=2)
plot(buf.g, add=T, border=4)
title('LDAS')
dev.off()
# Forcing:
# 0 LDAS mode: 0.1 CLDAS, 0.2 FLDAS, 0.3 GLDAS 0.4 NLDAS
# 1 Local data: 1.1 Points of metereo-station 1.2 Polygon of coverage
if ( xfg$iforcing == 0.1 ) {
# FLDAS
message('USING FLDAS FORCING DATA')
source('Rfunction/CLDAS_nc2RDS.R') # read the orginal fldas data and save to .RDS file.
source('Rfunction/CLDAS_RDS2csv.R') # read the RDS above, to save as .csv file.
}else if ( xfg$iforcing == 0.2 ) {
# FLDAS
message('USING FLDAS FORCING DATA')
source('Rfunction/FLDAS_nc2RDS.R') # read the orginal fldas data and save to .RDS file.
source('Rfunction/FLDAS_RDS2csv.R') # read the RDS above, to save as .csv file.
}else if( xfg$iforcing == 0.3 ){
# GLDAS
message('USING GLDA FORCING DATA')
source('Rfunction/GLDAS_nc2RDS.R') # read the orginal fldas data and save to .RDS file.
source('Rfunction/GLDAS_RDS2csv.R') # read the RDS above, to save as .csv file.
}else if( xfg$iforcing == 0.4 ){
# NLDAS
message('USING NLDAS FORCING DATA')
source('Rfunction/NLDAS_nc2RDS.R') # read the orginal fldas data and save to .RDS file.
source('Rfunction/NLDAS_RDS2csv.R') # read the RDS above, to save as .csv file.
}else{
stop(paste('WRONG LDAS CODE: ', xfg$iforcing))
}

View File

@ -0,0 +1,19 @@
# library(rgdal)
# library(raster)
# library(rgeos)
# library(rSHUD)
x=readOGR(xfg$fsp.forc)
# y=readOGR(
ysp=spTransform(y, crs(x))
e1 = extent(ysp)
e2 = extent(x)
rw = c(min(e1[1], e2[1]),
max(e1[2], e2[2]),
min(e1[3], e2[3]),
max(e1[4], e2[4]) ) + c(-1, 1, -1, 1)
vx=voronoipolygons(x, rw=rw, crs=crs(x))
plot(vx); plot(add=T, x); plot(add=T, ysp)
vx@data=data.frame(vx@data, 'ID'=x@data$ID)
writeshape(vx, '/Users/leleshu/Dropbox/Project/2020_Heihe/shud/Data/Forcing')

View File

@ -0,0 +1,3 @@
spl0 = readOGR(pd.pcs$lake)
sp.lake = gSimplify(spl0, bm.para$tol.wb)

View File

@ -0,0 +1,65 @@
# this script for HWSD data only.
cut_HWSD <- function(fn.r,
fn.buf,
fn.dbf,
fout.mask,
fa.soil,
fa.geol,
crs.out){
crs.gcs = sp::CRS('+init=epsg:4326')
# cmd=paste('gdalwarp -overwrite -cutline',
# fn.buf,
# '-dstnodata -9999',
# '-s_srs', paste0("'", as.character(crs.gcs), "'"),
# '-t_srs', paste0("'", as.character(crs.out), "'"),
# '-crop_to_cutline -of GTiff ',
# fn.r, fout.mask)
# message(cmd)
# system(cmd)
fun.gdalcut(f.in = fn.r, f.mask = fn.buf, f.out = fout.mask,
s_srs = crs.gcs, t_srs = crs.out)
r = raster::raster(fout.mask)
ur=sort(raster::unique(r))
x = foreign::read.dbf(fn.dbf)
cn = c('SILT', 'CLAY', 'OC', 'BULK_DEN')
cn.t = paste0('T_', cn )
cn.s=paste0('S_', cn )
idx = x[, 1] %in% ur
y.soil = x[idx, c('ID', cn.t)]
y.geol = x[idx, c('ID', cn.s)]
fn1 = fn2 = fout.mask
raster::extension(fn1) ='.Soil.csv'
raster::extension(fn2) ='.Geol.csv'
write.table(y.soil, file = fn1, quote = FALSE, row.names = FALSE, col.names = TRUE)
write.table(y.geol, file = fn2, quote = FALSE, row.names = FALSE, col.names = TRUE)
# foreign::write.dbf(y.geol, file = fn2)
# write.table(y, quote = FALSE, row.names = FALSE, col.names = TRUE)
return(list('Soil'=y.soil, 'Geol'=y.geol))
}
indir = xfg$dir$soil
outdir = xfg$dir$predata
fn.buf = pd.gcs$wbd.buf
fn.r = file.path(indir, 'hwsd.bil')
fn.dbf = file.path(indir, 'hwsd.dbf')
fout.mask = file.path(xfg$dir$predata, 'hwsd.tif')
fa.soil = file.path(xfg$dir$predata, 'hwsd.Soil.csv')
fa.geol = file.path(xfg$dir$predata, 'hwsd.Geol.csv')
tmp = cut_HWSD(fn.r, fn.buf, fn.dbf,
fout.mask, fa.soil, fa.geol,
crs.out = xfg$crs.pcs)
xfg = c(xfg,
list(fn.soil = fout.mask,
fn.geol = fout.mask,
fa.soil = fa.soil,
fa.geol = fa.geol) )
dat.soil = fun.Soil_Geol(xfg$fn.soil, xfg$fa.soil, outdir = xfg$dir$predata, TOP = TRUE)
dat.geol = fun.Soil_Geol(xfg$fn.geol, xfg$fa.geol, outdir = xfg$dir$predata, TOP = FALSE)

View File

@ -0,0 +1,55 @@
# this script for HWSD data only.
cut_HWSD <- function(fn.r,
fn.buf,
fn.dbf,
fout.mask,
fa.soil,
fa.geol,
crs.out,
crs.gcs){
fun.gdalcut(f.in = fn.r, f.mask = fn.buf, f.out = fout.mask, s_srs = crs.gcs, t_srs = crs.out)
r = raster::raster(fout.mask)
ur = sort(raster::unique(r))
x = foreign::read.dbf(fn.dbf)
cn = c('SILT', 'CLAY', 'OC', 'BULK_DEN')
cn.t = paste0('T_', cn )
cn.s=paste0('S_', cn )
idx = x[, 1] %in% ur
y.soil = x[idx, c('ID', cn.t)]
y.geol = x[idx, c('ID', cn.s)]
fn1 = fn2 = fout.mask
raster::extension(fn1) ='.Soil.csv'
raster::extension(fn2) ='.Geol.csv'
write.table(y.soil, file = fn1, quote = FALSE, row.names = FALSE, col.names = TRUE)
write.table(y.geol, file = fn2, quote = FALSE, row.names = FALSE, col.names = TRUE)
# foreign::write.dbf(y.geol, file = fn2)
# write.table(y, quote = FALSE, row.names = FALSE, col.names = TRUE)
return(list('Soil'=y.soil, 'Geol'=y.geol))
}
fun.soil.hwsd <-function(xfg){
indir = xfg$dir$soil
outdir = xfg$dir$predata
fn.buf = xfg$pd.gcs$wbd.buf
fn.r = file.path(indir, 'hwsd.bil')
fn.dbf = file.path(indir, 'hwsd.dbf')
fout.mask = file.path(xfg$dir$predata, 'hwsd.tif')
fa.soil = file.path(xfg$dir$predata, 'hwsd.Soil.csv')
fa.geol = file.path(xfg$dir$predata, 'hwsd.Geol.csv')
tmp = cut_HWSD(fn.r, fn.buf, fn.dbf, fout.mask, fa.soil, fa.geol, crs.out = xfg$crs.pcs, crs.gcs = xfg$crs.gcs)
xfg = c(xfg,
list(fn.soil = fout.mask,
fn.geol = fout.mask,
fa.soil = fa.soil,
fa.geol = fa.geol) )
dat.soil = fun.Soil_Geol(xfg=xfg, TOP = TRUE)
dat.geol = fun.Soil_Geol(xfg=xfg, TOP = FALSE)
return(xfg)
}

View File

@ -0,0 +1 @@

Binary file not shown.

Binary file not shown.

Binary file not shown.
1 ����Mac OS X ���� ���2��°�����â������������������������������������ATTR6o.��â���˜���������������������˜�����com.dropbox.attrs����
2 
3 ž;ä¼�™�����J�¡�Ô†���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������This resource fork intentionally left blank �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ÿÿ

View File

@ -0,0 +1,18 @@
0 186 248 254 255 Water
1 20 103 12 256 Evergreen Needle leaf Forest
2 85 168 89 257 Evergreen Broadleaf Forest
3 127 208 31 258 Deciduous Needle leaf Forest
4 115 234 105 259 Deciduous Broadleaf Forest
5 79 205 136 260 Mixed Forests
6 211 115 121 261 Closed Shrublands
7 250 236 165 262 Open Shrublands
8 184 234 142 263 Woody Savannas
9 248 234 44 264 Savannas
10 245 194 108 265 Grasslands
11 66 135 206 266 Permanent Wetland
12 251 255 45 267 Croplands
13 240 0 26 268 Urban and Built-Up
14 142 144 23 269 Cropland/Natural Vegetation Mosaic
15 251 220 212 270 Snow and Ice
16 189 189 189 271 Barren or Sparsely Vegetated

View File

@ -0,0 +1,19 @@
17 6.000
INDEX ALBEDO VEGFRAC ROUGH RZD SOILDGRD IMPAF remark
0 0.080 0.000 0.020 0.000 0.000 0.000 Water
1 0.140 0.800 0.070 0.600 0.000 0.000 Evergreen Needle leaf Forest
2 0.100 0.900 0.070 0.600 0.000 0.000 Evergreen Broadleaf Forest
3 0.140 0.800 0.070 0.600 0.000 0.000 Deciduous Needle leaf Forest
4 0.120 0.800 0.070 0.600 0.000 0.000 Deciduous Broadleaf Forest
5 0.110 0.700 0.060 0.600 0.000 0.000 Mixed Forests
6 0.120 0.700 0.060 0.000 0.000 0.000 Closed Shrublands
7 0.180 0.500 0.050 0.400 0.000 0.000 Open Shrublands
8 0.100 0.625 0.045 0.400 0.000 0.000 Woody Savannas
9 0.150 0.218 0.045 0.400 0.000 0.000 Savannas
10 0.150 0.726 0.040 0.400 0.000 0.000 Grasslands
11 0.100 0.200 0.035 0.000 0.000 0.000 Permanent Wetland
12 0.250 0.835 0.040 0.400 0.500 0.000 Croplands
13 0.246 0.200 0.010 0.050 0.900 0.900 Urban and Built-Up
14 0.200 0.835 0.040 0.400 0.500 0.000 Cropland/Natural Vegetation Mosaic
15 0.650 0.000 0.020 0.000 0.000 0.500 Snow and Ice
16 0.300 0.010 0.035 0.050 0.600 0.000 Barren or Sparsely Vegetated
1 17 6.000
2 INDEX ALBEDO VEGFRAC ROUGH RZD SOILDGRD IMPAF remark
3 0 0.080 0.000 0.020 0.000 0.000 0.000 Water
4 1 0.140 0.800 0.070 0.600 0.000 0.000 Evergreen Needle leaf Forest
5 2 0.100 0.900 0.070 0.600 0.000 0.000 Evergreen Broadleaf Forest
6 3 0.140 0.800 0.070 0.600 0.000 0.000 Deciduous Needle leaf Forest
7 4 0.120 0.800 0.070 0.600 0.000 0.000 Deciduous Broadleaf Forest
8 5 0.110 0.700 0.060 0.600 0.000 0.000 Mixed Forests
9 6 0.120 0.700 0.060 0.000 0.000 0.000 Closed Shrublands
10 7 0.180 0.500 0.050 0.400 0.000 0.000 Open Shrublands
11 8 0.100 0.625 0.045 0.400 0.000 0.000 Woody Savannas
12 9 0.150 0.218 0.045 0.400 0.000 0.000 Savannas
13 10 0.150 0.726 0.040 0.400 0.000 0.000 Grasslands
14 11 0.100 0.200 0.035 0.000 0.000 0.000 Permanent Wetland
15 12 0.250 0.835 0.040 0.400 0.500 0.000 Croplands
16 13 0.246 0.200 0.010 0.050 0.900 0.900 Urban and Built-Up
17 14 0.200 0.835 0.040 0.400 0.500 0.000 Cropland/Natural Vegetation Mosaic
18 15 0.650 0.000 0.020 0.000 0.000 0.500 Snow and Ice
19 16 0.300 0.010 0.035 0.050 0.600 0.000 Barren or Sparsely Vegetated

View File

@ -0,0 +1,21 @@
INDEX LAIMAX RMIN RSREF ALBEDO VEGFRAC ROUGH RZD SOILDGRD IMPAF
11 0.8540044 0.002011668 7861966 0.1617001 0.0799863 0.037 0 0 0
12 3.416018 0.002023736 12613991 0.1426286 0.0799863 0.045 0 0 0
21 4.997306 0.001886202 8555289 0.2610298 0.741792 0.012 0.19 0.58 0.54
22 4.925537 0.001803889 8422173 0.2506489 0.741792 0.022 0.085 0.58 0.72
23 4.997306 0.001886202 8555289 0.2610298 0.741792 0.012 0.19 0.58 0.54
24 4.925537 0.001803889 8422173 0.2506489 0.741792 0.022 0.085 0.58 0.72
31 0.1175883 0.002061292 12710286 0.2441793 0.0892185 0.036 0.19 0.36 0
41 6.2166 0.002013886 6462902 0.241202 0.792552 0.058 0.58 0.04 0
42 5.0835 0.001874998 8521377 0.239257 0.882552 0.068 0.52 0.04 0
43 7.2126 0.002013886 4951408 0.211052 0.788052 0.052 0.58 0.04 0
51 1.528394 0.001941826 9920107 0.2740451 0.2689095 0.045 0.4 0.04 0
52 3.444959 0.002013886 10669047 0.2534286 0.6350565 0.043 0.4 0.04 0
71 4.3039 0.002002312 11784039 0.2684654 0.660457 0.040 0.26 0.3 0
72 2.8696 0.001921294 9123698 0.282433 0.660457 0.038 0.365 0.3 0
73 4.3039 0.002002312 11784039 0.2684654 0.660457 0.040 0.26 0.3 0
74 2.8696 0.001921294 9123698 0.282433 0.660457 0.038 0.365 0.3 0
81 4.782 0.00179886 8640000 0.2632525 0.8243818 0.040 0.4 0.34 0
82 2.8696 0.001422424 9123698 0.2481395 0.7593188 0.038 0.365 0.54 0
90 2.298238 0.00202546 12573771 0.2094803 0.5625045 0.044 0.24 0 0
95 2.8692 0.001921294 9123800 0.272718 0.652968 0.038 0.36 0.06 0
1 INDEX LAIMAX RMIN RSREF ALBEDO VEGFRAC ROUGH RZD SOILDGRD IMPAF
2 11 0.8540044 0.002011668 7861966 0.1617001 0.0799863 0.037 0 0 0
3 12 3.416018 0.002023736 12613991 0.1426286 0.0799863 0.045 0 0 0
4 21 4.997306 0.001886202 8555289 0.2610298 0.741792 0.012 0.19 0.58 0.54
5 22 4.925537 0.001803889 8422173 0.2506489 0.741792 0.022 0.085 0.58 0.72
6 23 4.997306 0.001886202 8555289 0.2610298 0.741792 0.012 0.19 0.58 0.54
7 24 4.925537 0.001803889 8422173 0.2506489 0.741792 0.022 0.085 0.58 0.72
8 31 0.1175883 0.002061292 12710286 0.2441793 0.0892185 0.036 0.19 0.36 0
9 41 6.2166 0.002013886 6462902 0.241202 0.792552 0.058 0.58 0.04 0
10 42 5.0835 0.001874998 8521377 0.239257 0.882552 0.068 0.52 0.04 0
11 43 7.2126 0.002013886 4951408 0.211052 0.788052 0.052 0.58 0.04 0
12 51 1.528394 0.001941826 9920107 0.2740451 0.2689095 0.045 0.4 0.04 0
13 52 3.444959 0.002013886 10669047 0.2534286 0.6350565 0.043 0.4 0.04 0
14 71 4.3039 0.002002312 11784039 0.2684654 0.660457 0.040 0.26 0.3 0
15 72 2.8696 0.001921294 9123698 0.282433 0.660457 0.038 0.365 0.3 0
16 73 4.3039 0.002002312 11784039 0.2684654 0.660457 0.040 0.26 0.3 0
17 74 2.8696 0.001921294 9123698 0.282433 0.660457 0.038 0.365 0.3 0
18 81 4.782 0.00179886 8640000 0.2632525 0.8243818 0.040 0.4 0.34 0
19 82 2.8696 0.001422424 9123698 0.2481395 0.7593188 0.038 0.365 0.54 0
20 90 2.298238 0.00202546 12573771 0.2094803 0.5625045 0.044 0.24 0 0
21 95 2.8692 0.001921294 9123800 0.272718 0.652968 0.038 0.36 0.06 0

142
GO.R Normal file
View File

@ -0,0 +1,142 @@
#' ===============================================================
#' Author: Lele Shu <shulele@lzb.ac.cn>
#' Date: 2023.05.05
#' Function: The core function of the GHDC
#' ===============================================================
#'
rm(list=ls())
source('getReady.R')
debug=FALSE
# debug=TRUE
CV=list()
# system('cp -r bak/* data/')
CV$serv = load.conf(file = file.path('script', paste0('service_', Sys.info()['nodename'], '.cfg.txt') ) )
CV$para = list(projname = '', Area = -999, distBuff = -999, NumCellMin = -999,
dataonly = FALSE, # prepare data only.
gcs = sp::CRS('+init=epsg:4326'), pcs='')
CV$figtype='cairo'
caller = 'GO.R'
dir.out <- file.path(CV$serv$DIR.WORKING, 'rProcessing')
dir.log <- file.path(CV$serv$DIR.WORKING, 'rlog')
tmp = lapply(list(dir.out, dir.log), dir.create, showWarnings = FALSE, recursive = TRUE)
# LOGFILE = file.path(dir.log, paste0(format(Sys.time(), '%Y%m%d%H%M%S' ), '.log'))
LOGFILE = file.path(dir.log, paste0(format(Sys.time(), '%Y%m%d' ), '.log'))
assign('LOGFILE',LOGFILE, envir = .GlobalEnv)
if(!file.exists(LOGFILE)){
write('', file=LOGFILE)
}
writelog(LOGFILE, caller = caller)
writelog("======== RUNING ==========", caller = caller)
task.fns = list.files(path = CV$serv$TARGET.DIR, pattern = glob2rx('*.txt'), full.names = TRUE)
task.N = length(task.fns)
if(task.N <= 0){
writelog(paste('Empty dirs. Nothing to do. ( path = ', normalizePath(CV$serv$TARGET.DIR), ')'), caller = caller)
stop()
}
writelog(paste(task.N, 'task(s) in', CV$serv$TARGET.DIR), caller = caller)
itask = 1
# for(itask in 1:task.N){
for(itask in 1:task.N){
task.fn = task.fns[itask]
task.backup(task.fn, CV)
LOGFILE = file.path(dir.log, paste0(format(Sys.time(), '%Y%m%d' ), '.log'))
assign('LOGFILE',LOGFILE, envir = .GlobalEnv)
writelog(paste('===================================='), caller = caller)
writelog(paste('\t', itask, '/', task.N, 'task \t', task.fn), caller = caller)
theTask = readLines(task.fn)
theTask = gsub('/home/wwwroot/r', '.', theTask)
writelog(paste('\t', itask, '/', task.N, 'task \t', theTask), caller = caller)
writelog(paste('\t++++++START++++++:', theTask), caller = caller)
theTask = normalizePath(theTask)
CV=configure(CV, theTask)
# BACKUP the input.zip, input.json to UserData.
fn.input = list.files(path=theTask, pattern = glob2rx('input*'), full.names = TRUE, recursive = TRUE)
file.copy(from = fn.input, to = CV$dirs$userdata, overwrite = TRUE, recursive = TRUE)
file.copy(from = task.fn, to = file.path(CV$dirs$prj, basename(task.fn)), overwrite = TRUE, recursive = TRUE)
#————— Clean the Task file. —————————————————————————————————————
writelog(paste('REMOVING task file:', task.fn), caller = caller)
if(!debug){
unlink(task.fn, recursive = TRUE, force = TRUE, expand = TRUE)
}
#——————————————————————————————————————————
##### 1. Task.Ready.....
writemessage(paste0('Trying to run task.ready(CV)'), caller = caller, CV$task.log)
iflag=try(task.ready(CV),TRUE)
if( class(iflag)=="try-error" ) {
writemessage(paste0('ERROR: something wrong in task.ready(CV). '), caller = caller, CV$task.log)
warning('Task stop at task.ready(CV).')
print(iflag)
task.clean(task.fn); next
} else {
CV = iflag
writemessage(paste0('Finish the task.ready(CV). '), caller = caller, CV$task.log)
message('Step of task.ready finished. \n\n')
}
###### 2. Extract ETV
writemessage(paste0('Trying to run ETV.Delineation(CV)'), caller = caller, CV$task.log)
iflag=try(ETV.Delineation(CV),TRUE)
if( class(iflag)=="try-error" ) {
writemessage(paste0('ERROR: something wrong in ETV.Delineation(CV). '), caller = caller, CV$task.log)
warning('Task stop at ETV.Delineation(CV).')
print(iflag)
task.clean(task.fn); next
} else {
writemessage(paste0('Finish the ETV.Delineation(CV). '), caller = caller, CV$task.log)
message('Step of ETV.Delineation finished. \n\n')}
writemessage(paste0('Trying to run ExtractETV(CV)'), caller = caller, CV$task.log)
iflag=try(ExtractETV(CV),TRUE)
if( class(iflag)=="try-error" ) {
writemessage(paste0('ERROR: something wrong in ExtractETV(CV). '), caller = caller, CV$task.log)
warning('Task stop at ExtractETV(CV).')
print(iflag)
task.clean(task.fn); next
} else {
writemessage(paste0('Finish the ExtractETV(CV). '), caller = caller, CV$task.log)
message('Step of ExtractETV finished. \n\n')}
###### 3. Model Deployment
iflag=try(model.Deploy(CV),TRUE)
writemessage(paste0('Trying to run model.Deploy(CV)'), caller = caller, CV$task.log)
if( class(iflag)=="try-error" ) {
writemessage(paste0('ERROR: something wrong in model.Deploy(CV). '), caller = caller, CV$task.log)
warning('Task stop at model.Deploy(CV).')
print(iflag)
task.clean(task.fn); next
} else {
writemessage(paste0('Finish the model.Deploy(CV). '), caller = caller, CV$task.log)
message('Step of model.Deploy finished. \n\n') }
###### 4. Task done. Data packaging. update info.json/citys.js =====
iflag=try(task.done(CV),TRUE)
writemessage(paste0('Trying to run task.done(CV)'), caller = caller, CV$task.log)
if( class(iflag)=="try-error" ) {
writemessage(paste0('ERROR: something wrong in task.done(CV). '), caller = caller, CV$task.log)
warning('Task stop at task.done(CV)')
task.clean(task.fn);
# next
} else {
writemessage(paste0('Finish the task.done(CV). '), caller = caller, CV$task.log)
message('Step of task.done finished. \n\n')
}
writemessage(paste0('======== END ========'), caller = caller, CV$task.log)
writelog(paste('\n'), caller = caller)
}

123
GO.R.backup Normal file
View File

@ -0,0 +1,123 @@
#' ===============================================================
#' Author: Lele Shu <shulele@lzb.ac.cn>
#' Date: 2023.05.05
#' Function: The core function of the GHDC
#' ===============================================================
#'
rm(list=ls())
source('getReady.R')
debug=FALSE
debug=TRUE
CV=list()
# system('cp -r bak/* data/')
CV$serv = load.conf(file = file.path('script', paste0('service_', Sys.info()['nodename'], '.cfg.txt') ) )
CV$para = list(projname = '', Area = -999, distBuff = -999, NumCellMin = -999,
dataonly = FALSE, # prepare data only.
gcs = sp::CRS('+init=epsg:4326'), pcs='')
CV$figtype='cairo'
caller = 'GO.R'
dir.out <- file.path(CV$serv$DIR.WORKING, 'rProcessing')
dir.log <- file.path(CV$serv$DIR.WORKING, 'rlog')
tmp = lapply(list(dir.out, dir.log), dir.create, showWarnings = FALSE, recursive = TRUE)
# LOGFILE = file.path(dir.log, paste0(format(Sys.time(), '%Y%m%d%H%M%S' ), '.log'))
LOGFILE = file.path(dir.log, paste0(format(Sys.time(), '%Y%m%d' ), '.log'))
assign('LOGFILE',LOGFILE, envir = .GlobalEnv)
if(!file.exists(LOGFILE)){
write('', file=LOGFILE)
}
writelog(LOGFILE, caller = caller)
writelog("======== RUNING ==========", caller = caller)
args <- commandArgs(trailingOnly = TRUE)
if (length(args) < 1) {
writelog('Empty args. Nothing to do. ', caller = caller)
stop()
}
task.fn <- args[1]
writelog(paste('starting task: ', task.fn), caller = caller)
task.backup(task.fn, CV)
LOGFILE = file.path(dir.log, paste0(format(Sys.time(), '%Y%m%d' ), '.log'))
assign('LOGFILE',LOGFILE, envir = .GlobalEnv)
writelog(paste('===================================='), caller = caller)
theTask = gsub('/home/wwwroot/r', '.', task.fn)
writelog(paste('\t++++++START++++++:', theTask), caller = caller)
theTask = normalizePath(theTask)
CV=configure(CV, theTask)
# BACKUP the input.zip, input.json to UserData.
fn.input = list.files(path=theTask, pattern = glob2rx('input*'), full.names = TRUE, recursive = TRUE)
file.copy(from = fn.input, to = CV$dirs$userdata, overwrite = TRUE, recursive = TRUE)
##### 1. Task.Ready.....
writemessage(paste0('Trying to run task.ready(CV)'), caller = caller, CV$task.log)
iflag=try(task.ready(CV),TRUE)
if( class(iflag)=="try-error" ) {
writemessage(paste0('ERROR: something wrong in task.ready(CV). '), caller = caller, CV$task.log)
warning('Task stop at task.ready(CV).')
print(iflag)
} else {
CV = iflag
writemessage(paste0('Finish the task.ready(CV). '), caller = caller, CV$task.log)
message('Step of task.ready finished. \n\n')
}
###### 2. Extract ETV
writemessage(paste0('Trying to run ETV.Delineation(CV)'), caller = caller, CV$task.log)
iflag=try(ETV.Delineation(CV),TRUE)
if( class(iflag)=="try-error" ) {
writemessage(paste0('ERROR: something wrong in ETV.Delineation(CV). '), caller = caller, CV$task.log)
warning('Task stop at ETV.Delineation(CV).')
print(iflag)
} else {
writemessage(paste0('Finish the ETV.Delineation(CV). '), caller = caller, CV$task.log)
message('Step of ETV.Delineation finished. \n\n')}
writemessage(paste0('Trying to run ExtractETV(CV)'), caller = caller, CV$task.log)
iflag=try(ExtractETV(CV),TRUE)
if( class(iflag)=="try-error" ) {
writemessage(paste0('ERROR: something wrong in ExtractETV(CV). '), caller = caller, CV$task.log)
warning('Task stop at ExtractETV(CV).')
print(iflag)
} else {
writemessage(paste0('Finish the ExtractETV(CV). '), caller = caller, CV$task.log)
message('Step of ExtractETV finished. \n\n')}
###### 3. Model Deployment
iflag=try(model.Deploy(CV),TRUE)
writemessage(paste0('Trying to run model.Deploy(CV)'), caller = caller, CV$task.log)
if( class(iflag)=="try-error" ) {
writemessage(paste0('ERROR: something wrong in model.Deploy(CV). '), caller = caller, CV$task.log)
warning('Task stop at model.Deploy(CV).')
print(iflag)
} else {
writemessage(paste0('Finish the model.Deploy(CV). '), caller = caller, CV$task.log)
message('Step of model.Deploy finished. \n\n') }
###### 4. Task done. Data packaging. update info.json/citys.js =====
iflag=try(task.done(CV),TRUE)
writemessage(paste0('Trying to run task.done(CV)'), caller = caller, CV$task.log)
if( class(iflag)=="try-error" ) {
writemessage(paste0('ERROR: something wrong in task.done(CV). '), caller = caller, CV$task.log)
warning('Task stop at task.done(CV)')
# next
} else {
writemessage(paste0('Finish the task.done(CV). '), caller = caller, CV$task.log)
message('Step of task.done finished. \n\n')
}
writemessage(paste0('======== END ========'), caller = caller, CV$task.log)
writelog(paste('\n'), caller = caller)

21
LICENSE Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2023 Simulator of Hydrological Unstructured Domains
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

BIN
Markdown/Aster_GDEM.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 454 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 115 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 MiB

91
Markdown/ReadMe_cn.Rmd Normal file
View File

@ -0,0 +1,91 @@
---
title: "全球水文数据云"
author: 舒乐乐 [shulele@lzb.ac.cn](mailto:shulele@lzb.ac.cn)
date: 2022/10/05
output:
html_document:
toc: true
theme: united
df_print: paged
---
![](../static/res/logo_cn.png)
## 数据平台介绍
全球水文数据云(Global Hydrologic Data Cloud, GHDC)是一个快速获取水文建模基础数据实现快速模型部署的云平台可实现全球任意流域、任意大陆、任意国家范围快速水文模型部署。用户仅需提供欲建模的流域边界GHDC即可自动化完成数据前处理不仅生成建模所需要的基础数据高程、土地利用、土壤质地、水系等并能够制备SHUD(Simulator of Hydrologic Unstructured Domains)模型所需要的输入数据。用户可根据需要进行水文模拟、空间分析、数据挖掘等工作。
![GHDC的工作流程](../static/res/GHDC_flow.png)
### 版权和权益
GHDC并不生成数据仅提供提供数据处理服务。数据版权和权益全部归属于原始数据的作者们。当前平台处理的数据全部为开放版权(Public Domains)的数据产品——允许数据处理、修改和重发布放弃数据版权权益。本平台不提供未使用开放版权的数据产品的数据处理。例如GLDAS, NLDAS和FLDAS数据都使用了开放版权本平台可提供数据处理服务但是CMFDCLDAS等再分析数据资料未使用开放版权因此本平台无法提供数据处理服务。 若用户需要CMFD等未开放版权的数据集的处理任务请联系网站作者[(shulele@lzb.ac.cn)](mailto:shulele@lzb.ac.cn)商讨。
### 原始数据源
当前可用数据见表:
| 数据分类 | 数据名称 | 数据属性 | 数据版权 | 数据源 |
|:---------|:---------|:---------|:---------|:---------|
| 高程 | ASTER GDEM | 全球 30m| Public Domain | |
| 土地利用 | USGS Land Cover | 全球 1km| Public Domain | |
| 土壤质地 | HWSD v1.0 | 全球 1km | Public Domain | |
| 气象再分析资料 | GLDAS | 全球 0.25度1950至今| Public Domain | |
| 气象再分析资料 | FLDAS | 全部部分区域 0.1度1979至今| Public Domain | |
| 气象再分析资料 | NLDAS | 美国 0.125度1979至今 | Public Domain | |
| 气象再分析资料 | CLDAS | 中国 0.125度 | **版权私有** | |
| 气象再分析资料 | CMFD | 中国 0.1度 | **版权私有** | |
| | | | | |
![ASTER Global DEM](../static/res/Aster_GDEM.png)
![GLDAS, FLDAS, NLDAS, NCA-LDAS覆盖范围](../static/res/ldas-domain.jpg)
## 如何获取数据
1. 提供流域边界文件格式为ESRI Shapefile。请将Shapefile包含的四个基本子文件(.shp, .shx, .dbf, .shx)打包为.zip文件并上传。
2. 提供模拟所需要的参数,包含项目名称、模拟年份、最小单元数,最大单元面积,含水层厚度等。
3. 填写邮箱地址,并提交任务。 请查看您的邮箱GHDC会发送一封邮件请点击邮箱内的确认链接。点击确认链接之后GHDC才会启动数据处理任务。
4. GHDC数据处理完成后会向您的邮箱再发送一封邮件包含数据下载链接。
5. 请通过数据下载链接下载处理好的数据。
6. 模拟愉快~~~
## 数据引用
每个使用本平台的数据服务的用户都需要给GHDC平台建设者、程序开发者、SHUD模型作者和原始数据作者足够的学术肯定因此**强烈建议您使用以下引用**。
- 数据服务和SHUD模型
- Shu, L., Ullrich, P. A., & Duffy, C. J. (2020). Simulator for Hydrologic Unstructured Domains (SHUD v1.0): numerical modeling of watershed hydrology with the finite volume method. Geoscientific Model Development, 13(6), 27432762. https://doi.org/10.5194/gmd-13-2743-2020
- Shu L.Chang Y.Wang J.et al. A brief review of numerical distributed hydrological model SHUDJ. Advances in Earth Science2022377680-691. DOI10.11867/j.issn.1001-8166.2022.025.
- NLDAS
- Cosgrove, B. A. (2003). Real-time and retrospective forcing in the North American Land Data Assimilation System (NLDAS) project. Journal of Geophysical Research, 108(D22), 8842. https://doi.org/10.1029/2002JD003118
- Landuse, USGS 0.5 km MODIS-based Global Land Cover Climatology
- Broxton, P.D., Zeng, X., Sulla-Menashe, D., Troch, P.A., 2014a: A Global Land Cover Climatology Using MODIS Data. J. Appl. Meteor. Climatol., 53, 1593-1605. doi: http://dx.doi.org/10.1175/JAMC-D-13-0270.1
## 致谢
本平台的开发受到多个机构的研究经费支持。
- 中国科学院率先行动“BR计划”数值方法水文模型
- 中国科学院寒旱区陆面过程与气候变化重点实验室CLM-SHUD耦合模型研发
- 青海省防灾减灾重点实验室开放基金项目:布哈河流域径流变化及水循环机理研究
- 国家冰川冻土沙漠科学数据中心:水文模型自动化建模系统研发
- 美国能源部(DOE) Model Integration through Knowledge-Rich Data and Process Composition
- 美国自然科学基金(NSE)Knowledge-Guided Machine Learning: A Framework to Accelerate Scientific Discovery
## 微信群
公众号二维码
![公众号](Figure/weixin_search.png)
使用微信扫描二维码添加管理员,可以加入微信群。
![拉群微信](Figure/shudxyz.jpeg)

1883
Markdown/ReadMe_cn.html Normal file

File diff suppressed because one or more lines are too long

85
Markdown/ReadMe_en.Rmd Normal file
View File

@ -0,0 +1,85 @@
---
title: "The Global Hydrologic Data Cloud (GHDC)"
author: Lele Shu [shulele@lzb.ac.cn](mailto:shulele@lzb.ac.cn)
date: 2022/10/05
output:
html_document:
toc: true
theme: united
df_print: paged
---
![](../static/res/logo_en.png)
## What is the GHDC
The Global Hydrologic Data Cloud (GHDC)is to provide a rapid and reproducible hydrological model development in any watershed, any continent, or any country. The users provide the watershed boundary, GHDC will do the data retrieve, subset clipping, reprojection, spatial-temporal data pre-processing, and so forth. Then, the user will receive a download link for the watershed.
### License
We do not produce data, but process data for modelers. So the license and right belong to original data creators. The current datasets support Public Domain, that allows reprocess and redistribute the data.
### Data Source
| Category | Data name | Feature | License | Data source |
|:------------------------|:----------------|:--------------------------|:--------------|:------------|
| Elevation | ASTER GDEM | Global 30m | Public Domain | |
| Landuse | USGS Land Cover | Global 1km | Public Domain | |
| Soil | HWSD v1.0 | Global 1km | Public Domain | |
| Reanalysis forcing data | GLDAS | Global 0.25deg, 1950- | Public Domain | |
| Reanalysis forcing data | FLDAS | Continental 0.1deg, 1979- | Public Domain | |
| Reanalysis forcing data | NLDAS | US 0.125deg, 1979- | Public Domain | |
| Reanalysis forcing data | CLDAS | China 0.125deg | **private** | |
| Reanalysis forcing data | CMFD | China 0.1deg | **private** | |
| | | | | |
![ASTER Global DEM](../static/res/Aster_GDEM.png)
![GLDAS, FLDAS, NLDAS, NCA-LDAS覆盖范围](../static/res/ldas-domain.jpg)
## How to require a data service
1. Provide the watershed boundary. The file is in ESRI Shapefile format. The shapefile (including the .shp, .dbf, .shx, .prj files) must be ziped in a .zip file, and uploaded to GHDC.
2. Fill the form of parameters.
3. Fill your email address, and submit your request.
4. Check you email and click the confirm link in the email from GHDC. After your confirmation, the GHDC starts data processing.
5. After GHDC data processing, you will received the second email, which includes a download link. Please download the data within 14 days.
6. Enjoy your data and modeling journey.
## References/citations
For giving right credits to the platform developers, model developers and data creators, we suggest our users strongly to add following citations into your future work.
- SHUD:
- Shu, L., Ullrich, P. A., & Duffy, C. J. (2020). Simulator for Hydrologic Unstructured Domains (SHUD v1.0): numerical modeling of watershed hydrology with the finite volume method. Geoscientific Model Development, 13(6), 2743--2762. <https://doi.org/10.5194/gmd-13-2743-2020>
- Shu L.,Chang Y.,Wang J.,et al. A brief review of numerical distributed hydrological model SHUDJ. Advances in Earth Science,2022,377: 680-691. DOI: 10.11867/j.issn.1001-8166.2022.025.
- NLDAS
- Cosgrove, B. A. (2003). Real-time and retrospective forcing in the North American Land Data Assimilation System (NLDAS) project. Journal of Geophysical Research, 108(D22), 8842. <https://doi.org/10.1029/2002JD003118>
- Landuse, USGS 0.5 km MODIS-based Global Land Cover Climatology
- Broxton, P.D., Zeng, X., Sulla-Menashe, D., Troch, P.A., 2014a: A Global Land Cover Climatology Using MODIS Data. J. Appl. Meteor. Climatol., 53, 1593-1605. doi: <http://dx.doi.org/10.1175/JAMC-D-13-0270.1>
## Acknowledge
Thanks to the funding supporters.
- Chinese Academy of Sciences, BR program: Numerical hydrological model development
- Key Laboratory of Land Surface Process and Climate Change in Cold and Arid Regions, Chinese Academy of Sciences: Coupled CLM-SHUD model development
- Qinghai Key Laboratory of Disaster Prevention: Streamflow change and hydrological mechanism in Buha River (Grant No. QFZ-2021-Z02).
- National Cryosphere Desert Data Center (NCDC) : Automatic hydrological model deployment system.
- Department of Energy (USA), Knowledge-Guided Machine Learning: A Framework to Accelerate Scientific Discovery
- National Science Fundation (USA), Model Integration through Knowledge-Rich Data and Process Composition
## Wechat Group
Scanning the QR code follows our Wechat official page.
![公众号](Figure/weixin_search.png)
You may scan the following QR code to add the admin, then join the Wechat group.
![拉群微信](Figure/shudxyz.jpeg)

445
Markdown/ReadMe_en.html Normal file

File diff suppressed because one or more lines are too long

27
Markdown/emailerror.md Normal file
View File

@ -0,0 +1,27 @@
尊敬的SHUD用户[emailaddress]
您好,感谢您使用水文云服务。
您的数据请求失败。具体失败原因请看本邮件末尾的说明。请您排除故障后,重新提交数据请求。
如果您还有更多疑问,请邮件联系( shulele@lzb.ac.cn )。
SHUD研究组( https://www.shud.xyz )
----------------------------------------------------
Dear SHUD-user[emailaddress],
Thanks for using Global Hydrologic Data Cloud (https://www.ghdc.ac.cn or https://shud.ncdc.ac.cn ).
You data request failed, unfortunately. The error information is following this email. Please resubmit your data request after issue-fixing.
If you have more questions or suggestions, please contact ( shulele@lzb.ac.cn ).
Yours sincerely,
SHUD group ( https://www.shud.xyz )
=================== Error information ===================

29
Markdown/emailout.md Normal file
View File

@ -0,0 +1,29 @@
尊敬的SHUD用户[emailaddress]
您好,感谢您使用水文云服务。
您从全球水文数据云(https://www.ghdc.ac.cn , 备用地址https://shud.ncdc.ac.cn )请求的数据已经处理完毕。您可以通过链接(dataurl)下载数据该数据临时存放时间为14天14天后数据链接将失效。
水文云服务并不生产数据,只通过公开数据集进行数据处理;感谢原数据的分享。现能够提供的数据都使用了开放版权(Public Domain)——不保留版权权益;版权开放给公共用途;允许对数据进行处理、分享、再发布。
**强烈建议所有数据用户遵守引用规范给予数据生产者和处理者充分的学术肯定各数据和程序的引用请参考数据包内文件Citation.bib**。
如果您对下载的数据有疑问或者对shuddata服务有建议请邮件联系( shulele@lzb.ac.cn )。
SHUD研究组( https://www.shud.xyz )
----------------------------------------------------
Dear SHUD-user[emailaddress],
Thanks for using Global Hydrologic Data Cloud (https://www.ghdc.ac.cn or https://shud.ncdc.ac.cn ).
The data you required via HCS is ready for download. Please download the data through (dataurl), **in 14 days**. After 14 days, the link will be invalid.
Our HCS does not produce any data but process and redistribute the public-accessible data. Original data producers share the raw data with Public Domain licenses, allowing editing, modification, and redistribution of the data. But, we suggest our data users give appropriate references/citations for each dataset. **The citation information of the data is saved in the file Citation.bib in the data folder downloaded.**
If you have more questions or suggestions, please contact ( shulele@lzb.ac.cn ).
Yours sincerely,
SHUD group( https://www.shud.xyz )

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,11 @@
当前上传的边界文件无法使用GDAL打开。
可能原因是1.非英文方式的文件名或文件夹名称2. 文件格式与GDAL不兼容3. 投影信息(.prj文件)缺失
流域边界必须为多边形的shapefile无法处理线条、点、或者栅格文件定义的流域边界。
并且,边界文件的投影信息(.prj文件)是合理的。
The uploaded boundary file cannot be open with GDAL.
Possible reasons are 1. non-English name of folder/files; 2. incompatibility
between input file and GDAL format; 3. Projection infomation (.prj file) is missing.
The watershed boundary file must be SpatialPolygon/SpatialPolygonDataFrame
(in shapefile format) with a valid projection. The PolyLine/Points shapefiles
or tiff format are not acceptable.

View File

@ -0,0 +1,6 @@
流域边界必须为多边形的shapefile无法处理线条、点、或者栅格文件定义的流域边界。
并且,边界文件的投影信息(.prj文件)是合理的。
The watershed boundary file must be SpatialPolygon/SpatialPolygonDataFrame
(in shapefile format) with a valid projection. The PolyLine/Points shapefiles
or tiff format are not acceptable.

BIN
Markdown/ldas-domain.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

Some files were not shown because too many files have changed in this diff Show More