5 Make DAM Output

Steps to convert iLAM output into Trikinetics DAM format for locomotor activity analyses

  1. Read in iLAM output from image_analysis and parse into a dataframe containing the size, centroid location, and origin (time, pi) of all identified blobs (by_change) with parse_movements()
out_file_name = "Pgreeni"
start_photophase = 5 #project-specific, time that lights turn on
end_photophase = 21 #project-specific, time that dark starts

#parse movements into workable dfs: all movements (by_change) and
by_change_Pg <- parse_movements(file_mvmnts = paste0(out_file_name,".csv"),
                             start_photophase = start_photophase,
                             end_photophase = end_photophase)
Table 5.1: iLAM by_change data frame
…1 s x y pi time ID sex genus species treatment
1 2000000 0 0 mothra03 2022-06-24 21:00:00 99.9%_s10g15 male photinus greeni D
2 2799 1256 35 mothra03 2022-06-24 21:02:00 99.9%_s10g15 male photinus greeni D
3 2189 150 466 mothra03 2022-06-24 21:02:00 99.9%_s10g15 male photinus greeni D
4 731 1282 40 mothra03 2022-06-24 21:04:00 99.9%_s10g15 male photinus greeni D
5 442 1311 51 mothra03 2022-06-24 21:04:00 99.9%_s10g15 male photinus greeni D
  1. Collapse all identified blobs (within by_change_[]) into a dataframe containing the sum of blobs and number of blobs/movements observed per frame/timepoint (by_frame_[])
by_frame_Pg <- 
  by_change_Pg %>% ungroup() %>% 
  group_by(pi, ID, time, treatment) %>%
  dplyr::summarize(n = length(s[!is.na(s)]), #number of blobs of size (s) != NA
            s = sum(s, na.rm = TRUE)) %>% #sum of blob sizes, NA removed
  dplyr::mutate(n = ifelse(s == 0, 0, n)) %>% #if sum of blobs=0, then n<-0 (otherwise it'd be 1)
  distinct(pi, ID, time, treatment, n, s) #sanity check to remove any duplicates
  1. Filter movements captured from rare, noisy images.
  • Noisy values were initially assigned an arbitrary value (2,000,000) by find_movements(). This step changes 2,000,000 with NA and then replaces with average value of the preceding and succeeding time points. These rare cases typically only occur at the image following a light-dark transition.
    • For example, across a 7-day experiment (5040 images), only 0.4% image comparisons were assigned an arbitrary value.
library(zoo)

by_frame_Pg <-
  by_frame_Pg %>% ungroup() %>%
   mutate(s = replace(s, s==2000000, NA),
          n = replace(n, is.na(s), NA))

by_frame_Pg <-
  by_frame_Pg %>% group_by(pi) %>%
  mutate(s = round((na.locf0(s, fromLast = TRUE) + na.locf0(s, fromLast = FALSE))/2,0),
         n = round((na.locf0(n, fromLast = TRUE) + na.locf0(n, fromLast = FALSE))/2,0)) %>% ungroup()

by_frame_Pg <-
  by_frame_Pg %>% ungroup() %>%
   mutate(s = replace(s, is.na(s), 0),
          n = replace(n, is.na(n), 0))

dplyr::filter(by_frame_Pg, n>0) %>% group_by(pi) %>%
  dplyr::summarise(blob_size = mean((s/n), na.rm=TRUE)) #output the average blob size
  
Table 5.2: iLAM by_frame data frame
…1 pi ID time treatment n s
1 mothra01 99.9%_s10g15 2022-06-24 21:00:00 D 0 0
2 mothra01 99.9%_s10g15 2022-06-24 21:02:00 D 4 4084
3 mothra01 99.9%_s10g15 2022-06-24 21:04:00 D 2 2684
4 mothra01 99.9%_s10g15 2022-06-24 21:06:00 D 5 8803
5 mothra01 99.9%_s10g15 2022-06-24 21:08:00 D 9 18515
  1. Use iLAM wrapper make_dam_file() to convert by_frame_[] into a DAM-like output and save as a DAM file with summed blob sizes/total movement (in pixels) per timepoint
ilam_Pg = make_dam_file(by_frame_Pg, variable_name = "s") 

#output a tab-delimited file containing 
write_tsv(ilam_Pg, "ilam_Pg.tsv", col_names = F)
write_tsv(ilam_Pg, "Monitor42.txt", col_names = F) #some analysis programs require Monitor##.txt name
Table 5.3: iLAM by_frame converted to DAM format
X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 X31 X32 X33 X34 X35 X36 X37 X38 X39 X40 X41 X42
1 24 Jun 22 21:00:00 1 0 42 0 Ct 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
2 24 Jun 22 21:02:00 1 0 42 0 Ct 0 0 4084 1668 4988 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
3 24 Jun 22 21:04:00 1 0 42 0 Ct 0 0 2684 2981 3666 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
4 24 Jun 22 21:06:00 1 0 42 0 Ct 0 0 8803 22280 4058 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
5 24 Jun 22 21:08:00 1 0 42 0 Ct 0 0 18515 17325 5093 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
  1. Use iLAM wrapper make_dam_file() to convert by_frame_[] into a DAM-like output and save as a DAM file with the number of blobs/movements per timepoint
#parse movements into workable dfs: all movements (by_change) and
by_change_Pg <- parse_movements(file_mvmnts = paste0(out_file_name,".csv"),
                                start_photophase = start_photophase,
                                end_photophase = end_photophase)

by_frame_Pg = filter_nblobs(by_change_Pg) #filter out small nblobs using iLAM wrapper filter_nblobs()
ilam_Pg = make_dam_file(by_frame_Pg, variable_name = "n")

write_tsv(ilam_Pg, "ilam_Pg_n.tsv", col_names = F)
write_tsv(ilam_Pg, "Monitor43.txt", col_names = F) #some analysis programs require Monitor##.txt name
Table 5.4: iLAM by_frame converted to DAM format
X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 X16 X17 X18 X19 X20 X21 X22 X23 X24 X25 X26 X27 X28 X29 X30 X31 X32 X33 X34 X35 X36 X37 X38 X39 X40 X41 X42
1 24 Jun 22 21:00:00 1 0 42 0 Ct 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
2 24 Jun 22 21:02:00 1 0 42 0 Ct 0 0 2 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
3 24 Jun 22 21:04:00 1 0 42 0 Ct 0 0 2 1 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
4 24 Jun 22 21:06:00 1 0 42 0 Ct 0 0 5 3 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
5 24 Jun 22 21:08:00 1 0 42 0 Ct 0 0 8 6 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0