source: palm/trunk/SCRIPTS/palm_csd @ 4793

Last change on this file since 4793 was 4793, checked in by maronga, 4 years ago

allow for overhanging vegetation in palm_csd

  • Property svn:executable set to *
  • Property svn:keywords set to Id
File size: 62.3 KB
RevLine 
[3567]1#!/usr/bin/env python3
2# -*- coding: utf-8 -*-
3#--------------------------------------------------------------------------------#
4# This file is part of the PALM model system.
5#
6# PALM is free software: you can redistribute it and/or modify it under the terms
7# of the GNU General Public License as published by the Free Software Foundation,
8# either version 3 of the License, or (at your option) any later version.
9#
10# PALM is distributed in the hope that it will be useful, but WITHOUT ANY
11# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
12# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
13#
14# You should have received a copy of the GNU General Public License along with
15# PALM. If not, see <http://www.gnu.org/licenses/>.
16#
[4481]17# Copyright 1997-2020  Leibniz Universitaet Hannover
[3567]18#--------------------------------------------------------------------------------#
19#
20# Current revisions:
21# -----------------
[4746]22#
23#
[3567]24# Former revisions:
25# -----------------
26# $Id: palm_csd 4793 2020-11-24 09:48:21Z maronga $
[4793]27# Added output of tree_type (species or classification). Added tree_id for
28# vegetation patches. Allow for overlapping vegetation with buildings
29#
30# 4749 2020-10-16 11:21:27Z maronga
[4749]31# Bugfix: processing of patch height faulty for multiple domains
32#
33# 4746 2020-10-15 17:16:30Z maronga
[4746]34# Add support for backyard high vegetation, which is commonly classified as
35# short grass
36#
37# 4490 2020-04-10 05:32:45Z maronga
[4490]38# Bugfix: call of canopy generator was not made if tree heights were only
39# available via patch_height, but not in tree_height
40#
41# 4481 2020-03-31 18:55:54Z maronga
[4311]42# Bugfix: green roofs were assigned to all available roofs when switched on
43#
44# 4149 2019-08-08 14:02:18Z suehring
[4149]45# Bugfix, nbuilding_pars was 1 element to small
46#
47# 3955 2019-05-07 09:55:25Z maronga
[3955]48# Bugfix in preparaing of green roofs
49# Bugfix: remove LAI for bare soils
50#
51# 3859 2019-04-03 20:30:31Z maronga
[3859]52# Bugfix: wrong variable naming for 'y'
53#
54# 3773 2019-03-01 08:56:57Z maronga
[3773]55# Unspecificed changes
56#
57# 3726 2019-02-07 18:22:49Z maronga
[3726]58# Removed some more bugs
59#
60# 3688 2019-01-22 10:44:20Z maronga
[3688]61# Some unspecified bugfixes
62#
63# 3668 2019-01-14 12:49:24Z maronga
[3668]64# Various improvements and bugfixes
65#
66# 3629 2018-12-13 12:18:54Z maronga
[3629]67# Added canopy generator calls. Some improvements
68#
69# 3567 2018-11-27 13:59:21Z maronga
[3567]70# Initial revisions
71#
72# Description:
73# ------------
74# Processing tool for creating PIDS conform static drivers from rastered NetCDF
75# input
76#
77# @Author Bjoern Maronga (maronga@muk.uni-hannover.de)
78#
79# @todo Make input files optional
80# @todo Allow for ASCII input of terrain height and building height
81# @todo Modularize reading config file
[3688]82# @todo Convert to object-oriented treatment (buidings, trees)
83# @todo Automatically shift child domains so that their origin lies intersects
84#       a edge note of the parent grid
[3567]85#------------------------------------------------------------------------------#
86
87from palm_csd_files.palm_csd_netcdf_interface import *
88from palm_csd_files.palm_csd_tools import *
[3629]89from palm_csd_files.palm_csd_canopy_generator import *
[3567]90import numpy as np
91
92   
93def read_config_file():
94   
95   import configparser
96   from math import floor
97   import numpy as np
98   import os
99   import subprocess as sub
100   import sys
101
102#  Check if configuration files exists and quit otherwise
103   input_config = ".csd.config"
104   for i in range(1,len(sys.argv)): 
105      input_config = str(sys.argv[i])
106       
107   config = configparser.RawConfigParser(allow_no_value=True)
108
109   if ( os.path.isfile(input_config) == False ):
110      print ("Error. No configuration file " + input_config + " found.")
111      raise SystemExit   
112
113   config.read(input_config)
114
115
116#  Definition of settings
[3668]117
[3567]118   global settings_bridge_width
[3629]119   global settings_lai_roof_intensive
120   global settings_lai_roof_extensive
121   global settings_season
122   global settings_lai_low_default
123   global settings_lai_high_default
124   global settings_patch_height_default
125   global settings_lai_alpha
126   global settings_lai_beta
[3955]127   global settings_veg_type_below_trees
[3567]128   global ndomains
129
130#  Definition of global configuration parameters
131   global global_acronym
132   global global_angle
133   global global_author
134   global global_campaign
135   global global_comment
136   global global_contact
137   global global_data_content 
138   global global_dependencies
139   global global_institution
140   global global_keywords
141   global global_location
142   global global_palm_version
143   global global_references
144   global global_site
145   global global_source
146
[3668]147   global  path_out
148   global filename_out
149   global version_out
[3567]150
[3668]151
[3567]152#  Definition of domain parameters
153   global domain_names
154   global domain_px
155   global domain_x0
156   global domain_y0
157   global domain_x1
158   global domain_y1
159   global domain_nx
160   global domain_ny
161   global domain_dz
162   global domain_3d
[3629]163   global domain_high_vegetation
[3567]164   global domain_ip
165   global domain_za
166   global domain_parent
[3629]167   global domain_green_roofs
168   global domain_street_trees
169   global domain_canopy_patches
[4793]170   global domain_overhanging_trees
[3567]171
172#  Definition of input data parameters
173   global input_names
174   global input_px
175 
176       
177   global input_file_x
178   global input_file_y
179   global input_file_x_UTM
180   global input_file_y_UTM   
181   global input_file_lat
182   global input_file_lon 
183   global input_file_zt
184   global input_file_buildings_2d
185   global input_file_bridges_2d
186   global input_file_building_id
187   global input_file_bridges_id   
188   global input_file_building_type
189   global input_file_building_type
[3629]190   global input_file_lai 
[3567]191   global input_file_vegetation_type
192   global input_file_vegetation_height
193   global input_file_pavement_type
194   global input_file_water_type
195   global input_file_street_type
196   global input_file_street_crossings
197   global input_file_soil_type
[3629]198   global input_file_vegetation_on_roofs
199   global input_file_tree_crown_diameter
200   global input_file_tree_height
201   global input_file_tree_trunk_diameter
202   global input_file_tree_type
203   global input_file_patch_height
[3567]204
205   global zt_all
206   global zt_min
207
208   settings_bridge_width = 3.0
[3955]209   settings_lai_roof_intensive = 2.5
210   settings_lai_roof_extensive = 0.8
[3629]211   settings_season = "summer"
212   settings_lai_high_default = 6.0
213   settings_lai_low_default = 1.0
214   settings_patch_height_default = 10.0
215   settings_lai_alpha = 5.0
216   settings_lai_beta = 3.0
[3955]217   settings_veg_type_below_trees = 3
[3567]218   ndomains = 0
219
220   global_acronym = ""
221   global_angle = ""
222   global_author = ""
223   global_campaign = ""
224   global_comment = ""
225   global_contact = ""
226   global_data_content = ""
227   global_dependencies = ""
228   global_institution = ""
229   global_keywords = ""
230   global_location = ""
231   global_palm_version = 6.0
232   global_references = ""
233   global_site = ""
234   global_source = ""
235
[3668]236   path_out = ""
237   version_out = 1
238   filename_out = "default"
239   
[3567]240   domain_names = []
241   domain_px = []
242   domain_x0 = []
243   domain_y0 = []
244   domain_x1 = []
245   domain_y1 = []
246   domain_nx = []
247   domain_ny = []
248   domain_dz = []
249   domain_3d = []
[3629]250   domain_high_vegetation = []
[3567]251   domain_ip = []
252   domain_za = []
253   domain_parent = []
[3629]254   domain_green_roofs = []
255   domain_street_trees = []
256   domain_canopy_patches = []
[4793]257   domain_overhanging_trees = []
[3567]258
259   zt_min = 0.0
260   zt_all = []
261
262   input_names = []
263   input_px = []
264
265   input_file_x = []
266   input_file_y = [] 
267   input_file_x_UTM = []
268   input_file_y_UTM = [] 
269   input_file_lat = []
270   input_file_lon = [] 
271   
272   input_file_zt = []
273   input_file_buildings_2d = []
274   input_file_bridges_2d = []
275   input_file_building_id = []
276   input_file_bridges_id = []   
277   input_file_building_type = []
[3629]278   input_file_lai = []
[3567]279   input_file_vegetation_type = []
280   input_file_vegetation_height = []   
281   input_file_pavement_type = []
282   input_file_water_type = []
283   input_file_street_type = [] 
284   input_file_street_crossings = []     
285   input_file_soil_type = []
[3629]286   input_file_vegetation_on_roofs = []
287   input_file_tree_crown_diameter = []
288   input_file_tree_height = []
289   input_file_tree_trunk_diameter = []
290   input_file_tree_type = []
291   input_file_patch_height = []
[3567]292   
293# Load all user parameters from config file
294   for i in range(0,len(config.sections())):
295
296      read_tmp = config.sections()[i]
297     
298      if ( read_tmp == 'global' ):
299         global_acronym = config.get(read_tmp, 'acronym')
300         global_angle = float(config.get(read_tmp, 'rotation_angle'))
301         global_author = config.get(read_tmp, 'author')
302         global_campaign = config.get(read_tmp, 'campaign')
303         global_comment = config.get(read_tmp, 'comment')
304         global_contact = config.get(read_tmp, 'contact_person')
305         global_data_content = config.get(read_tmp, 'data_content')   
306         global_dependencies = config.get(read_tmp, 'dependencies')
307         global_institution = config.get(read_tmp, 'institution')
308         global_keywords = config.get(read_tmp, 'keywords')
309         global_location = config.get(read_tmp, 'location')
310         global_palm_version = float(config.get(read_tmp, 'palm_version'))
311         global_references = config.get(read_tmp, 'references')
312         global_site = config.get(read_tmp, 'site')
313         global_source = config.get(read_tmp, 'source')
314
[3668]315
[3567]316      if ( read_tmp == 'settings' ):
[3629]317         settings_lai_roof_intensive = config.get(read_tmp, 'lai_roof_intensive')
318         settings_lai_roof_extensive = config.get(read_tmp, 'lai_roof_extensive') 
319         settings_bridge_width = float(config.get(read_tmp, 'bridge_width'))   
320         settings_season = config.get(read_tmp, 'season')   
321         settings_lai_high_default = float(config.get(read_tmp, 'lai_high_vegetation_default'))
322         settings_lai_low_default = float(config.get(read_tmp, 'lai_low_vegetation_default'))         
323         settings_patch_height_default = float(config.get(read_tmp, 'patch_height_default')) 
324         settings_lai_alpha = float(config.get(read_tmp, 'lai_alpha')) 
325         settings_lai_beta = float(config.get(read_tmp, 'lai_beta')) 
[3955]326         settings_veg_type_below_trees = config.get(read_tmp, 'vegetation_type_below_trees') 
[3629]327
[3668]328      if ( read_tmp == 'output' ):
329         path_out = config.get(read_tmp, 'path')         
330         filename_out = config.get(read_tmp, 'file_out')
331         version_out = float(config.get(read_tmp, 'version'))
332
[3567]333      if ( read_tmp.split("_")[0] == 'domain' ):
334         ndomains = ndomains + 1
335         domain_names.append(read_tmp.split("_")[1])
336         domain_px.append(float(config.get(read_tmp, 'pixel_size')))
337         domain_nx.append(int(config.get(read_tmp, 'nx')))
338         domain_ny.append(int(config.get(read_tmp, 'ny')))
339         domain_dz.append(float(config.get(read_tmp, 'dz')))       
340         domain_3d.append(config.getboolean(read_tmp, 'buildings_3d'))
[3629]341         domain_high_vegetation.append(config.getboolean(read_tmp, 'allow_high_vegetation'))
342         domain_canopy_patches.append(config.getboolean(read_tmp, 'generate_vegetation_patches'))       
[3567]343         domain_ip.append(config.getboolean(read_tmp, 'interpolate_terrain'))
344         domain_za.append(config.getboolean(read_tmp, 'use_palm_z_axis')) 
345         if domain_ip[ndomains-1] and not domain_za[ndomains-1]:
346            domain_za[ndomains-1] = True
347            print("+++ Overwrite user setting for use_palm_z_axis")
348         
349         domain_parent.append(config.get(read_tmp, 'domain_parent'))
350
351         domain_x0.append(int(floor(float(config.get(read_tmp, 'origin_x'))/float(config.get(read_tmp, 'pixel_size')))))
352         domain_y0.append(int(floor(float(config.get(read_tmp, 'origin_y'))/float(config.get(read_tmp, 'pixel_size')))))       
353         domain_x1.append(int(floor(float(config.get(read_tmp, 'origin_x'))/float(config.get(read_tmp, 'pixel_size'))) + int(config.get(read_tmp, 'nx'))))
354         domain_y1.append(int(floor(float(config.get(read_tmp, 'origin_y'))/float(config.get(read_tmp, 'pixel_size'))) + int(config.get(read_tmp, 'ny'))))
[3629]355         domain_green_roofs.append(config.getboolean(read_tmp, 'vegetation_on_roofs')) 
356         domain_street_trees.append(config.getboolean(read_tmp, 'street_trees')) 
[4793]357         domain_overhanging_trees.append(config.getboolean(read_tmp, 'overhanging_trees')) 
358                 
[3567]359      if ( read_tmp.split("_")[0] == 'input' ):
360         input_names.append(read_tmp.split("_")[1])
361         input_px.append(float(config.get(read_tmp, 'pixel_size')))
362         input_file_x.append(config.get(read_tmp, 'path') + "/" + config.get(read_tmp, 'file_x'))
363         input_file_y.append(config.get(read_tmp, 'path') + "/" + config.get(read_tmp, 'file_y')) 
364         input_file_lat.append(config.get(read_tmp, 'path') + "/" + config.get(read_tmp, 'file_lat'))
365         input_file_lon.append(config.get(read_tmp, 'path') + "/" + config.get(read_tmp, 'file_lon'))   
366         input_file_x_UTM.append(config.get(read_tmp, 'path') + "/" + config.get(read_tmp, 'file_x_UTM'))
367         input_file_y_UTM.append(config.get(read_tmp, 'path') + "/" + config.get(read_tmp, 'file_y_UTM')) 
368         input_file_zt.append(config.get(read_tmp, 'path') + "/" + config.get(read_tmp, 'file_zt'))
369         input_file_buildings_2d.append(config.get(read_tmp, 'path') + "/" + config.get(read_tmp, 'file_buildings_2d'))
370         input_file_bridges_2d.append(config.get(read_tmp, 'path') + "/" + config.get(read_tmp, 'file_bridges_2d'))
371         input_file_building_id.append(config.get(read_tmp, 'path') + "/" + config.get(read_tmp, 'file_building_id')) 
372         input_file_bridges_id.append(config.get(read_tmp, 'path') + "/" + config.get(read_tmp, 'file_bridges_id')) 
[3629]373         input_file_building_type.append(config.get(read_tmp, 'path') + "/" + config.get(read_tmp, 'file_building_type'))
374         input_file_lai.append(config.get(read_tmp, 'path') + "/" + config.get(read_tmp, 'file_lai'))         
[3567]375         input_file_vegetation_type.append(config.get(read_tmp, 'path') + "/" + config.get(read_tmp, 'file_vegetation_type')) 
376         input_file_vegetation_height.append(config.get(read_tmp, 'path') + "/" + config.get(read_tmp, 'file_vegetation_height'))         
377         input_file_pavement_type.append(config.get(read_tmp, 'path') + "/" + config.get(read_tmp, 'file_pavement_type'))   
378         input_file_water_type.append(config.get(read_tmp, 'path') + "/" + config.get(read_tmp, 'file_water_type'))
379         input_file_street_type.append(config.get(read_tmp, 'path') + "/" + config.get(read_tmp, 'file_street_type'))   
[3629]380         input_file_street_crossings.append(config.get(read_tmp, 'path') + "/" + config.get(read_tmp, 'file_street_crossings')) 
381         input_file_patch_height.append(config.get(read_tmp, 'path') + "/" + config.get(read_tmp, 'file_patch_height')) 
[3668]382         
383         tmp = config.get(read_tmp, 'file_tree_crown_diameter')
384         if tmp is not None:
385            input_file_tree_crown_diameter.append(config.get(read_tmp, 'path') + "/" + tmp) 
386         else:
387            input_file_tree_crown_diameter.append(None)
[3629]388         input_file_tree_height.append(config.get(read_tmp, 'path') + "/" + config.get(read_tmp, 'file_tree_height')) 
389         input_file_tree_trunk_diameter.append(config.get(read_tmp, 'path') + "/" + config.get(read_tmp, 'file_tree_trunk_diameter')) 
390         input_file_tree_type.append(config.get(read_tmp, 'path') + "/" + config.get(read_tmp, 'file_tree_type')) 
391         input_file_vegetation_on_roofs.append(config.get(read_tmp, 'path') + "/" + config.get(read_tmp, 'file_vegetation_on_roofs'))           
[3567]392         #input_file_soil_type.append(config.get(read_tmp, 'path') + "/" + config.get(read_tmp, 'file_soil_type'))   
393   return 0
394
395
396############################################################
397
398# Start of main program
399datatypes = {
400   "x": "f4", 
401   "y": "f4", 
402   "z": "f4", 
403   "lat": "f4", 
404   "lon": "f4",   
405   "E_UTM": "f4", 
406   "N_UTM": "f4", 
407   "zt": "f4",
408   "buildings_2d": "f4",
409   "buildings_3d": "b",
410   "bridges_2d": "f4",
411   "building_id": "i",
412   "bridges_id": "i",
413   "building_type": "b",
414   "nsurface_fraction": "i",
415   "vegetation_type": "b",
416   "vegetation_height": "f4",
417   "pavement_type": "b", 
418   "water_type": "b", 
419   "street_type": "b", 
420   "street_crossings": "b",     
421   "soil_type": "b",
[3629]422   "surface_fraction": "f4",
423   "building_pars": "f4",
424   "vegetation_pars": "f4",
425   "tree_data": "f4",
[4793]426   "tree_id": "i", 
427   "tree_type": "f4",
428   "tree_types": "b", 
[3629]429   "nbuilding_pars": "i",
430   "nvegetation_pars": "i",
431   "zlad": "f4"
[3567]432   }
433
434fillvalues = {
435   "lat": float(-9999.0),
436   "lon": float(-9999.0),
437   "E_UTM": float(-9999.0),
438   "N_UTM": float(-9999.0),   
439   "zt": float(-9999.0),
440   "buildings_2d": float(-9999.0),
441   "buildings_3d": np.byte(-127),
442   "bridges_2d": float(-9999.0),
443   "building_id": int(-9999),
444   "bridges_id": int(-9999),
445   "building_type": np.byte(-127),
446   "nsurface_fraction": int(-9999),
447   "vegetation_type": np.byte(-127),
448   "vegetation_height": float(-9999.0),
449   "pavement_type": np.byte(-127),
450   "water_type": np.byte(-127),
451   "street_type": np.byte(-127), 
452   "street_crossings": np.byte(-127),   
453   "soil_type": np.byte(-127),
[3629]454   "surface_fraction": float(-9999.0),
455   "building_pars": float(-9999.0),
456   "vegetation_pars": float(-9999.0),
457   "tree_data": float(-9999.0),
[4793]458   "tree_id": int(-9999),
459   "tree_type": float(-9999.0),
460   "tree_types": np.byte(-127)
[3567]461   }
462
463defaultvalues = {
464   "lat": float(-9999.0),
465   "lon": float(-9999.0),
466   "E_UTM": float(-9999.0),
467   "N_UTM": float(-9999.0), 
468   "zt": float(0.0),
469   "buildings_2d": float(0.0),
470   "buildings_3d": 0,   
471   "bridges_2d": float(0.0),
472   "building_id": int(0),
473   "bridges_id": int(0),
474   "building_type": 1,
475   "nsurface_fraction": int(-9999),
476   "vegetation_type": 3,
477   "vegetation_height": float(-9999.0),
478   "pavement_type": 1, 
479   "water_type": 1, 
480   "street_type": 1, 
481   "street_crossings": 0,   
482   "soil_type": 1,
[3629]483   "surface_fraction": float(0.0),
484   "buildings_pars": float(-9999.0),
485   "tree_data": float(-9999.0),
[4793]486   "tree_type": np.byte(-127),
[3629]487   "vegetation_pars": float(-9999.0)   
[3567]488   }
489 
490# Read configuration file and set parameters accordingly
491read_config_file()
492
493
494filename = []
495ii = []
496ii_parent = []
497# Define indices and filenames for all domains and create netCDF files
498for i in range(0,ndomains):
499
500#  Calculate indices and input files
501   ii.append(input_px.index(domain_px[i]))
[3668]502   filename.append(path_out + "/" + filename_out + "_" + domain_names[i])
[3567]503   if domain_parent[i] is not None:
[3726]504      ii_parent.append(input_px.index(domain_px[domain_names.index(domain_parent[i])]))
[3567]505   else:
506      ii_parent.append(None)
507
508
[3726]509   x_UTM = nc_read_from_file_2d(input_file_x[ii[i]], "Band1", domain_x0[i], domain_x0[i]+1, domain_y0[i], domain_y0[i]+1)
510   y_UTM = nc_read_from_file_2d(input_file_y[ii[i]], "Band1", domain_x0[i], domain_x0[i]+1, domain_y0[i], domain_y0[i]+1)
511   lat = nc_read_from_file_2d(input_file_lat[ii[i]], "Band1", domain_x0[i], domain_x0[i]+1, domain_y0[i], domain_y0[i]+1)
512   lon = nc_read_from_file_2d(input_file_lon[ii[i]], "Band1", domain_x0[i], domain_x0[i]+1, domain_y0[i], domain_y0[i]+1) 
[3567]513   
[3726]514#  Calculate position of origin
515   x_UTM_origin = float(x_UTM[0,0]) - 0.5 * (float(x_UTM[0,1]) - float(x_UTM[0,0]))
516   y_UTM_origin = float(y_UTM[0,0]) - 0.5 * (float(y_UTM[1,0]) - float(y_UTM[0,0])) 
517   x_origin = float(lon[0,0]) - 0.5 * (float(lon[0,1]) - float(lon[0,0]))
518   y_origin = float(lat[0,0]) - 0.5 * (float(lat[1,0]) - float(lat[0,0]))   
519   
[3567]520#  Create NetCDF output file and set global attributes
521   nc_create_file(filename[i])
[3726]522   nc_write_global_attributes(filename[i],x_UTM_origin,y_UTM_origin,y_origin,x_origin,"",global_acronym,global_angle,global_author,global_campaign,global_comment,global_contact,global_data_content,global_dependencies,global_institution,global_keywords,global_location,global_palm_version,global_references,global_site,global_source,version_out)
[3567]523
[3688]524   del x_UTM, y_UTM, lat, lon
[3567]525   
526# Process terrain height
527for i in range(0,ndomains):
528
529#  Read and write terrain height (zt)
530   zt = nc_read_from_file_2d(input_file_zt[ii[i]], 'Band1', domain_x0[i], domain_x1[i], domain_y0[i], domain_y1[i])
531
532#  Final step: add zt array to the global array   
533   zt_all.append(zt)
534   del zt
535 
536#  Calculate the global (all domains) minimum of the terrain height. This value will be substracted for all
537#  data sets
538zt_min = min(zt_all[0].flatten()) 
539for i in range(0,ndomains):
540   zt_min = min(zt_min,min(zt_all[i].flatten()))
541   
542del zt_all[:]
543
[3726]544print( "Shift terrain heights by -" + str(zt_min))
[3567]545for i in range(0,ndomains):
546
547#  Read and write terrain height (zt)
548   zt = nc_read_from_file_2d(input_file_zt[ii[i]], 'Band1', domain_x0[i], domain_x1[i], domain_y0[i], domain_y1[i])
549   x = nc_read_from_file_1d(input_file_x[ii[i]], "x", domain_x0[i], domain_x1[i])
550   y = nc_read_from_file_1d(input_file_y[ii[i]], "y", domain_y0[i], domain_y1[i])
551
[3726]552 
[3567]553   zt = zt - zt_min
[3668]554   
555   nc_write_global_attribute(filename[i], 'origin_z', float(zt_min))
[3567]556
557#  If necessary, interpolate parent domain terrain height on child domain grid and blend the two
558   if domain_ip[i]:
[3726]559      parent_id = domain_names.index(domain_parent[i])
560      tmp_x0 = int( domain_x0[i] * domain_px[i] / domain_px[parent_id] ) - 1
561      tmp_y0 = int( domain_y0[i] * domain_px[i] / domain_px[parent_id] ) - 1
562      tmp_x1 = int( domain_x1[i] * domain_px[i] / domain_px[parent_id] ) + 1
563      tmp_y1 = int( domain_y1[i] * domain_px[i] / domain_px[parent_id] ) + 1
564
[3567]565      tmp_x = nc_read_from_file_1d(input_file_x[ii_parent[i]], "x", tmp_x0, tmp_x1)
566      tmp_y = nc_read_from_file_1d(input_file_y[ii_parent[i]], "y", tmp_y0, tmp_y1)
567
568      zt_parent = nc_read_from_file_2d(input_file_zt[ii_parent[i]], 'Band1', tmp_x0, tmp_x1, tmp_y0, tmp_y1)
569
570      zt_parent = zt_parent - zt_min
571
572#     Interpolate array and bring to PALM grid of child domain
573      zt_ip = interpolate_2d(zt_parent,tmp_x,tmp_y,x,y)
[3726]574      zt_ip = bring_to_palm_grid(zt_ip,x,y,domain_dz[parent_id])
575     
576     
577#     Shift the child terrain height according to the parent mean terrain height
[3773]578      print("shifting: -" + str(np.mean(zt)) + " +" + str(np.mean(zt_ip)))
579      #zt = zt - np.min(zt) + np.min(zt_ip)
[3726]580      zt = zt - np.mean(zt) + np.mean(zt_ip)
[3567]581 
582 
583#     Blend over the parent and child terrain height within a radius of 50 px 
584      zt = blend_array_2d(zt,zt_ip,50)
[3773]585     # zt = zt_ip
[3567]586   
587#  Final step: add zt array to the global array   
[3726]588
[3567]589   zt_all.append(zt)
590   del zt
591 
592
593# Read and shift x and y coordinates, shift terrain height according to its minimum value and write all data
594# to file 
595for i in range(0,ndomains):   
596#  Read horizontal grid variables from zt file and write them to output file
597   x = nc_read_from_file_1d(input_file_x[ii[i]], "x", domain_x0[i], domain_x1[i])
598   y = nc_read_from_file_1d(input_file_y[ii[i]], "y", domain_y0[i], domain_y1[i]) 
599   x = x - min(x.flatten()) + domain_px[i]/2.0
600   y = y - min(y.flatten()) + domain_px[i]/2.0 
601   nc_write_dimension(filename[i], 'x', x, datatypes["x"])
602   nc_write_dimension(filename[i], 'y', y, datatypes["y"]) 
603   nc_write_attribute(filename[i], 'x', 'long_name', 'x')
604   nc_write_attribute(filename[i], 'x', 'standard_name','projection_x_coordinate')   
605   nc_write_attribute(filename[i], 'x', 'units', 'm')
[3859]606   nc_write_attribute(filename[i], 'y', 'long_name', 'y')
[3567]607   nc_write_attribute(filename[i], 'y', 'standard_name', 'projection_y_coordinate')   
608   nc_write_attribute(filename[i], 'y', 'units', 'm')
609
610   lat = nc_read_from_file_2d(input_file_lat[ii[i]], "Band1", domain_x0[i], domain_x1[i], domain_y0[i], domain_y1[i])
611   lon = nc_read_from_file_2d(input_file_lon[ii[i]], "Band1", domain_x0[i], domain_x1[i], domain_y0[i], domain_y1[i]) 
612
613   nc_write_to_file_2d(filename[i], 'lat', lat, datatypes["lat"],'y','x',fillvalues["lat"])
614   nc_write_to_file_2d(filename[i], 'lon', lon, datatypes["lon"],'y','x',fillvalues["lon"]) 
615   
616   nc_write_attribute(filename[i], 'lat', 'long_name', 'latitude')
617   nc_write_attribute(filename[i], 'lat', 'standard_name','latitude')   
618   nc_write_attribute(filename[i], 'lat', 'units', 'degrees_north')
619 
620   nc_write_attribute(filename[i], 'lon', 'long_name', 'longitude')
621   nc_write_attribute(filename[i], 'lon', 'standard_name','longitude')   
622   nc_write_attribute(filename[i], 'lon', 'units', 'degrees_east') 
623   
624   x_UTM = nc_read_from_file_2d(input_file_x_UTM[ii[i]], "Band1", domain_x0[i], domain_x1[i], domain_y0[i], domain_y1[i])
625   y_UTM = nc_read_from_file_2d(input_file_y_UTM[ii[i]], "Band1", domain_x0[i], domain_x1[i], domain_y0[i], domain_y1[i]) 
[3726]626
[3567]627   
628   nc_write_to_file_2d(filename[i], 'E_UTM', x_UTM, datatypes["E_UTM"],'y','x',fillvalues["E_UTM"])
629   nc_write_to_file_2d(filename[i], 'N_UTM', y_UTM, datatypes["N_UTM"],'y','x',fillvalues["N_UTM"]) 
630   
631   nc_write_attribute(filename[i], 'E_UTM', 'long_name', 'easting')
632   nc_write_attribute(filename[i], 'E_UTM', 'standard_name','projection_x_coorindate')   
633   nc_write_attribute(filename[i], 'E_UTM', 'units', 'm')
634 
635   nc_write_attribute(filename[i], 'N_UTM', 'long_name', 'northing')
636   nc_write_attribute(filename[i], 'N_UTM', 'standard_name','projection_y_coorindate')   
637   nc_write_attribute(filename[i], 'N_UTM', 'units', 'm') 
638 
639   nc_write_crs(filename[i])
640   
641 
642 
643#  If necessary, bring terrain height to PALM's vertical grid. This is either forced by the user or implicitly
644#  by using interpolation for a child domain       
645   if domain_za[i]:
646      zt_all[i] = bring_to_palm_grid(zt_all[i],x,y,domain_dz[i])
647
648   nc_write_to_file_2d(filename[i], 'zt', zt_all[i], datatypes["zt"],'y','x',fillvalues["zt"])
649   nc_write_attribute(filename[i], 'zt', 'long_name', 'orography')
650   nc_write_attribute(filename[i], 'zt', 'units', 'm')
651   nc_write_attribute(filename[i], 'zt', 'res_orig', domain_px[i]) 
652   nc_write_attribute(filename[i], 'zt', 'coordinates', 'E_UTM N_UTM lon lat') 
653   nc_write_attribute(filename[i], 'zt', 'grid_mapping', 'E_UTM N_UTM lon lat')   
654
655del zt_all
656
657
658#  Process building height, id, and type
659for i in range(0,ndomains): 
660   buildings_2d = nc_read_from_file_2d(input_file_buildings_2d[ii[i]], 'Band1', domain_x0[i], domain_x1[i], domain_y0[i], domain_y1[i])
[3688]661
[3567]662   building_id = nc_read_from_file_2d(input_file_building_id[ii[i]], 'Band1', domain_x0[i], domain_x1[i], domain_y0[i], domain_y1[i]) 
663 
664   building_type = nc_read_from_file_2d(input_file_building_type[ii[i]], 'Band1', domain_x0[i], domain_x1[i], domain_y0[i], domain_y1[i]) 
[3668]665   building_type[building_type >= 254] = fillvalues["building_type"]
[3567]666   building_type = np.where(building_type < 1,defaultvalues["building_type"],building_type)
667 
668   check = check_arrays_2(buildings_2d,building_id,fillvalues["buildings_2d"],fillvalues["building_id"])
669   if not check:
670      buildings_2d = np.where(building_id != fillvalues["building_id"],buildings_2d,fillvalues["buildings_2d"])
671      building_id = np.where(buildings_2d == fillvalues["buildings_2d"],fillvalues["building_id"],building_id)
672      print("Data check #1 " + str(check_arrays_2(buildings_2d,building_id,fillvalues["buildings_2d"],fillvalues["building_id"])))
673
674   check = check_arrays_2(buildings_2d,building_type,fillvalues["buildings_2d"],fillvalues["building_type"])
675   if not check:
676      building_type = np.where(buildings_2d == fillvalues["buildings_2d"],fillvalues["building_type"],building_type)
677      building_type = np.where((building_type == fillvalues["building_type"]) & (buildings_2d != fillvalues["buildings_2d"]),defaultvalues["building_type"],building_type)
678      print("Data check #2 " + str(check_arrays_2(buildings_2d,building_type,fillvalues["buildings_2d"],fillvalues["building_type"])))
679 
[3688]680
[3567]681   nc_write_to_file_2d(filename[i], 'buildings_2d', buildings_2d, datatypes["buildings_2d"],'y','x',fillvalues["buildings_2d"])
682   nc_write_attribute(filename[i], 'buildings_2d', 'long_name', 'buildings')
683   nc_write_attribute(filename[i], 'buildings_2d', 'units', 'm')
684   nc_write_attribute(filename[i], 'buildings_2d', 'res_orig', domain_px[i]) 
685   nc_write_attribute(filename[i], 'buildings_2d', 'lod', 1) 
686   nc_write_attribute(filename[i], 'buildings_2d', 'coordinates', 'E_UTM N_UTM lon lat') 
687   nc_write_attribute(filename[i], 'buildings_2d', 'grid_mapping', 'E_UTM N_UTM lon lat')   
688   
689   nc_write_to_file_2d(filename[i], 'building_id', building_id, datatypes["building_id"],'y','x',fillvalues["building_id"])
690   nc_write_attribute(filename[i], 'building_id', 'long_name', 'building id')
691   nc_write_attribute(filename[i], 'building_id', 'units', '')
[3668]692   nc_write_attribute(filename[i], 'building_id', 'res _orig', domain_px[i]) 
[3567]693   nc_write_attribute(filename[i], 'building_id', 'coordinates', 'E_UTM N_UTM lon lat') 
694   nc_write_attribute(filename[i], 'building_id', 'grid_mapping', 'E_UTM N_UTM lon lat')   
695   
696   nc_write_to_file_2d(filename[i], 'building_type', building_type, datatypes["building_type"],'y','x',fillvalues["building_type"])
697   nc_write_attribute(filename[i], 'building_type', 'long_name', 'building type')
698   nc_write_attribute(filename[i], 'building_type', 'units', '')
699   nc_write_attribute(filename[i], 'building_type', 'res_orig', domain_px[i]) 
700   nc_write_attribute(filename[i], 'building_type', 'coordinates', 'E_UTM N_UTM lon lat') 
701   nc_write_attribute(filename[i], 'building_type', 'grid_mapping', 'E_UTM N_UTM lon lat')   
702 
703del buildings_2d
704del building_id
705del building_type
706
707# Create 3d buildings if necessary. In that course, read bridge objects and add them to building layer
708for i in range(0,ndomains): 
709   
710   if domain_3d[i]:
711      x = nc_read_from_file_2d_all(filename[i], 'x')
712      y = nc_read_from_file_2d_all(filename[i], 'y') 
713      buildings_2d = nc_read_from_file_2d_all(filename[i], 'buildings_2d') 
714      building_id = nc_read_from_file_2d_all(filename[i], 'building_id') 
715     
716      bridges_2d = nc_read_from_file_2d(input_file_bridges_2d[ii[i]], 'Band1', domain_x0[i], domain_x1[i], domain_y0[i], domain_y1[i])
717      bridges_id = nc_read_from_file_2d(input_file_bridges_id[ii[i]], 'Band1', domain_x0[i], domain_x1[i], domain_y0[i], domain_y1[i])
718     
719      bridges_2d = np.where(bridges_2d == 0.0,fillvalues["bridges_2d"],bridges_2d)
720      building_id = np.where(bridges_2d == fillvalues["bridges_2d"],building_id,bridges_id)
721     
722      if np.any(buildings_2d != fillvalues["buildings_2d"]):
723         buildings_3d, z = make_3d_from_2d(buildings_2d,x,y,domain_dz[i])
724         if np.any(bridges_2d != fillvalues["bridges_2d"]):
725            buildings_3d = make_3d_from_bridges_2d(buildings_3d,bridges_2d,x,y,domain_dz[i],settings_bridge_width,fillvalues["bridges_2d"])
726         else:
727            print("Skipping creation of 3D bridges (no bridges in domain)")
728           
729           
730         nc_write_dimension(filename[i], 'z', z, datatypes["z"]) 
731         nc_write_attribute(filename[i], 'z', 'long_name', 'z') 
732         nc_write_attribute(filename[i], 'z', 'units', 'm')
[3726]733         
734         nc_overwrite_to_file_2d(filename[i], 'building_id', building_id) 
[3567]735 
736         nc_write_to_file_3d(filename[i], 'buildings_3d', buildings_3d, datatypes["buildings_3d"],'z','y','x',fillvalues["buildings_3d"])   
737         nc_write_attribute(filename[i], 'buildings_3d', 'long_name', 'buildings 3d')
738         nc_write_attribute(filename[i], 'buildings_3d', 'units', '')
739         nc_write_attribute(filename[i], 'buildings_3d', 'res_orig', domain_px[i]) 
740         nc_write_attribute(filename[i], 'buildings_3d', 'lod', 2) 
741         
742         del buildings_3d
743         
744      else:
745         print("Skipping creation of 3D buildings (no buildings in domain)")
746
747
[3629]748      del bridges_2d, bridges_id, building_id, buildings_2d
[3567]749
750
751
752# Read vegetation type, water_type, pavement_type, soil_type and make fields consistent
753for i in range(0,ndomains): 
754
755   building_type = nc_read_from_file_2d_all(filename[i], 'building_type') 
[3773]756   
[3567]757   vegetation_type = nc_read_from_file_2d(input_file_vegetation_type[ii[i]], 'Band1', domain_x0[i], domain_x1[i], domain_y0[i], domain_y1[i])   
758   vegetation_type[vegetation_type == 255] = fillvalues["vegetation_type"]
759   vegetation_type = np.where((vegetation_type < 1) & (vegetation_type != fillvalues["vegetation_type"]),defaultvalues["vegetation_type"],vegetation_type)
760   
761   pavement_type = nc_read_from_file_2d(input_file_pavement_type[ii[i]], 'Band1', domain_x0[i], domain_x1[i], domain_y0[i], domain_y1[i])   
762   pavement_type[pavement_type == 255] = fillvalues["pavement_type"]
763   pavement_type = np.where((pavement_type < 1) & (pavement_type != fillvalues["pavement_type"]),defaultvalues["pavement_type"],pavement_type)
764
765   water_type = nc_read_from_file_2d(input_file_water_type[ii[i]], 'Band1', domain_x0[i], domain_x1[i], domain_y0[i], domain_y1[i])   
766   water_type[water_type == 255] = fillvalues["water_type"]
767   water_type = np.where((water_type < 1) & (water_type != fillvalues["water_type"]),defaultvalues["water_type"],water_type)
768 
769#  to do: replace by real soil input data
770   soil_type = nc_read_from_file_2d(input_file_vegetation_type[ii[i]], 'Band1', domain_x0[i], domain_x1[i], domain_y0[i], domain_y1[i]) 
771   soil_type[soil_type == 255] = fillvalues["soil_type"]
772   soil_type = np.where((soil_type < 1) & (soil_type != fillvalues["soil_type"]),defaultvalues["soil_type"],soil_type)
773
774#  Make arrays consistent
775#  #1 Set vegetation type to missing for pixel where a pavement type is set
776   vegetation_type = np.where((vegetation_type != fillvalues["vegetation_type"]) & (pavement_type != fillvalues["pavement_type"]),fillvalues["vegetation_type"],vegetation_type)
777
778#  #2 Set vegetation type to missing for pixel where a building type is set
779   vegetation_type = np.where((vegetation_type != fillvalues["vegetation_type"]) & (building_type != fillvalues["building_type"]) ,fillvalues["vegetation_type"],vegetation_type)
780
781#  #3 Set vegetation type to missing for pixel where a building type is set
782   vegetation_type = np.where((vegetation_type != fillvalues["vegetation_type"]) & (water_type != fillvalues["water_type"]),fillvalues["vegetation_type"],vegetation_type)   
783
784#  #4 Remove pavement for pixels with buildings
785   pavement_type = np.where((pavement_type != fillvalues["pavement_type"]) & (building_type != fillvalues["building_type"]),fillvalues["pavement_type"],pavement_type) 
786
[3773]787#  #5 Remove pavement for pixels with water.
788   pavement_type = np.where((pavement_type != fillvalues["pavement_type"]) & (water_type != fillvalues["water_type"]),fillvalues["pavement_type"],pavement_type) 
789   
[3567]790#  #6 Remove water for pixels with buildings
791   water_type = np.where((water_type != fillvalues["water_type"]) & (building_type != fillvalues["building_type"]),fillvalues["water_type"],water_type) 
[3773]792
[3668]793#  Correct vegetation_type when a vegetation height is available and is indicative of low vegeetation
794   vegetation_height = nc_read_from_file_2d(input_file_vegetation_height[ii[i]], 'Band1', domain_x0[i], domain_x1[i], domain_y0[i], domain_y1[i])   
795         
796   vegetation_type = np.where((vegetation_height != fillvalues["vegetation_height"]) & (vegetation_height == 0.0) & ((vegetation_type == 4) | (vegetation_type == 5) | (vegetation_type == 6) |(vegetation_type == 7) | (vegetation_type == 17) | (vegetation_type == 18)), 3, vegetation_type)
797   vegetation_height = np.where((vegetation_height != fillvalues["vegetation_height"]) & (vegetation_height == 0.0) & ((vegetation_type == 4) | (vegetation_type == 5) | (vegetation_type == 6) |(vegetation_type == 7) | (vegetation_type == 17) | (vegetation_type == 18)), fillvalues["vegetation_height"],vegetation_height)
[3567]798 
799#  Check for consistency and fill empty fields with default vegetation type
800   consistency_array, test = check_consistency_4(vegetation_type,building_type,pavement_type,water_type,fillvalues["vegetation_type"],fillvalues["building_type"],fillvalues["pavement_type"],fillvalues["water_type"])
801   
802   if test:
803      vegetation_type = np.where(consistency_array == 0,defaultvalues["vegetation_type"],vegetation_type)
804      consistency_array, test = check_consistency_4(vegetation_type,building_type,pavement_type,water_type,fillvalues["vegetation_type"],fillvalues["building_type"],fillvalues["pavement_type"],fillvalues["water_type"])
[3668]805
806#  #7 to be removed: set default soil type everywhere
807   soil_type = np.where((vegetation_type != fillvalues["vegetation_type"]) | (pavement_type != fillvalues["pavement_type"]),defaultvalues["soil_type"],fillvalues["soil_type"]) 
808       
[3567]809   
[3668]810#  Check for consistency and fill empty fields with default vegetation type
811   consistency_array, test = check_consistency_3(vegetation_type,pavement_type,soil_type,fillvalues["vegetation_type"],fillvalues["pavement_type"],fillvalues["soil_type"])
812       
[3567]813#  Create surface_fraction array
814   x = nc_read_from_file_2d_all(filename[i], 'x')
815   y = nc_read_from_file_2d_all(filename[i], 'y') 
816   nsurface_fraction = np.arange(0,3)
817   surface_fraction = np.ones((len(nsurface_fraction),len(y),len(x)))
818   
819   surface_fraction[0,:,:] = np.where(vegetation_type != fillvalues["vegetation_type"], 1.0, 0.0)
820   surface_fraction[1,:,:] = np.where(pavement_type != fillvalues["pavement_type"], 1.0, 0.0)
821   surface_fraction[2,:,:] = np.where(water_type != fillvalues["water_type"], 1.0, 0.0)
822   
823   nc_write_dimension(filename[i], 'nsurface_fraction', nsurface_fraction, datatypes["nsurface_fraction"]) 
824   nc_write_to_file_3d(filename[i], 'surface_fraction', surface_fraction, datatypes["surface_fraction"],'nsurface_fraction','y','x',fillvalues["surface_fraction"])     
825   nc_write_attribute(filename[i], 'surface_fraction', 'long_name', 'surface fraction')
826   nc_write_attribute(filename[i], 'surface_fraction', 'units', '')
827   nc_write_attribute(filename[i], 'surface_fraction', 'res_orig', domain_px[i])     
828   del surface_fraction   
829
830   nc_write_to_file_2d(filename[i], 'vegetation_type', vegetation_type, datatypes["vegetation_type"],'y','x',fillvalues["vegetation_type"])     
831   nc_write_attribute(filename[i], 'vegetation_type', 'long_name', 'vegetation type')
832   nc_write_attribute(filename[i], 'vegetation_type', 'units', '')
833   nc_write_attribute(filename[i], 'vegetation_type', 'res_orig', domain_px[i]) 
834   nc_write_attribute(filename[i], 'vegetation_type', 'coordinates', 'E_UTM N_UTM lon lat') 
835   nc_write_attribute(filename[i], 'vegetation_type', 'grid_mapping', 'E_UTM N_UTM lon lat')   
836   del vegetation_type
837
838   nc_write_to_file_2d(filename[i], 'pavement_type', pavement_type, datatypes["pavement_type"],'y','x',fillvalues["pavement_type"])   
839   nc_write_attribute(filename[i], 'pavement_type', 'long_name', 'pavement type')
840   nc_write_attribute(filename[i], 'pavement_type', 'units', '')
841   nc_write_attribute(filename[i], 'pavement_type', 'res_orig', domain_px[i]) 
842   nc_write_attribute(filename[i], 'pavement_type', 'coordinates', 'E_UTM N_UTM lon lat') 
843   nc_write_attribute(filename[i], 'pavement_type', 'grid_mapping', 'E_UTM N_UTM lon lat')   
844   del pavement_type
845
846   nc_write_to_file_2d(filename[i], 'water_type', water_type, datatypes["water_type"],'y','x',fillvalues["water_type"]) 
847   nc_write_attribute(filename[i], 'water_type', 'long_name', 'water type')
848   nc_write_attribute(filename[i], 'water_type', 'units', '')
849   nc_write_attribute(filename[i], 'water_type', 'res_orig', domain_px[i]) 
850   nc_write_attribute(filename[i], 'water_type', 'coordinates', 'E_UTM N_UTM lon lat') 
851   nc_write_attribute(filename[i], 'water_type', 'grid_mapping', 'E_UTM N_UTM lon lat')   
852   del water_type
853
854   nc_write_to_file_2d(filename[i], 'soil_type', soil_type, datatypes["soil_type"],'y','x',fillvalues["soil_type"]) 
855   nc_write_attribute(filename[i], 'soil_type', 'long_name', 'soil type')
856   nc_write_attribute(filename[i], 'soil_type', 'units', '')
857   nc_write_attribute(filename[i], 'soil_type', 'res_orig', domain_px[i])   
858   nc_write_attribute(filename[i], 'soil_type', 'coordinates', 'E_UTM N_UTM lon lat') 
859   nc_write_attribute(filename[i], 'soil_type', 'grid_mapping', 'E_UTM N_UTM lon lat')   
860   del soil_type
861
[3629]862   del x
863   del y
[3567]864
865#  pixels with bridges get building_type = 7 = bridge. This does not change the _type setting for the under-bridge
[3668]866#  area NOTE: when bridges are present the consistency check will fail at the moment
[3567]867   if domain_3d[i]:
868      if np.any(building_type != fillvalues["building_type"]):
869 
870         bridges_2d = nc_read_from_file_2d(input_file_bridges_2d[ii[i]], 'Band1', domain_x0[i], domain_x1[i], domain_y0[i], domain_y1[i])         
871         bridges_2d = np.where(bridges_2d == 0.0,fillvalues["bridges_2d"],bridges_2d)
872         building_type = np.where(bridges_2d != fillvalues["bridges_2d"],7,building_type)
873         nc_overwrite_to_file_2d(filename[i], 'building_type', building_type) 
874 
875         del building_type 
876         del bridges_2d
877
[3629]878# Read/write street type and street crossings
[3567]879for i in range(0,ndomains): 
880
881   street_type = nc_read_from_file_2d(input_file_street_type[ii[i]], 'Band1', domain_x0[i], domain_x1[i], domain_y0[i], domain_y1[i])   
882   street_type[street_type == 255] = fillvalues["street_type"]
883   street_type = np.where((street_type < 1) & (street_type != fillvalues["street_type"]),defaultvalues["street_type"],street_type)
[3773]884
885   pavement_type = nc_read_from_file_2d_all(filename[i], 'pavement_type') 
886   street_type = np.where((pavement_type == fillvalues["pavement_type"]),fillvalues["street_type"],street_type) 
887
[3567]888   nc_write_to_file_2d(filename[i], 'street_type', street_type, datatypes["street_type"],'y','x',fillvalues["street_type"]) 
889   nc_write_attribute(filename[i], 'street_type', 'long_name', 'street type')
890   nc_write_attribute(filename[i], 'street_type', 'units', '')
891   nc_write_attribute(filename[i], 'street_type', 'res_orig', domain_px[i]) 
892   nc_write_attribute(filename[i], 'street_type', 'coordinates', 'E_UTM N_UTM lon lat') 
893   nc_write_attribute(filename[i], 'street_type', 'grid_mapping', 'E_UTM N_UTM lon lat')   
894   del street_type
895   
896   street_crossings = nc_read_from_file_2d(input_file_street_crossings[ii[i]], 'Band1', domain_x0[i], domain_x1[i], domain_y0[i], domain_y1[i])   
897   street_crossings[street_crossings == 255] = fillvalues["street_crossings"]
898   street_crossings = np.where((street_crossings < 1) & (street_crossings != fillvalues["street_crossings"]),defaultvalues["street_crossings"],street_crossings)
899   
[3726]900   nc_write_to_file_2d(filename[i], 'street_crossing', street_crossings, datatypes["street_crossings"],'y','x',fillvalues["street_crossings"]) 
901   nc_write_attribute(filename[i], 'street_crossing', 'long_name', 'street crossings')
902   nc_write_attribute(filename[i], 'street_crossing', 'units', '')
903   nc_write_attribute(filename[i], 'street_crossing', 'res_orig', domain_px[i]) 
904   nc_write_attribute(filename[i], 'street_crossing', 'coordinates', 'E_UTM N_UTM lon lat') 
905   nc_write_attribute(filename[i], 'street_crossing', 'grid_mapping', 'E_UTM N_UTM lon lat')   
[3567]906   del street_crossings
[3629]907
908
909# Read/write vegetation on roofs
910for i in range(0,ndomains): 
911   if domain_green_roofs[i]: 
912      green_roofs = nc_read_from_file_2d(input_file_vegetation_on_roofs[ii[i]], 'Band1', domain_x0[i], domain_x1[i], domain_y0[i], domain_y1[i])   
913      buildings_2d = nc_read_from_file_2d_all(filename[i], 'buildings_2d') 
914
915
916      x = nc_read_from_file_2d_all(filename[i], 'x')
917      y = nc_read_from_file_2d_all(filename[i], 'y') 
[4149]918      nbuilding_pars = np.arange(0,47)
[3629]919      building_pars = np.ones((len(nbuilding_pars),len(y),len(x)))
920      building_pars[:,:,:] = fillvalues["building_pars"]
921
922#     assign green fraction on roofs
[3955]923      building_pars[3,:,:] = np.where( ( buildings_2d != fillvalues["buildings_2d"] ) & ( green_roofs != fillvalues["building_pars"] ) & ( green_roofs != 0.0 ),1,fillvalues["building_pars"] )
[3629]924
925#     assign leaf area index for vegetation on roofs
[4311]926      building_pars[4,:,:] = np.where( ( building_pars[3,:,:] != fillvalues["building_pars"] ) & ( green_roofs >= 0.5 ),settings_lai_roof_intensive,fillvalues["building_pars"])
927      building_pars[4,:,:] = np.where( ( building_pars[3,:,:] != fillvalues["building_pars"] ) & ( green_roofs < 0.5 ),settings_lai_roof_extensive,building_pars[4,:,:])
[3629]928   
929   
930      nc_write_dimension(filename[i], 'nbuilding_pars', nbuilding_pars, datatypes["nbuilding_pars"]) 
931      nc_write_to_file_3d(filename[i], 'building_pars', building_pars, datatypes["building_pars"],'nbuilding_pars','y','x',fillvalues["building_pars"]) 
932      nc_write_attribute(filename[i], 'building_pars', 'long_name', 'building_pars')
933      nc_write_attribute(filename[i], 'building_pars', 'units', '')
934      nc_write_attribute(filename[i], 'building_pars', 'res_orig', domain_px[i]) 
935      nc_write_attribute(filename[i], 'building_pars', 'coordinates', 'E_UTM N_UTM lon lat') 
936      nc_write_attribute(filename[i], 'building_pars', 'grid_mapping', 'E_UTM N_UTM lon lat')   
937         
938      del building_pars, buildings_2d, x, y
939
940
941# Read tree data and create LAD and BAD arrays using the canopy generator
942for i in range(0,ndomains): 
[3668]943   lai = nc_read_from_file_2d(input_file_lai[ii[i]], 'Band1', domain_x0[i], domain_x1[i], domain_y0[i], domain_y1[i])   
944     
945   vegetation_type = nc_read_from_file_2d_all(filename[i], 'vegetation_type')
946     
947   lai = np.where(vegetation_type == fillvalues["vegetation_type"],fillvalues["vegetation_pars"],lai)
948
[3629]949     
[3668]950   x = nc_read_from_file_2d_all(filename[i], 'x')
951   y = nc_read_from_file_2d_all(filename[i], 'y') 
952   nvegetation_pars = np.arange(0,12)
953   vegetation_pars = np.ones((len(nvegetation_pars),len(y),len(x)))
954   vegetation_pars[:,:,:] = fillvalues["vegetation_pars"] 
[3629]955     
[3668]956   vegetation_pars[1,:,:] = lai
[3629]957     
[3668]958
959#  Write out first version of LAI. Will later be overwritten.
960   nc_write_dimension(filename[i], 'nvegetation_pars', nvegetation_pars, datatypes["nvegetation_pars"]) 
961   nc_write_to_file_3d(filename[i], 'vegetation_pars', vegetation_pars, datatypes["vegetation_pars"],'nvegetation_pars','y','x',fillvalues["vegetation_pars"]) 
962   nc_write_attribute(filename[i], 'vegetation_pars', 'long_name', 'vegetation_pars')
963   nc_write_attribute(filename[i], 'vegetation_pars', 'units', '')
964   nc_write_attribute(filename[i], 'vegetation_pars', 'res_orig', domain_px[i]) 
965   nc_write_attribute(filename[i], 'vegetation_pars', 'coordinates', 'E_UTM N_UTM lon lat') 
966   nc_write_attribute(filename[i], 'vegetation_pars', 'grid_mapping', 'E_UTM N_UTM lon lat')   
967
968   del lai, vegetation_pars, vegetation_type
969
970# Read tree data and create LAD and BAD arrays using the canopy generator
971for i in range(0,ndomains): 
972   if domain_street_trees[i]: 
973
974      vegetation_pars =  nc_read_from_file_2d_all(filename[i], 'vegetation_pars')
975
[4793]976      lai = nc_read_from_file_2d(input_file_lai[ii[i]], 'Band1', domain_x0[i], domain_x1[i], domain_y0[i], domain_y1[i])   
[3668]977
[3629]978      x = nc_read_from_file_2d_all(filename[i], 'x')
979      y = nc_read_from_file_2d_all(filename[i], 'y') 
980
[3668]981#     Save lai data as default for low and high vegetation
982      lai_low = lai
983      lai_high = lai
984   
985#     Read all tree parameters from file
986      tree_height = nc_read_from_file_2d(input_file_tree_height[ii[i]], 'Band1', domain_x0[i], domain_x1[i], domain_y0[i], domain_y1[i])   
[3629]987
[3668]988      if (input_file_tree_crown_diameter[ii[i]] is not None):
989         tree_crown_diameter = nc_read_from_file_2d(input_file_tree_crown_diameter[ii[i]], 'Band1', domain_x0[i], domain_x1[i], domain_y0[i], domain_y1[i])   
990         tree_crown_diameter = np.where( (tree_crown_diameter == 0.0) | (tree_crown_diameter == -1.0) ,fillvalues["tree_data"],tree_crown_diameter)
991      else:
992         tree_crown_diameter = np.ones((len(y),len(x)))
993         tree_crown_diameter[:,:] = fillvalues["tree_data"]
[3629]994
[3668]995
[3629]996      tree_trunk_diameter = nc_read_from_file_2d(input_file_tree_trunk_diameter[ii[i]], 'Band1', domain_x0[i], domain_x1[i], domain_y0[i], domain_y1[i])         
997      tree_type = nc_read_from_file_2d(input_file_tree_type[ii[i]], 'Band1', domain_x0[i], domain_x1[i], domain_y0[i], domain_y1[i]) 
998      patch_height = nc_read_from_file_2d(input_file_patch_height[ii[i]], 'Band1', domain_x0[i], domain_x1[i], domain_y0[i], domain_y1[i]) 
999     
1000#     Remove missing values from the data. Reasonable values will be set by the tree generator   
1001      tree_height = np.where( (tree_height == 0.0) | (tree_height == -1.0) ,fillvalues["tree_data"],tree_height)
1002      tree_trunk_diameter = np.where( (tree_trunk_diameter == 0.0) | (tree_trunk_diameter == -1.0) ,fillvalues["tree_data"],tree_trunk_diameter)
1003      tree_type = np.where( (tree_type == 0.0) | (tree_type == -1.0) ,fillvalues["tree_data"],tree_type)
[4793]1004     
1005#     For vegetation pixel with missing height information (-1), set default patch height   
1006      patch_height = np.where( patch_height == -1.0 ,settings_patch_height_default,patch_height)     
[3629]1007
1008#     Convert trunk diameter from cm to m
1009      tree_trunk_diameter = np.where(tree_trunk_diameter != fillvalues["tree_data"], tree_trunk_diameter * 0.01,tree_trunk_diameter)
1010
1011
1012#     Temporarily change missing value for tree_type
1013      tree_type = np.where( (tree_type == fillvalues["tree_type"]),fillvalues["tree_data"],tree_type)   
1014
1015#     Compare patch height array with vegetation type and correct accordingly
1016      vegetation_type = nc_read_from_file_2d_all(filename[i], 'vegetation_type') 
1017
1018
1019#     For zero-height patches, set vegetation_type to short grass and remove these pixels from the patch height array
[4793]1020      vegetation_type = np.where( (patch_height == 0.0) & ( (vegetation_type == 4) | (vegetation_type == 5) | (vegetation_type == 6) |(vegetation_type == 7) | (vegetation_type == 17) | (vegetation_type == 18) ),3,vegetation_type) 
1021      patch_height = np.where( (patch_height == 0.0) & ( (vegetation_type == 4) | (vegetation_type == 5) | (vegetation_type == 6) |(vegetation_type == 7) | (vegetation_type == 17) | (vegetation_type == 18) ),fillvalues["tree_data"],patch_height)       
[3629]1022
1023      max_tree_height = max(tree_height.flatten())
1024      max_patch_height = max(patch_height.flatten())
1025     
[4490]1026#     Call canopy generator for single trees only if there is any tree height available in the domain.
1027#     This does not guarantee that there are street trees that can be processed. This is checked in the
1028#     canopy generator.
1029      if ( (max_tree_height != fillvalues["tree_data"]) | (max_patch_height != fillvalues["tree_data"]) ):
[3668]1030
[4793]1031         lad, bad, tree_ids, tree_types, zlad = generate_single_tree_lad(x,y,domain_dz[i],max_tree_height,max_patch_height,tree_type,tree_height,tree_crown_diameter,tree_trunk_diameter,lai,settings_season,fillvalues["tree_data"])
[3629]1032 
1033#        Remove LAD volumes that are inside buildings
[4793]1034         if not domain_overhanging_trees[i]:
1035            buildings_2d = nc_read_from_file_2d_all(filename[i], 'buildings_2d') 
1036            for k in range(0,len(zlad)-1):
[3629]1037 
[4793]1038               lad[k,:,:] = np.where(buildings_2d == fillvalues["buildings_2d"],lad[k,:,:],fillvalues["tree_data"])
1039               bad[k,:,:] = np.where(buildings_2d == fillvalues["buildings_2d"],bad[k,:,:],fillvalues["tree_data"])
1040               tree_ids[k,:,:] = np.where(buildings_2d == fillvalues["buildings_2d"],tree_ids[k,:,:],fillvalues["tree_id"])     
[3668]1041
[4793]1042            del buildings_2d
[3629]1043 
[4793]1044 
[3629]1045         nc_write_dimension(filename[i], 'zlad', zlad, datatypes["tree_data"]) 
[4793]1046
[3629]1047         nc_write_to_file_3d(filename[i], 'lad', lad, datatypes["tree_data"],'zlad','y','x',fillvalues["tree_data"]) 
1048         nc_write_attribute(filename[i], 'lad', 'long_name', 'leaf area density')
1049         nc_write_attribute(filename[i], 'lad', 'units', '')
1050         nc_write_attribute(filename[i], 'lad', 'res_orig', domain_px[i]) 
1051         nc_write_attribute(filename[i], 'lad', 'coordinates', 'E_UTM N_UTM lon lat') 
1052         nc_write_attribute(filename[i], 'lad', 'grid_mapping', 'E_UTM N_UTM lon lat') 
[4793]1053 
[3629]1054         nc_write_to_file_3d(filename[i], 'bad', bad, datatypes["tree_data"],'zlad','y','x',fillvalues["tree_data"]) 
1055         nc_write_attribute(filename[i], 'bad', 'long_name', 'basal area density')
1056         nc_write_attribute(filename[i], 'bad', 'units', '')
1057         nc_write_attribute(filename[i], 'bad', 'res_orig', domain_px[i]) 
1058         nc_write_attribute(filename[i], 'bad', 'coordinates', 'E_UTM N_UTM lon lat') 
1059         nc_write_attribute(filename[i], 'bad', 'grid_mapping', 'E_UTM N_UTM lon lat')
1060           
[4793]1061         nc_write_to_file_3d(filename[i], 'tree_id', tree_ids, datatypes["tree_id"],'zlad','y','x',fillvalues["tree_id"]) 
[3629]1062         nc_write_attribute(filename[i], 'tree_id', 'long_name', 'tree id')
1063         nc_write_attribute(filename[i], 'tree_id', 'units', '')
1064         nc_write_attribute(filename[i], 'tree_id', 'res_orig', domain_px[i]) 
1065         nc_write_attribute(filename[i], 'tree_id', 'coordinates', 'E_UTM N_UTM lon lat') 
1066         nc_write_attribute(filename[i], 'tree_id', 'grid_mapping', 'E_UTM N_UTM lon lat')           
[4793]1067
1068         nc_write_to_file_3d(filename[i], 'tree_type', tree_types, datatypes["tree_types"],'zlad','y','x',fillvalues["tree_types"]) 
1069         nc_write_attribute(filename[i], 'tree_type', 'long_name', 'tree type')
1070         nc_write_attribute(filename[i], 'tree_type', 'units', '')
1071         nc_write_attribute(filename[i], 'tree_type', 'res_orig', domain_px[i]) 
1072         nc_write_attribute(filename[i], 'tree_type', 'coordinates', 'E_UTM N_UTM lon lat') 
1073         nc_write_attribute(filename[i], 'tree_type', 'grid_mapping', 'E_UTM N_UTM lon lat')   
[3629]1074           
[4793]1075         del lai, lad, bad, tree_ids, tree_types, zlad
[3629]1076
[4793]1077      else:
1078         print('No street trees generated in domain ' + str(i))
1079         
[3668]1080      del vegetation_pars, tree_height, tree_crown_diameter, tree_trunk_diameter, tree_type, patch_height, x, y
[3629]1081
1082
1083# Create vegetation patches for locations with high vegetation type
1084for i in range(0,ndomains): 
1085   if domain_canopy_patches[i]: 
1086
1087      patch_height = nc_read_from_file_2d(input_file_patch_height[ii[i]], 'Band1', domain_x0[i], domain_x1[i], domain_y0[i], domain_y1[i]) 
1088
[4793]1089#     For vegetation pixel with missing height information (-1), set default patch height     
1090      patch_height = np.where( patch_height == -1.0 ,settings_patch_height_default,patch_height)
1091     
1092      max_patch_height = max(patch_height.flatten())
1093      if ( max_patch_height != fillvalues["tree_data"] ):
1094#        Call canopy generator for single trees only if there is any tree height available in the domain.
1095#        This does not guarantee that there are street trees that can be processed. This is checked in the
1096#        canopy generator.
[3629]1097
[4793]1098#        Load vegetation_type and lad array (at level z = 0) for re-processing
1099         vegetation_type = nc_read_from_file_2d_all(filename[i], 'vegetation_type') 
1100         lad = nc_read_from_file_3d_all(filename[i], 'lad') 
1101         tree_id = nc_read_from_file_3d_all(filename[i], 'tree_id') 
1102         tree_types = nc_read_from_file_3d_all(filename[i], 'tree_type') 
1103         zlad = nc_read_from_file_1d_all(filename[i], 'zlad') 
1104         vegetation_pars = nc_read_from_file_3d_all(filename[i], 'vegetation_pars') 
1105         lai = nc_read_from_file_2d(input_file_lai[ii[i]], 'Band1', domain_x0[i], domain_x1[i], domain_y0[i], domain_y1[i])   
1106   
1107         nc_write_to_file_2d(filename[i], 'patch_height', patch_height, datatypes["tree_data"],'y','x',fillvalues["tree_data"]) 
1108         nc_write_attribute(filename[i], 'patch_height', 'long_name', 'tree type')
1109         nc_write_attribute(filename[i], 'patch_height', 'units', '')
1110         nc_write_attribute(filename[i], 'patch_height', 'res_orig', domain_px[i]) 
1111         nc_write_attribute(filename[i], 'patch_height', 'coordinates', 'E_UTM N_UTM lon lat') 
1112         nc_write_attribute(filename[i], 'patch_height', 'grid_mapping', 'E_UTM N_UTM lon lat')     
[4746]1113
[4793]1114#        Determine all pixels that do not already have an LAD but which are high vegetation to a dummy value of 1.0 and remove all other pixels
1115         lai_high = np.where( (lad[0,:,:] == fillvalues["tree_data"]) & ( ( (vegetation_type == 4) | (vegetation_type == 5) | (vegetation_type == 6) |(vegetation_type == 7) | (vegetation_type == 17) | (vegetation_type == 18) ) & ( (patch_height == fillvalues["tree_data"]) | (patch_height >= domain_dz[i])) ),1.0,fillvalues["tree_data"])
1116
1117
1118#        Treat all pixels where short grass is defined, but where a patch_height >= dz is found, as high vegetation (often the case in backyards)
1119         lai_high = np.where( (lai_high == fillvalues["tree_data"]) & (patch_height >= domain_dz[i]) & (vegetation_type == 3), 1.0, lai_high)
[4746]1120                         
[4793]1121#        If overhanging trees are allowed, assign pixels with patch_height > dz that are not included in vegetation_type to high
1122         if domain_overhanging_trees[i]:
1123            lai_high = np.where( (lai_high == fillvalues["tree_data"]) & (patch_height >= domain_dz[i]), 1.0, lai_high)
[3668]1124
[4793]1125#        Now, assign either the default LAI for high vegetation or keep 1.0 from the lai_high array.
1126         lai_high = np.where( (lai_high != fillvalues["tree_data"]) & (lai == fillvalues["tree_data"]), settings_lai_high_default, lai_high)
[3726]1127
[4793]1128#        If LAI values are available in the LAI array, write them on the lai_high array
1129         lai_high = np.where( (lai_high != fillvalues["tree_data"]) & (lai != fillvalues["tree_data"]), lai, lai_high)
[4746]1130
[3629]1131
[4793]1132#        Define a patch height wherever it is missing, but where a high vegetation LAI was set
1133         patch_height = np.where ( (lai_high != fillvalues["tree_data"]) & (patch_height == fillvalues["tree_data"]), settings_patch_height_default, patch_height)
[4746]1134
[3629]1135
[4793]1136#        Remove pixels where street trees were already se
1137         patch_height = np.where ( (lad[0,:,:] != fillvalues["tree_data"]), fillvalues["tree_data"], patch_height)
[3668]1138
[4793]1139#        Remove patch heights that have no lai_high value
1140         patch_height = np.where ( (lai_high == fillvalues["tree_data"]), fillvalues["tree_data"], patch_height)
1141
1142
1143
1144
1145#        For missing LAI values, set either the high vegetation default or the low vegetation default   
1146         lai_high = np.where( (patch_height > 2.0) & (patch_height != fillvalues["tree_data"]) & (lai_high == fillvalues["tree_data"]),settings_lai_high_default,lai_high)
1147         lai_high = np.where( (patch_height <= 2.0) & (patch_height != fillvalues["tree_data"]) & (lai_high == fillvalues["tree_data"]),settings_lai_low_default,lai_high)
[3668]1148         
[4793]1149         if ( max(patch_height.flatten()) >= (2.0 * domain_dz[i]) ):
1150            print("    start calculating LAD (this might take some time)")       
[3726]1151
1152         
[4793]1153            lad_patch, patch_id, patch_types, patch_nz, status = process_patch(domain_dz[i],patch_height,vegetation_type,max(zlad),lai_high,settings_lai_alpha,settings_lai_beta)
[3629]1154
[4793]1155#           Increase the patch ids by the maximum id for street trees to avoid double ids
1156            max_id = max(tree_id.flatten())
1157            patch_id = np.where( patch_id != fillvalues["tree_id"], patch_id+max_id, patch_id)
[3629]1158
[4793]1159#           2D loop in order to avoid memory problems with large arrays
1160            for iii in range(0,domain_nx[i]):
1161               for jj in range(0,domain_ny[i]):           
[4746]1162
[4793]1163                  tree_id[0:patch_nz+1,jj,iii] = np.where( (lad[0:patch_nz+1,jj,iii] == fillvalues["tree_data"]),patch_id[0:patch_nz+1,jj,iii], tree_id[0:patch_nz+1,jj,iii] )
1164                  tree_types[0:patch_nz+1,jj,iii] = np.where( (lad[0:patch_nz+1,jj,iii] == fillvalues["tree_data"]),patch_types[0:patch_nz+1,jj,iii], tree_types[0:patch_nz+1,jj,iii] )                 
1165                  lad[0:patch_nz+1,jj,iii]     = np.where( (lad[0:patch_nz+1,jj,iii] == fillvalues["tree_data"]),lad_patch[0:patch_nz+1,jj,iii], lad[0:patch_nz+1,jj,iii] )
1166
1167#        Remove high vegetation wherever it is replaced by a leaf area density. This should effectively remove all high vegetation pixels
1168         vegetation_type = np.where((lad[0,:,:] != fillvalues["tree_data"]) & (vegetation_type != fillvalues["vegetation_type"]),settings_veg_type_below_trees,vegetation_type)
[3668]1169             
[4793]1170#        If desired, remove all high vegetation. TODO: check if this is still necessary
1171         if not domain_high_vegetation[i]:
1172            vegetation_type = np.where((vegetation_type != fillvalues["vegetation_type"]) & ( (vegetation_type == 4) | (vegetation_type == 5) | (vegetation_type == 6) |(vegetation_type == 7) | (vegetation_type == 17) | (vegetation_type == 18) ),3,vegetation_type)   
[3629]1173
1174 
[4793]1175#        Set default low LAI for pixels with an LAD (short grass below trees)
1176         lai_low = np.where( (lad[0,:,:] == fillvalues["tree_data"]), lai, settings_lai_low_default)
[3629]1177   
[4793]1178#        Fill low vegetation pixels without LAI set or with LAI = 0 with default value
1179         lai_low = np.where( ( (lai_low == fillvalues["tree_data"]) | (lai_low == 0.0) ) & (vegetation_type != fillvalues["vegetation_type"] ), settings_lai_low_default, lai_low)
[3629]1180
[4793]1181#        Remove lai for pixels that have no vegetation_type
1182         lai_low = np.where( ( (vegetation_type != fillvalues["vegetation_type"]) & (vegetation_type != 1) ), lai_low, fillvalues["tree_data"])
[3668]1183       
[4793]1184#        Overwrite lai in vegetation_parameters 
1185         vegetation_pars[1,:,:] = np.copy(lai_low)
1186         nc_overwrite_to_file_3d(filename[i], 'vegetation_pars', vegetation_pars) 
[3629]1187
[4793]1188#        Overwrite lad and id arrays
1189         nc_overwrite_to_file_3d(filename[i], 'lad', lad) 
1190         nc_overwrite_to_file_3d(filename[i], 'tree_id', tree_id) 
1191         nc_overwrite_to_file_3d(filename[i], 'tree_type', tree_types) 
[3668]1192
[4793]1193         nc_overwrite_to_file_2d(filename[i], 'vegetation_type', vegetation_type) 
[3668]1194
[3955]1195
[4793]1196         del vegetation_type, lad, lai, patch_height, vegetation_pars, zlad
1197      else:
1198         print('No tree patches found in domain ' + str(i))
1199
[3955]1200# Final adjustment of vegetation parameters: remove LAI where a bare soil was set
1201for i in range(0,ndomains): 
1202   
1203      vegetation_type = nc_read_from_file_2d_all(filename[i], 'vegetation_type') 
1204      vegetation_pars = nc_read_from_file_3d_all(filename[i], 'vegetation_pars') 
1205      lai = vegetation_pars[1,:,:]   
1206     
1207     
1208#     Remove lai for pixels that have no vegetation_type
1209      lai = np.where( ( (vegetation_type != fillvalues["vegetation_type"]) & (vegetation_type != 1) ), lai, fillvalues["tree_data"])
1210       
1211#     Overwrite lai in vegetation_parameters 
1212      vegetation_pars[1,:,:] = np.copy(lai)
1213      nc_overwrite_to_file_3d(filename[i], 'vegetation_pars', vegetation_pars) 
1214     
1215      del vegetation_type, lai, vegetation_pars
1216
1217
[3668]1218# Final consistency check
1219for i in range(0,ndomains): 
1220   vegetation_type = nc_read_from_file_2d_all(filename[i], 'vegetation_type') 
1221   pavement_type = nc_read_from_file_2d_all(filename[i], 'pavement_type') 
1222   building_type = nc_read_from_file_2d_all(filename[i], 'building_type') 
1223   water_type = nc_read_from_file_2d_all(filename[i], 'water_type')     
1224   soil_type = nc_read_from_file_2d_all(filename[i], 'soil_type') 
1225
1226#  Check for consistency and fill empty fields with default vegetation type
1227   consistency_array, test = check_consistency_4(vegetation_type,building_type,pavement_type,water_type,fillvalues["vegetation_type"],fillvalues["building_type"],fillvalues["pavement_type"],fillvalues["water_type"])
1228
1229#  Check for consistency and fill empty fields with default vegetation type
1230   consistency_array, test = check_consistency_3(vegetation_type,pavement_type,soil_type,fillvalues["vegetation_type"],fillvalues["pavement_type"],fillvalues["soil_type"])
1231
1232   surface_fraction = nc_read_from_file_3d_all(filename[i], 'surface_fraction')       
1233   surface_fraction[0,:,:] = np.where(vegetation_type != fillvalues["vegetation_type"], 1.0, 0.0)
1234   surface_fraction[1,:,:] = np.where(pavement_type != fillvalues["pavement_type"], 1.0, 0.0)
1235   surface_fraction[2,:,:] = np.where(water_type != fillvalues["water_type"], 1.0, 0.0)
1236   nc_overwrite_to_file_3d(filename[i], 'surface_fraction', surface_fraction) 
1237       
1238   del vegetation_type, pavement_type, building_type, water_type, soil_type
Note: See TracBrowser for help on using the repository browser.