Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

13randommove #14

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions source/campo/op_experimental/randommove.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import numpy as np
import random
from pathlib import Path
import sys
from field_agent.field_agent_interactions import raster_values_to_feature, zonal_values_to_feature
import campo
import math
import matplotlib.pyplot as plt

def randommove_to_boolean (boolean_fieldprop, field_pset, point_prop):
'''
- boolean_fieldprop = a property that is a field and contains true values for places where an agent may move to
- field_pset = a property set describing the domain of the field of the study area (Type: propertyset)
- point_propset = the property set that has the move (= point agents)
- nragents = the number of point agents
return lists of coordinates with the same length as the number of agents in a point propertyset (sueful wehn you want to make them move there)
'''
# need to flip again because when calculating with this map points have different orientation than field (see rerasterize)
if isinstance(boolean_fieldprop, np.ndarray):
map_flipped = np.flip (boolean_fieldprop, axis=0)
elif isinstance (boolean_fieldprop, campo.property.Property):
map_flipped = np.flip (boolean_fieldprop.values()[0], axis=0)
else:
raise TypeError ('boolean_fieldprop needs to be of type campo.property or of a numpy array with same dimensions as field property values')

nragents = len (point_prop.values().values.values())
for fidx, area in enumerate (field_pset.space_domain):
nr_cols = int(area[5])
xmin = area [0]
ymin = area [1]
resolution = math.fabs (area[2] - xmin)/nr_cols
# finding the indices of the places where the fieldcondition is true
coords_idx = np.argwhere (map_flipped) #coordinates of the spawning grounds in [y,x]
# collecting the coordinate combination in a tuple so as to prevent them from being 'disconnected' from eachother
coords_list = [tuple(row) for row in coords_idx]
random_newindex = random.sample (coords_list, nragents) # nr of agents is the subsetsize
# seperating the tuples in the list in two seperate list
yindex, xindex = zip(*random_newindex) #assuming that tuple list is reversed, first gives y then x as in column = x and row = y
xindex = np.array (xindex)
yindex = np.array (yindex)
xcoords = np.zeros(nragents)
ycoords = np.zeros(nragents)

# make from x index a x coordinate by using resolution and bounding box information
for i, xvalue in enumerate(xindex):
xcoords [i] = (xvalue*resolution + xmin)
for j, yvalue in enumerate(yindex):
ycoords[j] = (yvalue *resolution + ymin)
return xcoords, ycoords
58 changes: 58 additions & 0 deletions source/campo/op_experimental/zonal.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
from osgeo import gdal
from osgeo import osr
from osgeo import ogr

gdal.UseExceptions()

import math
import numpy as np

from campo.points import Points
from campo.areas import Areas
from campo.property import Property

def zonal_values_to_feature(point_pset, field_pset, field_prop_class, field_prop_var, operation):
''' Queries aggregative raster values of a zone of a field property based on the location
of point agents within a classification map, given a certain aggregative operation.
Writes this as a new point agent property. Only works for one fieldagent existing at the location.
Fieldagents with overlapping domains cannot generate an output
E.g.: According to both the agent's location and a soil map (field_prop_class), the agent is positioned in
soil '2' , which is clay. With the operation 'mean', the mean rainfall (from field_prop_var)
is calculated and attributed to the agent
Parameters:
point_pset: property set of the point agents to be attributed the location
field_pset: property set of a single field
field_prop_class: property describing classes or groups of cells of which the zonal extent shall be the windowsize of the aggregration
field_prop_var: property describing the variable which needs to be aggregated,
in case of a boolean map, 'True' values are 1
operation: operation: aggregative numpy operation as a string ('sum', 'mean', 'min', 'max', 'etc')
Returns:
point_prop: property of point agents with values of aggregated field values'''

# Generate operator, first checking if operation is available in numpy
if not hasattr (np, operation):
raise ValueError (f'Unsupported numpy operation, {operation}')
operator = getattr(np, operation)

# Identifying the zone the agent is in
agents_zoneIDs = raster_values_to_feature(point_pset,field_pset, field_prop_class)
# Generate empty point property given point property space definitions
point_prop = Property('emptycreatename', point_pset.uuid, point_pset.space_domain, point_pset.shapes)
# make as many field properties as there are agents:
# Loop over space attributes of the different points in the point agents propertyset
for pidx, ID in enumerate(agents_zoneIDs.values()):
# Making a boolean map concerning the extent of the zone for each agent
aggr_zone_var = np.zeros(1)
for fidx,area in enumerate(field_pset.space_domain):
zone_extent = np.where (field_prop_class.values()[fidx] == ID, 1, 0)
variable_zone_array = np.multiply (zone_extent, field_prop_var.values()[fidx])
# we don't need to flip this time, since the raster_values_to_feature already gave
# the right topological relationship between the field and the agent:
# the zone_extent array describes the zone in which the agent is positioned.
# This array might be flipped, but this won't lead to any different outcomes of aggregative operations
aggr_zone_var[fidx] = operator (variable_zone_array)
#field_prop_array [pidx] = field_prop# array as long as the number of agents filled with a field prop for each agent
# Write the value to the point property for each point agent
point_prop.values()[pidx] = aggr_zone_var.item()

return point_prop