def test_case_study(self): dataset = lue.create_dataset("planets.lue") planets = dataset.add_phenomenon("planets") nr_planets = 3 planets.object_id.expand(nr_planets)[:] = \ np.arange(nr_planets) constants = planets.add_property_set("constants") name = constants.add_property( "name", dtype=np.dtype(np.unicode_)) name.value.expand(nr_planets)[:] = \ np.array([ # Python 2: Byte string, encoded in UTF8 # Python 3: Unicode string "ñeptùne", "mærß", "ùræñùß" ]) gravity = constants.add_property( "gravity", dtype=np.dtype(np.float32)) gravity.value.expand(nr_planets)[:] = \ np.array([1.5, 2.5, 3.5], dtype=np.float32) lue.assert_is_valid(dataset)
def create_dataset(cls, name): """ Create dataset, removing an existing dataset first """ lue_test.remove_file_if_existant(name) return lue.create_dataset(name)
def test_case_study(self): dataset = lue.create_dataset("areas.lue") areas = dataset.add_phenomenon("areas") nr_areas = 10 # IDs ids = numpy.arange(nr_areas, dtype=numpy.uint64) areas.object_id.expand(nr_areas)[:] = ids space_configuration = lue.SpaceConfiguration( lue.Mobility.stationary, lue.SpaceDomainItemType.box) coordinate_datatype = numpy.dtype(numpy.float32) rank = 2 area_boxes = areas.add_property_set("areas", space_configuration, coordinate_datatype, rank) # Space domain space_domain = area_boxes.space_domain boxes = numpy.arange(nr_areas * rank * 2, dtype=coordinate_datatype).reshape(nr_areas, 4) space_domain.value.expand(nr_areas)[:] = boxes # Discretization property count_datatype = lue.dtype.Count discretization = area_boxes.add_property("discretization", dtype=count_datatype, shape=(rank, )) shapes = numpy.arange(nr_areas * rank, dtype=count_datatype).reshape(nr_areas, 2) discretization.value.expand(nr_areas)[:] = shapes # Elevation property elevation_datatype = numpy.dtype(numpy.float32) elevation = area_boxes.add_property("elevation", dtype=elevation_datatype, rank=rank) grids = elevation.value.expand(ids, shapes) for a in range(nr_areas): grids[ids[a]][:] = \ (10 * numpy.random.rand(*shapes[a])).astype(elevation_datatype) # Link elevation to discretization elevation.set_space_discretization( lue.SpaceDiscretization.regular_grid, discretization) lue.assert_is_valid(dataset)
def test_case_study(self): dataset = lue.create_dataset("planets.lue") planets = dataset.add_phenomenon("planets") nr_planets = 3 planets.object_id.expand(nr_planets)[:] = \ numpy.arange(nr_planets) constants = planets.add_property_set("constants") gravity = constants.add_property("gravity", dtype=numpy.dtype(numpy.float32)) gravity.value.expand(nr_planets)[:] = \ numpy.array([1.5, 2.5, 3.5], dtype=numpy.float32) lue.assert_is_valid(dataset)
def setUp(self): dataset_name = "my_dataset.lue" lue_test.remove_file_if_existant(dataset_name) self.dataset = lue.create_dataset(dataset_name) self.phenomenon = self.dataset.add_phenomenon("my_phenomenon") self.nr_objects = 5 self.phenomenon.object_id.expand(self.nr_objects)[:] = \ np.arange(self.nr_objects) self.nr_rows = 3 self.nr_cols = 2 self.value_shape = (self.nr_rows, self.nr_cols) self.numeric_value_type = np.dtype(np.int32) self.string_value_type = np.dtype(np.unicode_) self.property_set = \ self.phenomenon.add_property_set("my_property_set") numeric_property = self.property_set.add_property( "my_numeric_property", self.numeric_value_type, self.value_shape) string_property = self.property_set.add_property( "my_string_property", self.string_value_type, self.value_shape) self.lue_numeric_values = \ numeric_property.value.expand(self.nr_objects) self.numpy_numeric_values = np.arange( self.nr_objects * reduce(lambda x, y: x * y, self.value_shape), dtype=self.numeric_value_type).reshape((self.nr_objects, ) + self.value_shape) self.lue_numeric_values[:] = self.numpy_numeric_values self.lue_string_values = \ string_property.value.expand(self.nr_objects) self.numpy_string_values = \ self.numpy_numeric_values.astype(self.string_value_type) # self.lue_string_values[:] = self.numpy_string_values lue.assert_is_valid(self.dataset)
import numpy as np import lue nr_areas = 10 rank = 2 dataset = lue.create_dataset("elevation.lue") area = dataset.add_phenomenon("area") # id = [2, 4, 6, 8, 10, 9, 7, 5, 3, 1] # area.object_id.expand(nr_areas)[:] = id time_configuration = lue.TimeConfiguration(lue.TimeDomainItemType.box) clock = lue.Clock(lue.Unit.day, 1) space_configuration = lue.SpaceConfiguration(lue.Mobility.stationary, lue.SpaceDomainItemType.box) variable = area.add_property_set("variable", time_configuration, clock, space_configuration, space_coordinate_dtype=np.dtype(np.float32), rank=rank) object_tracker = variable.object_tracker ### # Time domain contains 1D boxes, with a resolution of 1 day ### time_domain = located.create_time_box_domain(areas, lue.Clock(lue.unit.day, 1)) ### nr_time_boxes = 4 ### time_boxes = time_domain.reserve(nr_time_boxes) ### # A box is defined by a begin and end time point (two coordinates per box) ### # Here, we configure time boxes with a duration of 10 days. The time
import numpy as np import lue nr_areas = 10 rank = 2 dataset = lue.create_dataset("areas.lue") area = dataset.add_phenomenon("area") id = [2, 4, 6, 8, 10, 9, 7, 5, 3, 1] area.object_id.expand(nr_areas)[:] = id space_configuration = lue.SpaceConfiguration(lue.Mobility.stationary, lue.SpaceDomainItemType.box) constant = area.add_property_set("constant", space_configuration, space_coordinate_dtype=np.dtype(np.float32), rank=rank) box = np.arange(nr_areas * rank * 2, dtype=np.float32).reshape(nr_areas, rank * 2) constant.space_domain.value.expand(nr_areas)[:] = box # Property with differently shaped 2D object arrays elevation_datatype = np.dtype(np.float32) elevation = constant.add_property("elevation", dtype=elevation_datatype, rank=rank) count_datatype = lue.dtype.Count shape = np.arange( # Dummy data nr_areas * rank, dtype=count_datatype).reshape(nr_areas, rank)
def test_case_study(self): # Time series as implemented here: # - Discharge at catchment outlets # - Located at fixed points in space # - Variable number of outlets per time box # - Discretized within multiple time boxes # - Time domain contains time boxes # - Space domain contains space points # - Property values are same_shape::different_shape (shape of value is # related to what is stored per box and boxes likely have different # numbers of cells) # - Property values are discretized # - Per time box the set of active objects is tracked # - Per time box active objects exist in all its cells # - Use this approach if the active set is constant within a time box nr_time_boxes = 3 shape_datatype = lue.dtype.Count shapes = numpy.random.randint( 10, 20, size=nr_time_boxes).astype(dtype=shape_datatype) def discharge_property(phenomenon): nr_outlets = 10 ids = numpy.arange(nr_outlets, dtype=numpy.uint64) phenomenon.object_id.expand(nr_outlets)[:] = ids # Time domain time_configuration = lue.TimeConfiguration( lue.TimeDomainItemType.box) clock = lue.Clock(lue.Unit.day, 1) # Space domain space_configuration = lue.SpaceConfiguration( lue.Mobility.stationary, lue.SpaceDomainItemType.point) space_coordinate_datatype = numpy.dtype(numpy.float64) rank = 2 # Property set outlet_points = phenomenon.add_property_set( "outlets", time_configuration, clock, space_configuration, space_coordinate_datatype, rank) # IDs object_tracker = outlet_points.object_tracker object_tracker.active_set_index.expand(nr_time_boxes) active_set_sizes = numpy.random.randint( 0, nr_outlets, nr_time_boxes).astype(dtype=lue.dtype.Count) active_set_idxs = numpy.empty(nr_time_boxes, dtype=lue.dtype.Index) active_object_ids = numpy.empty(active_set_sizes.sum(), dtype=lue.dtype.ID) lue.test.select_random_ids(active_set_sizes, active_set_idxs, active_object_ids, nr_outlets) object_tracker.active_object_id.expand(len(active_object_ids)) active_set_idx = numpy.uint64(0) for s in range(nr_time_boxes): active_set_size = active_set_sizes[s] object_tracker.active_set_index[s] = active_set_idxs[s] object_tracker.active_object_id[ active_set_idx:active_set_idx + active_set_size] = \ active_object_ids[active_set_idx:active_set_idx + active_set_size] active_set_idx += active_set_size # Time domain time_domain = outlet_points.time_domain time_coordinate_datatype = lue.dtype.TickPeriodCount time_boxes = numpy.arange(nr_time_boxes * 2, dtype=time_coordinate_datatype).reshape( nr_time_boxes, 2) time_domain.value.expand(nr_time_boxes)[:] = time_boxes # Space domain space_domain = outlet_points.space_domain space_points = numpy.arange( nr_outlets * rank, dtype=space_coordinate_datatype).reshape(nr_outlets, 2) space_domain.value.expand(nr_outlets)[:] = space_points # Property discharge_datatype = numpy.dtype(numpy.float32) discharge = outlet_points.add_property( "discharge", dtype=discharge_datatype, rank=1, shape_per_object=lue.ShapePerObject.same, shape_variability=lue.ShapeVariability.variable) discharge_values = [ numpy.arange(shapes[t] * active_set_sizes[t], dtype=discharge_datatype) for t in range(nr_time_boxes) ] for t in range(nr_time_boxes): discharge.value.expand( t, active_set_sizes[t], (shapes[t],))[:] = \ discharge_values[t] return discharge def discretization_property(phenomenon): # Property set collection = phenomenon.add_collection_property_set( "outlets_collection", phenomenon.property_sets["outlets"].time_domain) # IDs object_tracker = collection.object_tracker object_tracker.active_set_index.expand(nr_time_boxes) object_tracker.active_object_id.expand(nr_time_boxes) collection_id = 5 active_set_idx = 0 for s in range(nr_time_boxes): active_set_size = 1 object_tracker.active_set_index[s] = active_set_idx object_tracker.active_object_id[ active_set_idx:active_set_idx + active_set_size] = \ collection_id active_set_idx += active_set_size # Property discretization = collection.add_property( "discretization", dtype=shape_datatype, shape=(1, ), value_variability=lue.ValueVariability.variable) discretization.value.expand(nr_time_boxes)[:] = shapes return discretization dataset = lue.create_dataset("outlets1.lue") phenomenon = dataset.add_phenomenon("areas") discharge = discharge_property(phenomenon) discretization = discretization_property(phenomenon) # Link discharge to discretization discharge.set_time_discretization(lue.TimeDiscretization.regular_grid, discretization) lue.assert_is_valid(dataset)
def initial(self): self.startmap = scalar(0) self.startmap_home = scalar(0) self.lue_name = os.path.join( "LUE", "exposure_{0}.lue".format(str(self.currentSampleNumber()))) self.currentDate = self.startDate #pcraster.setrandomseed(self.currentSampleNumber()*1000) #random.seed(self.currentSampleNumber()*1000) self.workdf = self.workdf.sample( frac=1, replace=True, random_state=self.currentSampleNumber() * 1000) #randomly sample working locations self.work_realisation = os.path.join(str(self.currentSampleNumber()), "work_realisation.csv") self.workloc = os.path.join(str(self.currentSampleNumber()), "work_loc.map") # for testing self.workdf.to_csv(self.work_realisation, header=False) #save each realisation cmd = "col2map -S -s, --clone {0} -x 2 -y 3 -v 1 {1} {2} ".format( self.road_length_5000_file, self.work_realisation, self.workloc) subprocess.check_call(cmd, shell=True) #get extent form hdf file nr_rows, nr_cols, nl_west, nl_south, nl_north, nl_east = get_nrrow_nrcol_west_south_north_east( self.hdf5file, self.phenomena_name) cellsize = (nl_east - nl_west) / nr_cols self.window_size_x = int(nr_rows) self.window_size_y = int(nr_cols) print "input dataset:", nl_west, nl_south, nl_north, nl_east, nr_rows, nr_cols, cellsize, self.window_size_x, self.window_size_y # Here create the new dataset if LUE does not exists. if os.path.isfile(self.lue_name) == False: dataset = lue.create_dataset(self.lue_name) # add phenomenon phenomenon_exposure = dataset.add_phenomenon(self.lue_phenomena) #add propertyset ps_points = create_propertyset(phenomenon_exposure, self.lue_ps_points) ps_areas = create_propertyset(phenomenon_exposure, self.lue_ps_area) #load properties # ids for the properties are necessary for now ids_front = ps_points.reserve(self.nr_locations) ids_area = ps_areas.reserve(self.nr_locations) # assign a unique id ids_front[:] = range(0, self.nr_locations) ids_area[:] = range(0, self.nr_locations) load_route_LUE(ps_areas, self.nr_locations, self.homedf, self.workdf, self.window_size_x, self.window_size_y, self.lue_p_area_route) #load work and home locations to LUE load_home_work_LUE(ps_points, self.nr_locations, self.homedf, self.workdf, self.lue_p_points_home, self.lue_p_points_home_rowcol, self.lue_p_points_work, self.lue_p_points_work_rowcol, nl_west, nl_north, cellsize) lue.assert_is_valid(dataset) #open LUE for use dataset = lue.open_dataset(self.lue_name, "w") phenomenon = dataset.phenomena[self.lue_phenomena] self.route_set = phenomenon.property_sets[self.lue_ps_area] self.pslocations = phenomenon.property_sets[self.lue_ps_points] self.timestep = 1 #self.exposure_Map = scalar(1) # self.array0= numpy.zeros((self.window_size_x * self.window_size_y,), dtype=numpy.float32) # self.clone_array_home = self.array0.reshape(self.window_size_x,self.window_size_y) # for i in range(1, self.nr_locations): # home_loc_row = int(self.pslocations[self.lue_p_points_home_rowcol].values[i][:][0]) # home_loc_col = int(self.pslocations[self.lue_p_points_home_rowcol].values[i][:][1]) # # w_loc_row = self.pslocations[self.lue_p_points_work_rowcol].values[i][:][0] # # w_loc_col = self.pslocations[self.lue_p_points_work_rowcol].values[i][:][1] # # home_loc_row1 = self.pslocations[self.lue_p_points_home].values[i][:][0]) # # home_loc_col2 = self.pslocations[self.lue_p_points_home].values[i][:][1]) # # print home_loc_row, home_loc_col, home_loc_row1, home_loc_col2, w_loc_col,w_loc_row # self.clone_array_home[ home_loc_row, home_loc_col ]=1 # self.startcell_home = numpy2pcr(Boolean, self.clone_array_home, 0.0) # for homemakers self.test_dest = scalar(0)
def test_case_study1(self): # A number of trees # - Location of tree in space is stored as 2D points # - Location of crown in space is stored as 2D boxes with # discretized presence nr_trees = 10 nr_time_boxes = 6 rank = 2 # Space ids = np.arange(nr_trees, dtype=np.uint64) def add_stem_properties(phenomenon): # Property-set for properties attached to tree stems. Stems # are located in space using stationary 2D points. # Property-set space_configuration = lue.SpaceConfiguration( lue.Mobility.stationary, lue.SpaceDomainItemType.point) space_coordinate_datatype = np.dtype(np.float32) stem_points = phenomenon.add_property_set( "stems", space_configuration, space_coordinate_datatype, rank) # Space domain space_domain = stem_points.space_domain space_points = np.arange(nr_trees * rank, dtype=space_coordinate_datatype).reshape( nr_trees, 2) space_domain.value.expand(nr_trees)[:] = space_points # Property tree_kind = stem_points.add_property("kind", dtype=np.dtype(np.uint8)) tree_kind.value.expand(nr_trees)[:] = \ (10 * np.random.rand(nr_trees)).astype(np.uint8) return stem_points def discretized_presence(property_set): # Set-up a boolean property and a discretization property for # storing temporal boolean grids representing the presence # in space of tree crowns through time # Discretization property # Here, discretization does not change through time count_datatype = lue.dtype.Count discretization = property_set.add_property("discretization", dtype=count_datatype, shape=(rank, )) shapes = np.arange( 1, nr_trees * rank + 1, dtype=count_datatype) \ .reshape(nr_trees, 2) discretization.value.expand(nr_trees)[:] = shapes # Presence property presence_datatype = np.dtype(np.uint8) presence = property_set.add_property( "presence", dtype=presence_datatype, rank=rank, shape_per_object=lue.ShapePerObject.different, shape_variability=lue.ShapeVariability.constant) for t in range(nr_trees): value_array = \ presence.value.expand( ids[t], tuple(shapes[t]), nr_time_boxes) for b in range(nr_time_boxes): values = ( 10 * np.random.rand(*shapes[t])).astype(presence_datatype) value_array[b] = values # Link presence to discretization presence.set_space_discretization( lue.SpaceDiscretization.regular_grid, discretization) return presence def add_crown_properties(phenomenon): # Property-set for properties attached to tree crowns. Crowns # are located in space using stationary 2D boxes within # which the presence is discretized. The presence of the # growing crowns changes through time. # So, even though the boxes are stationary, presence can # still vary through time. # Property set time_configuration = lue.TimeConfiguration( lue.TimeDomainItemType.box) clock = lue.Clock(lue.Unit.week, 1) space_configuration = lue.SpaceConfiguration( lue.Mobility.stationary, lue.SpaceDomainItemType.box) space_coordinate_datatype = np.dtype(np.float32) crown_boxes = phenomenon.add_property_set( "crowns", time_configuration, clock, space_configuration, space_coordinate_datatype, rank) # [0, nr_trees, 2 * nr_tree, ..., t * nr_trees] crown_boxes.object_tracker.active_set_index.expand( nr_time_boxes)[:] = \ np.array( [t * nr_trees for t in range(nr_time_boxes)], dtype=lue.dtype.Index) # [0, 0, 0, ..., nr_time_boxes-1, nr_time_boxes-1] crown_boxes.object_tracker.active_object_index.expand( nr_time_boxes * nr_trees)[:] = \ np.repeat( np.arange(0, nr_time_boxes, dtype=lue.dtype.Index), repeats=nr_trees) # [id1, id2, ..., idn, ..., id1, id2, ...idn] crown_boxes.object_tracker.active_object_id.expand( nr_time_boxes * nr_trees)[:] = \ np.repeat( ids.reshape((1, nr_trees)), repeats=nr_time_boxes, axis=0).flatten() # Space domain space_domain = crown_boxes.space_domain boxes = np.arange( nr_trees * rank * 2, dtype=space_coordinate_datatype) \ .reshape(nr_trees, 4) space_domain.value.expand(nr_trees)[:] = boxes # Time domain time_domain = crown_boxes.time_domain time_coordinate_datatype = lue.dtype.TickPeriodCount boxes = np.arange( nr_time_boxes * 2, dtype=time_coordinate_datatype) \ .reshape(nr_time_boxes, 2) time_domain.value.expand(nr_time_boxes)[:] = boxes presence = discretized_presence(crown_boxes) crown_boxes.space_domain.set_presence_discretization(presence) return crown_boxes dataset = lue.create_dataset("trees.lue") trees = dataset.add_phenomenon("trees") trees.object_id.expand(nr_trees)[:] = ids stem_properties = add_stem_properties(trees) crown_properties = add_crown_properties(trees) lue.assert_is_valid(dataset)
def test_case_study2(self): dataset = lue.create_dataset("forest.lue") # We are assuming here that we can model biomass of trees in a # forest on a daily basis, during the growth season. This allows # us to use multiple discretized time boxes. time_cell_configuration = lue.TimeConfiguration( lue.TimeDomainItemType.cell) clock = lue.Clock(lue.Unit.day, 1) time_coordinate_datatype = lue.dtype.TickPeriodCount # Trees usually don't move. Forests neither. stationary_space_point_configuration = lue.SpaceConfiguration( lue.Mobility.stationary, lue.SpaceDomainItemType.point) stationary_space_box_configuration = lue.SpaceConfiguration( lue.Mobility.stationary, lue.SpaceDomainItemType.box) space_coordinate_datatype = np.dtype(np.float32) space_rank = 2 count_datatype = lue.dtype.Count cell_size = 0.5 # m max_size_of_crown = int(20 / cell_size) # 20 m in nr of cells nr_cells_in_crown = max_size_of_crown**2 biomass_datatype = np.dtype(np.float32) # Trees ---------------------------------------------------------------- trees = dataset.add_phenomenon("trees") stems = trees.add_property_set("stems", stationary_space_point_configuration, space_coordinate_datatype, space_rank) crowns = trees.add_property_set("crowns", time_cell_configuration, clock, stationary_space_box_configuration, space_coordinate_datatype, space_rank) crowns_biomass = crowns.add_property( "biomass", dtype=biomass_datatype, shape=(max_size_of_crown, max_size_of_crown), value_variability=lue.ValueVariability.variable) # Biomass discretization # Each biomass value is a 2D value with the same shape # (max_size_of_crown x max_size_of_crown). In this value biomass # values are stored per cell. The discretization of each extent # is stored in the crown discretization property. This property # only needs to store a single value with nr_rows/nr_cols of each # crown extent. This value is the same for each crown and does # not change through time. It can therefore be stored as a static # property in the collection property sets of the trees phenomenon. trees_globals = trees.add_collection_property_set("globals") crowns_biomass_discretization = trees_globals.add_property( "biomass_discretization", dtype=count_datatype, shape=(space_rank, )) crowns_biomass_discretization.value.expand(1)[:] = np.array( [max_size_of_crown, max_size_of_crown], dtype=count_datatype).reshape(1, space_rank) # Link biomass to discretization crowns_biomass.set_space_discretization( lue.SpaceDiscretization.regular_grid, crowns_biomass_discretization) # Forests -------------------------------------------------------------- # TODO Each forest could be represented by a boolean space # grid in the property set. If this is not necessary, biomass # can be a discretized property within an extent. forests = dataset.add_phenomenon("forests") areas = forests.add_property_set("areas", crowns.time_domain, stationary_space_box_configuration, space_coordinate_datatype, space_rank) areas_biomass = areas.add_property( "biomass", dtype=biomass_datatype, rank=space_rank, shape_per_object=lue.ShapePerObject.different, shape_variability=lue.ShapeVariability.constant) # Forest biomass discretization forests_globals = forests.add_collection_property_set("globals") forests_biomass_discretization = forests_globals.add_property( "biomass_discretization", dtype=count_datatype, shape=(space_rank, )) # TODO The extent of the forest must be known beforehand nr_forests = 1 forest_ids = np.arange(nr_forests, dtype=lue.dtype.ID) forest_shapes = \ np.arange(nr_forests * space_rank, dtype=count_datatype) \ .reshape(nr_forests, space_rank) + 10 forests_biomass_discretization.value.expand(nr_forests)[:] = np.array( [100, 100], dtype=count_datatype).reshape(nr_forests, space_rank) # Link biomass to discretization areas_biomass.set_space_discretization( lue.SpaceDiscretization.regular_grid, forests_biomass_discretization) # Iterate over time boxes (only growth season) # Iterate over time cells # - Calculate birth and death of trees # - Birth: # - Add ID to trees phenomenon # - Add location to stem property-set # - Add ID to crowns property set object tracker # - Center max_crown_extent sized space box # around stem and add to crowns property-set # - Store presence in boolean presence space grid # and for all true cell store a biomass, or # - store biomass distribution as a discretized # 2D value # - Death # - Stop writing ID to crowns property set # object tracker # - Stop writing (presence grid and) biomass # property values # - Calculate tree growth of living trees # - Calculate the distribution of biomass within the forest # - Per forest, write current biomass to biomass # property # TODO Fix handling of time # Per year, only changes in state during the growth season # are stored nr_years = 10 nr_days_per_year = 365 start_of_growth_season = 50 # Within each year nr_days_per_growth_season = 200 crowns_time_boxes = crowns.time_domain.value.expand(nr_years) crowns_time_cell_counts = \ crowns.time_domain.value.count.expand(nr_years) crowns_active_set_index = crowns.object_tracker.active_set_index crowns_active_object_id = crowns.object_tracker.active_object_id areas_active_set_index = areas.object_tracker.active_set_index areas_active_object_id = areas.object_tracker.active_object_id areas_active_object_idx = areas.object_tracker.active_object_index for id_ in forest_ids: areas_biomass.value.expand(forest_ids[id_], tuple(forest_shapes[id_]), nr_years * nr_days_per_growth_season) for y in range(nr_years): # Time domain item for this growth season t_start = (y * nr_days_per_year) + start_of_growth_season t_end = t_start + nr_days_per_growth_season time_box = np.array([t_start, t_end], dtype=time_coordinate_datatype) crowns_time_boxes[y] = time_box crowns_time_cell_counts[y] = nr_days_per_growth_season for d in range(nr_days_per_growth_season): d_idx = y * nr_days_per_growth_season + d # TODO # Determine collection of starting trees: # - ID # - Stem location # - Crown extent starting_tree_ids = np.array([d_idx], dtype=lue.dtype.ID) nr_starting_trees = len(starting_tree_ids) starting_tree_stem_locations = np.arange( nr_starting_trees * space_rank, dtype=space_coordinate_datatype).reshape( nr_starting_trees, space_rank) starting_tree_crown_locations = np.arange( nr_starting_trees * space_rank * 2, dtype=space_coordinate_datatype).reshape( nr_starting_trees, space_rank * 2) # Store IDs of starting trees in collection of IDs trees.object_id.expand(nr_starting_trees)[-nr_starting_trees] = \ starting_tree_ids # Store stem locations of starting trees stems.space_domain.value.expand(nr_starting_trees)[-nr_starting_trees] = \ starting_tree_stem_locations # Store crown extents of starting trees crowns.space_domain.value.expand(nr_starting_trees)[-nr_starting_trees] = \ starting_tree_crown_locations # Determine collection of stopping trees: # - ID stopping_tree_ids = np.array([], dtype=lue.dtype.ID) # Determine collection of active trees # - ID # - Biomass active_tree_ids = starting_tree_ids # TODO remove stopping trees # Store IDs of active trees in the active set object_index = crowns_active_object_id.nr_ids crowns_active_set_index.expand(1)[-1] = object_index nr_active_trees = len(active_tree_ids) crowns_active_object_id.expand(nr_active_trees)[object_index:] = \ active_tree_ids # For all active trees, calculate new biomass values and # write them to the biomass property crowns_biomass_values = \ np.arange( nr_active_trees * nr_cells_in_crown, dtype=biomass_datatype).reshape( nr_active_trees, max_size_of_crown, max_size_of_crown) crowns_biomass.value.expand(nr_active_trees)[object_index:] = \ crowns_biomass_values # Store IDs of active forests in the active set # Currently this is the one and only forest containing # all trees. active_forest_ids = np.array([0], dtype=lue.dtype.ID) active_forest_idxs = np.array([d], dtype=lue.dtype.Index) object_index = areas_active_object_id.nr_ids areas_active_set_index.expand(1)[-1] = object_index nr_active_forests = len(active_forest_ids) areas_active_object_id.expand(nr_active_forests)[object_index:] = \ active_forest_ids areas_active_object_idx.expand(nr_active_forests)[object_index:] = \ active_forest_idxs # For all forests, calculate new biomass values and # write them to the biomass property for id_ in forest_ids: forest_shape = tuple(forest_shapes[id_]) nr_cells_in_forest = forest_shape[0] * forest_shape[1] areas_biomass.value[id_][y] = \ np.arange(nr_cells_in_forest, dtype=biomass_datatype) \ .reshape(*forest_shape) # Initialize forests. All trees should be located within one of # the forests. For now, we assume all trees are part of a # single forest. The extent of this forest is the bounding box # around all tree crowns. nr_trees = len(crowns.space_domain.value) if nr_trees > 0: # Store IDs of starting trees in collection of IDs forests.object_id.expand(1)[-1] = 0 min_x, min_y, max_x, max_y = crowns.space_domain.value[0] for crown_space_box in crowns.space_domain.value[1:]: min_x, min_y, max_x, max_y = \ min(min_x, crown_space_box[0]), \ min(min_y, crown_space_box[1]), \ max(max_x, crown_space_box[2]), \ max(max_y, crown_space_box[3]) forest_space_box = np.array([min_x, min_y, max_x, max_y], dtype=space_coordinate_datatype) areas.space_domain.value.expand(1)[-1] = forest_space_box lue.assert_is_valid(dataset)
import numpy as np import lue # Create a dataset dataset = lue.create_dataset("planets.lue") # Add a phenomenon for storing information about planets planet = dataset.add_phenomenon("planet") # Add the IDs of three planets to the phenomenon nr_planets = 3 planet.object_id.expand(nr_planets)[:] = [4, 29, 13] # Add a property-set for storing constant information constant = planet.add_property_set("constant") # Add a property for storing gravity values gravity = constant.add_property("gravity", dtype=np.dtype(np.float32)) # Write the actual gravity values to the dataset gravity.value.expand(nr_planets)[:] = \ np.array([ 1.5, 2.5, 3.5 ], dtype=np.float32)
import numpy as np import lue nr_cities = 10 rank = 2 dataset = lue.create_dataset("cities.lue") city = dataset.add_phenomenon("city") id = [2, 4, 6, 8, 10, 9, 7, 5, 3, 1] city.object_id.expand(nr_cities)[:] = id space_configuration = lue.SpaceConfiguration( lue.Mobility.stationary, lue.SpaceDomainItemType.point ) constant = city.add_property_set( "constant", space_configuration, space_coordinate_dtype=np.dtype(np.float32), rank=rank) point = np.arange(nr_cities * rank, dtype=np.float32).reshape(nr_cities, rank) constant.space_domain.value.expand(nr_cities)[:] = point population = constant.add_property("population", dtype=np.dtype(np.int64)) population.value.expand(nr_cities)[:] = ( # Dummy data np.random.rand(nr_cities) * 1e6).astype(np.int64)
def test_case_study(self): # Time series as implemented here: # - Discharge at catchment outlets # - Located at fixed points in space # - Variable number of outlets per time cell # - Presence of outlets is discretized within multiple time boxes # - Time domain contains time cells # - Space domain contains space points # - Property values are same_shape::constant_shape (shape of value is # related to what is stored per cell) # - Property values are not discretized # - Per time cell the set of active objects is tracked # - Use this approach if the active set is variable within a # time box # - - Additional storage required for tracking active sets, # compared to Time series I # - + Possible to let objects be 'born' and 'die' during # iterative simulation dataset = lue.create_dataset("outlets2.lue") phenomenon = dataset.add_phenomenon("areas") # Assume we are simulating some temporal variable (discharge at # catchment outlets). # The existance of the objects is modelled using time cells, # which are discretized time boxes (daily time steps). Per cell we # can store which objects are active. # Property values are located in time at time cells. # Property values are located in space at stationary space points. # Time domain time_configuration = lue.TimeConfiguration(lue.TimeDomainItemType.cell) epoch = lue.Epoch(lue.Epoch.Kind.common_era, "2019-01-01", lue.Calendar.gregorian) clock = lue.Clock(epoch, lue.Unit.day, 1) time_coordinate_datatype = lue.dtype.TickPeriodCount # Space domain space_configuration = lue.SpaceConfiguration( lue.Mobility.stationary, lue.SpaceDomainItemType.point) space_coordinate_datatype = numpy.dtype(numpy.float32) rank = 2 # Property set outlet_points = phenomenon.add_property_set("outlets", time_configuration, clock, space_configuration, space_coordinate_datatype, rank) time_domain = outlet_points.time_domain space_domain = outlet_points.space_domain active_set_index = outlet_points.object_tracker.active_set_index active_object_id = outlet_points.object_tracker.active_object_id # Property discharge_datatype = numpy.dtype(numpy.float32) discharge = outlet_points.add_property( "discharge", dtype=discharge_datatype, shape=(1, ), value_variability=lue.ValueVariability.variable) nr_time_boxes = 5 max_nr_objects = 100 # Iterate over the time boxes for t in range(nr_time_boxes): # Store additional time box and count time_box = numpy.array([t, t + 1], dtype=time_coordinate_datatype) time_domain.value.expand(1)[-1] = time_box count = int(10 * random.random()) time_domain.value.count.expand(1)[-1] = count # Iterate over the time cells within each time box for c in range(count): # Store IDs of objects in the active set object_index = active_object_id.nr_ids active_set_index.expand(1)[-1] = object_index nr_objects = int(random.random() * max_nr_objects) object_id = numpy.empty(nr_objects, dtype=lue.dtype.ID) lue.test.select_random_ids(object_id, max_nr_objects) active_object_id.expand(nr_objects)[object_index:] = object_id # Store property values of active objects discharge_values = \ numpy.arange(nr_objects, dtype=discharge_datatype) discharge.value.expand(nr_objects)[object_index:] = \ discharge_values lue.assert_is_valid(dataset) del dataset dataset = lue.open_dataset("outlets2.lue") phenomenon = dataset.phenomena["areas"] outlet_points = phenomenon.property_sets["outlets"] time_domain = outlet_points.time_domain clock = time_domain.clock self.assertEqual(clock.epoch.kind, lue.Epoch.Kind.common_era) self.assertEqual(clock.epoch.origin, "2019-01-01") self.assertEqual(clock.epoch.calendar, lue.Calendar.gregorian) self.assertEqual(clock.unit, lue.Unit.day) self.assertEqual(clock.nr_units, 1)