@@ -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