Ejemplo n.º 1
0
    def make_strike_map(self, bounds_polygon, hour, raster_shape, resolution):
        generated_layers = [
            layer.generate(bounds_polygon, raster_shape, hour=hour, resolution=resolution) for layer in self._layers]
        raster_grid = np.flipud(np.sum(
            [remove_raster_nans(res[1]) for res in generated_layers if
             res[1] is not None],
            axis=0))
        raster_shape = raster_grid.shape
        x, y = np.mgrid[0:raster_shape[0], 0:raster_shape[1]]
        eval_grid = np.vstack((x.ravel(), y.ravel())).T
        samples = 5000
        # Conjure up our distributions for various things
        alt = ss.norm(self.alt, 5).rvs(samples)
        vel = ss.norm(self.vel, 2.5).rvs(samples)
        wind_vels = ss.norm(self.wind_vel, 1).rvs(samples)
        wind_dirs = bearing_to_angle(ss.norm(self.wind_dir, np.deg2rad(5)).rvs(samples))
        wind_vel_y = wind_vels * np.sin(wind_dirs)
        wind_vel_x = wind_vels * np.cos(wind_dirs)
        (bm_mean, bm_cov), v_ib, a_ib = self.bm.transform(alt, vel,
                                                          ss.uniform(0, 360).rvs(samples),
                                                          wind_vel_y, wind_vel_x,
                                                          0, 0)
        (gm_mean, gm_cov), v_ig, a_ig = self.gm.transform(alt, vel,
                                                          ss.uniform(0, 360).rvs(samples),
                                                          wind_vel_y, wind_vel_x,
                                                          0, 0)
        sm_b = StrikeModel(raster_grid, resolution ** 2, self.aircraft.width, a_ib)
        sm_g = StrikeModel(raster_grid, resolution ** 2, self.aircraft.width, a_ig)
        premult = sm_b.premult_mat + sm_g.premult_mat
        offset_y, offset_x = raster_shape[0] // 2, raster_shape[1] // 2
        bm_pdf = ss.multivariate_normal(bm_mean + np.array([offset_y, offset_x]), bm_cov).pdf(eval_grid)
        gm_pdf = ss.multivariate_normal(gm_mean + np.array([offset_y, offset_x]), gm_cov).pdf(eval_grid)
        pdf = bm_pdf + gm_pdf
        pdf = pdf.reshape(raster_shape)
        padded_pdf = np.zeros(((raster_shape[0] * 3) + 1, (raster_shape[1] * 3) + 1))
        padded_pdf[raster_shape[0]:raster_shape[0] * 2, raster_shape[1]:raster_shape[1] * 2] = pdf
        padded_pdf = padded_pdf * self.event_prob
        padded_centre_y, padded_centre_x = raster_shape[0] + offset_y, raster_shape[1] + offset_x
        # Check if CUDA toolkit available through env var otherwise fallback to CPU bound numba version
        if not os.getenv('CUDA_HOME'):
            print('CUDA NOT found, falling back to Numba JITed CPU code')
            # Leaving parallelisation to Numba seems to be faster
            risk_map = wrap_all_pipeline(raster_shape, padded_pdf, padded_centre_y, padded_centre_x, premult)

        else:

            risk_map = np.zeros(raster_shape, dtype=float)
            threads_per_block = (32, 32)  # 1024 max per block
            blocks_per_grid = (
                int(np.ceil(raster_shape[1] / threads_per_block[1])),
                int(np.ceil(raster_shape[0] / threads_per_block[0]))
            )
            print('CUDA found, using config <<<' + str(blocks_per_grid) + ',' + str(threads_per_block) + '>>>')
            wrap_pipeline_cuda[blocks_per_grid, threads_per_block](raster_shape, padded_pdf, padded_centre_y,
                                                                   padded_centre_x, premult, risk_map)
        ac_mass = self.aircraft.mass
        impact_kes = (velocity_to_kinetic_energy(ac_mass, v_ib), velocity_to_kinetic_energy(ac_mass, v_ig))

        return risk_map, impact_kes
Ejemplo n.º 2
0
def _make_fatality_grid(aircraft, strike_grid, v_is):
    fm = FatalityModel(0.3, 1e6, 34)
    ac_mass = aircraft.mass
    impact_ke_b = velocity_to_kinetic_energy(ac_mass, v_is[0])
    impact_ke_g = velocity_to_kinetic_energy(ac_mass, v_is[1])
    res = fm.transform(strike_grid, impact_ke=impact_ke_g) + fm.transform(
        strike_grid, impact_ke=impact_ke_b)
    return res
