Repository: SCECcode/pycsep (language: python)

Issue:
in_place option of the filter_spatial function does not properly bind region information
when in_place=False, the region information is not properly passed to the newly created class.


Discussion / hints:

Fix patch:
diff --git a/csep/core/catalogs.py b/csep/core/catalogs.py
index 5f3ad0af..2d8f6b3e 100644
--- a/csep/core/catalogs.py
+++ b/csep/core/catalogs.py
@@ -574,7 +574,7 @@ def filter_spatial(self, region=None, update_stats=False, in_place=True):
         else:
             cls = self.__class__
             inst = cls(data=filtered, catalog_id=self.catalog_id, format=self.format, name=self.name,
-                       region=region, compute_stats=update_stats)
+                       region=self.region, compute_stats=update_stats)
             return inst
 
     def apply_mct(self, m_main, event_epoch, mc=2.5):
@@ -855,6 +855,7 @@ def plot(self, ax=None, show=False, extent=None, set_global=False, plot_args=Non
                           set_global=set_global, plot_args=plot_args)
         return ax
 
+
 class CSEPCatalog(AbstractBaseCatalog):
     """
     Standard catalog class for PyCSEP catalog operations.


Test patch:
diff --git a/tests/test_catalog.py b/tests/test_catalog.py
index edb37563..150f7c7a 100644
--- a/tests/test_catalog.py
+++ b/tests/test_catalog.py
@@ -1,6 +1,7 @@
 import copy
 import unittest
 import os
+import itertools
 
 import numpy
 
@@ -8,6 +9,7 @@
 from csep.core import regions, forecasts
 from csep.utils.time_utils import strptime_to_utc_epoch, strptime_to_utc_datetime
 from csep.core.catalogs import CSEPCatalog
+from csep.core.regions import CartesianGrid2D, Polygon, compute_vertices
 
 def comcat_path():
     root_dir = os.path.dirname(os.path.abspath(__file__))
@@ -18,6 +20,18 @@ def comcat_path():
 class CatalogFiltering(unittest.TestCase):
     def setUp(self):
 
+        # create some arbitrary grid
+        self.nx = 8
+        self.ny = 10
+        self.dh = 1
+        x_points = numpy.arange(1.5, self.nx) * self.dh
+        y_points = numpy.arange(1.5, self.ny) * self.dh
+
+        # spatial grid starts at (1.5, 1.5); so the event at (1, 1) should be removed.
+        self.origins = list(itertools.product(x_points, y_points))
+        self.num_nodes = len(self.origins)
+        self.cart_grid = CartesianGrid2D([Polygon(bbox) for bbox in compute_vertices(self.origins, self.dh)], self.dh)
+
         # define dummy cat
         date1 = strptime_to_utc_epoch('2009-01-01 00:00:00.0000')
         date2 = strptime_to_utc_epoch('2010-01-01 00:00:00.0000')
@@ -72,6 +86,21 @@ def test_filter_with_datetime(self):
         filtered_test_cat = test_cat.filter(filters, in_place=False)
         numpy.testing.assert_equal(numpy.array([b'1', b'2'], dtype='S256').T, filtered_test_cat.get_event_ids())
 
+    def test_filter_spatial(self):
+
+        test_cat = copy.deepcopy(self.test_cat1)
+        filtered_test_cat = test_cat.filter_spatial(region=self.cart_grid)
+        numpy.testing.assert_equal(numpy.array([b'2', b'3'], dtype='S256').T, filtered_test_cat.get_event_ids())
+
+
+    def test_filter_spatial_in_place_return(self):
+        test_cat = copy.deepcopy(self.test_cat1)
+        filtered_test_cat = test_cat.filter_spatial(region=self.cart_grid, in_place=False)
+        numpy.testing.assert_array_equal(filtered_test_cat.region.midpoints(), test_cat.region.midpoints())
+        numpy.testing.assert_array_equal(filtered_test_cat.region.origins(), test_cat.region.origins())
+        numpy.testing.assert_array_equal(filtered_test_cat.region.bbox_mask, test_cat.region.bbox_mask)
+        numpy.testing.assert_array_equal(filtered_test_cat.region.idx_map, test_cat.region.idx_map)
+
     def test_catalog_binning_and_filtering_acceptance(self):
         # create space-magnitude region
         region = regions.create_space_magnitude_region(
@@ -93,7 +122,7 @@ def test_catalog_binning_and_filtering_acceptance(self):
             # catalog filtered cumulative
             c = comcat.filter([f'magnitude >= {m_min}'], in_place=False)
             # catalog filtered incrementally
-            c_int = comcat.filter([f'magnitude >= {m_min}', f'magnitude < {m_min + 0.09999999}'], in_place=False)
+            c_int = comcat.filter([f'magnitude >= {m_min}', f'magnitude < {m_min + 0.1}'], in_place=False)
             # sum from overall data set
             gs = d.data[:, idm:].sum()
             # incremental counts