From 671e64ae8e2d99399bd4c2ccbcbed4fc10efa3c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20M=C3=BCller?= <mueller.seb@posteo.de> Date: Wed, 22 Jan 2025 14:12:04 +0100 Subject: [PATCH] tests: add tests for regridding masked data --- tests/adapters/square_5x4/cells.txt | 198 +++++++++++++++++++++++++++ tests/adapters/square_5x4/points.txt | 118 ++++++++++++++++ tests/adapters/square_5x4/types.txt | 198 +++++++++++++++++++++++++++ tests/adapters/test_regrid_mask.py | 160 ++++++++++++++++++++++ 4 files changed, 674 insertions(+) create mode 100644 tests/adapters/square_5x4/cells.txt create mode 100644 tests/adapters/square_5x4/points.txt create mode 100644 tests/adapters/square_5x4/types.txt create mode 100644 tests/adapters/test_regrid_mask.py diff --git a/tests/adapters/square_5x4/cells.txt b/tests/adapters/square_5x4/cells.txt new file mode 100644 index 00000000..68fac1a8 --- /dev/null +++ b/tests/adapters/square_5x4/cells.txt @@ -0,0 +1,198 @@ +90 85 66 +89 39 77 +106 39 89 +97 94 44 +108 44 94 +87 63 66 +103 62 72 +87 69 63 +102 66 85 +100 85 90 +76 14 13 +104 72 62 +103 72 71 +112 76 13 +102 87 66 +97 79 94 +96 93 46 +108 68 91 +117 93 96 +104 89 77 +101 98 84 +109 91 68 +108 91 44 +101 69 87 +116 73 88 +105 77 39 +116 88 58 +95 67 94 +48 42 33 +74 47 11 +75 47 74 +75 74 72 +73 71 70 +73 70 36 +78 43 17 +76 47 75 +36 8 7 +74 11 10 +70 8 36 +77 76 75 +70 40 9 +79 34 42 +71 40 70 +47 12 11 +40 10 9 +42 34 33 +70 9 8 +79 35 34 +91 7 6 +41 26 25 +80 24 37 +83 56 53 +74 10 40 +82 26 41 +84 18 43 +80 41 25 +43 18 17 +85 80 37 +72 40 71 +81 41 80 +95 94 42 +84 19 18 +48 33 32 +59 58 57 +85 81 80 +61 59 60 +78 17 16 +82 27 26 +57 55 56 +95 42 48 +80 25 24 +91 36 7 +60 59 57 +37 24 23 +62 59 61 +58 55 57 +67 52 54 +89 62 61 +88 54 55 +68 67 54 +88 68 54 +88 55 58 +86 37 23 +56 55 53 +63 61 60 +55 54 53 +86 23 22 +83 53 51 +90 60 57 +74 40 72 +39 16 15 +90 57 56 +89 61 65 +54 52 53 +87 86 45 +90 66 60 +45 22 21 +66 63 60 +65 61 63 +53 52 51 +86 22 45 +83 51 64 +38 32 31 +91 6 44 +64 51 50 +52 49 51 +69 65 63 +44 6 5 +92 31 30 +46 30 29 +50 49 38 +78 16 39 +92 38 31 +51 49 50 +95 52 67 +92 30 46 +93 92 46 +92 50 38 +48 32 38 +49 48 38 +93 50 92 +94 79 42 +95 49 52 +93 64 50 +95 48 49 +115 101 84 +100 81 85 +96 28 27 +97 5 4 +98 21 20 +99 41 81 +100 56 83 +101 87 45 +102 85 37 +102 86 87 +103 58 59 +96 27 82 +97 44 5 +98 45 21 +104 75 72 +105 39 15 +108 94 67 +109 36 91 +99 82 41 +104 62 89 +110 29 3 +111 4 0 +111 0 35 +112 13 1 +112 1 12 +112 47 76 +113 2 19 +113 20 2 +110 3 28 +100 90 56 +102 37 86 +103 59 62 +117 64 93 +114 100 83 +117 96 82 +105 14 76 +109 88 73 +101 45 98 +115 84 43 +104 77 75 +109 68 88 +106 89 65 +107 65 69 +107 106 65 +105 15 14 +107 43 78 +105 76 77 +106 78 39 +107 78 106 +117 99 64 +108 67 68 +114 83 64 +114 81 100 +109 73 36 +110 28 96 +113 98 20 +111 97 4 +111 35 79 +112 12 47 +113 19 84 +110 46 29 +116 71 73 +116 58 103 +114 99 81 +114 64 99 +110 96 46 +113 84 98 +111 79 97 +117 82 99 +116 103 71 +115 69 101 +115 107 69 +115 43 107 diff --git a/tests/adapters/square_5x4/points.txt b/tests/adapters/square_5x4/points.txt new file mode 100644 index 00000000..5d49f103 --- /dev/null +++ b/tests/adapters/square_5x4/points.txt @@ -0,0 +1,118 @@ +0.000000000000000000e+00 0.000000000000000000e+00 +5.000000000000000000e+00 0.000000000000000000e+00 +5.000000000000000000e+00 4.000000000000000000e+00 +0.000000000000000000e+00 4.000000000000000000e+00 +4.999999999995947131e-01 0.000000000000000000e+00 +9.999999999984133803e-01 0.000000000000000000e+00 +1.499999999996955102e+00 0.000000000000000000e+00 +1.999999999995512923e+00 0.000000000000000000e+00 +2.499999999996204814e+00 0.000000000000000000e+00 +2.999999999996965983e+00 0.000000000000000000e+00 +3.499999999997728040e+00 0.000000000000000000e+00 +3.999999999998489209e+00 0.000000000000000000e+00 +4.499999999999245048e+00 0.000000000000000000e+00 +5.000000000000000000e+00 4.999999999990952237e-01 +5.000000000000000000e+00 9.999999999976482146e-01 +5.000000000000000000e+00 1.499999999996189937e+00 +5.000000000000000000e+00 1.999999999994775957e+00 +5.000000000000000000e+00 2.499999999996049826e+00 +5.000000000000000000e+00 2.999999999997366995e+00 +5.000000000000000000e+00 3.499999999998682831e+00 +4.499999999999999112e+00 4.000000000000000000e+00 +3.999999999999997780e+00 4.000000000000000000e+00 +3.499999999999996891e+00 4.000000000000000000e+00 +2.999999999999996003e+00 4.000000000000000000e+00 +2.499999999999995115e+00 4.000000000000000000e+00 +1.999999999999994005e+00 4.000000000000000000e+00 +1.499999999999992006e+00 4.000000000000000000e+00 +9.999999999999911182e-01 4.000000000000000000e+00 +4.999999999999956146e-01 4.000000000000000000e+00 +0.000000000000000000e+00 3.499999999998003819e+00 +0.000000000000000000e+00 3.000000000001386002e+00 +0.000000000000000000e+00 2.500000000004854783e+00 +0.000000000000000000e+00 2.000000000008236967e+00 +0.000000000000000000e+00 1.500000000006241896e+00 +0.000000000000000000e+00 1.000000000004162004e+00 +0.000000000000000000e+00 5.000000000020810020e-01 +2.265798546853971196e+00 4.238914066109839007e-01 +2.749999999999935163e+00 3.577350269190534782e+00 +4.330127018896737789e-01 2.250000000006775913e+00 +4.515887990308685040e+00 1.721291157952514972e+00 +3.249999999997145839e+00 4.330127018927403815e-01 +1.749999999999994005e+00 3.573329484275529211e+00 +4.330127018913362269e-01 1.250000000006348033e+00 +4.599679368559095316e+00 2.734037287364882829e+00 +1.206637172643693967e+00 4.481480624790066258e-01 +3.745775399958263030e+00 3.578703610545325819e+00 +4.233860225254563736e-01 3.247881315359677057e+00 +4.230662432701146614e+00 4.218481522081570234e-01 +4.330127018898574098e-01 1.750000000008703038e+00 +8.660254037804282490e-01 2.000000000008117063e+00 +8.660254037794199444e-01 2.500000000006437961e+00 +1.299038105671252108e+00 2.250000000007863044e+00 +1.299038105671842080e+00 1.750000000008790080e+00 +1.732050807563251027e+00 2.000000000008578915e+00 +1.732050807563606964e+00 1.500000000008993917e+00 +2.165063509455331214e+00 1.750000000009032108e+00 +2.168763921158598951e+00 2.243590698928989102e+00 +2.598692946631000034e+00 1.998931783162479991e+00 +2.625210852851048937e+00 1.535103350557095903e+00 +3.033703670897030857e+00 1.753920133713432028e+00 +3.031627495395729177e+00 2.250475319485361059e+00 +3.464627171766605951e+00 2.000732575539676095e+00 +3.464101615131112144e+00 1.500000000010194068e+00 +3.470262035740892870e+00 2.522530415211392985e+00 +1.305354910972956084e+00 2.788748402221191025e+00 +3.897114317022456031e+00 2.250000000009737100e+00 +3.031088913238387139e+00 2.750000000008742784e+00 +1.307411517935652912e+00 1.264503175480730990e+00 +1.733099282557412968e+00 1.015972093721750902e+00 +3.897114317022187802e+00 2.750000000009475087e+00 +2.752633091139478960e+00 4.314924860121975847e-01 +2.965664888242407038e+00 8.430407192711438791e-01 +3.473466298134646912e+00 9.485033022443511985e-01 +2.495283483432777949e+00 8.191813640038545508e-01 +3.749999999997362998e+00 4.330127018933099259e-01 +3.999999999998494982e+00 8.660254037854584475e-01 +4.539957219767416952e+00 8.147052950646799241e-01 +4.249999999998625100e+00 1.299038105677188915e+00 +4.566987298108965199e+00 2.249999999994134026e+00 +4.233860225288407220e-01 7.521186846436920259e-01 +2.249999999999953815e+00 3.569771490982977191e+00 +1.986017662442111087e+00 3.172602692073807962e+00 +1.278337285646486077e+00 3.591790500907492856e+00 +1.736885620003159048e+00 2.478141994818935157e+00 +4.527193881727244573e+00 3.220499339533433147e+00 +2.543206966671962999e+00 3.068203009786670155e+00 +3.249295899993029924e+00 3.581030149777149951e+00 +3.484672574077193108e+00 3.081218998192642999e+00 +2.224749828680767205e+00 1.226702911488599002e+00 +3.949238975830291043e+00 1.718453006844590014e+00 +2.598076211346683095e+00 2.500000000008701928e+00 +1.735657837491481947e+00 5.051897496787564057e-01 +4.314082553290368161e-01 2.749646885897047088e+00 +8.243663844143013231e-01 3.015277068572050023e+00 +9.086100644094758927e-01 9.243779422283027181e-01 +8.745184159297654247e-01 1.489813519623498062e+00 +7.910885367730781104e-01 3.530452272734196928e+00 +7.456552845443471522e-01 4.161816644597777226e-01 +4.234352555081294156e+00 3.603882322562967921e+00 +1.532342419179892001e+00 3.204280363629865125e+00 +2.126965062766455805e+00 2.722917844972307044e+00 +3.999171452587594988e+00 3.190116389084741044e+00 +3.008323479140071033e+00 3.207158181768441807e+00 +3.063606654562874176e+00 1.306322380129556038e+00 +3.820890929013136983e+00 1.258109208728056982e+00 +4.665063509458925672e+00 1.250000000000385914e+00 +4.232125541608215968e+00 2.032051323961315159e+00 +4.232050807571533291e+00 2.499999999993876898e+00 +1.378283175007543049e+00 8.316382047177097725e-01 +2.094791281142887041e+00 8.112976320968601218e-01 +3.660254037837317176e-01 3.633974596215732156e+00 +3.660254037858404197e-01 3.660254037865067200e-01 +4.633974596214726738e+00 3.660254037848266750e-01 +4.633974596214662789e+00 3.633974596214311958e+00 +1.728839994976222982e+00 2.874968674216736186e+00 +4.251041965493531194e+00 2.878930603197281890e+00 +2.690002125042068037e+00 1.148726086499350929e+00 +1.146297907397342941e+00 3.226109721612958836e+00 diff --git a/tests/adapters/square_5x4/types.txt b/tests/adapters/square_5x4/types.txt new file mode 100644 index 00000000..553cd6b0 --- /dev/null +++ b/tests/adapters/square_5x4/types.txt @@ -0,0 +1,198 @@ +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 +2 diff --git a/tests/adapters/test_regrid_mask.py b/tests/adapters/test_regrid_mask.py new file mode 100644 index 00000000..2beb72d8 --- /dev/null +++ b/tests/adapters/test_regrid_mask.py @@ -0,0 +1,160 @@ +""" +Unit tests for regridding with masked data. +""" + +import unittest +from pathlib import Path + +import numpy as np +from numpy.testing import assert_array_equal + +from finam import Composition, FinamDataError, Info, Mask, UniformGrid, UnstructuredGrid +from finam import data as fdata +from finam.adapters.regrid import RegridLinear, RegridNearest +from finam.modules import StaticSimplexNoise, debug + + +def get_mask(points, rad=1.5): + return (points[:, 0] - 2.5) ** 2 + (points[:, 1] - 2) ** 2 > rad**2 + + +class TestRegridMask(unittest.TestCase): + @classmethod + def setUpClass(self): + here = Path(__file__).parent + points = np.loadtxt(here / "square_5x4" / "points.txt", dtype=float) + cells = np.loadtxt(here / "square_5x4" / "cells.txt", dtype=int) + types = np.loadtxt(here / "square_5x4" / "types.txt", dtype=int) + + self.in_grid = UnstructuredGrid(points, cells, types) + self.out_grid = UniformGrid((25, 20), spacing=(0.2, 0.2)) + + self.in_mask = get_mask(self.in_grid.cell_centers, rad=1.5) + omask = get_mask(self.out_grid.cell_centers, rad=2.5) + self.out_mask = fdata.from_compressed( + omask, self.out_grid.data_shape, self.out_grid.order + ) + + def test_regrid_nearest_out_mask(self): + + in_info = Info(grid=self.in_grid, units="", mask=self.in_mask) + source = StaticSimplexNoise(in_info, 0.15, 3, 0.5) + sink = debug.DebugPushConsumer({"Input": Info()}) + regrid = RegridNearest(out_grid=self.out_grid, out_mask=self.out_mask) + composition = Composition([source, sink]) + + (source.outputs["Noise"] >> regrid >> sink.inputs["Input"]) + composition.connect() + + info = sink.inputs["Input"].info + data = sink.data["Input"][0, ...] + assert_array_equal(info.mask, data.mask) + assert_array_equal(info.mask, self.out_mask) + + i_data = source.outputs["Noise"].data[0][1].magnitude.compressed() + o_data = data.magnitude.compressed() + self.assertAlmostEqual(i_data.mean(), o_data.mean(), 2) + + def test_regrid_nearest_filled(self): + + in_info = Info(grid=self.in_grid, units="", mask=self.in_mask) + source = StaticSimplexNoise(in_info, 0.15, 3, 0.5) + sink = debug.DebugPushConsumer({"Input": Info()}) + regrid = RegridNearest(out_grid=self.out_grid, out_mask=Mask.NONE) + composition = Composition([source, sink]) + + (source.outputs["Noise"] >> regrid >> sink.inputs["Input"]) + composition.connect() + + info = sink.inputs["Input"].info + data = sink.data["Input"][0, ...].magnitude + self.assertEqual(info.mask, Mask.NONE) + self.assertFalse(fdata.is_masked_array(data)) + + i_data = source.outputs["Noise"].data[0][1].magnitude.compressed() + self.assertAlmostEqual(i_data.mean(), data.mean(), 1) + + def test_regrid_linear_determine_mask(self): + + in_info = Info(grid=self.in_grid, units="", mask=self.in_mask) + source = StaticSimplexNoise(in_info, 0.15, 3, 0.5) + sink = debug.DebugPushConsumer({"Input": Info()}) + regrid = RegridLinear( + out_grid=self.out_grid, fill_with_nearest=False, out_mask=None + ) + composition = Composition([source, sink]) + + (source.outputs["Noise"] >> regrid >> sink.inputs["Input"]) + composition.connect() + + info = sink.inputs["Input"].info + data = sink.data["Input"][0, ...] + assert_array_equal(info.mask, data.mask) + self.assertEqual(np.sum(data.mask), 306) + + i_data = source.outputs["Noise"].data[0][1].magnitude.compressed() + o_data = data.magnitude.compressed() + self.assertAlmostEqual(i_data.mean(), o_data.mean(), 2) + + def test_regrid_linear_error_domain(self): + + in_info = Info(grid=self.in_grid, units="", mask=self.in_mask) + source = StaticSimplexNoise(in_info, 0.15, 3, 0.5) + sink = debug.DebugPushConsumer({"Input": Info()}) + regrid = RegridLinear( + out_grid=self.out_grid, fill_with_nearest=False, out_mask=Mask.NONE + ) + composition = Composition([source, sink]) + + (source.outputs["Noise"] >> regrid >> sink.inputs["Input"]) + + # not covering domain without fill + with self.assertRaises(FinamDataError): + composition.connect() + + def test_regrid_linear_filled(self): + + in_info = Info(grid=self.in_grid, units="", mask=self.in_mask) + source = StaticSimplexNoise(in_info, 0.15, 3, 0.5) + sink = debug.DebugPushConsumer({"Input": Info()}) + regrid = RegridLinear( + out_grid=self.out_grid, fill_with_nearest=True, out_mask=Mask.NONE + ) + composition = Composition([source, sink]) + + (source.outputs["Noise"] >> regrid >> sink.inputs["Input"]) + composition.connect() + + info = sink.inputs["Input"].info + data = sink.data["Input"][0, ...].magnitude + self.assertEqual(info.mask, Mask.NONE) + self.assertFalse(fdata.is_masked_array(data)) + + i_data = source.outputs["Noise"].data[0][1].magnitude.compressed() + self.assertAlmostEqual(i_data.mean(), data.mean(), 1) + + def test_regrid_linear_filled_mask(self): + + in_info = Info(grid=self.in_grid, units="", mask=self.in_mask) + source = StaticSimplexNoise(in_info, 0.15, 3, 0.5) + sink = debug.DebugPushConsumer({"Input": Info()}) + regrid = RegridLinear( + out_grid=self.out_grid, fill_with_nearest=True, out_mask=self.out_mask + ) + composition = Composition([source, sink]) + + (source.outputs["Noise"] >> regrid >> sink.inputs["Input"]) + composition.connect() + + info = sink.inputs["Input"].info + data = sink.data["Input"][0, ...] + assert_array_equal(info.mask, data.mask) + assert_array_equal(info.mask, self.out_mask) + + i_data = source.outputs["Noise"].data[0][1].magnitude.compressed() + o_data = data.magnitude.compressed() + self.assertAlmostEqual(i_data.mean(), o_data.mean(), 2) + + +if __name__ == "__main__": + unittest.main() -- GitLab