set.seed(123)
Parts of this code take time to run, so if you want to go through examples fast and do not want to install all the software
Run_everything=FALSE # Change to TRUE if you want run everything by your computer
This script can operate with online or local data. If Use_local_data is set to TRUE the working directory expected to have folders data. If Run_everything is set to TRUE the results directory will be created and all the results will be saved there.
Use_local_data=FALSE # Change to TRUE if you want to use local data
if (Use_local_data) {
if (!'results' %in% list.dirs(full.names=FALSE, recursive=FALSE)) {
if (Run_everything) {
dir.create('results')
} else {
stop('results directory not found!')
}
}
if (!'data' %in% list.dirs(full.names=FALSE, recursive=FALSE)) stop('data directory not found!')
} else {
if (!'results' %in% list.dirs(full.names=FALSE, recursive=FALSE)) dir.create('results')
download.file('https://git.io/fAKZH', destfile='./results/Result.RDS', mode='wb')
download.file('https://git.io/fAK15', destfile='./results/Summary.RDS', mode='wb')
}
if (Use_local_data & !'data' %in% list.dirs(full.names=FALSE, recursive=FALSE)) stop('data directory not found')
Note that we used FLightR 0.4.7 version, and running this example in later versions may provide slightly different results. To install the latest CRAN version try
install.packages('FLightR')
To run version 0.4.7 which we use in this example try
library(devtools)
install_github('eldarrak/FLightR@0.4.7')
## Downloading GitHub repo eldarrak/FLightR@0.4.7
## from URL https://api.github.com/repos/eldarrak/FLightR/zipball/0.4.7
## Installation failed: 404: Not Found
## (404)
The latest version is available here:
install_github('eldarrak/FLightR')
Load package
library(FLightR)
The procedure of the definition of the twilight events, i.e. sunrises and sunsets, is not implemented in FLightR. For this purpose you can use other R packages, e.g. BAStag, twGeos or GeoLight Lisovski et al. 2012a, or online service http://tags.animalmigration.org. In this software, you will have to search for the twilight times semi-automatically and then visually explore the results, manually removing twilights defined obviously wrong or around which the light pattern is atypical or systematically biased, for instance, when a bird enters or exits a cavity during the twilight (Rakhimberdiev et al. 2016). An example of the routine for the twilight definition in BAStag is available as appendix A4 to Rakhimberdiev et al. 2016.
FLightR works with files of the ‘TAGS’ format, which are CSV files containing the following fields:
datetime – date and time in ISO 8601 format e.g. 2013-06-16T00:00:11.000Z;light – light value measured by tag;twilight – assigned by the software numeric indication of whether the record belongs to sunrise (1), sunset (2) or none of those (0);excluded – indication of whether a twilight was excluded during manual inspection (logical, TRUE | FALSE);interp - indication of whether the light value at twilight was interpolated (logical, TRUE | FALSE). The fields excluded and interp may have values of TRUE only for twilight > 0. The online service http://tags.animalmigration.org saves data in the TAGS format. In the R packages GeoLight and BAStag or twGeos, the annotated twilight data need to be exported to TAGS, for which the functions in the FLightR (GeoLight2TAGS, BAStag2TAGS or twGeos2TAGS) can be used.We will use the TAGS formatted data based on the original .lux file from Pedersen et al..
The original file is available here and the annotated file in tags format here.
The function get.tags.data reads comma separated file in the TAGS format, detects the tag type, checks whether the light data are log-transformed, transforms them back from the log scale if needed and creates an object, containing
The finction works with all the common tag types: mk tags (produced by British Antarctic Survey, Lotek, and Migrate Technology Ltd.), Intigeo tags (Migrate technology Ltd.) and GDL tags (Swiss Ornithological Institute).
if (Use_local_data) {
FLightR.data<-get.tags.data("./data/TAGS.M034_08jun15_135409driftadj.csv")
} else {
FLightR.data<-get.tags.data("https://git.io/fAoHs")
}
## Detected Intigeo_Mode_1 tag
## Data found to be logtransformed
## tag saved data every 300 seconds, and is assumed to measure data every 60 seconds, and write down max
Geolocators measure light levels with different precision, and calibration is needed to establish the relationship between the observed and the expected light levels for each device. This relationship is depicted by the calibration parameters (slopes), calculated using the data recorded in known (calibration) geographic positions, e.g. where the animal was tagged, recaptured or observed. FLightR uses a ‘template fit’ for calibration Ekstrom 2004, 2007. For each tag it finds the linear (on a log-log scale) relationship between the light levels measured in known locations and the theoretical light levels, estimated from current sun angle in these locations with the deterministic equation developed by Ekstrom Rakhimberdiev et al. 2015.
To calculate the calibration parameters user needs to create a data frame where the geographic coordinates of the calibration location, and the start and end dates of the calibration period, i. e. the period of residence in the known location, are specified: * calibration.start (POSIXct format) * calibration.stop (POSIXct format) * lon (numeric) * lat (numeric) The data frame contains as many rows as many distinct calibration periods the track contains.
Calibration.periods<-data.frame(
calibration.start=as.POSIXct(c(NA, '2015-05-15')),
calibration.stop=as.POSIXct(c('2014-07-15', NA)),
lon=12.23, lat=55.98)
#use c() also for the geographic coordinates,
#if you have more than one calibration location
# (e. g., lon=c(5.43, 6.00), lat=c(52.93,52.94))
print(Calibration.periods)
## calibration.start calibration.stop lon lat
## 1 <NA> 2014-07-15 12.23 55.98
## 2 2015-05-15 <NA> 12.23 55.98
** Please carefully look at the data.frame you have created!**
The first column should contain dates of the calibration start and the second - ends of the calibration periods.
In this example, we have two calibration periods in the same location, at the beginning and at the end of the track. This is a common case, as the birds are often recaptured at the same location, where they were tagged.
When multiple calibration locations are available, each of them has to be processed with the function plot_slopes_by_location. In this case, in the Calibration periods data frame, each row should refer to one calibration period. Compiling the data frame with multiple calibration locations, use c() also for the geographic coordinates (e. g., lon=c(5.43, 6.00), lat=c(52.93,52.94)).
A Calibration object is compiled with the functionmake.calibration from the created Calibration periods data frame and the FLightR.data object.
if (Run_everything) {
Calibration<-make.calibration(FLightR.data, Calibration.periods, model.ageing=TRUE)
} else {
Result<-readRDS(file='./results/Result.RDS')
Calibration<-Result[[3]]
rm(Result)
}
This object contains all the calibration parameters for the tag, and it will be further used for calculation of geographic positions across the track. When there are more than one calibration periods, the parameter model.ageing can be set TRUE to account for the tag ageing. In this case, the calibration parameters are calculated, based on the assumption that the calibration slope changes linearly with time. Alternatively, one can use one very long calibration period to try estimating ageing of the tag. We would reccommend to have at least two months in a known location to be able to do that.
The exact period of a tagged animal’s stay in a known location is usually unknown, but it can be derived from the data. For this, calibration slopes for the sunset and sunrise of each day of the tracking period are calculated, based on the assumption that the tag remained in the same known position all the time. The slopes are calculated and plotted with the function plot_slopes_by_location.
plot_slopes_by_location(Proc.data=FLightR.data, location=c(12.23, 55.98), ylim=c(-1.5, 1.5))
##
checking dawn 1
checking dawn 2
checking dawn 3
checking dawn 4
checking dawn 5
checking dawn 6
checking dawn 7
checking dawn 8
checking dawn 9
checking dawn 10
checking dawn 11
checking dawn 12
checking dawn 13
checking dawn 14
checking dawn 15
checking dawn 16
checking dawn 17
checking dawn 18
checking dawn 19
checking dawn 20
checking dawn 21
checking dawn 22
checking dawn 23
checking dawn 24
checking dawn 25
checking dawn 26
checking dawn 27
checking dawn 28
checking dawn 29
checking dawn 30
checking dawn 31
checking dawn 32
checking dawn 33
checking dawn 34
checking dawn 35
checking dawn 36
checking dawn 37
checking dawn 38
checking dawn 39
checking dawn 40
checking dawn 41
checking dawn 42
checking dawn 43
checking dawn 44
checking dawn 45
checking dawn 46
checking dawn 47
checking dawn 48
checking dawn 49
checking dawn 50
checking dawn 51
checking dawn 52
checking dawn 53
checking dawn 54
checking dawn 55
checking dawn 56
checking dawn 57
checking dawn 58
checking dawn 59
checking dawn 60
checking dawn 61
checking dawn 62
checking dawn 63
checking dawn 64
checking dawn 65
checking dawn 66
checking dawn 67
checking dawn 68
checking dawn 69
checking dawn 70
checking dawn 71
checking dawn 72
checking dawn 73
checking dawn 74
checking dawn 75
checking dawn 76
checking dawn 77
checking dawn 78
checking dawn 79
checking dawn 80
checking dawn 81
checking dawn 82
checking dawn 83
checking dawn 84
checking dawn 85
checking dawn 86
checking dawn 87
checking dawn 88
checking dawn 89
checking dawn 90
checking dawn 91
checking dawn 92
checking dawn 93
checking dawn 94
checking dawn 95
checking dawn 96
checking dawn 97
checking dawn 98
checking dawn 99
checking dawn 100
checking dawn 101
checking dawn 102
checking dawn 103
checking dawn 104
checking dawn 105
checking dawn 106
checking dawn 107
checking dawn 108
checking dawn 109
checking dawn 110
checking dawn 111
checking dawn 112
checking dawn 113
checking dawn 114
checking dawn 115
checking dawn 116
checking dawn 117
checking dawn 118
checking dawn 119
checking dawn 120
checking dawn 121
checking dawn 122
checking dawn 123
checking dawn 124
checking dawn 125
checking dawn 126
checking dawn 127
checking dawn 128
dawn 128 was excluded from the calibration
checking dawn 129
dawn 129 was excluded from the calibration
checking dawn 130
checking dawn 131
dawn 131 was excluded from the calibration
checking dawn 132
checking dawn 133
dawn 133 was excluded from the calibration
checking dawn 134
dawn 134 was excluded from the calibration
checking dawn 135
dawn 135 was excluded from the calibration
checking dawn 136
dawn 136 was excluded from the calibration
checking dawn 137
dawn 137 was excluded from the calibration
checking dawn 138
dawn 138 was excluded from the calibration
checking dawn 139
dawn 139 was excluded from the calibration
checking dawn 140
dawn 140 was excluded from the calibration
checking dawn 141
dawn 141 was excluded from the calibration
checking dawn 142
dawn 142 was excluded from the calibration
checking dawn 143
dawn 143 was excluded from the calibration
checking dawn 144
dawn 144 was excluded from the calibration
checking dawn 145
dawn 145 was excluded from the calibration
checking dawn 146
dawn 146 was excluded from the calibration
checking dawn 147
dawn 147 was excluded from the calibration
checking dawn 148
dawn 148 was excluded from the calibration
checking dawn 149
dawn 149 was excluded from the calibration
checking dawn 150
dawn 150 was excluded from the calibration
checking dawn 151
dawn 151 was excluded from the calibration
checking dawn 152
dawn 152 was excluded from the calibration
checking dawn 153
dawn 153 was excluded from the calibration
checking dawn 154
dawn 154 was excluded from the calibration
checking dawn 155
dawn 155 was excluded from the calibration
checking dawn 156
dawn 156 was excluded from the calibration
checking dawn 157
dawn 157 was excluded from the calibration
checking dawn 158
dawn 158 was excluded from the calibration
checking dawn 159
dawn 159 was excluded from the calibration
checking dawn 160
dawn 160 was excluded from the calibration
checking dawn 161
dawn 161 was excluded from the calibration
checking dawn 162
dawn 162 was excluded from the calibration
checking dawn 163
dawn 163 was excluded from the calibration
checking dawn 164
dawn 164 was excluded from the calibration
checking dawn 165
dawn 165 was excluded from the calibration
checking dawn 166
dawn 166 was excluded from the calibration
checking dawn 167
dawn 167 was excluded from the calibration
checking dawn 168
dawn 168 was excluded from the calibration
checking dawn 169
dawn 169 was excluded from the calibration
checking dawn 170
dawn 170 was excluded from the calibration
checking dawn 171
dawn 171 was excluded from the calibration
checking dawn 172
dawn 172 was excluded from the calibration
checking dawn 173
dawn 173 was excluded from the calibration
checking dawn 174
dawn 174 was excluded from the calibration
checking dawn 175
dawn 175 was excluded from the calibration
checking dawn 176
dawn 176 was excluded from the calibration
checking dawn 177
dawn 177 was excluded from the calibration
checking dawn 178
dawn 178 was excluded from the calibration
checking dawn 179
dawn 179 was excluded from the calibration
checking dawn 180
dawn 180 was excluded from the calibration
checking dawn 181
dawn 181 was excluded from the calibration
checking dawn 182
dawn 182 was excluded from the calibration
checking dawn 183
dawn 183 was excluded from the calibration
checking dawn 184
dawn 184 was excluded from the calibration
checking dawn 185
dawn 185 was excluded from the calibration
checking dawn 186
dawn 186 was excluded from the calibration
checking dawn 187
dawn 187 was excluded from the calibration
checking dawn 188
dawn 188 was excluded from the calibration
checking dawn 189
dawn 189 was excluded from the calibration
checking dawn 190
dawn 190 was excluded from the calibration
checking dawn 191
dawn 191 was excluded from the calibration
checking dawn 192
dawn 192 was excluded from the calibration
checking dawn 193
dawn 193 was excluded from the calibration
checking dawn 194
dawn 194 was excluded from the calibration
checking dawn 195
dawn 195 was excluded from the calibration
checking dawn 196
dawn 196 was excluded from the calibration
checking dawn 197
dawn 197 was excluded from the calibration
checking dawn 198
dawn 198 was excluded from the calibration
checking dawn 199
dawn 199 was excluded from the calibration
checking dawn 200
dawn 200 was excluded from the calibration
checking dawn 201
dawn 201 was excluded from the calibration
checking dawn 202
dawn 202 was excluded from the calibration
checking dawn 203
dawn 203 was excluded from the calibration
checking dawn 204
dawn 204 was excluded from the calibration
checking dawn 205
dawn 205 was excluded from the calibration
checking dawn 206
dawn 206 was excluded from the calibration
checking dawn 207
dawn 207 was excluded from the calibration
checking dawn 208
dawn 208 was excluded from the calibration
checking dawn 209
dawn 209 was excluded from the calibration
checking dawn 210
dawn 210 was excluded from the calibration
checking dawn 211
dawn 211 was excluded from the calibration
checking dawn 212
dawn 212 was excluded from the calibration
checking dawn 213
dawn 213 was excluded from the calibration
checking dawn 214
dawn 214 was excluded from the calibration
checking dawn 215
dawn 215 was excluded from the calibration
checking dawn 216
dawn 216 was excluded from the calibration
checking dawn 217
dawn 217 was excluded from the calibration
checking dawn 218
dawn 218 was excluded from the calibration
checking dawn 219
dawn 219 was excluded from the calibration
checking dawn 220
dawn 220 was excluded from the calibration
checking dawn 221
dawn 221 was excluded from the calibration
checking dawn 222
dawn 222 was excluded from the calibration
checking dawn 223
dawn 223 was excluded from the calibration
checking dawn 224
dawn 224 was excluded from the calibration
checking dawn 225
dawn 225 was excluded from the calibration
checking dawn 226
dawn 226 was excluded from the calibration
checking dawn 227
dawn 227 was excluded from the calibration
checking dawn 228
dawn 228 was excluded from the calibration
checking dawn 229
dawn 229 was excluded from the calibration
checking dawn 230
dawn 230 was excluded from the calibration
checking dawn 231
dawn 231 was excluded from the calibration
checking dawn 232
dawn 232 was excluded from the calibration
checking dawn 233
checking dawn 234
checking dawn 235
checking dawn 236
checking dawn 237
checking dawn 238
checking dawn 239
checking dawn 240
checking dawn 241
checking dawn 242
checking dawn 243
dawn 243 was excluded from the calibration
checking dawn 244
checking dawn 245
checking dawn 246
checking dawn 247
checking dawn 248
checking dawn 249
checking dawn 250
checking dawn 251
checking dawn 252
checking dawn 253
checking dawn 254
checking dawn 255
checking dawn 256
checking dawn 257
checking dawn 258
checking dawn 259
checking dawn 260
checking dawn 261
checking dawn 262
checking dawn 263
checking dawn 264
checking dawn 265
checking dawn 266
checking dawn 267
checking dawn 268
checking dawn 269
checking dawn 270
checking dawn 271
checking dawn 272
checking dawn 273
checking dawn 274
checking dawn 275
checking dawn 276
checking dawn 277
checking dawn 278
checking dawn 279
checking dawn 280
checking dawn 281
checking dawn 282
checking dawn 283
checking dawn 284
checking dawn 285
checking dawn 286
checking dawn 287
checking dawn 288
checking dawn 289
checking dawn 290
dawn 290 was excluded from the calibration
checking dawn 291
checking dawn 292
checking dawn 293
checking dawn 294
checking dawn 295
checking dawn 296
checking dawn 297
checking dawn 298
checking dawn 299
checking dawn 300
checking dawn 301
checking dawn 302
checking dawn 303
checking dawn 304
checking dawn 305
checking dawn 306
checking dawn 307
checking dawn 308
checking dawn 309
checking dawn 310
checking dawn 311
checking dawn 312
checking dawn 313
checking dawn 314
checking dawn 315
checking dawn 316
checking dawn 317
checking dawn 318
checking dawn 319
checking dawn 320
checking dawn 321
checking dawn 322
checking dawn 323
checking dawn 324
checking dawn 325
checking dawn 326
checking dawn 327
checking dawn 328
checking dawn 329
checking dawn 330
checking dawn 331
checking dawn 332
checking dawn 333
checking dawn 334
checking dawn 335
checking dawn 336
checking dawn 337
checking dawn 338
checking dawn 339
checking dawn 340
checking dawn 341
checking dawn 342
checking dawn 343
checking dawn 344
checking dawn 345
checking dawn 346
checking dusk 1
checking dusk 2
checking dusk 3
checking dusk 4
checking dusk 5
checking dusk 6
checking dusk 7
checking dusk 8
checking dusk 9
checking dusk 10
checking dusk 11
checking dusk 12
checking dusk 13
checking dusk 14
checking dusk 15
checking dusk 16
checking dusk 17
checking dusk 18
checking dusk 19
checking dusk 20
checking dusk 21
checking dusk 22
checking dusk 23
checking dusk 24
checking dusk 25
checking dusk 26
checking dusk 27
checking dusk 28
checking dusk 29
checking dusk 30
checking dusk 31
checking dusk 32
checking dusk 33
checking dusk 34
checking dusk 35
checking dusk 36
checking dusk 37
checking dusk 38
checking dusk 39
checking dusk 40
checking dusk 41
checking dusk 42
checking dusk 43
checking dusk 44
checking dusk 45
checking dusk 46
checking dusk 47
checking dusk 48
checking dusk 49
checking dusk 50
checking dusk 51
checking dusk 52
checking dusk 53
checking dusk 54
checking dusk 55
checking dusk 56
checking dusk 57
checking dusk 58
checking dusk 59
checking dusk 60
checking dusk 61
checking dusk 62
checking dusk 63
checking dusk 64
checking dusk 65
checking dusk 66
checking dusk 67
checking dusk 68
checking dusk 69
checking dusk 70
checking dusk 71
checking dusk 72
checking dusk 73
checking dusk 74
checking dusk 75
checking dusk 76
checking dusk 77
checking dusk 78
checking dusk 79
checking dusk 80
checking dusk 81
checking dusk 82
checking dusk 83
checking dusk 84
checking dusk 85
checking dusk 86
checking dusk 87
checking dusk 88
checking dusk 89
checking dusk 90
checking dusk 91
checking dusk 92
checking dusk 93
checking dusk 94
checking dusk 95
checking dusk 96
checking dusk 97
checking dusk 98
checking dusk 99
checking dusk 100
checking dusk 101
checking dusk 102
checking dusk 103
checking dusk 104
checking dusk 105
checking dusk 106
checking dusk 107
checking dusk 108
checking dusk 109
checking dusk 110
checking dusk 111
checking dusk 112
checking dusk 113
checking dusk 114
checking dusk 115
checking dusk 116
checking dusk 117
checking dusk 118
checking dusk 119
checking dusk 120
checking dusk 121
checking dusk 122
checking dusk 123
checking dusk 124
checking dusk 125
checking dusk 126
checking dusk 127
checking dusk 128
checking dusk 129
checking dusk 130
checking dusk 131
checking dusk 132
checking dusk 133
checking dusk 134
dusk 134 was excluded from the calibration
checking dusk 135
dusk 135 was excluded from the calibration
checking dusk 136
checking dusk 137
checking dusk 138
dusk 138 was excluded from the calibration
checking dusk 139
dusk 139 was excluded from the calibration
checking dusk 140
dusk 140 was excluded from the calibration
checking dusk 141
dusk 141 was excluded from the calibration
checking dusk 142
dusk 142 was excluded from the calibration
checking dusk 143
checking dusk 144
dusk 144 was excluded from the calibration
checking dusk 145
dusk 145 was excluded from the calibration
checking dusk 146
checking dusk 147
dusk 147 was excluded from the calibration
checking dusk 148
dusk 148 was excluded from the calibration
checking dusk 149
dusk 149 was excluded from the calibration
checking dusk 150
checking dusk 151
dusk 151 was excluded from the calibration
checking dusk 152
dusk 152 was excluded from the calibration
checking dusk 153
checking dusk 154
dusk 154 was excluded from the calibration
checking dusk 155
dusk 155 was excluded from the calibration
checking dusk 156
dusk 156 was excluded from the calibration
checking dusk 157
dusk 157 was excluded from the calibration
checking dusk 158
dusk 158 was excluded from the calibration
checking dusk 159
dusk 159 was excluded from the calibration
checking dusk 160
dusk 160 was excluded from the calibration
checking dusk 161
dusk 161 was excluded from the calibration
checking dusk 162
dusk 162 was excluded from the calibration
checking dusk 163
dusk 163 was excluded from the calibration
checking dusk 164
dusk 164 was excluded from the calibration
checking dusk 165
dusk 165 was excluded from the calibration
checking dusk 166
dusk 166 was excluded from the calibration
checking dusk 167
dusk 167 was excluded from the calibration
checking dusk 168
dusk 168 was excluded from the calibration
checking dusk 169
dusk 169 was excluded from the calibration
checking dusk 170
dusk 170 was excluded from the calibration
checking dusk 171
dusk 171 was excluded from the calibration
checking dusk 172
dusk 172 was excluded from the calibration
checking dusk 173
dusk 173 was excluded from the calibration
checking dusk 174
dusk 174 was excluded from the calibration
checking dusk 175
dusk 175 was excluded from the calibration
checking dusk 176
dusk 176 was excluded from the calibration
checking dusk 177
dusk 177 was excluded from the calibration
checking dusk 178
dusk 178 was excluded from the calibration
checking dusk 179
dusk 179 was excluded from the calibration
checking dusk 180
dusk 180 was excluded from the calibration
checking dusk 181
dusk 181 was excluded from the calibration
checking dusk 182
dusk 182 was excluded from the calibration
checking dusk 183
dusk 183 was excluded from the calibration
checking dusk 184
dusk 184 was excluded from the calibration
checking dusk 185
dusk 185 was excluded from the calibration
checking dusk 186
dusk 186 was excluded from the calibration
checking dusk 187
dusk 187 was excluded from the calibration
checking dusk 188
dusk 188 was excluded from the calibration
checking dusk 189
dusk 189 was excluded from the calibration
checking dusk 190
dusk 190 was excluded from the calibration
checking dusk 191
dusk 191 was excluded from the calibration
checking dusk 192
dusk 192 was excluded from the calibration
checking dusk 193
dusk 193 was excluded from the calibration
checking dusk 194
dusk 194 was excluded from the calibration
checking dusk 195
dusk 195 was excluded from the calibration
checking dusk 196
dusk 196 was excluded from the calibration
checking dusk 197
dusk 197 was excluded from the calibration
checking dusk 198
dusk 198 was excluded from the calibration
checking dusk 199
dusk 199 was excluded from the calibration
checking dusk 200
dusk 200 was excluded from the calibration
checking dusk 201
dusk 201 was excluded from the calibration
checking dusk 202
dusk 202 was excluded from the calibration
checking dusk 203
dusk 203 was excluded from the calibration
checking dusk 204
dusk 204 was excluded from the calibration
checking dusk 205
dusk 205 was excluded from the calibration
checking dusk 206
dusk 206 was excluded from the calibration
checking dusk 207
checking dusk 208
checking dusk 209
dusk 209 was excluded from the calibration
checking dusk 210
checking dusk 211
checking dusk 212
checking dusk 213
checking dusk 214
checking dusk 215
checking dusk 216
checking dusk 217
checking dusk 218
dusk 218 was excluded from the calibration
checking dusk 219
checking dusk 220
checking dusk 221
checking dusk 222
checking dusk 223
checking dusk 224
checking dusk 225
checking dusk 226
checking dusk 227
checking dusk 228
checking dusk 229
checking dusk 230
checking dusk 231
checking dusk 232
checking dusk 233
checking dusk 234
checking dusk 235
dusk 235 was excluded from the calibration
checking dusk 236
checking dusk 237
checking dusk 238
checking dusk 239
checking dusk 240
checking dusk 241
checking dusk 242
checking dusk 243
checking dusk 244
checking dusk 245
checking dusk 246
checking dusk 247
checking dusk 248
checking dusk 249
checking dusk 250
checking dusk 251
checking dusk 252
checking dusk 253
checking dusk 254
checking dusk 255
checking dusk 256
checking dusk 257
checking dusk 258
checking dusk 259
checking dusk 260
checking dusk 261
checking dusk 262
checking dusk 263
checking dusk 264
checking dusk 265
checking dusk 266
checking dusk 267
checking dusk 268
checking dusk 269
checking dusk 270
checking dusk 271
checking dusk 272
checking dusk 273
checking dusk 274
checking dusk 275
checking dusk 276
checking dusk 277
checking dusk 278
checking dusk 279
checking dusk 280
checking dusk 281
checking dusk 282
checking dusk 283
checking dusk 284
checking dusk 285
checking dusk 286
checking dusk 287
checking dusk 288
checking dusk 289
checking dusk 290
checking dusk 291
checking dusk 292
checking dusk 293
checking dusk 294
checking dusk 295
checking dusk 296
checking dusk 297
checking dusk 298
checking dusk 299
checking dusk 300
checking dusk 301
checking dusk 302
checking dusk 303
checking dusk 304
checking dusk 305
checking dusk 306
checking dusk 307
checking dusk 308
checking dusk 309
checking dusk 310
checking dusk 311
checking dusk 312
checking dusk 313
checking dusk 314
checking dusk 315
checking dusk 316
checking dusk 317
checking dusk 318
checking dusk 319
checking dusk 320
checking dusk 321
checking dusk 322
checking dusk 323
checking dusk 324
checking dusk 325
checking dusk 326
checking dusk 327
checking dusk 328
checking dusk 329
checking dusk 330
checking dusk 331
checking dusk 332
checking dusk 333
checking dusk 334
checking dusk 335
checking dusk 336
checking dusk 337
checking dusk 338
checking dusk 339
checking dusk 340
checking dusk 341
checking dusk 342
checking dusk 343
checking dusk 344
## calibration method used: parametric.slope
## NULL
abline(v=as.POSIXct("2015-05-15")) # end of first calibration period
abline(v=as.POSIXct("2014-07-15")) # start of the second calibration period
Looking at the plot, we can define the time periods, during which the tag resided in the calibration location (recall, that we assume that the tag remained in this location all the time). Because calibration slopes reflect the adequacy of the light level measured by the device, they vary little, in time and between sunsets and sunrises, as long as the tagged animal stays in the calibration location, but become apparently diverse, when it moves away from it. Both patterns are clearly distinguishable at the plot.
Play with abline() to find the proper boundaries for the calibration.
With the current tag it is a bit complicated to see the end of the calibration period and also the first arrival back to the calibration site. To solve the problem we have made two runs - first with the obcvious short calibration period:
Calibration.periods<-data.frame(
calibration.start=as.POSIXct(c(NA)),
calibration.stop=as.POSIXct(c("2014-07-07")),
lon=12.23, lat=55.98)
We ran the full estimation procedure with based on this short calibration. Looked at bird departure and arrival dates from and to breeding site (with simple plot_lon_lat(Result)), used these dates to create new calibration periods and to run the final analysis. If you will do the same, please note, that you should select edges of the calibration period on a safe side - at least 24 hours before the migration.
It may happen that an animal was tagged in the High Arctic under polar day conditions or that it moved far away from the capture site immedialtly after tagging and the roof-top calibration data are not available. Even in such cases it is still possibe to obtain calibration parameters for a resident period at unknown location. FLightR approach to this problem is similar to Hill-Ekstrom calibration Lisovski et al. 2012b implemented in GeoLight Lisovksi et al. 2012a. If bird is assumed to be resident at some period one can try:
# ~ 15 min run time
Location<-find.stationary.location(FLightR.data, '2014-09-05', '2014-10-07',
initial.coords=c(25, -10))
After 15 minutes the function will return geographic coordinates of the location for which the range of errors in slopes is minimal. User has to provide the initial coordinates, which should be within a few thousand kilometers from the hypothetical real location.
Note that this function is experimental and does not always produce meaningful results . Try it from different initial locations, and check whether it gets to the same result.
Before running the model you will have to make a scientific guess on where you expect your bird to fly and assign a spatial grid (50 X 50 km) with user-defined boundaries, within which your model will calculate probabilities of presence of the birds. The wider you set the grid boundaries,the longer will take the model to run. If you have set the boundaries too narrow, you will see it in the output map: the defined location points will bounce close to the grid boundaries (as in our example XXXX). In this case you will have to extend the grid and re-run the model.
To set up the grid use the function make.grid and define the boundaries: left, right. bottom and top. It is possible that your tagged animal cannot occur or stay between two subsequent twilights over particular areas, for example, over open water if it is a landbird or deep inland if it is a marine animal. In this case we recommend to apply additional parameters distance.from.land.allowed.to.use and distance.from.land.allowed.to.stay. Such restrictions will minimize the area processed and this way facilitate the analysis. Each of the parameters require a vector of two numbers: the minimal and the maximal distances (in km) from shoreline, at which the animal is allowed to occur/stay. The numbers can be negative. For instance, distance.from.land.allowed.to.stay=-30, will not allow your bird to stay further than 30 km inland from the shore. In our example we allow our shrike to fly over the water, but not further than 200 km offshore, and to be statuionary within 50 km from the land.
Grid<-make.grid(left=5, bottom=-33, right=50, top=60,
distance.from.land.allowed.to.use=c(-Inf, 200),
distance.from.land.allowed.to.stay=c(-Inf, 50))
The resulting
Grid is a matrix with the columns: lon (longitude), lat (latitude) and Stay (probability of stay). Grid cells that presumably cannot be visited by the animal are excluded from the data, while the locations at which an animal cannot be stationary are given a low probability of stay. The function produces a visual representation of the created grid with orange poins where the bird is allowed to be stationary and grey, where the bird can fly but not stay. Have a look at the figure and make sure it is correct. Using masks can side track model estimation to the local minima, and we recommend to initially run the model without the mask, enable the mask for the second run and visually compare the results to see if the model has converged to similar tracks.
At this stage, all the objects, created at earlier steps: the light data with the detected twilight events (FLightR.data), the spatial parameters (Grid), geographic coordinates of the initial location, where the tracking has started (start), and the calibration parameters (Calibration), are to be incorporated in one complex object , which will be used in the main run. Use the function make.prerun.object for the compilation. Using this function you can also change the priors for the movement model. For example we set M.mean parameter to 750 km, because we know that shrikes migrate fast and also because we have explored the results and figured out that average migration distance was actually 750 km.
if (Run_everything) {
# ~ 15 min run time
all.in<-make.prerun.object(FLightR.data, Grid, start=c(12.23, 55.98),
Calibration=Calibration, M.mean=750)
} else {
Result<-readRDS(file='./results/Result.RDS')
all.in<-Result[-c(5,6)]
rm(Result)
}
Once you have got the “run.particle.filter” running, expect your computer to be busy for about 45 minutes. During this time it will generate the model output (we will call it “Results”) containing: * a table of positions at each twilight ($Results$Quantiles), * statistics of the positions (mean, median values and credible intervals), * a table of parameters of the movement model ($Results$Movement.results), * posterior distribution of the parameters at every twilight ($Results$Points.rle) and * at every transition between twilights ($Results$Transitions.rle).
Within run.particle.filter, the following parameters can be defined: * nParticles - number of particles (we recommend to use 1e4 for test and 1e6 for the analysis); * threads - amount of parallel threads to use for the run default is -1 that means all available except one; * known.last - TRUE if you know that in the end of the logging period tag occurred in a known place (FALSE is the default option); * check.outliers – FALSE by default. Set it to TRUE if you wish on-the-fly outliers detection, highly recommended if the results have strong outliers. * b - the maximum distance allowed to be travelled between two subsequent twilights.
if (Run_everything) {
nParticles=1e6
Result<-run.particle.filter(all.in, threads=-1,
nParticles=nParticles, known.last=TRUE,
precision.sd=25, check.outliers=F,
b=1700)
saveRDS(Result, file='./results/Result.RDS')
} else {
Result<-readRDS(file='./results/Result.RDS')
}
After the results have been saved the first thing to do is to plot change of longitude and latitude over time. This is a very important graph.
plot_lon_lat(Result)
With this graph, please, carefully check whether: 1. Your track does not approach boundaries of the spatial grid you defined (you ave to keep those in mind assessing the graph). If this is the case, change spatial extend and rerun the analysis. 2. There are no sudden jumps that have no uncertainty measurements around them. These are likely outliers that should be excluded beforehands. 3. Presented by the model estiamates of time-periods spent by the bird at the calibration site match calibration periods assigned before the model run. If they do not, correct the calibration periods, redo the calibration and rerun the model. 4. There are no S-shape patterns in estimated latitude around equinox. Such patterns point at either incorrect calibration or very poor data. Try to improve your calibration periods or concider taking calibration data from another tag taken from the same species.
Note that however many times you will re-run the model with the same input parameters, you will never get the same output. Please, do not panic, as stochasticity of probabilities is an inherent feature of Bayesian analysis. Also, if you look closer at your results, you will notice that the outputs vary within each others’ standard errors.
FLightR is honest defining stopovers, which may seem a disappointing feature, but it makes us thinking. In general, geolocation analysis is all about how likely the bird was present in specific location at specific moment and how likely it was moving between two subsequent locations. It is not a problem when you work with long-distance migrants, such as bar-tailed godwit Rakhimberdiev et al. 2016, since it has very apparent stopover phases between apparent migration-flight bouts. However, many bird species migrate in little hops and literary stop “at every bush”. Here you can get rather messy results, due to the overlapping probability distributions. In any case, we recommend to play with the stopover probabilities by tweaking the cut-off probability parameter of 1stationary.migration.summary`. Recall that for each location and time moment the model generates a probability that the bird was moving to the next location. The cut-off probability is the minimal threshold probability of movement, at which we assume that the bird was actually moving. Depending on the assigned cut-off probability parameter, the model will consider the bird more or less likely to be stationary. In birds migrating in long leaps with few stops, defined stopovers are usually rather robust. However, in hopping migrants, probabilities of stopovers may vary, depending on the chosen cut-off probability parameter, which is a bad news if describing stopovers is the prior goal of your study. But, frankly speaking, what is stopover and does it exist in migrants moving in short hops? Presenting your results, you may arbitrarily choose the most adequate (repeatable) output and mention the cut-off probability, with which it was obtained. However, if you want to describe stopovers explicitly, you might want to present outputs obtained with several cut-off probability parameters and speculate about the variation. Most likely, some of your stopovers will be defined repeatedly with a range of cut-off parameters being assigned, and some will be less robust. Our shrike had rather distinct migration/stopover pattern. However, we get a slightly more stopovers with cut-off probabilities of 0.1 and 0.2.
To distinguish between the phases of movement and stationarity use the function stationary.migration.summary helps . The process usually takes around 15 minutes of computer time.
if (Run_everything) {
Summary<-stationary.migration.summary(Result, prob.cutoff = 0.2)
saveRDS(Summary, file='./results/Summary.RDS')
} else {
Summary<-readRDS(file='./results/Summary.RDS')
}
To visualise results of this function we will plot them on a map.
# Now we want to plot the detected stationary periods on a map
Summary$Stationary.periods$stopover_duration<-as.numeric(difftime(Summary$Stationary.periods$Departure.Q.50,Summary$Stationary.periods$Arrival.Q.50, units='days'))
# Now I want to select the periods which were >=2 days and
Main_stopovers<-Summary$Stationary.periods[is.na(Summary$Stationary.periods$stopover_duration) | Summary$Stationary.periods$stopover_duration>=2,]
# delete breeding season
Main_stopovers<-Main_stopovers[-which(is.na(Main_stopovers$stopover_duration)),]
Coords2plot<-cbind(Result$Results$Quantiles$Medianlat, Result$Results$Quantiles$Medianlon)
for (i in 1:nrow(Summary$Potential_stat_periods)) {
Coords2plot[Summary$Potential_stat_periods[i,1]:
Summary$Potential_stat_periods[i,2],1] =
Summary$Stationary.periods$Medianlat[i]
Coords2plot[Summary$Potential_stat_periods[i,1]:
Summary$Potential_stat_periods[i,2],2] =
Summary$Stationary.periods$Medianlon[i]
}
Coords2plot<-Coords2plot[!duplicated(Coords2plot),]
library(maps)
library(mapdata)
#pdf('FLightR_shrike_migration_with_stopovers.pdf', width=6, height=9)
par(mar=c(0,0,0,0))
map('worldHires', ylim=c(-35, 60), xlim=c(-20, 50), col=grey(0.7),
fill=TRUE, border=grey(0.9), mar=rep(0.5, 4), myborder=0)
lines(Coords2plot[,1]~Coords2plot[,2], col='red', lwd=2)
points(Coords2plot[,1]~Coords2plot[,2], ,lwd=2, col='red', pch=19)
# Here we assign the colours to represent time of the year
Seasonal_palette<-grDevices::colorRampPalette(grDevices::hsv(1-((1:365)+(365/4))%%365/365,
s=0.8, v=0.8), space="Lab")
Seasonal_colors<-Seasonal_palette(12)
Main_stopovers$Main_month<-as.numeric(format(Main_stopovers$Arrival.Q.50+
Main_stopovers$stopover_duration/2, format='%m'))
points(Main_stopovers$Medianlat~Main_stopovers$Medianlon, pch=21,
cex=log(as.numeric(Main_stopovers$stopover_duration)),
bg=Seasonal_colors[Main_stopovers$Main_month])
# Now, for each of these points we plot the uncertainties
# Horizontal
segments(y0=Main_stopovers$Medianlat, x0=Main_stopovers$FstQu.lon,
x1=Main_stopovers$TrdQu.lon, lwd=2)
# Vertical
segments(x0=Main_stopovers$Medianlon, y0=Main_stopovers$FstQu.lat,
y1=Main_stopovers$TrdQu.lat, lwd=2)
# and we also need to add breeding site here:
points(x=12.23, y=55.98, cex=6, pch=21 , bg=Seasonal_colors[6])
# dev.off()
The function find.times.distribution derives the time at which an animal arrived or departed from the area and provides the measure of its uncertainty. First, select grid points of interest. For example in the current data we are interested in the date when our bird left from the breding grounds and when it was back. We will make a boundary at 55.5° latitude:
Index<-which(Result$Spatial$Grid[,2]>55)
Estimate probabilities of occurrence within the area at each twilight:
Arrivals.breeding<-find.times.distribution(Result,Index)
print(Arrivals.breeding)
## Q.025 Q.25 Q.50
## 1 2014-07-16 03:05:31 2014-07-22 20:57:33 2014-07-23 01:24:22
## 2 2015-05-12 08:51:25 2015-05-12 23:41:42 2015-05-13 06:19:53
## Q.75 Q.975
## 1 2014-07-23 04:50:07 2014-07-24 04:45:13
## 2 2015-05-20 17:56:25 2015-05-26 09:59:18
Plot a map with the most probable positions, i. e. combinations of the most probable latitude and longitude for each twilight:
library(grid)
try(map.FLightR.ggmap(Result, zoom=3))
## Source : https://maps.googleapis.com/maps/api/staticmap?center=15.975,28.351289&zoom=3&size=640x640&scale=2&maptype=terrain&language=en-EN
## Scale for 'x' is already present. Adding another scale for 'x', which
## will replace the existing scale.
## Scale for 'y' is already present. Adding another scale for 'y', which
## will replace the existing scale.
## Coordinate system already present. Adding new coordinate system, which will replace the existing one.
## Saving 7 x 5 in image
Plot space utilisation distribution for the wintering range:
try(plot_util_distr(Result,
dates=data.frame(as.POSIXct('2014-12-01'), as.POSIXct('2015-01-31')),
add.scale.bar=TRUE, percentiles=0.5, zoom=7))
## function will plot 122 twilights
## Warning: bounding box given to google - spatial extent only approximate.
## converting bounding box to center/zoom specification. (experimental)
## Source : https://maps.googleapis.com/maps/api/staticmap?center=-21.37494,19.083408&zoom=7&size=640x640&scale=2&maptype=terrain&language=en-EN
## Saving 7 x 5 in image
## $res_buffers
## class : SpatialPolygonsDataFrame
## features : 1
## extent : 18.58561, 19.58121, -22.88378, -19.8661 (xmin, xmax, ymin, ymax)
## coord. ref. : +proj=longlat +datum=WGS84 +ellps=WGS84 +towgs84=0,0,0
## variables : 1
## names : percentile
## value : 0.5
##
## $p
##
## $bg
## 1280x1280 terrain map image from Google Maps. see ?ggmap to plot it.
P.S. The html file from this markdown can be recereated with folloing code
download.file('https://git.io/fAKP5', 'tmp2.rmd', cacheOK = FALSE)
rmarkdown::render('tmp2.rmd', output_format = 'html_document',
output_options=list(toc=TRUE, toc_float=list(collapsed=FALSE)),
encoding='utf-8')