import unittest import numpy as np from tests.helpers import fields, line_world from worldhistory.predicates import check, depth, evaluate, parse from worldhistory.regions import Regions, region_mask class PredicateTest(unittest.TestCase): def setUp(self): # cells: 0 forest land, 1 desert land by a river, 2 mountain land, 3 shelf sea, 4 deep sea with a vent self.w = line_world(5, ocean=[False, False, False, True, True], holdridge=[20, 23, 12, 0, 0], landform=[1, 1, 3, 0, 0], river=[False, True, False, False, False], strahler=[0, 4, 0, 0, 0], elevation_m=[100, 50, 2000, -150, -3000], vent_potential=[0, 0, 0, 0, 0.8], T_mean=[10, 30, 0, 12, 5], lithology=[1, 3, 4, 0, 0]) def test_parse(self): self.assertEqual(parse("land"), ("land", [])) self.assertEqual(parse("warm:5:20"), ("warm", [5.0, 20.0])) self.assertEqual(parse("lithology:3,4"), ("lithology", [[3, 4]])) self.assertEqual(parse("above:o2_fraction:0.3"), ("above", ["o2_fraction", 0.3])) def test_basic(self): e = lambda p: evaluate(p, self.w).tolist() self.assertEqual(e("land"), [1, 1, 1, 0, 0]) self.assertEqual(e("forest"), [1, 0, 0, 0, 0]) self.assertEqual(e("desert"), [0, 1, 0, 0, 0]) self.assertEqual(e("mountain"), [0, 0, 1, 0, 0]) self.assertEqual(e("coast"), [0, 0, 1, 0, 0]) self.assertEqual(e("shelf"), [0, 0, 0, 1, 0]) self.assertEqual(e("deep_sea"), [0, 0, 0, 0, 1]) self.assertAlmostEqual(e("water")[1], 1.0) # 0.4 + 0.15*4 = 1.0 self.assertAlmostEqual(e("vent")[4], 0.8) self.assertEqual(e("lithology:3,4"), [0, 1, 1, 0, 0]) def test_ranges_and_products(self): self.assertEqual(evaluate("warm:5:25", self.w).tolist(), [0.25, 1.0, 0.0, 0.35, 0.0]) self.assertEqual(evaluate(["land", "above:T_mean:20"], self.w).tolist(), [0, 1, 0, 0, 0]) np.testing.assert_array_equal(depth(self.w.fields), [0, 0, 0, 150, 3000]) def test_check(self): check(["land", "warm:1:2", "lithology:1"]) for bad in ("nosuch", "warm:1", "above:nofield:1"): with self.assertRaises(ValueError): check(bad, field_names=set(fields(1))) class RegionTest(unittest.TestCase): def test_kinds(self): w = line_world(4, ocean=[False, False, False, True], plate=[1, 1, 2, 2], gravity_g=1.0) w.eras["late"] = fields(4, ocean=[False, True, False, True], gravity_g=[1.0, 0.35, 0.35, 0.35]) self.assertEqual(region_mask(w, {"kind": "all"}).sum(), 4) self.assertEqual(region_mask(w, {"kind": "plate", "ids": [2]}).tolist(), [False, False, True, True]) self.assertEqual(region_mask(w, {"kind": "changed", "era": "late", "fields": ["gravity_g"]}).tolist(), [False, True, True, True]) self.assertEqual(region_mask(w, {"kind": "changed", "era": "late", "fields": ["gravity_g"], "land": "base"}) .tolist(), [False, True, True, False]) box = region_mask(w, {"kind": "box", "lat": [-1, 1], "lon": [0.5, 10]}) self.assertEqual(box.tolist(), [False, True, True, True]) self.assertEqual(region_mask(w, {"kind": "predicate", "p": "land"}).tolist(), [True, True, True, False]) def test_box_with_predicate_filter(self): w = line_world(4, ocean=[False, False, True, True]) m = region_mask(w, {"kind": "box", "lat": [-1, 1], "lon": [0.5, 10], "p": "land"}) self.assertEqual(m.tolist(), [False, True, False, False]) def test_exclude_other_region(self): w = line_world(4) r = Regions(w, {"east": {"kind": "box", "lat": [-1, 1], "lon": [0.5, 10]}, "land_not_east": {"kind": "predicate", "p": "land", "exclude": "east"}}) self.assertEqual(r("land_not_east").tolist(), [True, False, False, False]) def test_registry(self): w = line_world(3) r = Regions(w, {"west": {"kind": "box", "lat": [-1, 1], "lon": [-1, 0.5]}}) self.assertEqual(r("west").tolist(), [True, False, False]) self.assertTrue(r("all").all()) with self.assertRaises(KeyError): r("nowhere")