aboutsummaryrefslogtreecommitdiffziptar.gz
path: root/tests/helpers.py
diff options
context:
space:
mode:
Diffstat (limited to 'tests/helpers.py')
-rw-r--r--tests/helpers.py68
1 files changed, 68 insertions, 0 deletions
diff --git a/tests/helpers.py b/tests/helpers.py
new file mode 100644
index 0000000..28b6266
--- /dev/null
+++ b/tests/helpers.py
@@ -0,0 +1,68 @@
+import functools
+
+import numpy as np
+
+from worldhistory.world import World, neighbours_from_ids
+
+DEFAULTS = dict(ocean=False, elevation_m=100.0, T_mean=15.0, P_ann=1000.0, holdridge=20, landform=1, river=False,
+ strahler=0, lake=False, ice=0, coal_potential=False, iron_potential=False, vent_potential=0.0,
+ seabed_type=0, lithology=1, ground=0, gravity_g=1.0, o2_fraction=0.21, pressure_bar=1.0,
+ bottom_temp_c=2.0, plate=0)
+
+
+def fields(n, **over):
+ out = {}
+ for k, v in {**DEFAULTS, **over}.items():
+ a = np.asarray(v)
+ out[k] = np.broadcast_to(a, (n,)).copy() if a.ndim == 0 else a.copy()
+ return out
+
+
+def line_world(n, spacing_km=100.0, radius_km=6371.0, **over):
+ """Cells on the equator in a row, each linked to the next: 1-D worlds with hand-checkable answers."""
+ lon = np.arange(n) * np.degrees(spacing_km / radius_km)
+ lat = np.zeros(n)
+ xyz = np.stack([np.cos(np.radians(lon)), np.sin(np.radians(lon)), np.zeros(n)], 1)
+ nb = np.full((n, 6), -1, np.int64)
+ nb[1:, 0] = np.arange(n - 1)
+ nb[:-1, 1] = np.arange(1, n)
+ return World(nb=nb, lat=lat, lon=lon, xyz=xyz, area=np.full(n, spacing_km ** 2), radius_km=radius_km,
+ base=fields(n, **over))
+
+
+@functools.lru_cache(maxsize=4)
+def _h3_grid(res):
+ import h3.api.basic_int as h3
+ ids = sorted(c for r0 in h3.get_res0_cells() for c in h3.cell_to_children(r0, res))
+ ll = np.array([h3.cell_to_latlng(c) for c in ids])
+ area = np.array([h3.cell_area(c, unit="rads^2") for c in ids])
+ return np.array(ids, np.uint64), ll, area
+
+
+def globe_world(res=1, radius_km=6371.0):
+ """A whole H3 globe (res 1 = 842 cells) with default fields; tests edit world.base afterwards."""
+ ids, ll, area = _h3_grid(res)
+ lat, lon = ll[:, 0].copy(), ll[:, 1].copy()
+ la, lo = np.radians(lat), np.radians(lon)
+ xyz = np.stack([np.cos(la) * np.cos(lo), np.cos(la) * np.sin(lo), np.sin(la)], 1)
+ return World(nb=neighbours_from_ids(ids), lat=lat, lon=lon, xyz=xyz, area=area * radius_km ** 2,
+ radius_km=radius_km, base=fields(len(ids)))
+
+
+from worldhistory.config import parse_history, parse_race
+
+
+def make_race(id="a", **over):
+ """A land race with density 1/km² at q=1, growth 0.1/step, no Allee, founder 1, no mobility; sections override."""
+ d = {"id": id,
+ "demography": {"density": 1.0, "growth": 0.1, "allee": 0.0, "founder": 1.0, "mobility": 0.0},
+ "habitat": {"realm": "land", "terms": [{"p": "land", "w": 1.0}]}}
+ for k, v in over.items():
+ d[k] = {**d.get(k, {}), **v} if isinstance(v, dict) and isinstance(d.get(k), dict) else v
+ return parse_race(d, f"test:{id}")
+
+
+def make_history(**over):
+ d = {"run": {"years": 100, "step": 10, "snapshot_every": 50, "seed": 1}}
+ d.update(over)
+ return parse_history(d, "test:history")