jashubbard / itrackR

an R package for high-level analysis of eyetracking data
11 stars 2 forks source link

EDF messages missing #2

Open silberzwiebel opened 8 years ago

silberzwiebel commented 8 years ago

I'm trying to use itrackR for my data set and working through your introduction (I'm also implementing polygonal ROIs at the moment). When it comes to the merge with the behavioral data, I do have problems, though. It seems that there are EDF messages missing in itrackR. I do not have much knowledge of this whole EDF thing, but it looks to me, as if EDF messages that were send before or after the eye tracker was actually recording eye movements are not considered in itrackR (because they do not belong to a trial as defined in edf.trials from edfR). I would need this information as it contains the names of the stimuli that I have used (under the string !V TRIAL_VAR my_variable_name value).

I think this comes from using the edf.batch() function that uses edf.trials(). I changed the implementation of edf.trials() slightly so that it uses edf.messages() internally but this then crashes with the eyetrial column (so maybe I could have filed this bug over at edfR), the latest in find_messages()from itrackR.

Would it possible (and sensible) to include all messages? Or am I using your package in a wrong way?

Do you get my problem or do I need to be more specific and/or send examples?

jashubbard commented 8 years ago

I think I am following, but an example would be helpful. Could you send one of the EDFs? Also, what program are you using for stimulus presentation?

In our workflow, we present stimuli with Psychtoolbox, which records everything about the stimuli, etc. into a text file. Then we send "BLOCK" and "TRIAL" messages to Eyelink during recording, and based on those messages being in the EDF, we're able to merge the eye data with all the other information recorded by Psychtoolbox.

I think you could load everything with itrackR, then separately use edf.messages() to load all messages from your edf files, then merge that with the messages dataframe inside the itrackr object (z$messages in the example). It's a little clunky though.

silberzwiebel commented 8 years ago

You can download an EDF file for the next 7 days under this link. I've used SR-Research Experiment Builder for stimulus presentation.

My stimuli contain two objects and participants have to rate whether one object is above the other object. I do want to define AoIs on the objects and then calculate where people fixate on the objects. To do this I do need to know what objects have been actually presented and thus which AoI is the one that is interesting for the current trial.

Apparently, Experiment Builder does also store the stimuli list as a csv file and I managed to merge the data to the itrackR object now after I read your comment. But this is/was not so straightforward. If I got it right, the same variables that are stored in the stimuli list are also in the EDF file at the end of each trial with the coding !V TRIAL_VAR column_name value. They appear after the message DISPLAY_BLANK and before TRIAL_RESULT 0. Is there a possibility to just include messages of the form !V TRIAL_VAR to the itrackR object in the corresponding trial as it seems to be the way experiment builder stores this information? Then one would not need to do the extra step and import the same information again.

jashubbard commented 8 years ago

If I am understanding correctly, then the !V TRIAL_VAR variables are always appearing at the end of each trial (after recording stops) rather than at the beginning, correct? If this is always true, then this is pretty straightforward to add. If it can appear either before or after, then it becomes more complicated.

silberzwiebel commented 8 years ago

Yes, at least for my EDF files those messages all appear at the end of each trial after recording stopped.

YuanboBQ commented 5 years ago

Hi, first thank you for creating the useful package. I want to know whether this problem have been solved, because I also encountered the same problem. The !V TRIAL_VAR was missing in the z$messages, but when I used the edf.messages, it can read the completely message. How to add the missing message into the z$message. I want to analysis the fixation or saccade data from onset of a stimulus to the response was released. Is it possible to analyze using the itrackR. Also, can you provide an example about how to make the polygonal ROIs. I want to make a rectangle ROI, but could not find the example in the help document.

Thank you so much!

silberzwiebel commented 5 years ago

Sorry, but I'm not in that business anymore. I think, I ended up using fixation reports (output from data viewer) for my analyses in R, instead of itrackR...

jashubbard commented 5 years ago

@YuanboBQ yes sorry I wanted to address this issue, but have gone through a couple career changes that have limited my ability to work on this codebase, and on iTrackR. I would love to pick it up again, but just won't have the bandwidth in the near future. My recommendation would be to output the fixation reports and working with those in R. If I make the update, I'll definitely ping you about it. Could you do me a favor and share one of the EDF files that I could use as an example to test that it's working?

YuanboBQ commented 5 years ago

Hi, @jashubbard, it is great to hear that you would like to pick it up and make the package more perfect. I have shared one of the EDF file on the Dropbox. You can download the file form here. And below are codes that I try to read completely message using edf.messages and the save the message to beh. If you need further information, please let me know.

beh = NUL for (i in 1:length(z[["edfs"]])){ temp = edf.messages(EDFfile = z[["edfs"]][i]) ID = rep(z[["ids"]][i], 15) TrialNum = 1:15 Response = str_subset(temp$msg, "!V TRIAL_VAR PressID") %>% str_extract("[a-zA-Z]+$") RT = str_subset(temp$msg, "!V TRIAL_VAR RT \\d") %>% readr::parse_number() rating = str_subset(temp$msg, "!V TRIAL_VAR WentiID") %>% readr::parse_number() rating_RT = str_subset(temp$msg, "!V TRIAL_VAR WentiRT") %>% readr::parse_number() beh_temp = data.frame(ID, TrialNum, Response, RT, rating, rating_RT) beh = rbind(beh, beh_temp) }

jgeller112 commented 4 years ago

I created something like this for my gazeR package if folks are interested. I incorporated some some lovely edfR functions :) so I thought I would share.


# Collect trial variables for your experiment.

find_messages_edf <- function(file_list,varnames,patterns, output_directory)
{
  subs <- length(file_list)

  for (sub in 1:subs) {
    subject = basename(file_list[sub]) # get id from file

    msg=edf.messages.c(file_list[sub])

    messagelist = list()

    for(i in 1:length(varnames)){

      find_msg <- msg$msg %>%
        subset(str_detect(string=., pattern=varnames[i])) %>% # find specific pattern
        str_replace(pattern=patterns[i], replacement = "") %>% # replace pattern with white space
        str_replace_all(pattern=" ", repl="") # get rid of white space
      messagelist[[i]]<-find_msg
    }

    message_data=dplyr::bind_cols(messagelist) %>%
      set_names(varnames) %>%
      dplyr::mutate(subject=as.factor(subject)) %>%
      dplyr::rename(trial = "TRIALID")%>%
      dplyr::mutate(trial=as.integer(trial))

    setwd(output_directory)
    subOutData <- paste(file_list[sub], "_behave_data.csv", sep="") # save file

    write.table(message_data, file = subOutData, append = FALSE, sep = ",",
                row.names = FALSE, col.names = TRUE)
  }
}

It is not perfect. No way of knowing the column structure for all vars until after the table is created. 

![image](https://user-images.githubusercontent.com/18429968/70756591-9549c000-1d02-11ea-86f5-3bb87cb172b0.png)