Beispiel #1
0
 def test_hypocentres_as_mesh(self):
     # Tests the function to render the hypocentres to a
     # hazardlib.geo.mesh.Mesh object.
     cat = Catalogue()
     cat.data['longitude'] = np.array([2., 3.])
     cat.data['latitude'] = np.array([2., 3.])
     cat.data['depth'] = np.array([2., 3.])
     self.assertTrue(isinstance(cat.hypocentres_as_mesh(), Mesh))
Beispiel #2
0
 def test_hypocentres_as_mesh(self):
     # Tests the function to render the hypocentres to a
     # hazardlib.geo.mesh.Mesh object.
     cat = Catalogue()
     cat.data['longitude'] = np.array([2., 3.])
     cat.data['latitude'] = np.array([2., 3.])
     cat.data['depth'] = np.array([2., 3.])
     self.assertTrue(isinstance(cat.hypocentres_as_mesh(), Mesh))
Beispiel #3
0
class TestSelector(unittest.TestCase):
    '''
    Tests the hmtk.seismicity.selector.Selector class
    '''
    def setUp(self):
        '''
        '''

        self.catalogue = Catalogue()
        self.polygon = None


    def test_check_on_depth_limits(self):
        '''
        Tests the checks on depth limits
        '''
        test_dict = {'upper_depth': None, 'lower_depth': None}
        self.assertTupleEqual((0.0, np.inf), _check_depth_limits(test_dict))
        
        test_dict = {'upper_depth': 2.0, 'lower_depth': None}
        self.assertTupleEqual((2.0, np.inf), _check_depth_limits(test_dict))
        
        test_dict = {'upper_depth': None, 'lower_depth': 10.0}
        self.assertTupleEqual((0.0, 10.0), _check_depth_limits(test_dict))

        test_dict = {'upper_depth': -4.2, 'lower_depth': None}
        self.assertRaises(ValueError, _check_depth_limits, test_dict)

        test_dict = {'upper_depth': 5.0, 'lower_depth': 1.0}
        self.assertRaises(ValueError, _check_depth_limits, test_dict)


    def test_convert_datetime_to_decimal(self):
        '''
        Tests the function to convert a time from a datetime object to a 
        decimal - simple test to check conversion 
        NB Still will not work for BCE dates
        '''
        simple_time = datetime.datetime(1900, 6, 6, 1, 1, 1, 0)
        self.assertAlmostEqual(_get_decimal_from_datetime(simple_time), 
                               1900.42751335)


    def test_catalogue_selection(self):
        '''
        Tests the tools for selecting events within the catalogue
        '''
        self.catalogue.data['longitude'] =  np.arange(1.,6., 1.)
        self.catalogue.data['latitude'] = np.arange(6., 11., 1.)
        self.catalogue.data['depth'] = np.ones(5, dtype=bool)

        # No events selected
        flag_none = np.zeros(5, dtype=bool)
        selector0 = CatalogueSelector(self.catalogue)
        test_cat1 = selector0.select_catalogue(flag_none)
        self.assertEqual(len(test_cat1.data['longitude']), 0)
        self.assertEqual(len(test_cat1.data['latitude']), 0)
        self.assertEqual(len(test_cat1.data['depth']), 0)

        # All events selected
        flag_all = np.ones(5, dtype=bool)
        test_cat1 = selector0.select_catalogue(flag_all)
        self.assertTrue(np.allclose(test_cat1.data['longitude'], 
                                    self.catalogue.data['longitude']))
        self.assertTrue(np.allclose(test_cat1.data['latitude'], 
                                    self.catalogue.data['latitude']))
        self.assertTrue(np.allclose(test_cat1.data['depth'], 
                                    self.catalogue.data['depth']))

        
        # Some events selected    
        flag_1 = np.array([True, False, True, False, True])
        test_cat1 = selector0.select_catalogue(flag_1)
        self.assertTrue(np.allclose(test_cat1.data['longitude'], 
                                    np.array([1., 3., 5.])))
        self.assertTrue(np.allclose(test_cat1.data['latitude'], 
                                    np.array([6., 8., 10])))
        self.assertTrue(np.allclose(test_cat1.data['depth'], 
                                    np.array([1., 1., 1.])))


    def test_select_within_polygon(self):
        '''
        Tests the selection of points within polygon
        '''
        # Setup polygon
        nodes = np.array([[5.0, 6.0], [6.0, 6.0], [6.0, 5.0], [5.0, 5.0]])
        polygon0 = Polygon([Point(nodes[iloc, 0], nodes[iloc, 1])
                            for iloc in range(0, 4)])
        self.catalogue.data['longitude'] = np.arange(4.0, 7.5, 0.5)
        self.catalogue.data['latitude'] = np.arange(4.0, 7.5, 0.5)
        self.catalogue.data['depth'] = np.ones(7, dtype=float)
        # Simple case with nodes inside, outside and on the border of polygon
        selector0 = CatalogueSelector(self.catalogue)
        test_cat1 = selector0.within_polygon(polygon0)
        self.assertTrue(np.allclose(test_cat1.data['longitude'], 
                                    np.array([5.0, 5.5, 6.0])))
        self.assertTrue(np.allclose(test_cat1.data['latitude'], 
                                    np.array([5.0, 5.5, 6.0])))
        self.assertTrue(np.allclose(test_cat1.data['depth'], 
                                    np.array([1.0, 1.0, 1.0])))
        # CASE 2: As case 1 with one of the inside nodes outside of the depths 
        self.catalogue.data['depth'] = \
            np.array([1.0, 1.0, 1.0, 50.0, 1.0, 1.0, 1.0], dtype=float)
        selector0 = CatalogueSelector(self.catalogue)
        test_cat1 = selector0.within_polygon(polygon0, upper_depth=0.0,
                                             lower_depth=10.0)
        self.assertTrue(np.allclose(test_cat1.data['longitude'], 
                                    np.array([5.0, 6.0])))
        self.assertTrue(np.allclose(test_cat1.data['latitude'], 
                                    np.array([5.0, 6.0])))
        self.assertTrue(np.allclose(test_cat1.data['depth'], 
                                    np.array([1.0])))

    def test_point_in_circular_distance(self):
        '''
        Tests point in circular distance
        '''
        self.catalogue.data['longitude'] = np.arange(4.0, 7.5, 0.5)
        self.catalogue.data['latitude'] = np.arange(4.0, 7.5, 0.5)
        self.catalogue.data['depth'] = np.ones(7, dtype=float)
        test_point = Point(5.5, 5.5)
        test_mesh = self.catalogue.hypocentres_as_mesh()
        selector0 = CatalogueSelector(self.catalogue)
        # Within 10 km
        test_cat_10 = selector0.circular_distance_from_point(
            test_point, 10., distance_type='epicentral')
        np.testing.assert_array_equal(test_cat_10.data['longitude'],
                                      np.array([5.5]))
        np.testing.assert_array_equal(test_cat_10.data['latitude'],
                                      np.array([5.5]))
        np.testing.assert_array_equal(test_cat_10.data['depth'],
                                      np.array([1.0]))

        # Within 100 km
        test_cat_100 = selector0.circular_distance_from_point(
            test_point, 100., distance_type='epicentral')
        np.testing.assert_array_equal(test_cat_100.data['longitude'],
                                      np.array([5.0, 5.5, 6.0]))
        np.testing.assert_array_equal(test_cat_100.data['latitude'],
                                      np.array([5.0, 5.5, 6.0]))
        np.testing.assert_array_equal(test_cat_100.data['depth'],
                                      np.array([1.0, 1.0, 1.0]))

        # Within 1000 km
        test_cat_1000 = selector0.circular_distance_from_point(
            test_point, 1000., distance_type='epicentral')
        np.testing.assert_array_equal(test_cat_1000.data['longitude'],
                                      self.catalogue.data['longitude'])
        np.testing.assert_array_equal(test_cat_1000.data['latitude'],
                                      self.catalogue.data['latitude'])
        np.testing.assert_array_equal(test_cat_1000.data['depth'],
                                      self.catalogue.data['depth'])

    def test_cartesian_square_on_point(self):
        '''
        Tests the cartesian square centres on point
        '''
        self.catalogue.data['longitude'] = np.arange(4.0, 7.5, 0.5)
        self.catalogue.data['latitude'] = np.arange(4.0, 7.5, 0.5)
        self.catalogue.data['depth'] = np.ones(7, dtype=float)
        test_point = Point(5.5, 5.5)
        test_mesh = self.catalogue.hypocentres_as_mesh()
        selector0 = CatalogueSelector(self.catalogue)
        # Within 10 km
        test_cat_10 = selector0.cartesian_square_centred_on_point(
            test_point, 10., distance_type='epicentral')
        np.testing.assert_array_equal(test_cat_10.data['longitude'],
                                      np.array([5.5]))
        np.testing.assert_array_equal(test_cat_10.data['latitude'],
                                      np.array([5.5]))
        np.testing.assert_array_equal(test_cat_10.data['depth'],
                                      np.array([1.0]))

        # Within 100 km
        test_cat_100 = selector0.cartesian_square_centred_on_point(
            test_point, 100., distance_type='epicentral')
        np.testing.assert_array_almost_equal(test_cat_100.data['longitude'],
                                      np.array([5.0, 5.5, 6.0]))
        np.testing.assert_array_almost_equal(test_cat_100.data['latitude'],
                                      np.array([5.0, 5.5, 6.0]))
        np.testing.assert_array_almost_equal(test_cat_100.data['depth'],
                                      np.array([1.0, 1.0, 1.0]))

        # Within 1000 km
        test_cat_1000 = selector0.cartesian_square_centred_on_point(
            test_point, 1000., distance_type='epicentral')
        np.testing.assert_array_almost_equal(test_cat_1000.data['longitude'],
                                      self.catalogue.data['longitude'])
        np.testing.assert_array_almost_equal(test_cat_1000.data['latitude'],
                                      self.catalogue.data['latitude'])
        np.testing.assert_array_almost_equal(test_cat_1000.data['depth'],
                                      self.catalogue.data['depth'])

    def test_within_joyner_boore_distance(self):
        '''
        Tests the function to select within Joyner-Boore distance
        '''
        self.catalogue.data['longitude'] = np.arange(4.0, 7.5, 0.5)
        self.catalogue.data['latitude'] = np.arange(4.0, 7.5, 0.5)
        self.catalogue.data['depth'] = np.ones(7, dtype=float)
        selector0 = CatalogueSelector(self.catalogue)
        # Construct Fault
        trace0 = np.array([[5.5, 6.0], [5.5, 5.0]])
        fault_trace = Line([Point(trace0[i, 0], trace0[i, 1]) 
                           for i in range(0, 2)])
        
        # Simple fault with vertical dip
        fault0 = SimpleFaultSurface.from_fault_data(fault_trace, 0., 20., 90., 
                                                   1.)
        
        # Within 100 km
        test_cat_100 = selector0.within_joyner_boore_distance(fault0, 100.)
        np.testing.assert_array_almost_equal(test_cat_100.data['longitude'],
                                      np.array([5.0, 5.5, 6.0]))
        np.testing.assert_array_almost_equal(test_cat_100.data['latitude'],
                                      np.array([5.0, 5.5, 6.0]))
        np.testing.assert_array_almost_equal(test_cat_100.data['depth'],
                                      np.array([1.0, 1.0, 1.0]))

        # Simple fault with 30 degree dip
        fault0 = SimpleFaultSurface.from_fault_data(fault_trace, 0., 20., 30., 
                                                   1.)
        
        # Within 100 km
        test_cat_100 = selector0.within_joyner_boore_distance(fault0, 100.)
        np.testing.assert_array_almost_equal(test_cat_100.data['longitude'],
                                      np.array([4.5, 5.0, 5.5, 6.0]))
        np.testing.assert_array_almost_equal(test_cat_100.data['latitude'],
                                      np.array([4.5, 5.0, 5.5, 6.0]))
        np.testing.assert_array_almost_equal(test_cat_100.data['depth'],
                                      np.array([1.0, 1.0, 1.0, 1.0]))
    
    
    def test_within_rupture_distance(self):
        '''
        Tests the function to select within Joyner-Boore distance
        '''
        self.catalogue.data['longitude'] = np.arange(4.0, 7.5, 0.5)
        self.catalogue.data['latitude'] = np.arange(4.0, 7.5, 0.5)
        self.catalogue.data['depth'] = np.ones(7, dtype=float)
        selector0 = CatalogueSelector(self.catalogue)
        # Construct Fault
        trace0 = np.array([[5.5, 6.0], [5.5, 5.0]])
        fault_trace = Line([Point(trace0[i, 0], trace0[i, 1]) 
                           for i in range(0, 2)])
        
        # Simple fault with vertical dip
        fault0 = SimpleFaultSurface.from_fault_data(fault_trace, 0., 20., 90., 
                                                   1.)
        
        # Within 100 km
        test_cat_100 = selector0.within_rupture_distance(fault0, 100.)
        np.testing.assert_array_almost_equal(test_cat_100.data['longitude'],
                                      np.array([5.0, 5.5, 6.0]))
        np.testing.assert_array_almost_equal(test_cat_100.data['latitude'],
                                      np.array([5.0, 5.5, 6.0]))
        np.testing.assert_array_almost_equal(test_cat_100.data['depth'],
                                      np.array([1.0, 1.0, 1.0]))

        # Simple fault with 30 degree dip
        fault0 = SimpleFaultSurface.from_fault_data(fault_trace, 0., 20., 30., 
                                                   1.)
        
        # Within 100 km
        test_cat_100 = selector0.within_rupture_distance(fault0, 100.)
        np.testing.assert_array_almost_equal(test_cat_100.data['longitude'],
                                      np.array([4.5, 5.0, 5.5, 6.0]))
        np.testing.assert_array_almost_equal(test_cat_100.data['latitude'],
                                      np.array([4.5, 5.0, 5.5, 6.0]))
        np.testing.assert_array_almost_equal(test_cat_100.data['depth'],
                                      np.array([1.0, 1.0, 1.0, 1.0]))

    def test_select_within_time(self):
        '''
        Tests the function to select within a time period
        '''
        self.catalogue.data['year'] = np.arange(1900, 2010, 20)
        self.catalogue.data['month'] = np.arange(1, 12, 2)
        self.catalogue.data['day'] = np.ones(6, dtype=int)
        self.catalogue.data['hour'] = np.ones(6, dtype=int) 
        self.catalogue.data['minute'] = np.zeros(6, dtype=int)
        self.catalogue.data['second'] = np.ones(6, dtype=float)

        selector0 = CatalogueSelector(self.catalogue)

        # Start time and End time not defined
        test_cat_1 = selector0.within_time_period()
        self._compare_time_data_dictionaries(test_cat_1.data,
                                             self.catalogue.data)

        # Start time defined - end time not defined
        begin_time = datetime.datetime(1975, 1, 1, 0, 0, 0, 0)
        expected_data = {'year': np.array([1980, 2000]),
                         'month': np.array([9, 11]),
                         'day': np.array([1, 1]),
                         'hour': np.array([1, 1]),
                         'minute': np.array([0, 0]),
                         'second': np.array([1., 1.])}
        
        test_cat_1 = selector0.within_time_period(start_time=begin_time)
        self._compare_time_data_dictionaries(expected_data, test_cat_1.data)


        # Test 3 - Start time not defined, end-time defined
        finish_time = datetime.datetime(1965, 1, 1, 0, 0, 0, 0)
        expected_data = {'year': np.array([1900, 1920, 1940, 1960]),
                         'month': np.array([1, 3, 5, 7]),
                         'day': np.array([1, 1, 1, 1]),
                         'hour': np.array([1, 1, 1, 1]),
                         'minute': np.array([0, 0, 0, 0]),
                         'second': np.array([1., 1., 1., 1.])}
        
        test_cat_1 = selector0.within_time_period(end_time=finish_time)
        self._compare_time_data_dictionaries(expected_data, test_cat_1.data)

        # Test 4 - both start time and end-time defined
        begin_time = datetime.datetime(1935, 1, 1, 0, 0, 0, 0)
        finish_time = datetime.datetime(1995, 1, 1, 0, 0, 0, 0)
        expected_data = {'year': np.array([1940, 1960, 1980]),
                         'month': np.array([5, 7, 9]),
                         'day': np.array([1, 1, 1]),
                         'hour': np.array([1, 1, 1]),
                         'minute': np.array([0, 0, 0]),
                         'second': np.array([1., 1., 1.])}

        test_cat_1 = selector0.within_time_period(begin_time, finish_time)
        self._compare_time_data_dictionaries(expected_data, test_cat_1.data)

    def _compare_time_data_dictionaries(self, expected, modelled):
        '''
        Compares the relevent time and date information in the catalogue 
        data dictionaries
        '''
        time_keys = ['year', 'month', 'day', 'hour', 'minute', 'second']
        
        for key in time_keys:
            # The second value is a float - all others are integers
            if 'second' in key:
                np.testing.assert_array_almost_equal(expected[key],
                                                     modelled[key])
            else:
                np.testing.assert_array_equal(expected[key], modelled[key])
        

    def test_select_within_depth_range(self):
        '''
        Tests the function to select within the depth range
        '''
        # Setup function
        self.catalogue = Catalogue()
        self.catalogue.data['depth'] = np.array([5., 15., 25., 35., 45.])

        selector0 = CatalogueSelector(self.catalogue)
        # Test case 1: No limits specified - all catalogue valid
        test_cat_1 = selector0.within_depth_range()
        np.testing.assert_array_almost_equal(test_cat_1.data['depth'],
                                             self.catalogue.data['depth'])

        # Test case 2: Lower depth limit specfied only
        test_cat_1 = selector0.within_depth_range(lower_depth=30.)
        np.testing.assert_array_almost_equal(test_cat_1.data['depth'],
                                             np.array([5., 15., 25.]))
        # Test case 3: Upper depth limit specified only
        test_cat_1 = selector0.within_depth_range(upper_depth=20.)
        np.testing.assert_array_almost_equal(test_cat_1.data['depth'],
                                             np.array([25., 35., 45.]))

        # Test case 4: Both depth limits specified
        test_cat_1 = selector0.within_depth_range(upper_depth=20., 
                                                  lower_depth=40.)
        np.testing.assert_array_almost_equal(test_cat_1.data['depth'],
                                             np.array([25., 35.]))


    def test_select_within_magnitude_range(self):
        '''
        Tests the function to select within the magnitude range
        '''
        # Setup function
        self.catalogue = Catalogue()
        self.catalogue.data['magnitude'] = np.array([4., 5., 6., 7., 8.])

        selector0 = CatalogueSelector(self.catalogue)
        # Test case 1: No limits specified - all catalogue valid
        test_cat_1 = selector0.within_magnitude_range()
        np.testing.assert_array_almost_equal(test_cat_1.data['magnitude'],
                                             self.catalogue.data['magnitude'])

        # Test case 2: Lower depth limit specfied only
        test_cat_1 = selector0.within_magnitude_range(lower_mag=5.5)
        np.testing.assert_array_almost_equal(test_cat_1.data['magnitude'],
                                             np.array([6., 7., 8.]))
        # Test case 3: Upper depth limit specified only
        test_cat_1 = selector0.within_magnitude_range(upper_mag=5.5)
        np.testing.assert_array_almost_equal(test_cat_1.data['magnitude'],
                                             np.array([4., 5.]))

        # Test case 4: Both depth limits specified
        test_cat_1 = selector0.within_magnitude_range(upper_mag=7.5, 
                                                      lower_mag=5.5)
        np.testing.assert_array_almost_equal(test_cat_1.data['magnitude'],
                                             np.array([6., 7.]))
