diff --git a/README.md b/README.md index ef6fc54..f104e09 100644 --- a/README.md +++ b/README.md @@ -54,3 +54,50 @@ In Rstudio, the vignette may not be built per default. You will turn this on in ```{r} devtools::build_vignettes("rLPJGUESS") ``` +### Workflow when using the package: + +#### 1. Define a folder to run the simulations, e.g. +```{r} +mainDir <- file.path(getwd(), "LPJrunTest") +``` +and place the binary (exectuable) of LPJ-GUESS into this folder (the binary does not come with this package). + +#### 2. Provide a valid instruction file that you usually use to define the set-up of LPJ-GUESS to the InferParameterAndDesignList function. +```{r} +defaultparameters <- InferParameterAndDesignList(list(main = paste0(mainDir,"LPJ_instruction_file.ins")), + NameMainFile = "main.ins", NamePftFile = "pft.ins", + vectorvaluedparams = c("rootdist","eps_mon", + "storfrac_mon","photo", + "fertdates","fertrate")) +``` + +This function extracts the parameters, design and driver-files used to run LPJ-GUESS and splits the instruction into a main file containing inputs and a PFT file, which has all the settings. Because we cannot handle vectorvalued parameters at the moment, they have to be provided to this function as well. + +#### 3. Call the adjust template function, which rewrites the templates to new destinations (IMPORTANT: the files need to be in the same directory as the binary, here: LPJrunTest) +```{r} +AdjustTemplates(defaultparameters = defaultparameters$defaultparameters, + defaultlist = defaultparameters$defaultlist, + MainTemplateDestination = "./LPJrunTest/main_new.ins", + PftTemplateDestination = "./LPJrunTest/pft_new.ins", + NameMainFile = "main.ins", NamePftFile = "pft.ins") +``` + +#### 4. Generate a set of parameters for the species (GetRunAbleParameters), we want to simulate, here Fagus sylvatica (Fag_syl): +```{r} +parameters <- GetRunAbleParameters(defaultparameters = defaultparameters, PFTs = c("Fag_syl")) +``` +#### 5. Change some of these parameters and provide it as matrix with a set of parameters per row and parameter names as colnames (here: new parameter matrix is called parameters_new) + +#### 6. Define the settings and input files, we want to use as input for the simulations in a list (the required files depend on the LPJ-Version, here: the list is called LPJsettings) + +#### 7. Define the setup (i.e. sequential, parallel, which kind of parallelisation, here a SOCK cluster with numCores cores) +```{r} +LPJsetup <- setupLPJParallel(numCores = numCores, clusterType = "SOCK", + mainDir = mainDir) +``` + +#### 8. Run the simulations with the model +```{r} +results <- runLPJ(x = LPJsetup, parameterList = parameters_new, + typeList = typeList, settings = LPJsettings) +``` diff --git a/rLPJGUESS/R/AdjustTemplates.R b/rLPJGUESS/R/AdjustTemplates.R new file mode 100644 index 0000000..d4e9918 --- /dev/null +++ b/rLPJGUESS/R/AdjustTemplates.R @@ -0,0 +1,106 @@ +#' @title This function writes the two main templates in the correct order +#' @description This function takes the defaultparameters and a defaultlist of +#' of files and writes the main and pft instruction file into the defined destinations +#' which are MainTemplateDestination and PftTemplateDestination +#' @param defaultobjects R object produced by \code{\link{InferParameterAndDesignList}}. Its first list contains the data frame with default parameters extracted from the instruction files +#' @param defaultlist a matrix with the design parameters which should be used +#' in rlpjguess runs +#' @param MainTemplateDestination a character string indicating the location to which +#' one should write the main file +#' @param PftTemplateDestination a character string indicating the location to which +#' one should write the pft file +#' @param NameMainFile a character string with the name of the main file +#' which was produced with the default parameters before +#' @param NamePftFile a character string with the name of the pft file +#' which was produced with the default parameters before +#' @return writes the two files which serve as templates +#' @author Johannes Oberpriller +#' @export + + +AdjustTemplates <- function(defaultobjects, + MainTemplateDestination = NULL, + PftTemplateDestination = NULL, + NameMainFile = NULL, + NamePftFile = NULL){ + + + + # check if there is a destination to save the main template + + if(is.null(MainTemplateDestination)){ + stop("Please provide a destination for the Main template") + } + + #check if there is a destination to save the pft/species template + + else if(is.null(PftTemplateDestination)){ + stop("Please provide a destination for the PFT template") + } + + else if(is.null(NameMainFile)){ + stop("Please provide a valid main template") + } + + else if(is.null(NamePftFile)){ + stop("Please provide a valid pft template") + } + + + ## define the thinks used here + + defaultparameters = defaultobjects$defaultparameters + defaultlist = defaultobjects$defaultlist + + ## read in text and adjust the templates + + + tx <- readLines(NamePftFile) + for(i in 1:nrow(defaultparameters)){ + if(defaultparameters[i,"group"] == "run"){ + tx <- gsub(paste0(defaultparameters[i,"name"]," "), + paste0(defaultparameters[i,"name"]," ", + defaultparameters[i,"rlpjname"]," !"), x = tx) + } + else{ + linenumber_group = grep(paste0("group \"",defaultparameters[i,"group"],"\""), + x = tx, fixed = T) + linenumber_pft = grep(paste0("pft \"",defaultparameters[i,"group"],"\""), + x = tx, fixed = T) + linenumber_st = grep(paste0("st \"",defaultparameters[i,"group"],"\""), + x = tx, fixed = T) + linenumber = c(linenumber_group, linenumber_pft, linenumber_st) + for(j in 1:length(linenumber)){ + endofgroup = grep(")", x = substring(tx[(linenumber[j]+1):length(tx)],1,1))[1] + exchange = grep(paste0(as.character(defaultparameters[i,"name"])), + x = tx[(linenumber[j]+1):(linenumber[j]+1+endofgroup+1)], fixed = T) + tx[(linenumber[j])+exchange] <- gsub(paste0(defaultparameters[i,"name"]," "), + paste0(defaultparameters[i,"name"]," ", + defaultparameters[i,"rlpjname"]," ","!"), + x = tx[(linenumber[j])+exchange]) + } + } + } + + + + writeLines(tx, con = PftTemplateDestination) + + + files <- defaultlist + #change the actual file names with the rlpjnames + + maintemplate <- readLines(NameMainFile) + + for(i in 1:nrow(files)){ + maintemplate <- gsub(paste0("\"",files[i,"name"],"\""), + paste0("\"",files[i,"name"],"\"", + " ","(str ", "\"_",files[i,"name"],"_\")","!"), + x = maintemplate) + } + + #writes the Template to the given MainTemplateDestination + writeLines(maintemplate, con = MainTemplateDestination) + + +} diff --git a/rLPJGUESS/R/GetRunAbleParameters.R b/rLPJGUESS/R/GetRunAbleParameters.R new file mode 100644 index 0000000..3f1b32b --- /dev/null +++ b/rLPJGUESS/R/GetRunAbleParameters.R @@ -0,0 +1,49 @@ +#' @title A function to separate all default values into parameters, design parameters and input files. +#' @description This function organizes the parameters extracted from the instruction files in order to run the model. +#' @param defaultobjects R object produced by \code{\link{InferParameterAndDesignList}}. Its first list contains the data frame with default parameters extracted from the instruction files +#' @param PFTs the PFTs or species, which should be included into the model run +#' @keywords rLPJGUESS +#' @author Johannes Oberpriller +#' @return list consisting of a data.frame for runable parameters, a data.frame for design parameters and a data.frame for the default input files. +#' @export + +GetRunAbleParameters <- function(defaultobjects,PFTs){ + + + LPJparameters_PFT <- matrix(defaultobjects$defaultparameters[,4]) + rownames(LPJparameters_PFT) = defaultobjects$defaultparameters[,3] + LPJrunParameters = matrix(LPJparameters_PFT[-which(substr(rownames(LPJparameters_PFT),1,3)== "run"),]) + rownames(LPJrunParameters) = rownames(LPJparameters_PFT)[-which(substr(rownames(LPJparameters_PFT),1,3)== "run")] + + designLPJ = LPJparameters_PFT[which(substr(rownames(LPJparameters_PFT),1,3)== "run"),] + designLPJ = designLPJ[-which(names(designLPJ) == "run_outputdirectory")] + + lpjvalues = as.matrix(defaultobjects$defaultlist[,c(2,3)]) + + filelist = split(t(lpjvalues),rep(1:nrow(lpjvalues),each = ncol(lpjvalues))) + + names(filelist) = gsub("_", ".",defaultobjects$defaultlist[,1]) + + spp <- as.matrix(LPJrunParameters[grep("_include", rownames(LPJrunParameters )),]) + PFTsRows <- c() + for(i in PFTs) PFTsRows <- c(PFTsRows, grep(i, rownames(spp))) + spp[-PFTsRows, 1] <- 0 + spp[PFTsRows,1] <- 1 + print(spp) + + parameterStandard_PFT <- as.matrix(LPJrunParameters[-grep("_include", + rownames(LPJrunParameters)),]) + + parameterStandard_PFT <- rbind(parameterStandard_PFT, spp) + + + tmp <- as.list(parameterStandard_PFT) + namestmp <- rownames(parameterStandard_PFT) + names(tmp) <- namestmp + + parameterStandard_PFT <- tmp + + + return(list(runParameters = parameterStandard_PFT, design = designLPJ, defaultfiles = filelist)) +} + diff --git a/rLPJGUESS/R/InferParameterAndDesignList.R b/rLPJGUESS/R/InferParameterAndDesignList.R new file mode 100644 index 0000000..7e68b40 --- /dev/null +++ b/rLPJGUESS/R/InferParameterAndDesignList.R @@ -0,0 +1,432 @@ +#' @title A function to infer the parameters and design parameters from the +#' instruction file +#' @description This function returns a list of parameters and design parameters +#' used for the later model runs. It also allows the user to see a summary +#' of all his parameters +#' @param MainInputFile a list with one element named "main" which contains the name of the main +#' instruction file given to lpj-guess when running it on the command line +#' @param NameMainFile a character string with the name of the new main file. Into +#' this file this function will write all input parameters. When no value is +#' provided the default main instruction file name while be main.ins +#' @param NamePftFile a character string with the name of the pft file. Into this +#' file the function will write all parameters specific for pfts and design. +#' When no file is provided the default main instruction file name will be pft.ins +#' @param vectorvaluedparams a vector of character strings providing the vector +#' valued parameters. rlpjguess can in the moment not handle vectorvalued +#' parameters. An example for this type of parameters is the "rootdist"-parameters, +#' which has for each soil layer an individual parameter. +#' @return a list a containing matrix with the default parameter values (called defaultparameters) +#' read from the instruction file and a matrix +#' with default design values (called defaultdesign) read from the instruction file +#' @author Johannes Oberpriller +#' @export + + +InferParameterAndDesignList <- function(MainInputFile,NameMainFile = "main.ins", + NamePftFile = "pft.ins", + vectorvaluedparams){ + + ## get the main and pft template from the origin main instruction files + + runlist <- write_main_templates(MainInputFile, NameMainFile = NameMainFile, + NamePftFile = NamePftFile) + + # set up matrix to save all defaultparameters and give them names + + defaultparameters <- data.frame(matrix(nrow = 1, ncol = 5)) + colnames(defaultparameters) = c("type","name", "rlpjname","value", "group") + + for(i in 1:length(runlist$design)){ + parametersnew = vector(length = 4) + parametersnew[1] = "design" + parametersnew[2] = strsplit(runlist$design[[i]]," ")[[1]][1] + parametersnew[3] = paste0("run_",parametersnew[2]) + parametersnew[4] = gsub("[[:space:]]", "", strsplit(runlist$design[[i]]," ")[[1]][2]) + parametersnew[4] = gsub("!","",parametersnew[4]) + parametersnew[5] = "run" + defaultparameters = rbind(defaultparameters, parametersnew) + } + defaultparameters = defaultparameters[-1,] + + runlist_pfts = unlist(runlist$pfts) + # handel all possible ways the instruciton files are + # ordered or the code is saved + for(i in 1:length(runlist$pfts)){ + linenumber = c() + linenumber_group = c() + linenumber_pft =c() + linenumber_st = c() + # get if line is beginning of group,pft or stand + linenumber_group = grep("group ", x = substr(runlist_pfts[i], + start = 1, stop = 6)) + linenumber_pft = grep("pft ", x = substr(runlist_pfts[i], + start = 1, stop = 4)) + linenumber_st = grep("st ", x = substr(runlist_pfts[i], + start = 1, stop = 3)) + linenumber = c(linenumber_group, linenumber_pft, linenumber_st) + linename = strsplit(runlist_pfts[i]," ")[[1]][2] + if(length(linenumber)!=0){ + endoufgroup = c() + # get the end of the group + endofgroup = grep(")", x = substr(runlist_pfts[(i+1):length(runlist_pfts)],1,2), fixed = T)[1] + # put all lines between beginning and end into the parametermatrix + for(j in 1:(endofgroup-1)){ + parametersnew = vector(length = 4) + parametersnew[1] = "pft" + if(nchar(trimws(runlist_pfts[i+j])) != 0){ + while(nchar(trimws(substring(runlist_pfts[i+j],1,1)))==0){ + runlist_pfts[i+j] = substring(runlist_pfts[i+j],2,nchar(runlist_pfts[i+j])) + } + } + parametersnew[2] = gsub("[[:space:]]","",strsplit(runlist_pfts[i+j]," ")[[1]][1]) + parametersnew[3] = paste0(gsub("\"","",linename),"_", parametersnew[2]) + parameterposition = 2 + parametersnew[4] = "" + while(grepl("^\\s*$", parametersnew[4])){ + parametersnew[4] = gsub("[[:space:]]"," ", + strsplit(runlist_pfts[i+j]," ", fixed = T)[[1]][parameterposition]) + parameterposition = parameterposition + 1 + if(grepl("^!", parametersnew[4])){ + parametersnew[4] = "" + break + } + } + parametersnew[4] = gsub("^!","",parametersnew[4]) + parametersnew[5] = gsub("\"","",linename) + if(substring(runlist_pfts[i+j],1,1) != "!"){ + defaultparameters = rbind(defaultparameters, parametersnew) + } + } + } + } + #print(defaultparameters) + # handle possible errors + defaultparameters = defaultparameters[which(defaultparameters[,2] != ""),] + defaultparameters = defaultparameters[which(defaultparameters[,2] != "!"),] + defaultparameters = defaultparameters[which(defaultparameters[,4] != "NA"),] + # get ride of spaces and comments for possible multiplications later + for(i in 1:nrow(defaultparameters)){ + startofcomments = gregexpr("!",defaultparameters[i,4])[[1]][1] + if(startofcomments != "-1"){ + defaultparameters[i,4] = sub("[[:space:]]+","",substr(defaultparameters[i,4], start = 1, stop = startofcomments -1)) + } + } + # exclude all vectorvalued parameters from the list + for(i in 1:length(vectorvaluedparams)){ + defaultparameters = defaultparameters[which(defaultparameters[,2] != vectorvaluedparams[i]),] + } + + + + ### Infer the Design list + + # unpack all variables and climate input files + + runlist_variables = unlist(runlist$variables,use.names = F) + runlist_inputfiles = unlist(runlist$files, use.names = F) + + # define matrix to store them + + defaultlist = data.frame(matrix(nrow = 1, ncol = 3)) + colnames(defaultlist) = c("name","rlpjnames","value") + + # handle all possible ways stored in file + for(i in 1:length(runlist_variables)){ + new_variable = vector(length = 3) + new_variable[1] = gsub("\"","",strsplit(runlist_variables[i]," ")[[1]][2]) + beginn = gregexpr("\\(",runlist_variables[i]) + end = gregexpr("\\)", runlist_variables[i]) + parameterpart = gsub("\"", "",strsplit(substr(runlist_variables[i], start = beginn[[1]], stop = end[[1]]-1), " ")[[1]][2]) + new_variable[2] = paste0("_",new_variable[1],"_") + new_variable[3] = parameterpart + defaultlist = rbind(defaultlist, new_variable) + } + + defaultlist = defaultlist[-1,] + # handle all possible ways stored in file + for(i in 1:length(runlist_inputfiles)){ + new_variable = vector(length = 3) + new_variable[1] = gsub("\"","",strsplit(runlist_inputfiles[i]," ")[[1]][2]) + beginn = gregexpr("\\(",runlist_inputfiles[i]) + end = gregexpr("\\)", runlist_inputfiles[i]) + parameterpart = gsub("\"", "",strsplit(substr(runlist_inputfiles[i], start = beginn[[1]], stop = end[[1]]-1), " ")[[1]][2]) + new_variable[2] = paste0("_",new_variable[1],"_") + new_variable[3] = parameterpart + defaultlist = rbind(defaultlist, new_variable) + } + + # get ride of empty lines + #print(defaultparameters) + defaultlist = defaultlist[which(defaultlist[,1] != ""),] + + return(list(defaultparameters = defaultparameters, defaultlist = defaultlist)) +} + + +# @description This function takes the main input input files and desired file +# names and returns a list with files, variables, parameters and design parameters +# @param MainInputFile is a list with the first element being the name of the main input file see InferParameterAndDesignList +# @param NameMainFile is the main file after reordering see InferParameterAndDesignList +# @param NamePftFile is the pft file after reordering see InferParameterAndDesignList +# @return returns a list with the entries parameters,files, variables and design +# which are all themselves matrices +# @author Johannes Oberpriller + +write_main_templates <- function(MainInputFile,NameMainFile, NamePftFile){ + + # Infer the correct order of instruction files + + insfilelist = infer_instruction_order(MainInputFile = MainInputFile) + + # If the main input file imports information from other input files, create + # one large temporary .ins file + + if(length(insfilelist) > 1){ + + # Create the temporary files to get all lines + + file.create("./main_tryout.ins") + outcon <- file("./main_tryout.ins", "w") + for(i in 1:length(insfilelist)){ + lines <- readLines(insfilelist[[i]]) + writeLines(lines,outcon) + } + close(outcon) + + # Create the Main and Ins file + + file.create(paste0("./",NameMainFile)) + file.create(paste0("./",NamePftFile)) + lines <- readLines("./main_tryout.ins") + + # delete all import files + + importlines = grepl("import",substr(lines, start = 1, stop = 7)) # AHES I would increase stop, you never know whether the 'import' statement is somehwere further down. As we have learned today, the .ins files can be quite different. + lines = lines[-which(importlines)] + + }else{ + + # Else, if there is only one .ins file, read in all its lines. + + lines <- readLines(MainInputFile[['main']]) + + } + + # Grep all "param" lines and the ndep_timeseries, delete duplicates + # and write them to the parameterfiles + + paramlines = grepl("param", substr(lines, start = 1, stop = 7)) + parameters = lines[which(paramlines)] + + parameternames = sapply(strsplit(parameters," "), function (x) x[2]) + duplicates_parameters = which(duplicated(parameternames) ==T) + + + while(length(duplicates_parameters) != 0 ){ + first_appearance = c() + for(i in duplicates_parameters){ + first_appearance <- c(first_appearance, which(parameternames == parameternames[i])[1]) + } + parameters = parameters[-first_appearance] + parameternames = sapply(strsplit(parameters," "), function (x) x[2]) + duplicates_parameters = which(duplicated(parameternames) ==T) + } + + + ndep_time = grepl("!ndep_timeseries", substr(lines, start = 1, stop = 15)) + if(length(which(ndep_time ==T)) ==0){ + ndep_time = grepl("ndep_timeseries", substr(lines, start =1, stop =15)) + } + parameters = c(parameters, lines[which(ndep_time)]) + + parameternames = sapply(strsplit(parameters," "), function (x) x[2]) + parameterfiles = grepl("file", parameternames) + parametervariables = parameters[-which(parameterfiles)] + parameterfiles = parameters[parameterfiles] + + # Write the main Files and delete all lines which are written there + + FileCon = file(NameMainFile) + mainimport = paste("import ",paste0("\"", "path_to_globalTemplate", "\"", "\n"), sep =" ") + writeLines(c(mainimport,parameters), FileCon) + close(FileCon) + lines = lines[-c(which(paramlines),which(ndep_time))] + headingfileline <- paste("\n", "!Which files to include in the output","\n") + + ## Get the Title, the Outputfiles and the outcommented lines + + titleline <- grepl("title",substr(lines, start = 1, stop = 10)) + filelines <- grepl("file", substr(lines, start = 1, stop = 5)) + outcommented <- grepl("!", substr(lines, start = 1, stop = 1)) + + ## get the lines where pfts and/or species parameters are specified + + pftlines = c() + for(i in 1:length(lines)){ + linenumber = c() + linenumber_group = c() + linenumber_pft =c() + linenumber_st = c() + linenumber_group = grep("group ", x = substr(lines[i], start = 1, stop = 6)) + linenumber_pft = grep("pft ", x = substr(lines[i], start = 1, stop = 4)) + linenumber_st = grep("st ", x = substr(lines[i], start = 1, stop = 3)) + linenumber = c(linenumber_group, linenumber_pft, linenumber_st) + if(length(linenumber)!=0){ + endoufgroup = c() + endofgroup = grep(")", x = substr(lines[(i+1):length(lines)],1,2), fixed = T)[1] + pftlines = c(pftlines, lines[i:(i+endofgroup)],"\n") + } + } + + titel = lines[titleline] + files = lines[filelines] + files = gsub("^file","!file", files) + + # delete lines which are titlelines, filelines ( which we alter to be + # all outcommented), and outcommented lines and pftlines + + lines = lines[-c(which(titleline),which(filelines), + which(outcommented),which(lines %in% pftlines))] + + # grep empty and tabed lines and delete them + + tablines = grepl("\t", x = substr(lines, start =1, stop = 2)) + emptylines = grepl(" ", substr(lines, start = 1, stop =2)) + lines = lines[-c(which(tablines), which(emptylines))] + + # get the unique designnames from the parameters + + designnames = sapply(strsplit(lines," "), function (x) x[1]) + duplicates_design = which(duplicated(designnames) ==T) + + + if(length(duplicates_design) != 0){ + first_apperance = c() + for(i in duplicates_design){ + first_apperance <- c(first_apperance, which(designnames == designnames[i])[1]) + } + design = lines[-first_apperance] + }else{ + design = lines + } + + + # write the PFT or Species file which includes the title, the files, + # the designvariables and all pft/speciesspecific lines into the + # main Pft file + + Pftcon <- file(NamePftFile) + writeLines(c(titel,headingfileline,files,"\n",design, "\n",pftlines),Pftcon) + close(Pftcon) + + # If there were multiple .insfiles, which first had to be merged, a temporary merged file + # had been created. Delete this file now. + # remove the main file written in the beginning because no more need + + if(length(insfilelist) > 1) file.remove("./main_tryout.ins") + + return(list(files = parameterfiles, variables = parametervariables, + pfts = pftlines, design = design )) + +} + +# @description This function infers the correct order of the instruction files +# and returns it +# @param MainInputFile is the main input file see InferParameterAndDesignList +# @return returns a vector with the names of correctly ordered instruction files +# @author Johannes Oberpriller + +infer_instruction_order <- function(MainInputFile){ + + # get the main directory where the instruction file is stored + + dashes = gregexpr("/",MainInputFile[["main"]]) + + lastdash = dashes[[1]][length(dashes[[1]])] + + maindirectory = substr(MainInputFile[["main"]],start = 1, + stop = lastdash) + + # get all imports from the file + + imports = get_imports(MainInputFile[["main"]], maindirectory = maindirectory) + + # order the imports like they are in the main instruction file + + ordered_imports = imports + i = 1 + while(i <= length(ordered_imports)){ + new_imports = get_imports(ordered_imports[[i]], maindirectory = maindirectory) + if(any((new_imports %in% ordered_imports))){ + i = i+1 + } + else{ + if(length(new_imports) == 0){ + i = i+1 + } + else{ + number_new = length(new_imports) + number_old = length(ordered_imports) + if((i+1)>number_old){ + ordered_imports[number_new + number_old] = ordered_imports[number_old] + ordered_imports[i:(i+number_new-1)] = new_imports + } + else{ + ordered_imports[(i+number_new):(number_new+number_old)] = ordered_imports[i:number_old] + ordered_imports[(i):(i+number_new-1)] = new_imports + } + } + } + } + # return the correct order + return(c(MainInputFile, ordered_imports)) +} + +# @description this function takes the main file and the main directroy +# and returns the imported files +# @param a file with all instruction files below each other +# @param maindirectory the main directory for the analysis +# @return returns the ordered imports +# @author Johannes Oberpriller + + +get_imports <- function(file,maindirectory){ + + # read main file + + linesfile = readLines(file) + imports = list() + import_number = c() + + # loop over files and get instruction order + for(i in 1:length(linesfile)){ + is_in = grepl("import", linesfile[i]) + out_commented = grepl("!import",substr(linesfile[i], start = 1, stop = 8)) + if(is_in == T){ + if(out_commented == T){ + next + } + else{ + import_number =c(import_number, i) + } + } + else + { + next + } + } + # check that the imports have all the same apperance in code + ins_order = 1 + for(i in import_number){ + imports_file = substr(x=linesfile[i], + start = gregexpr("\"",linesfile[i])[[1]][1]+1, + stop = gregexpr("\"",linesfile[i])[[1]][2]-1) + if(substr(imports_file,1,2) =="./"){ + imports_file = substr(imports_file,3,stop =100) + } + imports[ins_order] = paste0(maindirectory,imports_file) + ins_order = ins_order +1 + } + return(imports) +} + diff --git a/rLPJGUESS/R/callLPJ.R b/rLPJGUESS/R/callLPJ.R index 78ad299..4c6f20e 100644 --- a/rLPJGUESS/R/callLPJ.R +++ b/rLPJGUESS/R/callLPJ.R @@ -28,9 +28,9 @@ callLPJ <- function(mainDir, runDir , template2, mode){ if (is.null(template2) || !file.exists(file.path(runDir, template2))){ stop ("Please provide a valid template name") } - if (is.null(mode) || mode != "cf" & mode != "cru"){ - stop("Please provide a valid cluster type: cf or cru") - } + # if (is.null(mode) || mode != "cf" & mode != "cru"){ + # stop("Please provide a valid cluster type: cf or cru") + # } #----------------------------------------------------------------------------# # CALL MODELL diff --git a/rLPJGUESS/R/checkDesign.R b/rLPJGUESS/R/checkDesign.R index 3b13ef9..01bf5fe 100644 --- a/rLPJGUESS/R/checkDesign.R +++ b/rLPJGUESS/R/checkDesign.R @@ -1,7 +1,7 @@ # @title A check design function # @description This function checks the provided design against the -# default values, and returns a complete design. If wrong desing is passed, +# default values, and returns a complete design. If wrong design is passed, # the fucntion will raise an error. # @param scale a character string indicating whether the model runs global or for europe. # @param design a named list or matrix holding the design diff --git a/rLPJGUESS/R/checkParameters.R b/rLPJGUESS/R/checkParameters.R index 48afaa8..80971d2 100644 --- a/rLPJGUESS/R/checkParameters.R +++ b/rLPJGUESS/R/checkParameters.R @@ -17,9 +17,9 @@ # } checkParameters <- function(scale, parameterList = NULL, type = "serial"){ # include check - if ( scale != "global" & scale != "europe"){ - stop("Invalid scale: neither global nor europe") - } + # if ( scale != "global" & scale != "europe"){ + # stop("Invalid scale: neither global nor europe") + # } if (type != "parallel" & type != "serial" ){ stop("Invalid check type") } @@ -36,6 +36,7 @@ checkParameters <- function(scale, parameterList = NULL, type = "serial"){ stop("Please provide a valid parameterList") } # Throw an error if wrong parameter names + dummyCheck <- !names(parameterList) %in% names(default) if(any(dummyCheck)){ warning(paste("Wrong parameterList in ", paste(names(parameterList)[dummyCheck], collapse = ", " ))) @@ -64,15 +65,16 @@ checkParameters <- function(scale, parameterList = NULL, type = "serial"){ checkParameters.names <- function(scale, parameterNames){ # include check - if ( scale != "global" & scale != "europe"){ - stop("Invalid scale: neither global nor europe") - } + # if ( scale != "global" & scale != "europe"){ + # stop("Invalid scale: neither global nor europe") + # } # call the default template + default <- getParameterList(scale, list = T) - if(is.null(parameterNames)){ - parameterList <- default - } + # if(is.null(parameterNames)){ + # parameterList <- default + # } # Throw an error if wrong parameter names dummyCheck <- !parameterNames %in% names(default) if(any(dummyCheck)){ diff --git a/rLPJGUESS/R/createRunParameters.R b/rLPJGUESS/R/createRunParameters.R index cacc039..1e3f1d7 100644 --- a/rLPJGUESS/R/createRunParameters.R +++ b/rLPJGUESS/R/createRunParameters.R @@ -12,7 +12,8 @@ createRunParameters <- function(x, singleRun, parameterList){ # Check the parameters: length, type and names - parameterList <- try(checkParameters.matrix(singleRun$scale, parameterList), FALSE) + #parameterList <- try(checkParameters.matrix(singleRun$scale, parameterList), FALSE) + parameterList <- checkParameters.matrix(singleRun$scale, parameterList) if ('try-error' %in% class(parameterList)){ stop("Invalid parameterList provided") } if (class(parameterList[[1]])== "list"){ @@ -32,18 +33,20 @@ createRunParameters <- function(x, singleRun, parameterList){ # Based on parameter Names write the general template # and if no parameter is present raise and error? - parameterCommon <- checkParameters.names(scale= singleRun$scale, parameterNames) + #parameterCommon <- checkParameters.names(scale = singleRun$scale, parameterNames) + #print(parameterList) + # parameterCommon <- parameterList[[1]] + # + # if(length(parameterCommon) > 0){ + # #parameterCommon <- checkParameters.rootDist(parameterCommon) + # #write common template + # parameterCommonNames <- names(parameterCommon) + # for(i in 1:length(parameterCommon)){ + # singleRun$template1Mem <- sub(paste0(" ",parameterCommonNames[i]," "), paste0(" ",parameterCommon[[i]]," "), singleRun$template1Mem) + # } + # } - if(length(parameterCommon) > 0){ - parameterCommon <- checkParameters.rootDist(parameterCommon) - # write common template - parameterCommonNames <- names(parameterCommon) - for(i in 1:length(parameterCommon)) { - singleRun$template1Mem <- sub(parameterCommonNames[i], parameterCommon[[i]], singleRun$template1Mem) - } - - } # Check the grids gridListCell <- readLines(file.path(singleRun$mainDir,singleRun$gridList)) diff --git a/rLPJGUESS/R/createSingleObject.R b/rLPJGUESS/R/createSingleObject.R index 5b80e93..57ddf3a 100644 --- a/rLPJGUESS/R/createSingleObject.R +++ b/rLPJGUESS/R/createSingleObject.R @@ -6,7 +6,7 @@ # Default value is all outputs. # @param settings additional parameters # @seealso \code{\link{runLPJ}} -# @author Ramiro Silveyra Gonzalez, Maurizio Bagnara, Florian Hartig +# @author Ramiro Silveyra Gonzalez, Maurizio Bagnara, Florian Hartig, Johannes Oberpriller # @return TODO createSingleObject <- function(mainDir, typeList, settings){ @@ -14,24 +14,18 @@ createSingleObject <- function(mainDir, typeList, settings){ file.co2 = NULL, file.cru = NULL, file.cru.misc = NULL, file.ndep= NULL, file.temp = NULL, file.prec = NULL, file.insol = NULL, file.wetdays = NULL, file.minTemp = NULL, - file.maxTemp = NULL, variable.temp = NULL, + file.soildata = NULL, + file.maxTemp = NULL, variable.temp = NULL, variable.ndep = NULL, variable.prec = NULL, variable.insol = NULL, variable.wetdays = NULL, variable.minTemp = NULL, variable.maxTemp = NULL, template1 = NULL, template2=NULL, plot.data = FALSE, save.plots = FALSE, processing = FALSE, delete = TRUE, save= TRUE, runID = "", parallel = "auto", - checkParameters = "serial", design = NULL) + checkParameters = "serial", design = NULL, defaultlist = NULL) #, fun = NULL) # This would be to allow havin own functions in parallel. settings <- c(settings[names(settings) %in% names(defaultSettings)], defaultSettings[ !names(defaultSettings) %in% names(settings)]) - # mode - if (is.null(settings[["mode"]]) || settings[["mode"]] != "cf" & settings[["mode"]] != "cru"){ - stop("Please provide a valid cluster type: cf or cru") - } - if ( is.null(settings[["scale"]]) || settings[["scale"]] != "global" & settings[["scale"]] != "europe"){ # this is relevant if getting template - stop("Please provide a valid scale: global or europe") - } if (is.null(typeList) || !class(typeList) == "character"){ settings$typeList <- typelist.default message("Output typeList has not been provided") @@ -87,50 +81,54 @@ createSingleObject <- function(mainDir, typeList, settings){ # to replace in the template # Go throught the files and check whether they provided, if so add them to # default list, otherwise stop the function + + # Johannes: Depending on the version of LPJ different parameters are + # required to run the model. + # I think, every LPJ user has working instruction files, + # which allow to infer all required files and it is enough to provide + # the functionality to substitute them in the main file if they want to change + # this from the wrapper + files <- settings[grepl("file", names(settings))] - files.default <- files.parameters[[settings[["mode"]]]] - files.names <- names(files.default) + variables <- settings[grepl("variable", names(settings))] + filesandvariables = c(files,variables) + + files.names <- names(settings$defaultlist) + for (i in 1:length(files.names)){ - if (is.null(files[[files.names[i]]])){ - warning(paste("The", files.names[i], "has not been provided", sep = " ")) - }else if(!file.exists(files[[files.names[i]]])){ + if (is.null(filesandvariables[[files.names[i]]])){ + next + }else if(!file.exists(filesandvariables[[files.names[i]]])){ warning(paste("The", files.names[i], "does not exist", sep = " ")) }else{ - files.default[[files.names[i]]][2] <- files[[files.names[i]]] - } - } - #files.default <- files.default[keep] + #print(i) + #print(filesandvariables[[files.names[i]]]) + settings$defaultlist[[files.names[i]]][2] <- filesandvariables[[files.names[i]]] - variables <- settings[grepl("variable", names(settings))] - variables.default <- variables.parameters[[settings[["mode"]]]] - variables.names <- names(variables.default) - for (i in 1:length(variables.names)){ - if (is.null(variables[[variables.names[i]]])){ - warning(paste("The", variables.names[i], "has not been provided", sep = " ")) - }else{ - variables.default[[variables.names[i]]][2] <- variables[[variables.names[i]]] } } - #variables.default <- variables.default[keep] + singleObject <- settings[!grepl("file", names(settings))] singleObject <- singleObject[!grepl("variable", names(singleObject))] - singleObject$filesNames <- files.default - singleObject$variablesNames <- variables.default + singleObject$filesNames <- settings$defaultlist singleObject$mainDir <- mainDir singleObject$runInfoDir <- file.path(singleObject$mainDir, paste("runInfo", format(Sys.time(), "%Y_%m_%d_%H%M%S"), sep = "_")) - # Read template one and replace desing + # Read template one and replace design singleObject$template1Mem <- readLines(file.path(singleObject$mainDir, singleObject$template1)) # Check the design - settings$design <- checkDesign(settings$scale , settings$design) + #settings$design <- checkDesign(settings$scale , settings$design) designNames <- names(settings$design) - for(i in 1:length(settings$design)) { - singleObject$template1Mem <- sub(designNames[i], settings$design[[i]], singleObject$template1Mem) + + for(i in 1:length(settings$design)){ + singleObject$template1Mem <- gsub(paste0(" ",designNames[[i]]," "), + paste0(" ",settings$design[[i]]," "), + singleObject$template1Mem) } if(settings$design[["run_ifcalcsla"]]==as.character(0)){ singleObject$template1Mem <- sub("!sla", "sla", singleObject$template1Mem) diff --git a/rLPJGUESS/R/getData.R b/rLPJGUESS/R/getData.R index 7a909c4..972453d 100644 --- a/rLPJGUESS/R/getData.R +++ b/rLPJGUESS/R/getData.R @@ -23,18 +23,18 @@ #' @export #' @example /inst/examples/getDataHelp.R getLPJData <- function(x, typeList = NULL, runInfo=NULL, processing = FALSE){ - #, fun = NULL){ + #, fun = NULL){ # other options which could be included: - #lon.extent=c(-180, 180), lat.extent=c(-90, 90), - #area.weighted=FALSE, year.offset=0 ) { - # @param lon.extent a numeric vector containing the min and max values used - # for west-east extent(default -180 to 180) - # @param lat.extent a numeric vector containing the max and min values used - # for north-south extent (default 90 to -90). - # @param area.weighted a boolean indicating whether the gridcells should be - # weighted by their size (regular grids only, default FALSE). - # @param year.offset a integer indicating the value to be added to the 'Year' - # column in the LPJ-GUESS output. + #lon.extent=c(-180, 180), lat.extent=c(-90, 90), + #area.weighted=FALSE, year.offset=0 ) { + # @param lon.extent a numeric vector containing the min and max values used + # for west-east extent(default -180 to 180) + # @param lat.extent a numeric vector containing the max and min values used + # for north-south extent (default 90 to -90). + # @param area.weighted a boolean indicating whether the gridcells should be + # weighted by their size (regular grids only, default FALSE). + # @param year.offset a integer indicating the value to be added to the 'Year' + # column in the LPJ-GUESS output. # checking provided parameters @@ -63,91 +63,78 @@ getLPJData <- function(x, typeList = NULL, runInfo=NULL, processing = FALSE){ keep <- rep(FALSE, length(typeList)) for (i in 1:length(typeList)){ if (file.exists(file.path(x, paste(typeList[[i]], ".out", sep="")))){ - if ( file.info( file.path(x, paste(typeList[[i]], ".out", sep="")) )[['size']] == 0){ + if ( file.info( file.path(x, paste(typeList[[i]], ".out", sep="")) )[['size']] == 0){ warning( paste("The ", typeList[[i]], ".out is empty!", sep = "") ) }else{ keep[i] <- TRUE } }else{ warning( paste("There is no ", typeList[[i]], ".out", sep = "") ) - } } - if (any(keep)){ + } + if(any(keep)){ typeList.valid <- typeList[keep] # Creating a list to hold data listData <- vector(mode="list", length=length(typeList.valid)) names(listData) <- typeList.valid }else{ - stop("There are not model outputs. Please check the guess.log files") + stop("There are no model outputs. Please check the guess.log files") } - # storing run info + # storing run info #----------------------------------------------------------------------------# # OBTAIN OUTPUTS: #----------------------------------------------------------------------------# - if (processing == FALSE){ - # Adding Data to listData - # looping over data types, reading files, no processing data and adding it to the Data Class - # list append data, probably will have to use the name() function to give it the right name - # in the end, make the list of class LPJData - # Add data to LPJout Data class - for (j in 1:length(typeList.valid)) { - data <- try(read.table(file.path(x, paste( typeList.valid[j], ".out", sep="")),header=T), TRUE) - if ('try-error' %in% class(data)){ - data <- try(data <-readTableHeaderLPJ(file.path(x, paste( typeList.valid[j], ".out", sep=""))), TRUE) - if ('try-error' %in% class(data)){ - stop("Model outputs are not readable") - } + if (processing == FALSE){ + # Adding Data to listData + # looping over data types, reading files, no processing data and adding it to the Data Class + # list append data, probably will have to use the name() function to give it the right name + # in the end, make the list of class LPJData + # Add data to LPJout Data class + for(j in 1:length(typeList.valid)){ + data <- try(read.table(file.path(x, paste(typeList.valid[[j]], ".out", sep="")),header=T), TRUE) + if('try-error' %in% class(data)){ + data <- try(data <-readTableHeaderLPJ(file.path(x, paste(typeList.valid[[j]], ".out", sep=""))), TRUE) + if('try-error' %in% class(data)){ + stop("Model outputs are not readable") } - listData[[typeList.valid[[j]]]] <- data } - }else{ - for (j in 1:length(typeList.valid)) { - # Chekc how many grids in output - data <- try(read.table(file.path(x, paste( typeList.valid[j], ".out", sep="")),header=T), TRUE) + listData[[typeList.valid[[j]]]] <- data + } + }else{ + for(j in 1:length(typeList.valid)) { + data <- try(read.table(file.path(x, paste( typeList.valid[j], ".out", sep="")),header=T), TRUE) + if ('try-error' %in% class(data)){ + data <- try(data <-readTableHeaderLPJ(file.path(x, paste( typeList.valid[j], ".out", sep=""))), TRUE) if ('try-error' %in% class(data)){ - data <- try(data <-readTableHeaderLPJ(file.path(x, paste( typeList.valid[j], ".out", sep=""))), TRUE) - if ('try-error' %in% class(data)){ - stop("Model outputs are not readable") - } + stop("Model outputs are not readable") } - coordinates <- unique(paste(data$Lat, data$Lon, sep = "_")) + } + listData[[typeList.valid[[j]]]] <- data + } + coordinates <- unique(paste(data$Lat, data$Lon, sep = "_")) + if(length(coordinates) > 1 ){ + coordinates <- lapply(coordinates, function(x){as.numeric(unlist(strsplit(x, "_")))}) + listData <- rep(list(listData), length(coordinates)) + names(listData) <- paste0("gridcell",coordinates) # will need better name + #Adding Data to listData + #looping over data types, reading files, processing data and adding it to the Data Class + #list append data, probably will have to use the name() function to give it the right name + #in the end, make the list of class LPJData - if(length(coordinates) > 1 ){ - # Now we stop but eventually we want to do something out of this - # Below there is code that would do it - # This would also affect plotLPJData - stop("Processing is not supported for more than one grid") - # if only one grid, simplify the list - # if (length(listData) == 1){ - # listData <- listData[[1]] - # Adding Data to listData - # looping over data types, reading files, processing data and adding it to the Data Class - # list append data, probably will have to use the name() function to give it the right name - # in the end, make the list of class LPJData - # Add data to LPJout Data class - #coordinates <- lapply(coordinates, function(x){as.numeric(unlist(strsplit(x, "_")))}) - #listData <- rep(list(listData), length(coordinates)) - #names(listData) <- paste("grid", coordinates, sep = "_") # will need better named - # Adding Data to listData - # looping over data types, reading files, processing data and adding it to the Data Class - # list append data, probably will have to use the name() function to give it the right name - # in the end, make the list of class LPJData - #keep <- rep(TRUE, length(coord)) - #sub_data <- coord[coord>=min(lon.extent) & Lon<=max(lon.extent) & Lat <=max(lat.extent) & Lat>=min(lat.extent)) - #for (k in 1:length(listData)){ - # data <- data[data$Lat==coordinates[[k]][1] & data$Lon==coordinates[[k]][2],] + for(k in 1:length(listData)){ - # for (j in 1:length(typeList.valid)) { - # # reading output - # data <- read.table(file.path(x, paste(typeList.valid[[j]], ".out", sep="")),header=T) - # data.ts <- convertTS(data) - # listData[[k]][[typeList.valid[[j]]]] <- data.ts - # } - }else{ + for(j in 1:length(typeList.valid)){ + # reading output + data <- read.table(file.path(x, paste(typeList.valid[[j]], ".out", sep="")),header=T) + data <- data[data$Lat==coordinates[[k]][1] & data$Lon==coordinates[[k]][2],] data.ts <- convertTS(data) - listData[[typeList.valid[[j]]]] <- data.ts + listData[[k]][[typeList.valid[[j]]]] <- data.ts + } } + }else{ + data.ts <- convertTS(data) + listData[[typeList.valid[[j]]]] <- data.ts } } # add it to the data class diff --git a/rLPJGUESS/R/getDesign.R b/rLPJGUESS/R/getDesign.R index b495b68..a284576 100644 --- a/rLPJGUESS/R/getDesign.R +++ b/rLPJGUESS/R/getDesign.R @@ -8,10 +8,10 @@ #' @author Ramiro Silveyra Gonzalez, Maurizio Bagnara #' @example /inst/examples/getDesignHelp.R getDesign <- function(scale, list = F){ - if ( is.null(scale) || scale != "global" & scale != "europe"){ - stop("Please provide a valid scale: global or europe") - } - tmp <- design.default[[scale]] + # if ( is.null(scale) || scale != "global" & scale != "europe"){ + # stop("Please provide a valid scale: global or europe") + # } + tmp <- design.default$scale if (list){ tmp.names <- rownames(tmp) tmp <- as.vector(tmp, mode = "list") diff --git a/rLPJGUESS/R/getParameterList.R b/rLPJGUESS/R/getParameterList.R index 820b2b2..b91e0e3 100644 --- a/rLPJGUESS/R/getParameterList.R +++ b/rLPJGUESS/R/getParameterList.R @@ -11,11 +11,12 @@ #' @author Ramiro Silveyra Gonzalez, Maurizio Bagnara #' @example /inst/examples/getParameterListHelp.R getParameterList <- function(scale, list = TRUE){ - if ( is.null(scale) || scale != "global" & scale != "europe"){ + if (is.null(scale)){ stop("Please provide a valid scale: global or europe") } - tmp <- parameterList.default[[scale]] + #tmp <- parameterList.default[1]$normal + tmp <- parameterList.default if (list){ tmp.names <- rownames(tmp) diff --git a/rLPJGUESS/R/plotLPJData.R b/rLPJGUESS/R/plotLPJData.R index a907857..45d2d5e 100644 --- a/rLPJGUESS/R/plotLPJData.R +++ b/rLPJGUESS/R/plotLPJData.R @@ -17,89 +17,102 @@ #' \url{https://cran.r-project.org/web/packages/zoo/zoo.pdf} #' @export #' @keywords rLPJGUESS -#' @author Ramiro Silveyra Gonzalez, Maurizio Bagnara, Florian Hartig +#' @author Ramiro Silveyra Gonzalez, Maurizio Bagnara, Florian Hartig, Johannes Oberpriller #' @example /inst/examples/plotLPJDataHelp.R -plotLPJData <- function(x, typeList = NULL, outDir= NULL, save.plots = FALSE, prefix = ""){ +plotLPJData <- function(x, typeList = NULL, gridlist = NULL, outDir= NULL, + save.plots = FALSE, prefix = "", plot_avg = F){ # checking input parameters - if (is.null(x)){ + if(is.null(x)){ stop("No data has been provided") } - if (!class(x)=="LPJData"){ + if(!class(x)=="LPJData"){ stop("Invalid data has been provided") } if (save.plots){ - if ( is.null(outDir) || !file.exists(outDir)){ + if( is.null(outDir) || !file.exists(outDir)){ stop("No outDir has been provided") } } - if (!requireNamespace("zoo", quietly = TRUE)){ + if(!requireNamespace("zoo", quietly = TRUE)){ stop("Can't load required library 'zoo'") } data <- x@dataTypes # Plot from - typeList.available <- sort(names(data)) - - if (is.null(typeList) || !class(typeList) == "character"){ + gridlist.available <- sort(names(data)) + typeList.available <- names(data[[1]][which(names(data[[1]]) %in% + gridlist.available == F)]) + if(is.null(typeList) || !class(typeList) == "character"){ message("No typeList has been provided. Plotting all data") typeList.valid <- typeList.available }else{ keep <- rep(FALSE, length(typeList)) - for (i in 1:length(typeList)){ - if (typeList[i] %in% typeList.available){ + for(i in 1:length(typeList)){ + if(typeList[i] %in% typeList.available){ keep[i] <- TRUE } } - if (any(keep)){ + if(any(keep)){ typeList.valid <-typeList[keep] }else{ stop("None of the requested output types exists") } } - ## if plotting true, start the fucntion - # Check if data is a df - # Checking existentce of data types # in theory do not need if your plotting from class object - for (i in 1:length(typeList.valid)){ - df <- data[[typeList.valid[[i]] ]] + + if(is.null(gridlist)){ + message("No gridlist has been provided. Plotting all gridcells") + gridlist.valid <- gridlist.available + }else{ + gridlist.check = apply(X = gridlist,MARGIN = 1, FUN = function (x) { + y = paste0("gridcellc(",x[1], ", ", x[2],")") + return(y) + }) + keep <- rep(FALSE, length(gridlist.available)) + for(i in 1:length(gridlist.check)){ + if(gridlist.check[i] %in% gridlist.available){ + keep[i] <- TRUE + } + } + if(any(keep)){ + gridlist.valid <-gridlist.check[keep] + }else{ + stop("None of the requested gridcells exists") + } + } + average = matrix(data = 0,ncol = length(gridlist.valid), + nrow = nrow(data[[gridlist.valid[[1]]]][[typeList.valid[[1]]]])) + colnames(average) = typeList.valid + for (i in 1:length(gridlist.valid)){ + df <- data[[gridlist.valid[[i]]]] + coordinates = get_gridlist_values(gridlist.valid[[i]]) if(zoo::is.zoo(df) == FALSE){ - # check how many coordinates - coordinates <- unique(paste(df$Lat, df$Lon, sep = "_")) - #if(length(coordinates) > 1 ){ - # if only one grid, simplify the list - # if (length(listData) == 1){ - # listData <- listData[[1]] - # Adding Data to listData - # looping over data types, reading files, processing data and adding it to the Data Class - # list append data, probably will have to use the name() function to give it the right name - # in the end, make the list of class LPJData - # Add data to LPJout Data class - coordinates <- lapply(coordinates, function(x){as.numeric(unlist(strsplit(x, "_")))}) - #keep <- rep(TRUE, length(coord)) - #sub_data <- coord[coord>=min(lon.extent) & Lon<=max(lon.extent) & Lat <=max(lat.extent) & Lat>=min(lat.extent)) - for (k in 1:length(coordinates)){ - values <- df[df$Lat==coordinates[[k]][1] & df$Lon==coordinates[[k]][2],] - values <- convertTS(values) - if (save.plots){ - pdf(file.path(outDir, paste(prefix, typeList.valid[[i]], ".pdf", sep="")))#width=1000,height=750 - if(length(colnames(values))==1){ - plot(values, main =paste("Grid", coordinates[[k]][1], coordinates[[k]][2], - "Variable:", typeList.valid[[i]]),xlab="Years") - }else{ - plot(values, main =paste("Grid", coordinates[[k]][1], coordinates[[k]][2], - "Variable:", typeList.valid[[i]]),xlab="Years") - } - dev.off() + + for (k in 1:length(typeList.valid)){ + values <- df[[typeList.valid[[k]]]] + average[,k] = average[,k] + values[,ncol(values)] + if(save.plots){ + pdf(file.path(outDir, paste(prefix, gridlist.valid[[i]],typeList.valid[[k]], ".pdf", sep="")))#width=1000,height=750 + if(length(colnames(values))==1){ + plot(values, main =paste("Gridcell Lon:", coordinates[1],"Lat", coordinates[2], + "Variable:", typeList.valid[[k]]),xlab="Years") }else{ - plot(values, main =paste("Grid", coordinates[[k]][1], coordinates[[k]][2], - "Variable:", typeList.valid[[i]]),xlab="Years") + plot(values, main =paste("Gridcell Lon:", coordinates[1],"Lat", coordinates[2], + "Variable:", typeList.valid[[k]]),xlab="Years") } + dev.off() + }else{ + plot(values, main =paste("Gridcell Lon:", coordinates[1],"Lat", coordinates[2], + "Variable:", typeList.valid[[k]]),xlab="Years") } - }else{ + + } + } + else{ values <- df - # something like is zoo + # something like is zoo if (save.plots){ pdf(file.path(outDir, paste(prefix, typeList.valid[[i]], ".pdf", sep="")))#width=1000,height=750 plot(values, main =paste("Variable:", typeList.valid[[i]]),xlab="Years") @@ -108,11 +121,27 @@ plotLPJData <- function(x, typeList = NULL, outDir= NULL, save.plots = FALSE, pr plot(values, main =paste("Variable:", typeList.valid[[i]]),xlab="Years") } } + } + if(plot_avg == T){ + for(k in 1:length(typeList.valid)){ + plot(y = average[,typeList.valid[[k]]]/length(gridlist.valid), x = as.numeric(rownames(values)), + main = paste("Average of", "Variable:",typeList.valid[[k]]), + xlab = "Years",ylab = "total", type = "l") + } + + } } +get_gridlist_values <- function(gridcell){ + coordinates = strsplit(gridcell, "c")[[1]][3] + coordinates = unlist(strsplit(coordinates, ",")) + coordinates = sub("\\(","", coordinates) + coordinates = sub("\\)","", coordinates) + return(coordinates) +} diff --git a/rLPJGUESS/R/readTableHeaderLPJ.R b/rLPJGUESS/R/readTableHeaderLPJ.R index e5de9b5..788b485 100644 --- a/rLPJGUESS/R/readTableHeaderLPJ.R +++ b/rLPJGUESS/R/readTableHeaderLPJ.R @@ -14,7 +14,7 @@ readTableHeaderLPJ <- function(x){ columnNames <- unlist(strsplit(splitted_clean, " ")) df <- read.table(x, header =F, skip = 1) - if (ncol(df) != length(columnNames)){ + if(ncol(df) != length(columnNames)){ stop("Model output is not readable") }else{ names(df) <- columnNames diff --git a/rLPJGUESS/R/runLPJ.R b/rLPJGUESS/R/runLPJ.R index dc823e7..75eb51e 100644 --- a/rLPJGUESS/R/runLPJ.R +++ b/rLPJGUESS/R/runLPJ.R @@ -6,8 +6,8 @@ #' character string indicating the path to the directory where #' the model link and template are located, and in which the function will create #' the directory structure for the outputs. -#' @param parameterList either a named list containing the parameters to be calibrated -#' or a matrix. If running in parallel, parameter list should be either a list of of list or +#' @param parameterList a named list containing the parameters (when not run in parallel) to be calibrated +#' or a matrix (when run in parallel). If running in parallel, parameter list should be either a list of of list or #' a matrix where each row is a parameter combination and the column names should be named #' after the parameters. See fucntion \code{\link{getParameterList}}) for default values. #' @param typeList a character vector with the outputs to be analyzed. @@ -105,7 +105,7 @@ #' \linkS4class{LPJSetup}, \code{\link{getParameterList}}, \code{\link{getDesign}} #' @export #' @keywords rLPJGUESS -#' @author Ramiro Silveyra Gonzalez, Maurizio Bagnara, Florian Hartig +#' @author Ramiro Silveyra Gonzalez, Maurizio Bagnara, Florian Hartig, Johannes Oberpriller #' @example /inst/examples/runLPJHelp.R runLPJ <- function(x, settings, typeList=NULL, parameterList=NULL){ @@ -150,7 +150,7 @@ runLPJ <- function(x, settings, typeList=NULL, parameterList=NULL){ #singleRun$template1Mem <- readLines(file.path(singleRun$mainDir, singleRun$template1)) # template 2: the cru or cf template #singleRun$template2Mem <- readLines(file.path(singleRun$mainDir,singleRun$template2)) - result <- try(runLPJWrapper(singleRun), FALSE) + result <- runLPJWrapper(singleRun) if ('try-error' %in% class(result)){ stop("Error when running the model") } @@ -192,19 +192,18 @@ runLPJ <- function(x, settings, typeList=NULL, parameterList=NULL){ #----------------------------------------------------------------------------# message("\n\nReading the parallel object structure") # do the settings check - runParameters <- try(createRunParameters(x, singleRun, parameterList), FALSE) + #runParameters <- try(createRunParameters(x, singleRun, parameterList), FALSE) + runParameters <- createRunParameters(x, singleRun, parameterList) if ('try-error' %in% class(runParameters)){ stop("Invalid settings provided") } # SOCK CLUSTER #----------------------------------------------------------------------------# - # Initialisation of snowfall. - #message("\n");message("\n");str(runParameters[[1]]) # Create cluster if (x@clusterType =="SOCK"){ message( paste ("Creating a", x@clusterType, "cluster with", x@numCores, " cores", sep = " " )) - cl <- snow::makeSOCKcluster(x@numCores) + cl <- snow::makeSOCKcluster(x@numCores,useXDR = F) # Exporting needed data and loading required # packages on workers. --> If daa is loaded firs it can be exporte to all workers snow::clusterEvalQ(cl, library(rLPJGUESS)) @@ -213,15 +212,12 @@ runLPJ <- function(x, settings, typeList=NULL, parameterList=NULL){ message ("Sending tasks to the cores") # Try catch prevent the package for crashing # the implemented try catch in snow is not satisfactory - #result <- try(snow::clusterMap(cl, runLPJWrapper, runParameters ), FALSE) - #if ('try-error' %in% class(result)){ - # stop("Error when running the model") - #} - result <- snow::clusterMap(cl, runLPJWrapper, runParameters ) - #result <- snow::clusterApply(cl, runParameters, runLPJWrapper )resul + result <- try(snow::clusterMap(cl, runLPJWrapper, runParameters), FALSE) + if ('try-error' %in% class(result)){ + stop("Error when running the model") + } # Destroy cluster snow::stopCluster(cl) - # deliver data to clusters # Snow's close command, shuts down and quits from script # MPI CLUSTER diff --git a/rLPJGUESS/R/runLPJWrapper.R b/rLPJGUESS/R/runLPJWrapper.R index 15cf256..12ed14a 100644 --- a/rLPJGUESS/R/runLPJWrapper.R +++ b/rLPJGUESS/R/runLPJWrapper.R @@ -27,24 +27,24 @@ runLPJWrapper <- function(runObject){ stop("Please provide a valid output directory") } if (is.null(runObject[["template1"]])){ - stop("Please provide a valid template1 name") + stop("Please provide a valid template1 name") } if (is.null(runObject[["template2"]])){ - stop("Please provide a valid template2 name") + stop("Please provide a valid template2 name") } #if (is.null(runObject[["parameterList"]])){ No because it could run with default values # stop("Please provide a valid parameter list.") #} - if (is.null(runObject[["plot.data"]])){ + if(is.null(runObject[["plot.data"]])){ warning("The plot.data boolean has not been provided. It will be set to FALSE") runObject$plot.data <- FALSE runObject$save.plots <- FALSE } - if ( is.null(runObject[["save.plots"]])){ + if(is.null(runObject[["save.plots"]])){ warning("The save.plots boolean has not been provided. It will be set to FALSE") runObject$save.plots <- FALSE } - if (is.null(runObject[["typeList"]])){ + if(is.null(runObject[["typeList"]])){ runObject$typeList <- typelist.default warning("The output type list has not been provided") warning("Setting type list to default values") @@ -60,24 +60,28 @@ runLPJWrapper <- function(runObject){ previouswd <- getwd() setwd(runObject$runDir) # write out files - runObject$template1Mem <- sub("path_to_output/", - paste(runObject$outDir, "/", sep =""), runObject$template1Mem) - for ( j in 1:length(runObject$typeList)) { - runObject$template1Mem <- sub(paste("! file", runObject$typeList[j], sep="_"), - paste("file", runObject$typeList[j], sep="_") , runObject$template1Mem) + runObject$template1Mem <- sub("run_outputdirectory", + paste("\"",runObject$outDir, "/","\"", sep =""), runObject$template1Mem) + + ## we have to do an exact search, this here has the problem of + ## cmass and cmass_st would both be activated + for (j in 1:length(runObject$typeList)) { + runObject$template1Mem <- sub(paste("!file", paste0(runObject$typeList[j]," ") ,sep="_"), + paste("file", paste0(runObject$typeList[j], " "),sep="_") , runObject$template1Mem) } writeLines(runObject$template1Mem,file.path(runObject$runDir,runObject$template1)) #runObject$template2Mem <- readLines(file.path(runObject$mainDir,runObject$template2)) runObject$template2Mem <- gsub("path_to_globalTemplate", - paste(runObject$runDir, "/", runObject$template1, sep=""), - runObject$template2Mem ) - runObject$template2Mem <- gsub("_file_gridlist_", - paste(runObject$runDir,"/", runObject$gridList, sep=""), + paste(runObject$runDir, "/", runObject$template1, sep=""), + runObject$template2Mem) + runObject$template2Mem <- sub("_file_gridlist_", + paste(runObject$runDir,"/", runObject$gridList,sep=""), runObject$template2Mem ) - for ( j in 1:length(runObject$filesNames)){ - if (is.na(runObject$filesNames[[j]][2])){ + + for (j in 1:length(runObject$filesNames)){ + if(is.na(runObject$filesNames[[j]][2])){ runObject$template2Mem <- gsub(paste("\\<",runObject$filesNames[[j]][1], "\\>", sep=""), "",runObject$template2Mem) }else{ @@ -86,17 +90,17 @@ runLPJWrapper <- function(runObject){ runObject$template2Mem) } } - for ( j in 1:length(runObject$variablesNames)){ - if (!is.na(runObject$variablesNames[[j]][2])){ - runObject$template2Mem[grep(paste("\\<",runObject$variablesNames[[j]][1], "\\>", sep=""), - runObject$template2Mem, value=F)] <- gsub("! param", "param", - grep(paste("\\<",runObject$variablesNames[[j]][1], "\\>", sep=""), - runObject$template2Mem, value=T)) - runObject$template2Mem <- gsub(paste("\\<",runObject$variablesNames[[j]][1], "\\>", sep=""), - runObject$variablesNames[[j]][2], - runObject$template2Mem) - } - } + # for ( j in 1:length(runObject$variablesNames)){ + # if (!is.na(runObject$variablesNames[[j]][2])){ + # runObject$template2Mem[grep(paste("\\<",runObject$variablesNames[[j]][1], "\\>", sep=""), + # runObject$template2Mem, value=F)] <- gsub("! param", "param", + # grep(paste("\\<",runObject$variablesNames[[j]][1], "\\>", sep=""), + # runObject$template2Mem, value=T)) + # runObject$template2Mem <- gsub(paste("\\<",runObject$variablesNames[[j]][1], "\\>", sep=""), + # runObject$variablesNames[[j]][2], + # runObject$template2Mem) + # } + # } writeLines(runObject$template2Mem,file.path(runObject$runDir,runObject$template2)) writeLines(runObject$gridListCell, file.path(runObject$runDir, runObject$gridList)) @@ -145,7 +149,7 @@ runLPJWrapper <- function(runObject){ outDir = runObject$outDir, save.plots = runObject$save.plots, prefix = paste("run",runObject$runID, "_", sep="")) } - message(paste("Finished run ", runObject$runID, sep = "")) + message(paste("Finished run ", runObject$runID, sep = "")) #----------------------------------------------------------------------------# # END #----------------------------------------------------------------------------# diff --git a/rLPJGUESS/R/sysdata.rda b/rLPJGUESS/R/sysdata.rda index 137759a..73adf10 100644 Binary files a/rLPJGUESS/R/sysdata.rda and b/rLPJGUESS/R/sysdata.rda differ diff --git a/rLPJGUESS/R/writeTemplate.R b/rLPJGUESS/R/writeTemplate.R index a903196..a3f22b5 100644 --- a/rLPJGUESS/R/writeTemplate.R +++ b/rLPJGUESS/R/writeTemplate.R @@ -27,37 +27,38 @@ #' @note Based an older code of Istem Fer, Uni Potsdam #' @example /inst/examples/writeTemplateHelp.R writeTemplate <- function(template1, parameterList, runDir, check = "serial"){ - # Checking provided parameters - if (is.null(runDir) || !file.exists(runDir) ){ - stop("Please provide a valid run directory") - } - if (is.null(template1) || !file.exists(file.path(runDir, template1))){ - stop("The provided template does not exits. Please provide a template name") - } + # if (is.null(runDir) || !file.exists(runDir) ){ + # stop("Please provide a valid run directory") + # } + # if (is.null(template1) || !file.exists(file.path(runDir, template1))){ + # stop("The provided template does not exits. Please provide a template name") + # } if (is.null(parameterList) || !class(parameterList) =="list"){ stop("Please provide a parameterList") } - # call the function - if (grepl("global",template1)){ - # Checking paramaterList and if null, setting to default values - # 256 physiological parameters can be calibrated right now. Exceptions are the fine roots distributions for all PFTs - parameterList <- checkParameters(scale= "global", parameterList, type = check ) - }else if (grepl("europe", template1)){ - # Checking paramaterList and if null, setting to default values - # 585 physiological parameters, both general and species-specific, can be calibrated right now. - # Exceptions are the fine roots distributions for all species and PFTs - parameterList <- checkParameters(scale = "europe", parameterList, type = check) - }else{ - stop("Cannot recognize the template: neither global nor europe") - } - parameterList <- checkParameters.rootDist(parameterList) - # getting parameters names +# # call the function +# if (grepl("global",template1)){ +# # Checking paramaterList and if null, setting to default values +# # 256 physiological parameters can be calibrated right now. Exceptions are the fine roots distributions for all PFTs +# parameterList <- checkParameters(scale= "global", parameterList, type = check ) +# }else if (grepl("europe", template1)){ +# # Checking paramaterList and if null, setting to default values +# # 585 physiological parameters, both general and species-specific, can be calibrated right now. +# # Exceptions are the fine roots distributions for all species and PFTs +# parameterList <- checkParameters(scale = "europe", parameterList, type = check) +# }else{ +# stop("Cannot recognize the template: neither global nor europe") +# } +# parameterList <- checkParameters.rootDist(parameterList) +# # getting parameters names parameterNames <- names(parameterList) + #message(parameterNames) # looping over parameters ## Faster + #print(str(parameterList)) template <- readLines(file.path(runDir, template1)) - for(i in 1:length(parameterNames)) { - template <- sub( parameterNames[i], parameterList[[i]], template) + for(i in 1:length(parameterNames)){ + template <- gsub(paste0(" ",parameterNames[i]," "), paste0(" ",parameterList[[i]]," "), template) } writeLines(template, file.path(runDir, template1)) }