#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #load functions ---- #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ library(probGLS) library(GeoLight) library(readxl) #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #load meta data ---- #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ meta <- read_excel('meta.xlsx') #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #load light data ---- #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ setwd('raw data location') ll <- list.files(pattern="*driftadj.lux$") for(i in c(1:length(ll))){ lig <- read.table(ll[i],sep="\t",skip=19,header=T) colnames(lig) <- c('dtime','lig') lig$dtime <- as.POSIXct(strptime(lig$dtime, format="%d/%m/%Y %H:%M:%S"), tz="UTC") trn <- twilightCalc(lig$dtime,lig$lig,ask=F,LightThreshold = 2) trn <- trn[trn$type>0,] trn$id <- substr(ll[i],1,4) if(i==1) trn2 <- trn else trn2 <- rbind(trn2,trn) } trn2$daylength <- abs(as.numeric(difftime(trn2$tFirst, trn2$tSecond, units="hours"))) trn2 <- trn2[trn2$daylength < 24,] #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #load sensor data ---- #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # mode 9 # wet/dry every 6 sec and length recorded at every switch # full light range every 5 min setwd('raw data location') aa <- list.files(pattern="*driftadj.deg$") tt <- list.files(pattern="*.sst$") for( i in c(1:length(aa))){ ad <- read.table(aa[i],sep="\t",skip=19,header=T) ad$dtime <- as.POSIXct(strptime(ad[,1], format = "%d/%m/%Y %H:%M:%S"),tz='UTC') ad$date <- as.Date(ad$dtime) ad$id <- substr(aa[i],1,4) ad <- ad[ad$dtime >= meta$Deployed[meta$GLS_id==substr(aa[i],2,4)] & ad$dtime <= meta$Retrieved[meta$GLS_id==substr(aa[i],2,4)],] ad$WetDryState <- ad[,2]/60/60 ad <- ad[ad$wet.dry=="wet",] td <- read.csv(tt[i],sep="\t",skip=19,header=T) td$dtime <- as.POSIXct(strptime(td[,1], format = "%d/%m/%Y %H:%M:%S"),tz='UTC') td$date <- as.Date(td$dtime) sensor <- sst_deduction(datetime = td$dtime,temp = td[,4]) sensor$doy <- as.numeric(strftime(sensor$date, format = "%j")) sensor$month <- as.numeric(strftime(sensor$date, format = "%m")) sensor$year <- as.numeric(strftime(sensor$date, format = "%Y")) sensor$jday <- as.numeric(julian(sensor$date)) sensor$id <- substr(aa[i],1,4) if(i==1) act <- ad else act <- rbind(act,ad) if(i==1) sen <- sensor else sen <- rbind(sen,sensor) } #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #load GPS data ---- #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ setwd('gps data location') gps <- read.csv('gps.csv') gps$dtime <- as.POSIXct(strptime(paste(gps$Date,gps$Time,sep=" "),'%d/%m/%Y %H:%M:%S'),tz="UTC") gps$lon <- gps$Longitude gps$lat <- gps$Latitude for( i in c(1:length(ll))){ start <- meta$Deployed[i] end <- meta$Retrieved[i] id <- paste('P',meta$GLS_id[i],sep="") gps$id [gps$dtime >= start & gps$dtime <= end & gps$Id == meta$Darvic[i]] <- id gps$i [gps$dtime >= start & gps$dtime <= end & gps$Id == meta$Darvic[i]] <- i gps$i.id[gps$dtime >= start & gps$dtime <= end & gps$Id == meta$Darvic[i]] <- paste(gps$i[gps$dtime >= start & gps$dtime <= end & gps$Id == meta$Darvic[i]],gps$id[gps$dtime >= start & gps$dtime <= end & gps$Id == meta$Darvic[i]],sep='.') } gps <- gps[!is.na(gps$i.id),] rm(co,ad,sensor,td,temp,trn,lig) rm(end,i,id,ll,start,tt,aa) #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #run model with 200 iterations and 1 to 10 000 particles ---- #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ tw <- twilight_error_estimation() for(part in c(1,5,10,20,40,60,80,100,200,300,400,500,600,800,1000,1250,1500,2000,3000,4000,5000,10000)){ for(i in c(1:nrow(meta))){ start <- meta$Last_fix_colony[i] end <- meta$first_fix_colony[i] id <- paste('P',meta$GLS_id[i],sep="") trn <- trn2[trn2$id==id,] sensor <- sen[sen$id==id,] trn <- trn[trn$tFirst > (start) & trn$tSecond < (end),] if(nrow(trn)>1){ trn$id <- id trn$i <- i trn$i.id <- paste(trn$i,trn$id,sep='.') sensor <- sensor[sensor$date >= as.Date(start) & sensor$date <= as.Date(end),] sensor$id <- id sensor$i <- i sensor$i.id <- paste(sensor$i,sensor$id,sep='.') act2 <- act[act$id==id,] act2$i <- i act2$i.id <- paste(act2$i,act2$id,sep='.') mm.list <- prob_algorithm(particle.number = part, iteration.number = 200, trn = trn, sensor = sensor, act = act2, loess.quartile = NULL, sunrise.sd = tw, sunset.sd = tw, tagging.location = c(-36.816,-54.316), tagging.date = start, retrieval.date = end, speed.wet = c(1,1.3,5), speed.dry = c(12,6,45), boundary.box = c(-120,40,-90,0), days.around.spring.equinox = c(20,20), days.around.fall.equinox = c(20,20), ice.conc.cutoff = 1.1, land.mask = T, med.sea = F, black.sea = F, baltic.sea = F, caspian.sea = F, wetdry.resolution = 1) # all computed tracks newt2 <- mm.list[[1]] newt2$id <- id newt2$i <- i newt2$i.id <- paste(newt2$i,newt2$id,sep='.') if(i==1) newt3 <- newt2 else newt3 <- spRbind(newt3,newt2) } } newt3$available.particles <- part if(part==1) newt4 <- newt3 else newt4 <- spRbind(newt4,newt3) } # dataframe containing all computed tracks for each individual using 200 iterations and 1 to 10 000 particles newt4 <- data.frame(newt4) newt4$identity <- paste(newt4$available.particles, newt4$step, newt4$i.id, sep=".") #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #calculate distance for each set of tracks using 1 to 200 #iterations to compute the geographic median track ---- #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ for(vb in c(1,5,10,15,seq(20,200,20))){ nat <- newt4[newt4$bootstrap %in% c(1:vb),] print(vb) nag2 <- NULL for(g in c(1:length(unique(nat$identity)))){ print(paste(g,length(unique(nat$identity)),sep=" / ")) identity <- unique(nat$identity)[g] nat2 <- nat[nat$identity == identity,] # create new median location with available bootstraps newt2 <- nat2 sf <- data.frame(spDists(as.matrix(newt2[,1:2],ncol=2),longlat=T),ncol=length(newt2$step)) sa <- data.frame(sum.dist=rowMeans(sf),bot=seq(1,length(newt2$step),1)) gmp <- newt2 [sa$sum.dist==min(sa$sum.dist),] [1,] gmp$median.sat.sst <- median(newt2$sat.sst) gmp$median.sun.elev <- median(newt2$sun.elev) gmp$median.wrel <- median(newt2$wrel) nag <- gmp nag$gps.lon.mean <- NA nag$gps.lat.mean <- NA nag$mean.median.distance <- NA nag$mean.distance <- NA nag$wrel.median <- median(nat$wrel[nat$identity==identity],na.rm=T) nag$wrel.mean <- mean (nat$wrel[nat$identity==identity],na.rm=T) nag$wrel.sd <- sd (nat$wrel[nat$identity==identity],na.rm=T) nag$wrel.chosen <- nag$wrel if(g==1){ nag.empty <- nag nag.empty$lon <- NA } # check if any GPS position for this time and id are available gps3b <- gps[gps$dtime >= nag$tFirst-1800 & gps$dtime <= nag$tSecond+1800 & gps$i.id==nag$i.id,] gps3b <- gps3b[!is.na(gps3b$lon),] gps3c <- gps3b gps3c <- gps3c[!is.na(gps3c$lon),] if(nrow(gps3b)>0){ nag$gps.lon.mean <- mean(gps3c$lon) nag$gps.lat.mean <- mean(gps3c$lat) nag$mean.median.distance <- spDistsN1(matrix(c(nag$gps.lon.mean,nag$gps.lat.mean),ncol=2),matrix(c(nag$lon,nag$lat),ncol=2),longlat=T) nag$mean.distance <- min(spDistsN1(matrix(c(nat2$lon,nat2$lat),ncol=2),matrix(c(nag$gps.lon.mean,nag$gps.lat.mean),ncol=2),longlat=T))[1] if(is.null(nag2)==T) nag2 <- nag else nag2 <- rbind(nag2,nag) } else { nag <- nag.empty} } nag2$daylength <- abs(as.numeric(difftime(nag2$tFirst, nag2$tSecond, units="hours"))) nag2$sst.used <- 0 nag2$sst.used[!is.na(nag2$sst.diff)] <- 1 nag2$available.bootstraps <- vb if(vb == 1) nag3 <- nag2 else nag3 <- rbind(nag3,nag2) } ### nag3 is a dataframe containing all distance measurements for the geopgraphic ### median track as well as the closest location to each average GPS location for all ### tracks computed with a range of particles and iterations