def test_set_one_pass(self):
        """Test _tc_from_track function."""
        intensity_idx = [0, 1, 2,  3,  80, 100, 120, 200, 220, 250, 260, 295]
        intensity_values = {
            "geosphere": [25.60794285, 26.90906280, 28.26649026, 25.54076797, 31.21986961,
                          36.17171808, 21.11408573, 28.01457948, 32.65349378, 31.34027741, 0,
                          40.27362679],
            "equirect": [25.60778909, 26.90887264, 28.26624642, 25.54092386, 31.21941738,
                         36.16596567, 21.11399856, 28.01452136, 32.65076804, 31.33884098, 0,
                         40.27002104]
        }
        # the values for the two metrics should agree up to first digit at least
        for i, val in enumerate(intensity_values["geosphere"]):
            self.assertAlmostEqual(intensity_values["equirect"][i], val, 1)

        tc_track = TCTracks()
        tc_track.read_processed_ibtracs_csv(TEST_TRACK)
        tc_track.equal_timestep()
        tc_track.data = tc_track.data[:1]

        for metric in ["equirect", "geosphere"]:
            tc_haz = TropCyclone()
            tc_haz.set_from_tracks(tc_track, centroids=CENTR_TEST_BRB, model='H08',
                                   store_windfields=True, metric=metric)

            self.assertEqual(tc_haz.tag.haz_type, 'TC')
            self.assertEqual(tc_haz.tag.description, '')
            self.assertEqual(tc_haz.tag.file_name, 'Name: 1951239N12334')
            self.assertEqual(tc_haz.units, 'm/s')
            self.assertEqual(tc_haz.centroids.size, 296)
            self.assertEqual(tc_haz.event_id.size, 1)
            self.assertEqual(tc_haz.date.size, 1)
            self.assertEqual(dt.datetime.fromordinal(tc_haz.date[0]).year, 1951)
            self.assertEqual(dt.datetime.fromordinal(tc_haz.date[0]).month, 8)
            self.assertEqual(dt.datetime.fromordinal(tc_haz.date[0]).day, 27)
            self.assertEqual(tc_haz.event_id[0], 1)
            self.assertEqual(tc_haz.event_name, ['1951239N12334'])
            self.assertTrue(np.array_equal(tc_haz.frequency, np.array([1])))
            self.assertTrue(isinstance(tc_haz.fraction, sparse.csr.csr_matrix))
            self.assertEqual(tc_haz.fraction.shape, (1, 296))
            self.assertEqual(tc_haz.fraction[0, 100], 1)
            self.assertEqual(tc_haz.fraction[0, 260], 0)
            self.assertEqual(tc_haz.fraction.nonzero()[0].size, 280)

            self.assertTrue(isinstance(tc_haz.intensity, sparse.csr.csr_matrix))
            self.assertEqual(tc_haz.intensity.shape, (1, 296))
            self.assertEqual(np.nonzero(tc_haz.intensity)[0].size, 280)

            for idx, val in zip(intensity_idx, intensity_values[metric]):
                if val == 0:
                    self.assertEqual(tc_haz.intensity[0, idx], 0)
                else:
                    self.assertAlmostEqual(tc_haz.intensity[0, idx], val)

            windfields = tc_haz.windfields[0].toarray()
            windfields = windfields.reshape(windfields.shape[0], -1, 2)
            windfield_norms = np.linalg.norm(windfields, axis=-1).max(axis=0)
            intensity = tc_haz.intensity.toarray()[0, :]
            msk = (intensity > 0)
            np.testing.assert_array_equal(windfield_norms[msk], intensity[msk])
