Getting Started With Mimas
Published:
Getting Started with MIMAS
Ben Tonelli
2023-07-19
Introduction
What is MIMAS?
Models for the Individual Movements of Avian Species (MIMAS) is a tool to create realistic models of bird movements across the annual cycle. MIMAS relies on individual-based models (IBMs), simulating the movement of individual birds as they move between breeding and wintering sites. MIMAS was built so that other scientists and practitioners can train and use models to answer questions related to bird behavior and broader ecological questions. You can read more about MIMAS in Tonelli et. al, 2023, MEE.
How is MIMAS used to get species-specific models?
MIMAS relies on eBird Status and Trends relative abundance maps to train species-specific IBMs. How MIMAS does this is a longer discussion (see the paper), but the quick version is that MIMAS tries lots of different possible bird behavioral traits that could explain population-scale patterns by running tons of simulations, and then saves simulations that best match relative abundance patterns from eBird Status and Trends.
The output of the MIMAS training process is a collection of thousands of parameter sets for species of interest, which can then be used downstream (by people like you!) to run new simulations. Having lots of parameter sets accounts for the uncertainty surrounding the behavioral traits that govern migration.
MIMAS is currently trained for 10 species, listed below. The tutorial will only work (at present) for these 10 species. If there are other species that you are interested in seeing added to this list, please fill out this form, or contact me directly.
- Brewer’s Sparrow (Spizella breweri)
- Bullock’s Oriole (Icterus bullockii)
- Clay-colored Sparrow (Spizella pallida)
- Hooded Warbler (Setophaga citrina)
- Orchard Oriole (Icterus spurius)
- Red-naped Sapsucker (Sphyrapicus nuchalis)
- Townsend’s Warbler (Setophaga townsendi)
- Varied Thrush (Ixoreus naevius)
- Wood Thrush (Hylocichla mustelina)
- Yellow-bellied Sapsucker (Sphyrapicus varius)
What can MIMAS do for you?
Likely the most useful application of MIMAS is estimating migratory routes of individual birds of a given species. Running a simulation will give you the daily locations of a bunch of birds throughout the year. Below is a short walkthrough of how to get set up so that you can run simulations and extract information from those simulations.
If this code is too complex or daunting for you to tackle, but you are interested in using these models for your research, please don’t hesitate to reach out to me directly: btonelli (at) ucla [dot] edu. I would love to hear from you! Similarly, if something doesn’t work with this tutorial, please let me know!
MIMAS Vignette
Step 1: Download MIMAS data, set working directory
To download MIMAS, you’ll need to navigate to the github page and download it as a ZIP file (or at least, that’s the easiest way to get it).
Once you have it, you can open up the R project in R studio. Make sure your working directory is set to the MIMAS folder.
Step 2: Download eBird ST data
To run the simulations, MIMAS IBMs need the eBird relative abundance of a species at the breeding and wintering grounds. This will give the IBMs the range information necessary to run the simulations. This will take about 20 minutes to do for each species. I’m sorry I can’t provide this directly - if I did, I think Big Brother (Cornell Lab of Ornithology) would sue me!
# Load the eBirdST and other necessary packages (make sure to install, if you don't have these already)
library(ebirdst)
library(raster)
library(sf)
library(lubridate)
library(readr)
library(dplyr)
#Get MIMAS functions
source(file = "scripts/sim_functions/sim_funct.R")
# Now we can download the breeding and wintering relative abundance maps for a particular species of interest from eBird
# We don't want the error maps used for model training, so we can set the "with_error_maps" function to FALSE
# Be warned - this will take ~20 minutes to download and process all the data.
# Luckily, you only need to do this once (for each species, that is!)
spec_to_download <- "Townsend's Warbler"
if(file.exists(paste("data/species_maps/breeding/",gsub(" ", "_", spec_to_download),"_breeding_all",sep="",".csv"))){
print("You are good to go!")
} else {
get_spec_maps(spec_to_download,with_error_maps = FALSE)
}
Step 3: Run a simulation
OK, now that the simulation has all the data it needs, we can run a simulation
# Load necessary packages (make sure to install, if you don't have these already)
library(ebirdst)
library(lubridate)
library(geosphere)
library(dplyr)
library(truncnorm)
library(sf)
library(spData)
#Read in functions (you may have just done this in the last code block)
source(file = "scripts/sim_functions/sim_funct.R")
#Define species
species_target <- "Townsend's Warbler"
# Read in parameter set of trained simulations. Make sure to check out which species
# have trained models. Also note these use species 4-letter codes.
param_set <- readRDS("data/output/Spec_IBM_output/TOWA_9_20_22/TOWA_best.rds")
# Check out the structure of this data frame: each row is an accepted simulation
# Each row is a parameter value.
head(param_set[,1:10])
## X speed_mean_s speed_sd_s speed_mean_f speed_sd_f start_date_u_s
## 35 err_add.34 366.6116 114.3894 264.9069 147.68078 108.8201
## 44 err_add.43 496.0171 186.0010 134.4196 213.81981 102.0622
## 85 err_add.84 590.4652 428.0007 263.8382 38.57714 104.7679
## 90 err_add.89 586.8561 179.7476 231.9514 185.53872 113.7986
## 137 err_add.36 344.9553 348.2315 144.4236 201.51000 104.1346
## 161 err_add.60 578.2226 116.5893 188.7008 93.13021 103.7410
## start_date_sd_s start_date_u_f start_date_sd_f max_mig_time_s
## 35 9.062488 241.5033 16.32981 150
## 44 21.575423 242.5887 17.98947 150
## 85 15.567748 244.3561 11.47185 150
## 90 10.990954 235.9102 18.57646 150
## 137 13.310079 238.1036 17.74258 150
## 161 16.001086 240.8870 19.47620 150
# We are going to pull one of these simulations/parameter sets at random to use,
# and we are going to save these to the environment
rand_sim <- sample(1:nrow(param_set),1)
for (each_var in 1:ncol(param_set)){
assign(colnames(param_set)[each_var],param_set[rand_sim,each_var])
}
#Set number of birds to include in simulation, 1000 birds is a reasonable starting point
num_pulls <- 1000
#Set number of days to run the simulation for.
num_days <- 365
#Import breeding, non-breeding maps
breeding_file <- read.csv(paste("data/species_maps/breeding/",gsub(" ","_",species_target),"_breeding_all.csv",sep=""))
nonbreeding_file <- read.csv(paste("data/species_maps/non_breeding/",gsub(" ","_",species_target),"_non_breeding_all.csv",sep=""))
#Define starting season, leave this at 1 (breeding season)
season <- 1
#We will set the start date as the midpoint of the breeding season.
start_date <- (ebirdst_runs[which(ebirdst_runs$common_name==species_target),7:8])
start_date <- as.numeric(start_date[1] + (start_date[2]-start_date[1])/2)
start_date <- yday(as.Date(start_date,origin = "1970-01-01"))
acceptable_week_dates <- seq(1,365,by=7)
start_date <- acceptable_week_dates[which(abs(acceptable_week_dates - start_date) == min(abs(acceptable_week_dates - start_date)))]
#Initialize model using parameters pulled above
initial_dfs <- initialize_MIBM(num_pulls,breeding_file,nonbreeding_file,speed_mean_s,
speed_sd_s,speed_mean_f,speed_sd_f,start_date_u_s,
start_date_sd_s,start_date_u_f,start_date_sd_f,
max_mig_time_s,max_mig_time_f,bear_err_mean_s,
bear_err_sd_s,bear_err_mean_f,bear_err_sd_f,
max_energy_s,max_energy_f,recovery_rate_s,
recovery_rate_f,season,start_date,goal_radius,
mig_con,migr_timing_lat_s,migr_timing_lat_f)
# The IBMs rely on two dataframes - one that stays the same (Static) and the other
# that updates based on the location, status of individual birds
static_df <- initial_dfs[[1]]
upd_df <- initial_dfs[[2]]
#Set up a dataframe to record the locations of birds on each day
locs_rec <- as.data.frame(matrix(NA,ncol = 5,nrow = (num_days*num_pulls)))
colnames(locs_rec) <- c("ID","Lon","Lat","Day","Season")
# Run the simulation for the prescribed amount of time, saving the locations each day
for (days in 1:num_days){
upd_df <- run_day(upd_df,static_df)
locs <- save_locations(upd_df,save_season = TRUE)
loc_ind_s <- (days - 1)*num_pulls + 1
loc_ind_e <- (days - 1)*num_pulls + num_pulls
locs_rec[loc_ind_s:loc_ind_e,] <- locs
}
#See the structure of the saved data
head(locs_rec)
## ID Lon Lat Day Season
## 1 1 -123.9120 53.77182 184 1
## 2 2 -121.2808 46.35489 184 1
## 3 3 -120.8402 49.07585 184 1
## 4 4 -115.8017 48.06861 184 1
## 5 5 -116.7225 50.14089 184 1
## 6 6 -134.0118 58.12379 184 1
Using simulation data
So now we have the locations of each simulated bird on each day. We can see what this looks like for a single bird. This code will plot species locations colored by season, with species.
library(dplyr)
library(ggplot2)
single_bird <- locs_rec %>% filter(ID == 1)
countries <- map_data("world")
states <- map_data("state")
countries <- countries %>% filter(long < -32)
p <- ggplot() + coord_map("mollweide",xlim=c(-130,-80),ylim=c(15,70)) +
geom_polygon(data=countries, aes(x=long, y=lat, group=group), fill="grey90", color="darkgrey") +
geom_polygon(data=states, aes(x=long, y=lat, group=group), fill="grey90", color="darkgrey") +
geom_point(data=single_bird,aes(x=Lon,y=Lat,col=as.factor(Season))) +
scale_colour_manual(values=c("firebrick3","goldenrod2","skyblue3","seagreen"),
labels=c("Breeding","Post-breeding migration","Wintering","Pre-breeding migration")) +
theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank()) +
theme(axis.ticks.x = element_blank(),axis.text.x = element_blank(),
axis.ticks.y = element_blank(),axis.text.y = element_blank(),
axis.title.x=element_blank(),axis.title.y=element_blank(),
plot.margin = unit(c(0, 0, 0, 0), "null"),
panel.spacing = unit(c(0, 0, 0, 0), "null"),
legend.title=element_blank()) +
theme(panel.background = element_rect(fill = alpha("lightskyblue2",.5)))
print(p)
There are many potential uses for MIMAS, some of which I’ve outlined below.
- Estimating behavioral traits of migrants (e.g. flight speed, migration length, stopover behavior, etc.)
- Measuring likely migratory routes/timing based on breeding or wintering locations.
- Simulation of ecological interactions, suh as dispersal of parasites and pathogens.
My hope is that others will use these models to further their own own research and expand the list of applications for MIMAS! If you have any questions/comments/concerns/ideas for collaboration I would appreciate hearing from you!