Skip to content

Commit 5b20889

Browse files
committed
Update world_gen.R
1 parent b898faf commit 5b20889

1 file changed

Lines changed: 71 additions & 41 deletions

File tree

R/world_gen.R

Lines changed: 71 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -121,37 +121,51 @@ world_gen = function(template,
121121
# If n_basestations is 0 -> do NOT include base_station_ID
122122
# If n_basestations is > 0 -> must include base_station_ID, even if doing redefine w/ -9999
123123
n_basestations_index = which(endsWith(var_names, "n_basestations"))
124+
if (length(n_basestations_index) != 5) {stop("Could not find state variable 'n_basestations' at each level, variable must be present - check template")}
125+
126+
# check base_station to basestation since thats current in code
127+
base_station_wrong = which(endsWith(var_names, "base_station_ID"))
128+
if (length(base_station_wrong) > 0) {
129+
#change var names everywhere
130+
warning("State variable '<level>_base_station_ID' should be '<level>_basestation_ID' in RHESSys 7.1+")
131+
fix = FALSE
132+
if (fix) {
133+
var_names[base_station_wrong] = gsub("base_station_ID", "basestation_ID", var_names[base_station_wrong])
134+
template_clean[[base_station_wrong]][1] = gsub("base_station_ID", "basestation_ID", template_clean[[base_station_wrong]][1])
135+
}
136+
}
137+
basestation_ID_index = which(endsWith(var_names, "base_station_ID") | endsWith(var_names, "basestation_ID"))
124138

125139
# get n basestations , check that strata are the same
126140
n_base = sapply(template_clean[n_basestations_index],FUN = function(x) as.integer(unique(x[3:length(x)])))
127141
if (length(n_base[[5]]) > 1) {stop(noquote("Canopy Strata n_basestations are inconsistent"))}
128-
n_base_nl = template_clean[n_basestations_index + 1] # get next line
129-
id_bad = n_base == 0 & !sapply(n_base_nl,is.null) # t/t for if n_base is 0 and next line IS base_station_ID
130-
131-
id_bad[id_bad] = grepl("basestation_ID",unlist(lapply(n_base_nl[id_bad],"[[",1))) # get var names of next lines, update id_bad
132-
133-
id_need = n_base > 0 & !sapply(n_base_nl,is.null) # t/f for if n_base is >0 and next line IS NOT base_station_ID
134-
id_need[id_need] = !grepl("basestation_ID",unlist(lapply(n_base_nl[id_need],"[[",1))) # get var names of next lines, update id_bad
135-
136-
if (any(id_need)) {
137-
i_need = n_basestations_index[id_need]
138-
stop(noquote(paste("n_basestations on template line(s)",paste(i_need,collapse = ", "),
139-
"is >0 & the following line is missing a base_station_ID.\n Either set n_basestations to 0 or add the base_station_ID.")))
140-
}
141-
142-
if (any(id_bad)) {
143-
# indices to remove
144-
i_rm = n_basestations_index[id_bad]
145-
# removes from list and names vector regardless of if ID is -9999 or not
146-
template_clean = template_clean[-(i_rm + 1)]
147-
var_names = var_names[-(i_rm + 1)]
148-
# shift indices
149-
level_index[level_index > min(i_rm + 1)] = level_index[level_index > min(i_rm + 1)] - 1
150-
var_index = var_index[-which(var_index == i_rm + 1)]
151-
var_index[var_index > min(i_rm + 1)] = var_index[var_index > min(i_rm + 1)] - 1
152-
print(paste("n_basestations on template line(s)", paste(i_rm,collapse = ", "),
153-
"is 0. The base_station_ID on the following line has been omitted from the worldfile."),quote = FALSE)
154-
}
142+
for (i in seq_along(n_basestations_index)) {
143+
if (n_base[i] > 0) {
144+
if (!any((n_basestations_index[i] + 1) %in% basestation_ID_index)) {
145+
stop(noquote(paste("Missing basestation_ID on line", n_basestations_index[i] + 1,
146+
", ID is required since previous n_basestations is > 0, please fix in template")))
147+
}
148+
} else if (n_base[i] == 0) {
149+
if (any((n_basestations_index[i] + 1) %in% basestation_ID_index)) {
150+
stop(noquote(paste("Basestation_ID is present on line", n_basestations_index[i] + 1,
151+
" while previous n_basestations is 0, either remove basestation_ID or modify n_basestaions to be > 0")))
152+
fixthis = FALSE
153+
if (fixthis) {
154+
# indices to remove
155+
i_rm = n_basestations_index[id_bad]
156+
# removes from list and names vector regardless of if ID is -9999 or not
157+
template_clean = template_clean[-(i_rm + 1)]
158+
var_names = var_names[-(i_rm + 1)]
159+
# shift indices
160+
level_index[level_index > min(i_rm + 1)] = level_index[level_index > min(i_rm + 1)] - 1
161+
var_index = var_index[-which(var_index == i_rm + 1)]
162+
var_index[var_index > min(i_rm + 1)] = var_index[var_index > min(i_rm + 1)] - 1
163+
print(paste("n_basestations on template line(s)", paste(i_rm,collapse = ", "),
164+
"is 0. The base_station_ID on the following line has been omitted from the worldfile."),quote = FALSE)
165+
}
166+
}
167+
}
168+
} # end loop through n_basestations
155169

156170
# -------------------- Process Template + Maps --------------------
157171
# Build list based on operations called for by template
@@ -171,23 +185,42 @@ world_gen = function(template,
171185
strata = 1
172186
}
173187

174-
for (s in strata) {
175-
# evalueate based on operator at 2nd element
176-
if (template_clean[[i]][2] == "value") { #use value
177-
if (suppressWarnings(all(is.na(as.numeric(template_clean[[i]][2 + s]))))) {
178-
stop(noquote(paste("\"",template_clean[[i]][2 + s],"\" on template line ",i," is not a valid value.",sep = "")))
188+
# some error check, line by line
189+
if (template_clean[[i]][2] %in% c("value", "dvalue")) {
190+
if (suppressWarnings(all(is.na(as.numeric(template_clean[[i]][3]))))) {
191+
stop(noquote(paste0("\"",template_clean[[i]][3],"\" on template line ",i," is not a valid value.")))
192+
}
193+
if (length(strata) == 2) {
194+
if (suppressWarnings(all(is.na(as.numeric(template_clean[[i]][4]))))) {
195+
stop(noquote(paste0("\"",template_clean[[i]][4],"\" on template line ",i," is not a valid value.")))
179196
}
180-
statevars[[i]][[s]] = as.double(template_clean[[i]][2 + s])
197+
}
198+
}
181199

182-
} else if (template_clean[[i]][2] == "dvalue") { #integer value
183-
statevars[[i]][[s]] = as.integer(template_clean[[i]][2 + s])
200+
strata_values = 2
201+
if (length(template_clean[[i]]) != 2 + length(strata) & template_clean[[i]][2] %in% c("value", "dvalue", "aver", "mode")) {
202+
if (length(template_clean[[i]]) == 2) {
203+
stop(noquote(paste0("Only 2 elements recognized ontemplate line ", i, ", expected format is <var name> <function> <value>")))
204+
} else if (length(template_clean[[i]]) == 3 & length(strata) == 2) {
205+
#warning("Using value '", template_clean[[i]][3], "' on template line ", i, " for both canopy strata")
206+
strata_values = 1
207+
}
208+
}
184209

210+
s2 = 0
211+
for (s in strata) {
212+
if (s == 2 & strata_values == 1) {
213+
s2 = 1
214+
}
215+
if (template_clean[[i]][2] == "value") { # value (numeric)
216+
statevars[[i]][[s]] = as.double(template_clean[[i]][2 + s - s2])
217+
} else if (template_clean[[i]][2] == "dvalue") { #integer value
218+
statevars[[i]][[s]] = as.integer(template_clean[[i]][2 + s - s2])
185219
} else if (template_clean[[i]][2] == "aver") { #average
186-
maptmp = as.vector(t(map_df[template_clean[[i]][2 + s]]))
220+
maptmp = as.vector(t(map_df[template_clean[[i]][2 + s - s2]]))
187221
statevars[[i]][[s]] = aggregate(maptmp, by = level_agg, FUN = "mean")
188-
189222
} else if (template_clean[[i]][2] == "mode") { #mode
190-
maptmp = as.vector(t(map_df[template_clean[[i]][2 + s]]))
223+
maptmp = as.vector(t(map_df[template_clean[[i]][2 + s - s2]]))
191224
statevars[[i]][[s]] = aggregate(
192225
maptmp,
193226
by = level_agg,
@@ -196,12 +229,10 @@ world_gen = function(template,
196229
ux[which.max(tabulate(match(x, ux)))]
197230
}
198231
)
199-
200232
} else if (template_clean[[i]][2] == "eqn") { # only for horizons old version -- use normal mean in future
201233
maptmp = as.vector(t(map_df[template_clean[[i]][5]]))
202234
statevars[[i]][[s]] = aggregate(maptmp, by = level_agg, FUN = "mean")
203235
statevars[[i]][[s]][, "x"] = statevars[[i]][[s]][, "x"] * as.numeric(template_clean[[i]][3])
204-
205236
} else if (template_clean[[i]][2] == "spavg") { #spherical average
206237
maptmp = as.vector(t(map_df[template_clean[[i]][3]]))
207238
rad = (maptmp * pi) / (180) #convert to radians
@@ -218,7 +249,6 @@ world_gen = function(template,
218249
statevars[[i]][[s]][, "x"] = aspect_deg
219250
} else if (template_clean[[i]][2] == "area") { #only for state var area
220251
statevars[[i]][[s]] = aggregate(cellarea, by = level_agg, FUN = "sum")
221-
222252
} else {
223253
print(paste("Unexpected 2nd element on line", i))
224254
}

0 commit comments

Comments
 (0)