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
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
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()