-
Notifications
You must be signed in to change notification settings - Fork 2
/
example_calc_vis_angle.R
348 lines (240 loc) 路 11.3 KB
/
example_calc_vis_angle.R
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
## Last updated 2020/05/28 by ERP
##### Worked example for using calc_vis_angle functions #####
## The calc_vis_angle functions reference the Position_widths and Position_heights
## variables of raw motive data files and require the following arguments:
## Ground plane (gnd_plane) - at baseline, this indicates the vertical distance
## between the bottom of the "V" and the height of the grounding tool.
## Following raw data processing using the utility functions, it must indicate
## the vertical distance between the bottom of the "V" and the height of the
## perches. An incorrect gnd_plane for a given tunnel set up may calculate
## negative visual angles (as if the bird is flying outside the tunnel).
## gnd_plane should be reported in the same units as Position_widths and
## Position_heights (meters I believe).
## Vertex angle (vertex_angle) - this is included in the calc_vis_angle_mod
## functions and it represents the acute angle each screen creates with a
## vertical axis. It is also equal to the angle of the "V" divided by 2.
## It's reported in degrees (because who measures things in radians anyway)
## and is converted to radians within the functions so that it works with the
## trig functions.
## Stimulus parameter (stim_param) - this reflects the size of the visual
## stimulus being displayed on either side of the tunnel. For example, if the
## screens display 10cm wide vertical or horizontal bars, stim_param = 0.1.
### NOTE: Perhaps these arguments can eventually be supplied or referenced
### from within each file's metadata.
## The first several sections of this example simply run through the steps of
## importing and cleaning raw data files using the utility functions written by
## VBB.
## The calc_vis_angle functions will be run on the these objects after they've
## been processed
##### Load packages #####
library(tidyverse)
##### Source scripts #####
## First define the directory to inspect
scripts_path <- "./R scripts/"
## calc_vis_angle functions now included in this path
## Now list all the .R files
scripts_list <- list.files(path = scripts_path,
pattern = "*.R",
full.names = TRUE,
recursive = TRUE
)
## Using a for() loop instead of lapply() because the latter produces messages
## we don't need.
for (i in 1:length(scripts_list)) {
source(scripts_list[i])
}
##### Working with motive objects #####
# Lets try a few examples using the all in one function (import_and_clean_motive)
##### All in one function #####
jul_29_path <- './data/July 29/july-29_group-I_16-20.csv'
aug_01_path <- './data/Aug 1/aug-1_group-II_14-45.csv'
jul_29_all_defaults <-
jul_29_path %>% import_and_clean_motiv()
aug_01_all_defaults <-
aug_01_path %>% import_and_clean_motiv()
## or we could use the utility functions in sequence
##### Utility functions in sequence #####
## default arguments used for every step to see if the product mirrors the all
## in one function output
##### Data import #####
jul_29 <- read_motiv_csv('./data/July 29/july-29_group-I_16-20.csv')
aug_01 <- read_motiv_csv("./data/Aug 1/aug-1_group-II_14-45.csv")
##### Rename axes #####
jul_29 <- relabel_motiv_axes(jul_29,
tunnel_length = "_Z",
tunnel_width = "_X",
tunnel_height = "_Y")
aug_01 <- relabel_motiv_axes(aug_01,
tunnel_length = "_Z",
tunnel_width = "_X",
tunnel_height = "_Y")
##### Gather data #####
jul_29_gathered <- gather_tunnel_data(jul_29)
aug_01_gathered <- gather_tunnel_data(aug_01)
##### Trim outliers #####
jul_29_trimmed <- trim_tunnel_outliers(jul_29_gathered)
aug_01_trimmed <- trim_tunnel_outliers(aug_01_gathered)
##### Rotate tunnel #####
jul_29_rotated <-
jul_29_trimmed %>% rotate_tunnel()
aug_01_rotated <-
aug_01_trimmed %>% rotate_tunnel()
##### Select X percent #####
jul_29_selected <-
jul_29_rotated %>% select_x_percent()
aug_01_selected <-
aug_01_rotated %>% select_x_percent()
##### Separate trajectories #####
jul_29_labeled <-
jul_29_selected %>% separate_trajectories()
aug_01_labeled <-
aug_01_selected %>% separate_trajectories()
##### Keep full trajectories #####
jul_29_full <-
jul_29_labeled %>% get_full_trajectories()
aug_01_full <-
aug_01_labeled %>% get_full_trajectories()
identical(jul_29_all_defaults, jul_29_full)
identical(aug_01_all_defaults, aug_01_full)
## beautiful
################ calc_vis_angle functions #############
#### calc_vis_angle_1 and calc_vis_angle_1.1 ####
## Assuming fixed horizontal gaze, calculates the visual angle subtended by the
## length of a stimulus feature on either screen and the eye of the bird.
## Positive and negative sides of tunnel reflect positive and negative
## values of "Position_widths".
# # # # # NOTE THIS FUNCTION ONLY WORKS WITH VERTEX ANGLE = 45藲 # # # # # #
jul_29_all_defaults_1 <-
calc_vis_angle_1(jul_29_all_defaults,
gnd_plane = 0.5,
stim_param_pos = 0.1,
stim_param_neg = 0.1)
jul_29_full_1 <-
calc_vis_angle_1(jul_29_full,
gnd_plan = 0.5,
stim_param_pos = 0.1,
stim_param_neg = 0.1)
# produces new variables for all calculations internal to the function
## check to see if everthing worked out the same
identical(jul_29_all_defaults_1, jul_29_full_1)
## noice.
View(jul_29_full_1)
# This version produces new variables only for the visual angles perceived on the
# positive and negative sides of the tunnel.
jul_29_all_defaults_1.1 <-
calc_vis_angle_1.1(jul_29_all_defaults,
gnd_plane = 0.5,
stim_param_pos = 0.1,
stim_param_neg = 0.1)
jul_29_full_1.1 <-
calc_vis_angle_1.1(jul_29_full,
gnd_plane = 0.5,
stim_param_pos = 0.1,
stim_param_neg = 0.1)
## check to see if everthing worked out the same
identical(jul_29_all_defaults_1.1, jul_29_full_1.1)
## double noice.
View(jul_29_full_1.1)
#### calc_vis_angle_2 and calc_vis_angle_2.1 ####
## Assuming gaze is fixed at the point on each screen such that the axis of gaze
## is orthogonal to the plane of each screen. This function minimizes the distance
## to both screens and therefore maximizes the visual angles calculated.
# # # # # NOTE THIS FUNCTION ONLY WORKS WITH VERTEX ANGLE = 45藲 # # # # # #
jul_29_all_defaults_2 <-
calc_vis_angle_2(jul_29_all_defaults,
gnd_plane = 0.5,
stim_param_pos = 0.1,
stim_param_neg = 0.1)
jul_29_full_2 <-
calc_vis_angle_2(jul_29_full,
gnd_plane = 0.5,
stim_param_pos = 0.1,
stim_param_neg = 0.1)
# produces new variables for all calculations internal to the function
## check to see if everthing worked out the same
identical(jul_29_all_defaults_2, jul_29_full_2)
## shablam.
View(jul_29_full_2)
# This version produces new variables only for the visual angles perceived on the
# positive and negative sides of the tunnel.
jul_29_all_defaults_2.1 <-
calc_vis_angle_2.1(jul_29_all_defaults,
gnd_plane = 0.5,
stim_param_pos = 0.1,
stim_param_neg = 0.1)
jul_29_full_2.1 <-
calc_vis_angle_2.1(jul_29_full,
gnd_plane = 0.5,
stim_param_pos = 0.1,
stim_param_neg = 0.1)
## check to see if everthing worked out the same
identical(jul_29_all_defaults_2, jul_29_full_2)
## double shablam.
View(jul_29_full_2.1)
#### calc_vis_angle_mod and calc_vis_angle_mod.1 ####
## Assuming gaze is fixed at the point on each screen such that the axis of gaze
## is orthogonal to the plane of each screen, this function function accomodates
## for different vertex angles that the tunnel may be set at. It minimizes the
## distance to the screen closer to the bird and therefore maximizes the visual
## angle calculated for the closer screen.
## However, this does not hold true for the opposite screen in the following
## condition. If the vertex angle of the tunnel is > 45藲 and the bird's position
## extends beyond the boundary created by a 45藲 vertex angle, i.e. the bird is
## quite close to one screen, then the closest point to the opposite screen is the
## vertex itself. Given that the birds tend to fly fairly close to the center of
## the tunnel, this may not be encountered very often.
jul_29_all_defaults_mod <-
calc_vis_angle_mod(jul_29_all_defaults,
gnd_plane = 0.5,
vertex_angle = 45,
stim_param_pos = 0.1,
stim_param_neg = 0.1)
jul_29_full_mod <-
calc_vis_angle_mod(jul_29_full,
gnd_plane = 0.5,
vertex_angle = 45,
stim_param_pos = 0.1,
stim_param_neg = 0.1)
# produces new variables for all calculations internal to the function
## check to see if everthing worked out the same
identical(jul_29_all_defaults_mod, jul_29_full_mod)
## bazinga!
View(jul_29_full_mod)
# This version produces new variables only for the visual angles perceived on the
# positive and negative sides of the tunnel.
jul_29_all_defaults_mod.1 <-
calc_vis_angle_mod.1(jul_29_all_defaults,
gnd_plane = 0.5,
vertex_angle = 45,
stim_param_pos = 0.1,
stim_param_neg = 0.1)
jul_29_full_mod.1 <-
calc_vis_angle_mod.1(jul_29_full,
gnd_plane = 0.5,
vertex_angle = 45,
stim_param_pos = 0.1,
stim_param_neg = 0.1)
## check to see if everthing worked out the same
identical(jul_29_all_defaults_mod.1, jul_29_full_mod.1)
## you get it now
View(jul_29_full_mod.1)
## because vertex angle is set to 45藲, calc_vis_angle_2 and calc_vis_angle_mod
## should produce identical results
identical(jul_29_full_2, jul_29_full_mod)
identical(jul_29_full_2.1, jul_29_full_mod.1)
# WAT!?
# it looks the same. I don't get it...
############## Next Steps #############
## Assuming I figure out what's going on above, the next steps would be to:
##
## 1. Improve the latest function (calc_vis_angle_mod) by including head
## orientation to calculate visual angles based on where the bird
## is actually looking. This could take a while
##
## 2. Figure out how to visualize or otherwise use the visual angles calculated
## from these functions.
## - I believe this variable can be the nucleus with which to design functions
## that more accurately estimate optic flow by calculating how it changes over
## time in various dimensions, i.e. how it increases or decreases with the
## bird's movements.
## Thoughts?