Beispiel #4
0
class TestSelector(unittest.TestCase):
    '''
    Tests the hmtk.seismicity.selector.Selector class
    '''
    def setUp(self):
        '''
        '''

        self.catalogue = Catalogue()
        self.polygon = None

    def test_check_on_depth_limits(self):
        '''
        Tests the checks on depth limits
        '''
        test_dict = {'upper_depth': None, 'lower_depth': None}
        self.assertTupleEqual((0.0, np.inf), _check_depth_limits(test_dict))

        test_dict = {'upper_depth': 2.0, 'lower_depth': None}
        self.assertTupleEqual((2.0, np.inf), _check_depth_limits(test_dict))

        test_dict = {'upper_depth': None, 'lower_depth': 10.0}
        self.assertTupleEqual((0.0, 10.0), _check_depth_limits(test_dict))

        test_dict = {'upper_depth': -4.2, 'lower_depth': None}
        self.assertRaises(ValueError, _check_depth_limits, test_dict)

        test_dict = {'upper_depth': 5.0, 'lower_depth': 1.0}
        self.assertRaises(ValueError, _check_depth_limits, test_dict)

    def test_convert_datetime_to_decimal(self):
        '''
        Tests the function to convert a time from a datetime object to a 
        decimal - simple test to check conversion 
        NB Still will not work for BCE dates
        '''
        simple_time = datetime.datetime(1900, 6, 6, 1, 1, 1, 0)
        self.assertAlmostEqual(_get_decimal_from_datetime(simple_time),
                               1900.42751335)

    def test_catalogue_selection(self):
        '''
        Tests the tools for selecting events within the catalogue
        '''
        self.catalogue.data['longitude'] = np.arange(1., 6., 1.)
        self.catalogue.data['latitude'] = np.arange(6., 11., 1.)
        self.catalogue.data['depth'] = np.ones(5, dtype=bool)

        # No events selected
        flag_none = np.zeros(5, dtype=bool)
        selector0 = CatalogueSelector(self.catalogue)
        test_cat1 = selector0.select_catalogue(flag_none)
        self.assertEqual(len(test_cat1.data['longitude']), 0)
        self.assertEqual(len(test_cat1.data['latitude']), 0)
        self.assertEqual(len(test_cat1.data['depth']), 0)

        # All events selected
        flag_all = np.ones(5, dtype=bool)
        test_cat1 = selector0.select_catalogue(flag_all)
        self.assertTrue(
            np.allclose(test_cat1.data['longitude'],
                        self.catalogue.data['longitude']))
        self.assertTrue(
            np.allclose(test_cat1.data['latitude'],
                        self.catalogue.data['latitude']))
        self.assertTrue(
            np.allclose(test_cat1.data['depth'], self.catalogue.data['depth']))

        # Some events selected
        flag_1 = np.array([True, False, True, False, True])
        test_cat1 = selector0.select_catalogue(flag_1)
        self.assertTrue(
            np.allclose(test_cat1.data['longitude'], np.array([1., 3., 5.])))
        self.assertTrue(
            np.allclose(test_cat1.data['latitude'], np.array([6., 8., 10])))
        self.assertTrue(
            np.allclose(test_cat1.data['depth'], np.array([1., 1., 1.])))

    def test_select_within_polygon(self):
        '''
        Tests the selection of points within polygon
        '''
        # Setup polygon
        nodes = np.array([[5.0, 6.0], [6.0, 6.0], [6.0, 5.0], [5.0, 5.0]])
        polygon0 = Polygon(
            [Point(nodes[iloc, 0], nodes[iloc, 1]) for iloc in range(0, 4)])
        self.catalogue.data['longitude'] = np.arange(4.0, 7.5, 0.5)
        self.catalogue.data['latitude'] = np.arange(4.0, 7.5, 0.5)
        self.catalogue.data['depth'] = np.ones(7, dtype=float)
        # Simple case with nodes inside, outside and on the border of polygon
        selector0 = CatalogueSelector(self.catalogue)
        test_cat1 = selector0.within_polygon(polygon0)
        self.assertTrue(
            np.allclose(test_cat1.data['longitude'], np.array([5.0, 5.5,
                                                               6.0])))
        self.assertTrue(
            np.allclose(test_cat1.data['latitude'], np.array([5.0, 5.5, 6.0])))
        self.assertTrue(
            np.allclose(test_cat1.data['depth'], np.array([1.0, 1.0, 1.0])))
        # CASE 2: As case 1 with one of the inside nodes outside of the depths
        self.catalogue.data['depth'] = \
            np.array([1.0, 1.0, 1.0, 50.0, 1.0, 1.0, 1.0], dtype=float)
        selector0 = CatalogueSelector(self.catalogue)
        test_cat1 = selector0.within_polygon(polygon0,
                                             upper_depth=0.0,
                                             lower_depth=10.0)
        self.assertTrue(
            np.allclose(test_cat1.data['longitude'], np.array([5.0, 6.0])))
        self.assertTrue(
            np.allclose(test_cat1.data['latitude'], np.array([5.0, 6.0])))
        self.assertTrue(np.allclose(test_cat1.data['depth'], np.array([1.0])))

    def test_point_in_circular_distance(self):
        '''
        Tests point in circular distance
        '''
        self.catalogue.data['longitude'] = np.arange(4.0, 7.5, 0.5)
        self.catalogue.data['latitude'] = np.arange(4.0, 7.5, 0.5)
        self.catalogue.data['depth'] = np.ones(7, dtype=float)
        test_point = Point(5.5, 5.5)
        test_mesh = self.catalogue.hypocentres_as_mesh()
        selector0 = CatalogueSelector(self.catalogue)
        # Within 10 km
        test_cat_10 = selector0.circular_distance_from_point(
            test_point, 10., distance_type='epicentral')
        np.testing.assert_array_equal(test_cat_10.data['longitude'],
                                      np.array([5.5]))
        np.testing.assert_array_equal(test_cat_10.data['latitude'],
                                      np.array([5.5]))
        np.testing.assert_array_equal(test_cat_10.data['depth'],
                                      np.array([1.0]))

        # Within 100 km
        test_cat_100 = selector0.circular_distance_from_point(
            test_point, 100., distance_type='epicentral')
        np.testing.assert_array_equal(test_cat_100.data['longitude'],
                                      np.array([5.0, 5.5, 6.0]))
        np.testing.assert_array_equal(test_cat_100.data['latitude'],
                                      np.array([5.0, 5.5, 6.0]))
        np.testing.assert_array_equal(test_cat_100.data['depth'],
                                      np.array([1.0, 1.0, 1.0]))

        # Within 1000 km
        test_cat_1000 = selector0.circular_distance_from_point(
            test_point, 1000., distance_type='epicentral')
        np.testing.assert_array_equal(test_cat_1000.data['longitude'],
                                      self.catalogue.data['longitude'])
        np.testing.assert_array_equal(test_cat_1000.data['latitude'],
                                      self.catalogue.data['latitude'])
        np.testing.assert_array_equal(test_cat_1000.data['depth'],
                                      self.catalogue.data['depth'])

    def test_cartesian_square_on_point(self):
        '''
        Tests the cartesian square centres on point
        '''
        self.catalogue.data['longitude'] = np.arange(4.0, 7.5, 0.5)
        self.catalogue.data['latitude'] = np.arange(4.0, 7.5, 0.5)
        self.catalogue.data['depth'] = np.ones(7, dtype=float)
        test_point = Point(5.5, 5.5)
        test_mesh = self.catalogue.hypocentres_as_mesh()
        selector0 = CatalogueSelector(self.catalogue)
        # Within 10 km
        test_cat_10 = selector0.cartesian_square_centred_on_point(
            test_point, 10., distance_type='epicentral')
        np.testing.assert_array_equal(test_cat_10.data['longitude'],
                                      np.array([5.5]))
        np.testing.assert_array_equal(test_cat_10.data['latitude'],
                                      np.array([5.5]))
        np.testing.assert_array_equal(test_cat_10.data['depth'],
                                      np.array([1.0]))

        # Within 100 km
        test_cat_100 = selector0.cartesian_square_centred_on_point(
            test_point, 100., distance_type='epicentral')
        np.testing.assert_array_almost_equal(test_cat_100.data['longitude'],
                                             np.array([5.0, 5.5, 6.0]))
        np.testing.assert_array_almost_equal(test_cat_100.data['latitude'],
                                             np.array([5.0, 5.5, 6.0]))
        np.testing.assert_array_almost_equal(test_cat_100.data['depth'],
                                             np.array([1.0, 1.0, 1.0]))

        # Within 1000 km
        test_cat_1000 = selector0.cartesian_square_centred_on_point(
            test_point, 1000., distance_type='epicentral')
        np.testing.assert_array_almost_equal(test_cat_1000.data['longitude'],
                                             self.catalogue.data['longitude'])
        np.testing.assert_array_almost_equal(test_cat_1000.data['latitude'],
                                             self.catalogue.data['latitude'])
        np.testing.assert_array_almost_equal(test_cat_1000.data['depth'],
                                             self.catalogue.data['depth'])

    def test_within_joyner_boore_distance(self):
        '''
        Tests the function to select within Joyner-Boore distance
        '''
        self.catalogue.data['longitude'] = np.arange(4.0, 7.5, 0.5)
        self.catalogue.data['latitude'] = np.arange(4.0, 7.5, 0.5)
        self.catalogue.data['depth'] = np.ones(7, dtype=float)
        selector0 = CatalogueSelector(self.catalogue)
        # Construct Fault
        trace0 = np.array([[5.5, 6.0], [5.5, 5.0]])
        fault_trace = Line(
            [Point(trace0[i, 0], trace0[i, 1]) for i in range(0, 2)])

        # Simple fault with vertical dip
        fault0 = SimpleFaultSurface.from_fault_data(fault_trace, 0., 20., 90.,
                                                    1.)

        # Within 100 km
        test_cat_100 = selector0.within_joyner_boore_distance(fault0, 100.)
        np.testing.assert_array_almost_equal(test_cat_100.data['longitude'],
                                             np.array([5.0, 5.5, 6.0]))
        np.testing.assert_array_almost_equal(test_cat_100.data['latitude'],
                                             np.array([5.0, 5.5, 6.0]))
        np.testing.assert_array_almost_equal(test_cat_100.data['depth'],
                                             np.array([1.0, 1.0, 1.0]))

        # Simple fault with 30 degree dip
        fault0 = SimpleFaultSurface.from_fault_data(fault_trace, 0., 20., 30.,
                                                    1.)

        # Within 100 km
        test_cat_100 = selector0.within_joyner_boore_distance(fault0, 100.)
        np.testing.assert_array_almost_equal(test_cat_100.data['longitude'],
                                             np.array([4.5, 5.0, 5.5, 6.0]))
        np.testing.assert_array_almost_equal(test_cat_100.data['latitude'],
                                             np.array([4.5, 5.0, 5.5, 6.0]))
        np.testing.assert_array_almost_equal(test_cat_100.data['depth'],
                                             np.array([1.0, 1.0, 1.0, 1.0]))

    def test_within_rupture_distance(self):
        '''
        Tests the function to select within Joyner-Boore distance
        '''
        self.catalogue.data['longitude'] = np.arange(4.0, 7.5, 0.5)
        self.catalogue.data['latitude'] = np.arange(4.0, 7.5, 0.5)
        self.catalogue.data['depth'] = np.ones(7, dtype=float)
        selector0 = CatalogueSelector(self.catalogue)
        # Construct Fault
        trace0 = np.array([[5.5, 6.0], [5.5, 5.0]])
        fault_trace = Line(
            [Point(trace0[i, 0], trace0[i, 1]) for i in range(0, 2)])

        # Simple fault with vertical dip
        fault0 = SimpleFaultSurface.from_fault_data(fault_trace, 0., 20., 90.,
                                                    1.)

        # Within 100 km
        test_cat_100 = selector0.within_rupture_distance(fault0, 100.)
        np.testing.assert_array_almost_equal(test_cat_100.data['longitude'],
                                             np.array([5.0, 5.5, 6.0]))
        np.testing.assert_array_almost_equal(test_cat_100.data['latitude'],
                                             np.array([5.0, 5.5, 6.0]))
        np.testing.assert_array_almost_equal(test_cat_100.data['depth'],
                                             np.array([1.0, 1.0, 1.0]))

        # Simple fault with 30 degree dip
        fault0 = SimpleFaultSurface.from_fault_data(fault_trace, 0., 20., 30.,
                                                    1.)

        # Within 100 km
        test_cat_100 = selector0.within_rupture_distance(fault0, 100.)
        np.testing.assert_array_almost_equal(test_cat_100.data['longitude'],
                                             np.array([4.5, 5.0, 5.5, 6.0]))
        np.testing.assert_array_almost_equal(test_cat_100.data['latitude'],
                                             np.array([4.5, 5.0, 5.5, 6.0]))
        np.testing.assert_array_almost_equal(test_cat_100.data['depth'],
                                             np.array([1.0, 1.0, 1.0, 1.0]))

    def test_select_within_time(self):
        '''
        Tests the function to select within a time period
        '''
        self.catalogue.data['year'] = np.arange(1900, 2010, 20)
        self.catalogue.data['month'] = np.arange(1, 12, 2)
        self.catalogue.data['day'] = np.ones(6, dtype=int)
        self.catalogue.data['hour'] = np.ones(6, dtype=int)
        self.catalogue.data['minute'] = np.zeros(6, dtype=int)
        self.catalogue.data['second'] = np.ones(6, dtype=float)

        selector0 = CatalogueSelector(self.catalogue)

        # Start time and End time not defined
        test_cat_1 = selector0.within_time_period()
        self._compare_time_data_dictionaries(test_cat_1.data,
                                             self.catalogue.data)

        # Start time defined - end time not defined
        begin_time = datetime.datetime(1975, 1, 1, 0, 0, 0, 0)
        expected_data = {
            'year': np.array([1980, 2000]),
            'month': np.array([9, 11]),
            'day': np.array([1, 1]),
            'hour': np.array([1, 1]),
            'minute': np.array([0, 0]),
            'second': np.array([1., 1.])
        }

        test_cat_1 = selector0.within_time_period(start_time=begin_time)
        self._compare_time_data_dictionaries(expected_data, test_cat_1.data)

        # Test 3 - Start time not defined, end-time defined
        finish_time = datetime.datetime(1965, 1, 1, 0, 0, 0, 0)
        expected_data = {
            'year': np.array([1900, 1920, 1940, 1960]),
            'month': np.array([1, 3, 5, 7]),
            'day': np.array([1, 1, 1, 1]),
            'hour': np.array([1, 1, 1, 1]),
            'minute': np.array([0, 0, 0, 0]),
            'second': np.array([1., 1., 1., 1.])
        }

        test_cat_1 = selector0.within_time_period(end_time=finish_time)
        self._compare_time_data_dictionaries(expected_data, test_cat_1.data)

        # Test 4 - both start time and end-time defined
        begin_time = datetime.datetime(1935, 1, 1, 0, 0, 0, 0)
        finish_time = datetime.datetime(1995, 1, 1, 0, 0, 0, 0)
        expected_data = {
            'year': np.array([1940, 1960, 1980]),
            'month': np.array([5, 7, 9]),
            'day': np.array([1, 1, 1]),
            'hour': np.array([1, 1, 1]),
            'minute': np.array([0, 0, 0]),
            'second': np.array([1., 1., 1.])
        }

        test_cat_1 = selector0.within_time_period(begin_time, finish_time)
        self._compare_time_data_dictionaries(expected_data, test_cat_1.data)

    def _compare_time_data_dictionaries(self, expected, modelled):
        '''
        Compares the relevent time and date information in the catalogue 
        data dictionaries
        '''
        time_keys = ['year', 'month', 'day', 'hour', 'minute', 'second']

        for key in time_keys:
            # The second value is a float - all others are integers
            if 'second' in key:
                np.testing.assert_array_almost_equal(expected[key],
                                                     modelled[key])
            else:
                np.testing.assert_array_equal(expected[key], modelled[key])

    def test_select_within_depth_range(self):
        '''
        Tests the function to select within the depth range
        '''
        # Setup function
        self.catalogue = Catalogue()
        self.catalogue.data['depth'] = np.array([5., 15., 25., 35., 45.])

        selector0 = CatalogueSelector(self.catalogue)
        # Test case 1: No limits specified - all catalogue valid
        test_cat_1 = selector0.within_depth_range()
        np.testing.assert_array_almost_equal(test_cat_1.data['depth'],
                                             self.catalogue.data['depth'])

        # Test case 2: Lower depth limit specfied only
        test_cat_1 = selector0.within_depth_range(lower_depth=30.)
        np.testing.assert_array_almost_equal(test_cat_1.data['depth'],
                                             np.array([5., 15., 25.]))
        # Test case 3: Upper depth limit specified only
        test_cat_1 = selector0.within_depth_range(upper_depth=20.)
        np.testing.assert_array_almost_equal(test_cat_1.data['depth'],
                                             np.array([25., 35., 45.]))

        # Test case 4: Both depth limits specified
        test_cat_1 = selector0.within_depth_range(upper_depth=20.,
                                                  lower_depth=40.)
        np.testing.assert_array_almost_equal(test_cat_1.data['depth'],
                                             np.array([25., 35.]))

    def test_select_within_magnitude_range(self):
        '''
        Tests the function to select within the magnitude range
        '''
        # Setup function
        self.catalogue = Catalogue()
        self.catalogue.data['magnitude'] = np.array([4., 5., 6., 7., 8.])

        selector0 = CatalogueSelector(self.catalogue)
        # Test case 1: No limits specified - all catalogue valid
        test_cat_1 = selector0.within_magnitude_range()
        np.testing.assert_array_almost_equal(test_cat_1.data['magnitude'],
                                             self.catalogue.data['magnitude'])

        # Test case 2: Lower depth limit specfied only
        test_cat_1 = selector0.within_magnitude_range(lower_mag=5.5)
        np.testing.assert_array_almost_equal(test_cat_1.data['magnitude'],
                                             np.array([6., 7., 8.]))
        # Test case 3: Upper depth limit specified only
        test_cat_1 = selector0.within_magnitude_range(upper_mag=5.5)
        np.testing.assert_array_almost_equal(test_cat_1.data['magnitude'],
                                             np.array([4., 5.]))

        # Test case 4: Both depth limits specified
        test_cat_1 = selector0.within_magnitude_range(upper_mag=7.5,
                                                      lower_mag=5.5)
        np.testing.assert_array_almost_equal(test_cat_1.data['magnitude'],
                                             np.array([6., 7.]))