Ejemplo n.º 3
0
def make_fatality_grid(aircraft, strike_grid, v_is):
    from seedpod_ground_risk.path_analysis.harm_models.fatality_model import FatalityModel
    from seedpod_ground_risk.path_analysis.utils import velocity_to_kinetic_energy

    fm = FatalityModel(0.3, 1e6, 34)
    ac_mass = aircraft.mass
    impact_ke_b = velocity_to_kinetic_energy(ac_mass, v_is[0])
    impact_ke_g = velocity_to_kinetic_energy(ac_mass, v_is[1])
    res = fm.transform(strike_grid, impact_ke=impact_ke_g) + fm.transform(
        strike_grid, impact_ke=impact_ke_b)
    return res
    def test_kinetic_energy_multiple_vect(self):
        mass = 2
        vel = np.array([[3, 5, 8, 7], [4, 12, 15, 24]])

        out = velocity_to_kinetic_energy(mass, vel)

        np.testing.assert_equal(out, np.array([5**2, 13**2, 17**2, 25**2]))
    def test_kinetic_energy_single_vect(self):
        mass = 2
        vel = np.array([[3], [4]])

        out = velocity_to_kinetic_energy(mass, vel)

        np.testing.assert_equal(out, 25)
    def test_kinetic_energy_multiple_scalar(self):
        mass = 2
        vel = np.linspace(5, 20, 4)

        out = velocity_to_kinetic_energy(mass, vel)

        np.testing.assert_array_equal(out, np.array([25, 100, 225, 400]))
    def test_kinetic_energy_single_scalar(self):
        mass = 2
        vel = 5

        out = velocity_to_kinetic_energy(mass, vel)

        self.assertEqual(out, 25)
        def wrap_pipeline(path_point_state):
            impact_pdf = point_distr(path_point_state)
            impact_vel = dists_for_hdg[path_point_state[2]][2]
            impact_angle = dists_for_hdg[path_point_state[2]][3]
            impact_ke = velocity_to_kinetic_energy(ac_mass, impact_vel)

            strike_pdf = sm.transform(impact_pdf, impact_angle=impact_angle)
            fatality_pdf = fm.transform(strike_pdf, impact_ke=impact_ke)

            return fatality_pdf, fatality_pdf.max(), strike_pdf.max()
    def test_full_risk_map(self):

        bm = BallisticModel(self.aircraft)
        gm = GlideDescentModel(self.aircraft)
        fm = FatalityModel(0.3, 1e6, 34)
        ac_mass = self.aircraft.mass

        x, y = np.mgrid[0:self.raster_shape[0], 0:self.raster_shape[1]]
        eval_grid = np.vstack((x.ravel(), y.ravel())).T

        samples = 5000
        # Conjure up our distributions for various things
        alt = ss.norm(self.alt, 5).rvs(samples)
        vel = ss.norm(self.vel, 2.5).rvs(samples)
        wind_vels = ss.norm(self.wind_vel, 1).rvs(samples)
        wind_dirs = bearing_to_angle(
            ss.norm(self.wind_dir, np.deg2rad(5)).rvs(samples))
        wind_vel_y = wind_vels * np.sin(wind_dirs)
        wind_vel_x = wind_vels * np.cos(wind_dirs)

        (bm_mean,
         bm_cov), v_ib, a_ib = bm.transform(alt, vel,
                                            ss.uniform(0, 360).rvs(samples),
                                            wind_vel_y, wind_vel_x, 0, 0)
        (gm_mean,
         gm_cov), v_ig, a_ig = gm.transform(alt, vel,
                                            ss.uniform(0, 360).rvs(samples),
                                            wind_vel_y, wind_vel_x, 0, 0)
        sm_b = StrikeModel(self.raster_grid, self.resolution**2,
                           self.aircraft.width, a_ib)
        sm_g = StrikeModel(self.raster_grid, self.resolution**2,
                           self.aircraft.width, a_ig)
        premult = sm_b.premult_mat + sm_g.premult_mat

        offset_y, offset_x = self.raster_shape[0] // 2, self.raster_shape[
            1] // 2
        bm_pdf = ss.multivariate_normal(
            bm_mean + np.array([offset_y, offset_x]), bm_cov).pdf(eval_grid)
        gm_pdf = ss.multivariate_normal(
            gm_mean + np.array([offset_y, offset_x]), gm_cov).pdf(eval_grid)
        pdf = bm_pdf + gm_pdf
        pdf = pdf.reshape(self.raster_shape)

        padded_pdf = np.zeros(
            ((self.raster_shape[0] * 3) + 1, (self.raster_shape[1] * 3) + 1))
        padded_pdf[self.raster_shape[0]:self.raster_shape[0] * 2,
                   self.raster_shape[1]:self.raster_shape[1] * 2] = pdf
        padded_pdf = padded_pdf * self.event_prob
        padded_centre_y, padded_centre_x = self.raster_shape[
            0] + offset_y, self.raster_shape[1] + offset_x
        impact_ke_b = velocity_to_kinetic_energy(ac_mass, v_ib)
        impact_ke_g = velocity_to_kinetic_energy(ac_mass, v_ig)

        # Check if CUDA toolkit available through env var otherwise fallback to CPU bound numba version
        if not os.getenv('CUDA_HOME'):
            print('CUDA NOT found, falling back to Numba JITed CPU code')
            # Leaving parallelisation to Numba seems to be faster
            res = wrap_all_pipeline(self.raster_shape, padded_pdf,
                                    padded_centre_y, padded_centre_x, premult)

        else:

            res = np.zeros(self.raster_shape, dtype=float)
            threads_per_block = (32, 32)  # 1024 max per block
            blocks_per_grid = (int(
                np.ceil(self.raster_shape[1] / threads_per_block[1])),
                               int(
                                   np.ceil(self.raster_shape[0] /
                                           threads_per_block[0])))
            print('CUDA found, using config <<<' + str(blocks_per_grid) + ',' +
                  str(threads_per_block) + '>>>')
            wrap_pipeline_cuda[blocks_per_grid,
                               threads_per_block](self.raster_shape,
                                                  padded_pdf, padded_centre_y,
                                                  padded_centre_x, premult,
                                                  res)

        # Alternative joblib parallelisation
        # res = jl.Parallel(n_jobs=-1, prefer='threads', verbose=1)(
        #     jl.delayed(wrap_row_pipeline)(c, self.raster_shape, padded_pdf, (padded_centre_y, padded_centre_x), sm)
        #     for c in range(self.raster_shape[0]))

        strike_pdf = res
        # snapped_points = [snap_coords_to_grid(self.raster_indices, *coords) for coords in self.path_coords]

        import matplotlib.pyplot as mpl
        import matplotlib.colors as mc
        fig1, ax1 = mpl.subplots(1, 1)
        m1 = ax1.matshow(self.raster_grid, norm=mc.LogNorm())
        fig1.colorbar(m1, label='Population Density [people/km$^2$]')
        ax1.set_title(f'Population Density at t={self.hour}')
        ax1.set_xticks([0, self.raster_shape[1] - 1])
        ax1.set_yticks([0, self.raster_shape[0] - 1])
        ax1.set_xticklabels(
            [self.test_bound_coords[0], self.test_bound_coords[2]], )
        ax1.set_yticklabels(
            [self.test_bound_coords[3], self.test_bound_coords[1]], )
        fig1.tight_layout()
        fig1.savefig(f'tests/layers/figs/tpe_t{self.hour}.png',
                     bbox_inches='tight')
        fig1.show()

        if self.serialise:
            np.savetxt(f'strike_map_t{self.hour}', strike_pdf, delimiter=',')

        fig2, ax2 = mpl.subplots(1, 1)
        m2 = ax2.matshow(strike_pdf)
        fig2.colorbar(m2, label='Strike Risk [h$^{-1}$]')
        ax2.set_title(f'Strike Risk Map at t={self.hour}')
        ax2.set_xticks([0, self.raster_shape[1] - 1])
        ax2.set_yticks([0, self.raster_shape[0] - 1])
        ax2.set_xticklabels(
            [self.test_bound_coords[0], self.test_bound_coords[2]], )
        ax2.set_yticklabels(
            [self.test_bound_coords[3], self.test_bound_coords[1]], )
        fig2.tight_layout()
        fig2.savefig(f'tests/layers/figs/risk_strike_t{self.hour}.png',
                     bbox_inches='tight')
        fig2.show()

        fatality_pdf = fm.transform(strike_pdf,
                                    impact_ke=impact_ke_g) + fm.transform(
                                        strike_pdf, impact_ke=impact_ke_b)
        if self.serialise:
            np.savetxt(f'fatality_map_t{self.hour}',
                       fatality_pdf,
                       delimiter=',')

        fig3, ax3 = mpl.subplots(1, 1)
        m3 = ax3.matshow(fatality_pdf)
        fig3.colorbar(m3, label='Fatality Risk [h$^{-1}$]')
        ax3.set_title(f'Fatality Risk Map at t={self.hour}')
        ax3.set_xticks([0, self.raster_shape[1] - 1])
        ax3.set_yticks([0, self.raster_shape[0] - 1])
        ax3.set_xticklabels(
            [self.test_bound_coords[0], self.test_bound_coords[2]], )
        ax3.set_yticklabels(
            [self.test_bound_coords[3], self.test_bound_coords[1]], )
        fig3.tight_layout()
        fig3.savefig(f'tests/layers/figs/risk_fatality_t{self.hour}.png',
                     bbox_inches='tight')
        fig3.show()

        import rasterio
        from rasterio import transform
        trans = transform.from_bounds(*self.test_bound_coords,
                                      *self.raster_shape)
        rds = rasterio.open(
            f'tests/layers/tiffs/fatality_risk_h{self.hour}.tif',
            'w',
            driver='GTiff',
            count=1,
            dtype=rasterio.float64,
            crs='EPSG:4326',
            transform=trans,
            compress='lzw',
            width=self.raster_shape[0],
            height=self.raster_shape[1])
        rds.write(fatality_pdf, 1)
        rds.close()