# Start at 1 so the bearing at t - 1 is available
# for i in range(1, n_samples):
for i in range(1, 100):
sample = test_data.iloc[i]
# Current location (x1, y1)
x = sample['x1_']
y = sample['y1_']
# Convert geographic coordinates to pixel coordinates
px, py = ~raster_transform * (x, y)
# Next step location (x2, y2)
x2 = sample['x2_']
y2 = sample['y2_']
# Convert geographic coordinates to pixel coordinates
px2, py2 = ~raster_transform * (x2, y2)
# The difference in x and y coordinates
d_x = x2 - x
d_y = y2 - y
# print('d_x and d_y are ', d_x, d_y) # Debugging
# Temporal covariates
hour_t2_sin = sample['hour_t2_sin']
hour_t2_cos = sample['hour_t2_cos']
yday_t2_sin = sample['yday_t2_sin']
yday_t2_cos = sample['yday_t2_cos']
# Bearing of previous step (t - 1)
bearing = sample['bearing_tm1']
# Hour of the day (for saving the plot)
hour_t2 = sample['hour_t2']
# Day of the year
yday = sample['yday_t2']
# Convert day of the year to month index
month_index = day_to_month_index(yday)
# print(month_index)
# Extract the subset of the covariates at the location of x1, y1
# NDVI
ndvi_subset, origin_x, origin_y = subset_raster(ndvi_landscape_norm[month_index,:,:],
x, y,
window_size,
raster_transform)
# Canopy cover
canopy_subset, origin_x, origin_y = subset_raster(canopy_landscape_norm,
x, y,
window_size,
raster_transform)
# Herbaceous vegetation
herby_subset, origin_x, origin_y = subset_raster(herby_landscape_norm,
x, y,
window_size,
raster_transform)
# Slope
slope_subset, origin_x, origin_y = subset_raster(slope_landscape_norm,
x, y,
window_size,
raster_transform)
# Location of the next step in local pixel coordinates
px2_subset = px2 - origin_x
py2_subset = py2 - origin_y
# print('px2_subset and py2_subset are ', px2_subset, py2_subset) # Debugging
# Extract the value of the covariates at the location of x2, y2
# value = ndvi_subset.detach().cpu().numpy()[(int(py2_subset), int(px2_subset))]
# Stack the channels along a new axis
x1 = torch.stack([ndvi_subset, canopy_subset, herby_subset, slope_subset], dim=0)
# Add a batch dimension (required to be the correct dimension for the model)
x1 = x1.unsqueeze(0)
# print(x1.shape)
# Convert lists to PyTorch tensors
hour_t2_sin_tensor = torch.tensor(hour_t2_sin).float()
hour_t2_cos_tensor = torch.tensor(hour_t2_cos).float()
yday_t2_sin_tensor = torch.tensor(yday_t2_sin).float()
yday_t2_cos_tensor = torch.tensor(yday_t2_cos).float()
# Stack tensors
x2 = torch.stack((hour_t2_sin_tensor.unsqueeze(0),
hour_t2_cos_tensor.unsqueeze(0),
yday_t2_sin_tensor.unsqueeze(0),
yday_t2_cos_tensor.unsqueeze(0)),
dim=1)
# print(x2)
# print(x2.shape)
# Put bearing in the correct dimension (batch_size, 1)
bearing = torch.tensor(bearing).float().unsqueeze(0).unsqueeze(0)
# print(bearing)
# print(bearing.shape)
# -------------------------------------------------------------------------
# Run the model
# -------------------------------------------------------------------------
model_output = model((x1, x2, bearing))
# -------------------------------------------------------------------------
# Habitat selection probability
# -------------------------------------------------------------------------
hab_density = model_output.detach().cpu().numpy()[0,:,:,0]
hab_density_exp = np.exp(hab_density)
# print(np.sum(hab_density_exp)) # Should be 1
# Store the probability of habitat selection at the location of x2, y2
# These probabilities are normalised in the model function
habitat_probs[i] = hab_density_exp[(int(py2_subset), int(px2_subset))]
# print('Habitat probability value = ', habitat_probs[i])
# -------------------------------------------------------------------------
# Movement probability
# -------------------------------------------------------------------------
move_density = model_output.detach().cpu().numpy()[0,:,:,1]
move_density_exp = np.exp(move_density)
# print(np.sum(move_density_exp)) # Should be 1
# Store the movement probability at the location of x2, y2
# These probabilities are normalised in the model function
move_probs[i] = move_density_exp[(int(py2_subset), int(px2_subset))]
# print('Movement probability value = ', move_probs[i])
# -------------------------------------------------------------------------
# Next step probability
# -------------------------------------------------------------------------
step_density = hab_density + move_density
step_density_exp = np.exp(step_density)
# print('Sum of step density exp = ', np.sum(step_density_exp)) # Won't be 1
step_density_exp_norm = step_density_exp / np.sum(step_density_exp)
# print('Sum of step density exp norm = ', np.sum(step_density_exp_norm)) # Should be 1
# Extract the value of the covariates at the location of x2, y2
next_step_probs[i] = step_density_exp_norm[(int(py2_subset), int(px2_subset))]
# print('Next-step probability value = ', next_step_probs[i])
# -------------------------------------------------------------------------
# Plot the next-step predictions
# -------------------------------------------------------------------------
# Plot the first few probability surfaces - change the condition to i < n_steps to plot all
if i < 3:
# Mask out bordering cells
hab_density_mask = hab_density * x_mask * y_mask
move_density_mask = move_density * x_mask * y_mask
step_density_mask = step_density * x_mask * y_mask
# Create a mask for the next step
next_step_mask = np.ones_like(hab_density)
next_step_mask[int(py2_subset), int(px2_subset)] = -np.inf
# Plot the outputs
fig_out, axs_out = plt.subplots(2, 2, figsize=(10, 8))
# Plot NDVI
im1 = axs_out[0, 0].imshow(ndvi_subset.numpy(), cmap='viridis')
axs_out[0, 0].set_title('NDVI')
fig_out.colorbar(im1, ax=axs_out[0, 0], shrink=0.7)
# Plot habitat selection log-probability
im2 = axs_out[0, 1].imshow(hab_density_mask * next_step_mask, cmap='viridis')
axs_out[0, 1].set_title('Habitat selection log-probability')
fig_out.colorbar(im2, ax=axs_out[0, 1], shrink=0.7)
# Movement density log-probability
im3 = axs_out[1, 0].imshow(move_density_mask * next_step_mask, cmap='viridis')
axs_out[1, 0].set_title('Movement log-probability')
fig_out.colorbar(im3, ax=axs_out[1, 0], shrink=0.7)
# Next-step probability
im4 = axs_out[1, 1].imshow(step_density_mask * next_step_mask, cmap='viridis')
axs_out[1, 1].set_title('Next-step log-probability')
fig_out.colorbar(im4, ax=axs_out[1, 1], shrink=0.7)
filename_covs = f'{output_dir}/id{buffalo_id}_step{i+1}_yday{yday}_hour{hour_t2}.png'
plt.tight_layout()
plt.savefig(filename_covs, dpi=600, bbox_inches='tight')
plt.show()
plt.close() # Close the figure to free memory