Skip to content

Commit

Permalink
Merge branch 'gh4'
Browse files Browse the repository at this point in the history
  • Loading branch information
OliverSchmitz committed Mar 13, 2024
2 parents 3970e6b + 74ef7a3 commit 42f38ec
Show file tree
Hide file tree
Showing 4 changed files with 136 additions and 23 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.22)

project(campo
VERSION 0.3.11
VERSION 0.3.12
DESCRIPTION "Modelling framework for fields and agents"
HOMEPAGE_URL "https://campo.computationalgeography.org/"
LANGUAGES NONE
Expand Down
24 changes: 21 additions & 3 deletions source/campo/values.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,36 @@ def __init__(self, nr_objects, shapes, values):

if isinstance(values, (int, float)):
self._init_numbers(shapes, values)

elif isinstance(values, np.ndarray):
self._init_array(shapes, values)
elif isinstance(values, property.Property):
self._init_prop(shapes, values)
else:
raise NotImplementedError
msg = f"Setting values with '{type(values).__name__}' is not implemented. Use NumPy arrays instead."
raise NotImplementedError(msg)

def _init_array(self, shapes, values):

dim = len(shapes[0])

if values.ndim == 2:
msg = f"Array of shape ({values.shape[0]}, {values.shape[1]}) cannot be assigned to one agent, use shape (1, {values.shape[0]}, {values.shape[1]})"
raise ValueError(msg)

if len(shapes) != values.shape[0]:
msg = f"Number of provided values ({values.shape[0]}) does not match number of agents ({len(shapes)})"
raise ValueError(msg)

for idx, shape in enumerate(shapes):
self.values[idx] = values[idx]
if dim == 1:
self.values[idx] = np.array([values[idx]])
elif dim == 2:
if shape != values[idx].shape:
msg = f"The provided shape {values[idx].shape} does not match the expected shape {shape}"
raise ValueError(msg)
self.values[idx] = values[idx]
else:
raise NotImplementedError

def _init_numbers(self, shapes, values):

Expand Down
19 changes: 18 additions & 1 deletion source/test/test_dataframe.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ def test_2(self):
tmp_df = campo.to_df(dataframe, timestep)
campo.mobile_points_to_gpkg(coords, tmp_df, f"tmp_{timestep}.gpkg", 'EPSG:28992')


def test_3(self):
""" Writing GeoTiff stationary dynamic field agent """

Expand All @@ -64,3 +63,21 @@ def test_3(self):
raster = df["phen"]["field"]["fdata"][agent_id][timestep - 1]
filename = pathlib.Path(directory, f"fdata_{agent_id}_{timestep}.tiff")
campo.to_geotiff(raster, filename, crs)

def test_4(self):
""" Writing GeoTiff stationary dynamic field agent """

dataset = ldm.open_dataset("TestDynamicModel_test_2.lue", "r")
df = campo.dataframe.select(dataset.phen2, property_names=['fdata'])

agent_id = 0
crs = "EPSG:4326"
directory = "TestDataframe_test_4"

if not pathlib.Path(directory).exists():
pathlib.Path(directory).mkdir()

for timestep in range(1, 6):
raster = df["phen2"]["field"]["fdata"][agent_id][timestep - 1]
filename = pathlib.Path(directory, f"fdata_{agent_id}_{timestep}.tiff")
campo.to_geotiff(raster, filename, crs)
114 changes: 96 additions & 18 deletions source/test/test_property.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,22 +15,22 @@ def tearDownClass(self):
def setUpClass(self):

# Some dummy spatial domain
with open('locations.csv', 'w') as content:
content.write('1,2\n3,4\n5,6\n7,8')
with open("locations.csv", "w") as content:
content.write("1,2\n3,4\n5,6\n7,8")

with open('extent.csv', 'w') as content:
with open("extent.csv", "w") as content:
content.write("0,0,20,40,2,3\n")
content.write("0,0,20,30,2,3\n")
content.write("0,0,20,30,2,3\n")
content.write("0,0,20,30,2,3\n")

self.ds = campo.Campo(seed=13)

self.a = self.ds.add_phenomenon('a')
self.a.add_property_set('b', 'locations.csv')
self.a.add_property_set('field', 'extent.csv')
self.a = self.ds.add_phenomenon("a")
self.a.add_property_set("b", "locations.csv")
self.a.add_property_set("field", "extent.csv")

def test_1(self):
def test_01(self):
""" Point agents getting same values """

self.a.b.c = 500
Expand All @@ -39,7 +39,7 @@ def test_1(self):
for idx, value in enumerate(self.a.b.c.values()):
self.assertEqual(arr[idx], value[0])

def test_2(self):
def test_02(self):
""" Point agents getting values from normal distribution """
self.a.b.lower = -8
self.a.b.upper = 2
Expand All @@ -49,7 +49,7 @@ def test_2(self):
for idx, value in enumerate(self.a.b.c.values()):
self.assertAlmostEqual(arr[idx], value[0])

def test_3(self):
def test_03(self):
""" Point agents getting values from uniform distribution """
self.a.b.lower = -4
self.a.b.upper = 10
Expand All @@ -59,7 +59,7 @@ def test_3(self):
for idx, value in enumerate(self.a.b.c.values()):
self.assertAlmostEqual(arr[idx], value[0])

def test_4(self):
def test_04(self):
""" Field agents getting same values """

self.a.field.c = 500
Expand All @@ -69,8 +69,7 @@ def test_4(self):
for idx, value in enumerate(self.a.field.c.values()):
self.assertTrue((arr==value).all())


def test_5(self):
def test_05(self):
""" Field agents getting values from normal distribution """
self.a.field.lower = -8
self.a.field.upper = 2
Expand All @@ -87,8 +86,7 @@ def test_5(self):
for idx, value in enumerate(self.a.field.c.values()):
self.assertTrue((np.isclose(arr[idx], value).all()))


def test_6(self):
def test_06(self):
""" Field agents getting values from uniform distribution """
self.a.field.lower = -4
self.a.field.upper = 10
Expand All @@ -106,8 +104,7 @@ def test_6(self):
for idx, value in enumerate(self.a.field.c.values()):
self.assertTrue((np.isclose(arr[idx], value).all()))


def test_7(self):
def test_07(self):
""" Point agents getting values from random_integers distribution """
self.a.b.lower = -25
self.a.b.upper = 25
Expand All @@ -117,8 +114,7 @@ def test_7(self):
for idx, value in enumerate(self.a.b.c.values()):
self.assertEqual(arr[idx], value[0])


def test_8(self):
def test_08(self):
""" Field agents getting values from random_integers distribution """
self.a.field.lower = -4
self.a.field.upper = 10
Expand All @@ -135,3 +131,85 @@ def test_8(self):

for idx, value in enumerate(self.a.field.c.values()):
self.assertTrue((arr[idx]==value).all())

def test_09(self):
""" Point agents, assigning values with NumPy array """
self.a.b.c = np.array([500, 600, 700, 800], dtype=np.int32)
arr = np.array([500, 600, 700, 800], dtype=np.int32)

for idx, value in enumerate(self.a.b.c.values()):
self.assertEqual(arr[idx], value[0])

def test_10(self):
""" Point agents, assigning values with unsupported """
with self.assertRaises(Exception) as context_manager:
self.a.b.c = [12, 34, 56, 78]

self.assertRegex(str(context_manager.exception),
"Setting values with 'list' is not implemented. Use NumPy arrays instead.")

with self.assertRaises(Exception) as context_manager:
self.a.b.c = "unexpected"

self.assertRegex(str(context_manager.exception),
"Setting values with 'str' is not implemented. Use NumPy arrays instead.")

def test_11(self):
""" Point agents, assigning array with different nr of agents """
with self.assertRaises(Exception) as context_manager:
self.a.b.c = np.array([500, 600, 700])

self.assertEqual(str(context_manager.exception),
"Number of provided values (3) does not match number of agents (4)")

def test_12(self):
""" Field agents, assigning arrays with different nr of agents """
with self.assertRaises(Exception) as context_manager:
self.a.field.a = np.arange(1, 19).reshape(3, 2, 3)

self.assertEqual(str(context_manager.exception),
"Number of provided values (3) does not match number of agents (4)")

def test_13(self):
""" Field agents, assigning arrays """
self.a.field.a = np.arange(1, 25).reshape(4, 2, 3)

val = np.arange(1, 25).reshape(4, 2, 3)

for idx, value in enumerate(self.a.field.a.values()):
self.assertTrue((val[idx]==value).all())

def test_14(self):
""" Field agents, assigning arrays incorrect shape"""
with self.assertRaises(Exception) as context_manager:
self.a.field.a = np.arange(1, 25).reshape(4, 3, 2)

self.assertEqual(str(context_manager.exception),
"The provided shape (3, 2) does not match the expected shape (2, 3)")

def test_15(self):
""" One field agent, assigning array values"""
with open("extent2.csv", "w") as content:
content.write("0,0,20,40,2,3\n")

ds = campo.Campo(seed=13)
phen2 = self.ds.add_phenomenon("phen2")
phen2.add_property_set("field", "extent2.csv")

phen2.field.a = np.arange(1, 7).reshape(1, 2, 3)
val = np.arange(1, 7).reshape(1, 2, 3)

for idx, value in enumerate(phen2.field.a.values()):
self.assertTrue((val[idx]==value).all())

with self.assertRaises(Exception) as context_manager:
phen2.field.a = np.arange(1, 7).reshape(1, 3, 2)

self.assertEqual(str(context_manager.exception),
"The provided shape (3, 2) does not match the expected shape (2, 3)")

with self.assertRaises(Exception) as context_manager:
phen2.field.a = np.arange(1, 7).reshape(2, 3)

self.assertEqual(str(context_manager.exception),
"Array of shape (2, 3) cannot be assigned to one agent, use shape (1, 2, 3)")

0 comments on commit 42f38ec

Please sign in to comment.