예제 #2
0
    def test_set_one_pass(self):
        """Test _tc_from_track function."""
        tc_track = TCTracks()
        tc_track.read_processed_ibtracs_csv(TEST_TRACK)
        tc_track.equal_timestep()
        tc_track.data = tc_track.data[:1]
        tc_haz = TropCyclone()
        tc_haz.set_from_tracks(tc_track,
                               centroids=CENTR_TEST_BRB,
                               model='H08',
                               store_windfields=True)

        self.assertEqual(tc_haz.tag.haz_type, 'TC')
        self.assertEqual(tc_haz.tag.description, '')
        self.assertEqual(tc_haz.tag.file_name, 'Name: 1951239N12334')
        self.assertEqual(tc_haz.units, 'm/s')
        self.assertEqual(tc_haz.centroids.size, 296)
        self.assertEqual(tc_haz.event_id.size, 1)
        self.assertEqual(tc_haz.date.size, 1)
        self.assertEqual(dt.datetime.fromordinal(tc_haz.date[0]).year, 1951)
        self.assertEqual(dt.datetime.fromordinal(tc_haz.date[0]).month, 8)
        self.assertEqual(dt.datetime.fromordinal(tc_haz.date[0]).day, 27)
        self.assertEqual(tc_haz.event_id[0], 1)
        self.assertEqual(tc_haz.event_name, ['1951239N12334'])
        self.assertTrue(np.array_equal(tc_haz.frequency, np.array([1])))
        self.assertTrue(isinstance(tc_haz.fraction, sparse.csr.csr_matrix))
        self.assertEqual(tc_haz.fraction.shape, (1, 296))
        self.assertEqual(tc_haz.fraction[0, 100], 1)
        self.assertEqual(tc_haz.fraction[0, 260], 0)
        self.assertEqual(tc_haz.fraction.nonzero()[0].size, 280)

        self.assertTrue(isinstance(tc_haz.intensity, sparse.csr.csr_matrix))
        self.assertEqual(tc_haz.intensity.shape, (1, 296))
        self.assertEqual(np.nonzero(tc_haz.intensity)[0].size, 280)

        self.assertEqual(tc_haz.intensity[0, 260], 0)
        self.assertAlmostEqual(tc_haz.intensity[0, 1], 27.08333002)
        self.assertAlmostEqual(tc_haz.intensity[0, 2], 28.46008202)
        self.assertAlmostEqual(tc_haz.intensity[0, 3], 25.70445069)
        self.assertAlmostEqual(tc_haz.intensity[0, 100], 36.45564037)
        self.assertAlmostEqual(tc_haz.intensity[0, 250], 31.60115745)
        self.assertAlmostEqual(tc_haz.intensity[0, 295], 40.62433745)

        to_kn = (1.0 * ureg.meter / ureg.second).to(ureg.knot).magnitude
        wind = tc_haz.intensity.toarray()[0, :]
        self.assertAlmostEqual(wind[0] * to_kn, 50.08492156)
        self.assertAlmostEqual(wind[80] * to_kn, 61.13812028)
        self.assertAlmostEqual(wind[120] * to_kn, 41.26159439)
        self.assertAlmostEqual(wind[200] * to_kn, 54.85572160)
        self.assertAlmostEqual(wind[220] * to_kn, 63.99749424)

        windfields = tc_haz.windfields[0].toarray()
        windfields = windfields.reshape(windfields.shape[0], -1, 2)
        windfield_norms = np.linalg.norm(windfields, axis=-1).max(axis=0)
        intensity = tc_haz.intensity.toarray()[0, :]
        msk = (intensity > 0)
        self.assertTrue(np.allclose(windfield_norms[msk], intensity[msk]))
    def test_two_files_pass(self):
        """Test set function set_from_tracks with two ibtracs."""
        tc_track = TCTracks()
        tc_track.read_processed_ibtracs_csv([TEST_TRACK_SHORT, TEST_TRACK_SHORT])
        tc_haz = TropCyclone()
        tc_haz.set_from_tracks(tc_track, CENTR_TEST_BRB)
        tc_haz.remove_duplicates()
        tc_haz.check()

        self.assertEqual(tc_haz.tag.haz_type, 'TC')
        self.assertEqual(tc_haz.tag.description, '')
        self.assertEqual(tc_haz.tag.file_name, ['Name: 1951239N12334', 'Name: 1951239N12334'])
        self.assertEqual(tc_haz.units, 'm/s')
        self.assertEqual(tc_haz.centroids.size, 296)
        self.assertEqual(tc_haz.event_id.size, 1)
        self.assertEqual(tc_haz.event_id[0], 1)
        self.assertEqual(tc_haz.event_name, ['1951239N12334'])
        self.assertTrue(np.array_equal(tc_haz.frequency, np.array([1])))
        self.assertTrue(np.array_equal(tc_haz.orig, np.array([True])))
        self.assertTrue(isinstance(tc_haz.intensity, sparse.csr.csr_matrix))
        self.assertTrue(isinstance(tc_haz.fraction, sparse.csr.csr_matrix))
        self.assertEqual(tc_haz.intensity.shape, (1, 296))
        self.assertEqual(tc_haz.fraction.shape, (1, 296))

        self.assertEqual(tc_haz.fraction.nonzero()[0].size, 0)
        self.assertEqual(tc_haz.intensity.nonzero()[0].size, 0)
    def test_set_one_file_pass(self):
        """Test from_tracks with one input."""
        tc_track = TCTracks.from_processed_ibtracs_csv(TEST_TRACK_SHORT)
        tc_haz = TropCyclone.from_tracks(tc_track, centroids=CENTR_TEST_BRB)
        tc_haz.check()

        self.assertEqual(tc_haz.tag.haz_type, 'TC')
        self.assertEqual(tc_haz.tag.description, '')
        self.assertEqual(tc_haz.tag.file_name, 'Name: 1951239N12334')
        self.assertEqual(tc_haz.units, 'm/s')
        self.assertEqual(tc_haz.centroids.size, 296)
        self.assertEqual(tc_haz.event_id.size, 1)
        self.assertEqual(tc_haz.event_id[0], 1)
        self.assertEqual(tc_haz.event_name, ['1951239N12334'])
        self.assertEqual(tc_haz.category, tc_track.data[0].category)
        self.assertEqual(tc_haz.basin[0], 'NA')
        self.assertIsInstance(tc_haz.basin, list)
        self.assertIsInstance(tc_haz.category, np.ndarray)
        self.assertTrue(np.array_equal(tc_haz.frequency, np.array([1])))
        self.assertTrue(isinstance(tc_haz.intensity, sparse.csr.csr_matrix))
        self.assertTrue(isinstance(tc_haz.fraction, sparse.csr.csr_matrix))
        self.assertEqual(tc_haz.intensity.shape, (1, 296))
        self.assertEqual(tc_haz.fraction.shape, (1, 296))

        self.assertEqual(tc_haz.fraction.nonzero()[0].size, 0)
        self.assertEqual(tc_haz.intensity.nonzero()[0].size, 0)
예제 #5
0
    def test_set_one_pass(self):
        """Test _hazard_from_track function."""
        tc_track = TCTracks()
        tc_track.read_processed_ibtracs_csv(TEST_TRACK_SHORT)
        tc_track.equal_timestep()
        coastal_centr = tc.coastal_centr_idx(CENT_CLB)
        tc_haz = TropCyclone._tc_from_track(tc_track.data[0], CENT_CLB,
                                            coastal_centr)

        self.assertEqual(tc_haz.tag.haz_type, 'TC')
        self.assertEqual(tc_haz.tag.description, '')
        self.assertEqual(tc_haz.tag.file_name, 'IBTrACS: 1951239N12334')
        self.assertEqual(tc_haz.units, 'm/s')
        self.assertEqual(tc_haz.centroids.size, 1656093)
        self.assertEqual(tc_haz.event_id.size, 1)
        self.assertEqual(tc_haz.date.size, 1)
        self.assertEqual(dt.datetime.fromordinal(tc_haz.date[0]).year, 1951)
        self.assertEqual(dt.datetime.fromordinal(tc_haz.date[0]).month, 8)
        self.assertEqual(dt.datetime.fromordinal(tc_haz.date[0]).day, 27)
        self.assertEqual(tc_haz.event_id[0], 1)
        self.assertEqual(tc_haz.event_name, ['1951239N12334'])
        self.assertTrue(np.array_equal(tc_haz.frequency, np.array([1])))
        self.assertTrue(isinstance(tc_haz.intensity, sparse.csr.csr_matrix))
        self.assertTrue(isinstance(tc_haz.fraction, sparse.csr.csr_matrix))
        self.assertEqual(tc_haz.intensity.shape, (1, 1656093))
        self.assertEqual(tc_haz.fraction.shape, (1, 1656093))

        self.assertAlmostEqual(tc_haz.intensity[0, 1630393],
                               18.511077471450232, 6)
        self.assertEqual(tc_haz.intensity[0, 1630394], 0)
        self.assertEqual(tc_haz.fraction[0, 1630393], 1)
        self.assertEqual(tc_haz.fraction[0, 1630394], 0)

        self.assertEqual(tc_haz.fraction.nonzero()[0].size, 7)
        self.assertEqual(tc_haz.intensity.nonzero()[0].size, 7)
예제 #6
0
    def set_from_tracks(self,
                        tracks,
                        centroids=None,
                        dist_degree=3,
                        description=''):
        """Computes rainfield from tracks based on the RCLIPER model.
        Parallel process.
        Parameters:
            tracks (TCTracks): tracks of events
            centroids (Centroids, optional): Centroids where to model TC.
                Default: global centroids.
            disr_degree (int): distance (in degrees) from node within which
                               the rainfield is processed (default 3 deg,~300km)
            description (str, optional): description of the events

        """
        num_tracks = tracks.size
        if centroids is None:
            centroids = Centroids.from_base_grid(res_as=360, land=True)

        if not centroids.coord.size:
            centroids.set_meta_to_lat_lon()

        LOGGER.info('Mapping %s tracks to %s centroids.', str(tracks.size),
                    str(centroids.size))
        if self.pool:
            chunksize = min(num_tracks // self.pool.ncpus, 1000)
            tc_haz = self.pool.map(self._set_from_track,
                                   tracks.data,
                                   itertools.repeat(centroids, num_tracks),
                                   itertools.repeat(dist_degree, num_tracks),
                                   itertools.repeat(self.intensity_thres,
                                                    num_tracks),
                                   chunksize=chunksize)
        else:
            tc_haz = list()
            for track in tracks.data:
                tc_haz.append(
                    self._set_from_track(track,
                                         centroids,
                                         dist_degree=dist_degree,
                                         intensity=self.intensity_thres))
        LOGGER.debug('Append events.')
        self.concatenate(tc_haz)
        LOGGER.debug('Compute frequency.')
        TropCyclone.frequency_from_tracks(self, tracks.data)
        self.tag.description = description
예제 #7
0
    def test_set_one_file_pass(self):
        """ Test set function set_from_tracks with one input."""

        pool = Pool()

        tc_track = TCTracks(pool)

        tc_track.read_processed_ibtracs_csv(TEST_TRACK)
        tc_track.calc_random_walk()
        tc_track.equal_timestep()

        tc_haz = TropCyclone(pool)
        tc_haz.set_from_tracks(tc_track, CENTR_TEST_BRB)
        tc_haz.check()

        pool.close()
        pool.join()

        self.assertEqual(tc_haz.tag.haz_type, 'TC')
        self.assertEqual(tc_haz.tag.description, '')
        self.assertEqual(tc_haz.units, 'm/s')
        self.assertEqual(tc_haz.centroids.size, 296)
        self.assertEqual(tc_haz.event_id.size, 10)
        self.assertTrue(isinstance(tc_haz.intensity, sparse.csr.csr_matrix))
        self.assertTrue(isinstance(tc_haz.fraction, sparse.csr.csr_matrix))
        self.assertEqual(tc_haz.intensity.shape, (10, 296))
        self.assertEqual(tc_haz.fraction.shape, (10, 296))
예제 #8
0
    def test_windfield_models(self):
        """Test _tc_from_track function with different wind field models."""
        intensity_idx = [0, 1, 2, 3, 80, 100, 120, 200, 220, 250, 260, 295]
        intensity_values = {
            "H08": [
                25.60778909, 26.90887264, 28.26624642, 25.54092386,
                31.21941738, 36.16596567, 21.11399856, 28.01452136,
                32.65076804, 31.33884098, 0, 40.27002104
            ],
            "H10": [
                27.477252, 28.626236, 29.829914, 27.393616, 32.495186,
                37.113324, 23.573216, 29.552127, 33.767067, 32.530964,
                19.656737, 41.014578
            ],
            # Holland 1980 is the only model that uses recorded wind speeds, while the above use
            # pressure values only. That's why the results for Holland 1980 are so different:
            "H1980": [
                20.291397, 22.678914, 25.428598, 20.44718, 31.868592,
                41.920317, 0, 25.715983, 38.351686, 35.591153, 0, 46.873912
            ],
        }

        tc_track = TCTracks()
        tc_track.read_processed_ibtracs_csv(TEST_TRACK)
        tc_track.equal_timestep()
        tc_track.data = tc_track.data[:1]

        for model in ["H08", "H10", "H1980"]:
            tc_haz = TropCyclone()
            tc_haz.set_from_tracks(tc_track,
                                   centroids=CENTR_TEST_BRB,
                                   model=model)
            np.testing.assert_array_almost_equal(
                tc_haz.intensity[0, intensity_idx].toarray()[0],
                intensity_values[model])
            for idx, val in zip(intensity_idx, intensity_values[model]):
                if val == 0:
                    self.assertEqual(tc_haz.intensity[0, idx], 0)
    def test_negative_freq_error(self):
        """Test _apply_knutson_criterion with infeasible input."""
        criterion = [{'basin': 'SP', 'category': [0, 1],
                      'year': 2100, 'change': 0.5,
                      'variable': 'frequency'}
                     ]

        tc = TropCyclone()
        tc.frequency = np.ones(2)
        tc.basin = ['SP', 'SP']
        tc.category = np.array([0, 1])
        with self.assertRaises(ValueError):
            tc._apply_knutson_criterion(criterion, 3)
    def test_two_criterion_track(self):
        """Test _apply_criterion function with two criteria"""
        criterion = [
            {'basin': 'NA', 'category': [1, 2, 3, 4, 5],
             'year': 2100, 'change': 1.045, 'variable': 'intensity'},
            {'basin': 'WP', 'category': [1, 2, 3, 4, 5],
             'year': 2100, 'change': 1.025, 'variable': 'intensity'},
            {'basin': 'WP', 'category': [1, 2, 3, 4, 5],
             'year': 2100, 'change': 1.025, 'variable': 'frequency'},
            {'basin': 'NA', 'category': [0, 1, 2, 3, 4, 5],
             'year': 2100, 'change': 0.7, 'variable': 'frequency'},
            {'basin': 'NA', 'category': [1, 2, 3, 4, 5],
             'year': 2100, 'change': 1, 'variable': 'frequency'},
            {'basin': 'NA', 'category': [3, 4, 5],
             'year': 2100, 'change': 1, 'variable': 'frequency'},
            {'basin': 'NA', 'category': [4, 5],
             'year': 2100, 'change': 2, 'variable': 'frequency'}
            ]
        scale = 0.75

        tc = TropCyclone()
        tc.intensity = np.zeros((4, 10))
        tc.intensity[0, :] = np.arange(10)
        tc.intensity[1, 5] = 10
        tc.intensity[2, :] = np.arange(10, 20)
        tc.intensity[3, 3] = 3
        tc.intensity = sparse.csr_matrix(tc.intensity)
        tc.frequency = np.ones(4) * 0.5
        tc.basin = ['NA'] * 4
        tc.basin[3] = 'WP'
        tc.category = np.array([2, 0, 4, 1])
        tc.event_id = np.arange(4)

        tc_cc = tc._apply_knutson_criterion(criterion, scale)
        self.assertTrue(np.allclose(tc.intensity[1, :].toarray(), tc_cc.intensity[1, :].toarray()))
        self.assertFalse(
            np.allclose(tc.intensity[3, :].toarray(), tc_cc.intensity[3, :].toarray()))
        self.assertFalse(
            np.allclose(tc.intensity[0, :].toarray(), tc_cc.intensity[0, :].toarray()))
        self.assertFalse(
            np.allclose(tc.intensity[2, :].toarray(), tc_cc.intensity[2, :].toarray()))
        self.assertTrue(
            np.allclose(tc.intensity[0, :].toarray() * 1.03375, tc_cc.intensity[0, :].toarray()))
        self.assertTrue(
            np.allclose(tc.intensity[2, :].toarray() * 1.03375, tc_cc.intensity[2, :].toarray()))
        self.assertTrue(
            np.allclose(tc.intensity[3, :].toarray() * 1.01875, tc_cc.intensity[3, :].toarray()))

        res_frequency = np.ones(4) * 0.5
        res_frequency[1] = 0.5 * (1 + (0.7 - 1) * scale)
        res_frequency[2] = 0.5 * (1 + (2 - 1) * scale)
        res_frequency[3] = 0.5 * (1 + (1.025 - 1) * scale)
        self.assertTrue(np.allclose(tc_cc.frequency, res_frequency))
    def test_apply_criterion_track(self):
        """Test _apply_criterion function."""
        criterion = [{'basin': 'NA', 'category': [1, 2, 3, 4, 5],
                   'year': 2100, 'change': 1.045, 'variable': 'intensity'}
                   ]
        scale = 0.75

        # artificially increase the size of the hazard by repeating (tiling) the data:
        ntiles = 8

        tc = TropCyclone()
        tc.intensity = np.zeros((4, 10))
        tc.intensity[0, :] = np.arange(10)
        tc.intensity[1, 5] = 10
        tc.intensity[2, :] = np.arange(10, 20)
        tc.intensity[3, 3] = 3
        tc.intensity = np.tile(tc.intensity, (ntiles, 1))
        tc.intensity = sparse.csr_matrix(tc.intensity)
        tc.basin = ['NA'] * 4
        tc.basin[3] = 'WP'
        tc.basin = ntiles * tc.basin
        tc.category = np.array(ntiles * [2, 0, 4, 1])
        tc.event_id = np.arange(tc.intensity.shape[0])

        tc_cc = tc._apply_knutson_criterion(criterion, scale)
        for i_tile in range(ntiles):
            offset = i_tile * 4
            # no factor applied because of category 0
            np.testing.assert_array_equal(
                tc.intensity[offset + 1, :].toarray(), tc_cc.intensity[offset + 1, :].toarray())
            # no factor applied because of basin "WP"
            np.testing.assert_array_equal(
                tc.intensity[offset + 3, :].toarray(), tc_cc.intensity[offset + 3, :].toarray())
            # factor is applied to the remaining events
            np.testing.assert_array_almost_equal(
                tc.intensity[offset + 0, :].toarray() * 1.03375,
                tc_cc.intensity[offset + 0, :].toarray())
            np.testing.assert_array_almost_equal(
                tc.intensity[offset + 2, :].toarray() * 1.03375,
                tc_cc.intensity[offset + 2, :].toarray())
    def test_apply_criterion_track(self):
        """Test _apply_criterion function."""
        tc = TropCyclone()
        tc.intensity = np.zeros((4, 10))
        tc.intensity[0, :] = np.arange(10)
        tc.intensity[1, 5] = 10
        tc.intensity[2, :] = np.arange(10, 20)
        tc.intensity[3, 3] = 3
        tc.intensity = sparse.csr_matrix(tc.intensity)
        tc.basin = ['NA'] * 4
        tc.basin[3] = 'NO'
        tc.category = np.array([2, 0, 4, 1])
        tc.event_id = np.arange(4)
        tc.frequency = np.ones(4) * 0.5

        tc_cc = tc.set_climate_scenario_knu(ref_year=2050, rcp_scenario=45)
        self.assertTrue(np.allclose(tc.intensity[1, :].toarray(), tc_cc.intensity[1, :].toarray()))
        self.assertTrue(np.allclose(tc.intensity[3, :].toarray(), tc_cc.intensity[3, :].toarray()))
        self.assertFalse(
            np.allclose(tc.intensity[0, :].toarray(), tc_cc.intensity[0, :].toarray()))
        self.assertFalse(
            np.allclose(tc.intensity[2, :].toarray(), tc_cc.intensity[2, :].toarray()))
        self.assertTrue(np.allclose(tc.frequency, tc_cc.frequency))
        self.assertEqual(
            tc_cc.tag.description,
            'climate change scenario for year 2050 and RCP 45 from Knutson et al 2015.')
예제 #13
0
    def test_two_criterion_track(self):
        """Test _apply_criterion function with two criteria"""
        criterion = list()
        tmp_chg = {
            'criteria': {
                'basin': ['NA'],
                'category': [1, 2, 3, 4, 5]
            },
            'year': 2100,
            'change': 1.045,
            'variable': 'intensity',
            'function': np.multiply
        }
        criterion.append(tmp_chg)
        tmp_chg = {
            'criteria': {
                'basin': ['WP'],
                'category': [1, 2, 3, 4, 5]
            },
            'year': 2100,
            'change': 1.025,
            'variable': 'intensity',
            'function': np.multiply
        }
        criterion.append(tmp_chg)
        tmp_chg = {
            'criteria': {
                'basin': ['WP'],
                'category': [1, 2, 3, 4, 5]
            },
            'year': 2100,
            'change': 1.025,
            'variable': 'frequency',
            'function': np.multiply
        }
        criterion.append(tmp_chg)
        scale = 0.75

        tc = TropCyclone()
        tc.intensity = np.zeros((4, 10))
        tc.intensity[0, :] = np.arange(10)
        tc.intensity[1, 5] = 10
        tc.intensity[2, :] = np.arange(10, 20)
        tc.intensity[3, 3] = 3
        tc.intensity = sparse.csr_matrix(tc.intensity)
        tc.frequency = np.ones(4) * 0.5
        tc.basin = ['NA'] * 4
        tc.basin[3] = 'WP'
        tc.category = np.array([2, 0, 4, 1])
        tc.event_id = np.arange(4)

        tc_cc = tc._apply_criterion(criterion, scale)
        self.assertTrue(
            np.allclose(tc.intensity[1, :].toarray(),
                        tc_cc.intensity[1, :].toarray()))
        self.assertFalse(
            np.allclose(tc.intensity[3, :].toarray(),
                        tc_cc.intensity[3, :].toarray()))
        self.assertFalse(
            np.allclose(tc.intensity[0, :].toarray(),
                        tc_cc.intensity[0, :].toarray()))
        self.assertFalse(
            np.allclose(tc.intensity[2, :].toarray(),
                        tc_cc.intensity[2, :].toarray()))
        self.assertTrue(
            np.allclose(tc.intensity[0, :].toarray() * 1.03375,
                        tc_cc.intensity[0, :].toarray()))
        self.assertTrue(
            np.allclose(tc.intensity[2, :].toarray() * 1.03375,
                        tc_cc.intensity[2, :].toarray()))
        self.assertTrue(
            np.allclose(tc.intensity[3, :].toarray() * 1.01875,
                        tc_cc.intensity[3, :].toarray()))
        res_frequency = np.ones(4) * 0.5
        res_frequency[3] = 0.5 * 1.01875
        self.assertTrue(np.allclose(tc_cc.frequency, res_frequency))
    def test_read_and_tc_fail(self):
        """ Append Hazard and Tropical Cyclone. Fail because of missing 
        category in hazard. """
        tc_track = TCTracks()
        tc_track.read_processed_ibtracs_csv(TEST_TRACK_SHORT)

        tc_haz1 = TropCyclone()
        tc_haz1.read_mat(HAZ_TEST_MAT)

        tc_haz2 = TropCyclone()
        tc_haz2.set_from_tracks(tc_track, CENTR_TEST_BRB)

        tc_haz2.append(tc_haz1)
        self.assertEqual(tc_haz2.intensity.shape, (14451, 396))
        with self.assertRaises(ValueError):
            tc_haz2.check()