hfoGUI User Guide Draft

Posted by Geoff, Published: 4 years, 11 months ago (Updated: 4 years, 11 months ago)

This post will tell you everything you need to know about using the hfoGUI, from how to add personalized plots to visualize, to saving events of interest that you wish to use for a manuscript or further analysis. Be sure to provide feedback for how to improve the GUI. This was created with my workflow in mind, so it might be lacking simple things that make it better for everyone. I tried my best to optimize it so that it is able to work well on slower computers (with the use of PyQtGraph), if it is slow with your computer feel free to let me know so I know its limitations.

If you prefer to see a tutorial in a video format, feel free to check the YouTube video below. Keep in mind that I do provide more detailed explanations in this text-based tutorial.

Adding Graphs

You must first determine which session you'd like to analyze, then you will have to manually add the graphs to visualize. This is to provide the end-users with a tool that is as flexible as possible. hfoGUI is based off a GUI that I used to visualize High Frequency Oscillations (HFO's) during my research at Drexel University. However, that program only allowed you to visualize using three predetermined traces, a raw trace, a trace that is filtered within the "Ripple Band" (80 Hz - 250 Hz) and a trace that is filtered within the "Fast Ripple" band (250 Hz - 500 Hz). Although this method is great for visualizing HFO's, I felt like it would be beneficial to allow users to provide their own filtering options.

  1. Before adding plots, you will need to press the "Graph Settings" button in the bottom of the Main Window. After pressing that button you will see the Graph Settings Window pop-up, pictured below.
  2. To add a graph to the Main Window, you will begin by selecting the source that you wish to plot. This data will be in the Tint format, thus you will likely have options such as: .eeg, .eeg2, .egf, .egf2, and etc. I suggest choosing one of the .egf options as it is sampled at 4.8 kHz, as it has a higher sampling rate than the .eeg files (sampled at 250 Hz). If you are using hfoGUI to visualize HFO's, you will be required to use the .egf's exclusively as the upper bounds of an HFO is ~500 Hz. Nyquist rate states that the sampling rate must be at least twice highest frequency present in the signal. Therefore, 250 Hz from the .eeg files will not be sufficient to properly visualize entire HFO frequency spectrum. Note: speed is a source. However, to use this you must also choose the appropriate "Arena" value that corresponds to this session's data. Each Arena has a varying pixel-per-meter value that will be used to convert the positions from pixels to centimeters. In the current state, you will have to choose between the current Arenas, which are likely only convenient for my lab. In the near future I will likely replace this field with a "Pixel Per Meter" field. If you are trying to use hfoGUI and the Pixel Per Meter field is not there, feel free to clone the project from GitHub and add your own Arena values, or choose the one with the closest pixel-per-meter value.
  3. After you have a selected source, you will be able to modify this source's output with a multitude of parameters listed below:
    • Filter Method: you have the option to choose between a few various filters (butterworth, chebyshev 1/2, elliptic, and bessel). I have plotted the frequency response of these various plots below to give you an idea of the different filter methods. I tend to use butterworth, but if you have a preferred filtering method, feel free to use it. Note: in the frequency response, unfiltered signals will have a gain of 1, completely filtered frequencies have a gain of 0.
    • Filter Type: with this parameter you can choose between low-pass, high-pass, and band-pass. Low-pass filters out frequencies higher than a provided cutoff value, high-pass filters out frequencies below a provided cutoff value, and band-pass filters between two provided cutoff values.
    • Filter Order: this parameter represents the number of roots/poles of the differential equation describing the filter. This value will affect the filter roll-off (steepness). Tint tends to use 6th order filters for .eeg/.egf data, and 3rd order filters for the spike data. I have plotted some examples of high-pass butterworth filters with varying orders just to visualize the impact of order on the frequency response. As you see, the larger the order, the steeper the roll-off. Note: be careful not to have an order value that is too large as it could cause ringing.
    • Lower Cutoff (Hz): this will be the lower bound cutoff value for your desired filter. For example, if you wanted to band-pass filter the signal between 4 Hz and 12 Hz (theta band), then you will type a value of 4 in this text field. Be careful how close to zero your lower cutoff value is. Depending on how large the sampling rate of your signal is, you can create some strange looking frequency responses. I always suggest plotting the frequency response to double check.
    • Upper Cutoff (Hz): this will be the value for the upper bound cutoff for your filter. For that same 4 Hz - 12 Hz filter that we proposed above, you will type a value of 12 in this text field. The maximum value possible for this field is half the sampling rate (Nyquist frequency). Therefore, if you choose a .egf source, the highest upper cutoff value is 2.4 kHz (as it is sampled at 4.8 kHz). If you choose the .eeg files, the maximum possible value is 125 Hz (as these files are sampled at 250 Hz). Like the lower cutoff, be careful with how close this value is to the Nyquist frequency.
    • Notch Filter (Hz): I have provided the following notch filtering options: None, 60 Hz, and 50 Hz. This will allow you to remove any 50 or 60 Hz noise from your signal if you'd like to.
    • Mark Peaks: when checked, this parameter will provide an indication (vertical line) at every local maxima in the signal. This parameter will look something like the picture below (without the red dots indicating the peaks). Keep in mind this can slow down the visualization if you have a signal with too many peaks. I generally don't use this parameter, but I imagine it could be useful if you are trying to visualize phase-locking. You could theoretically filter the .egf signal within the theta band, and use the mark peak parameter on this theta source to determine if the peaks align with another source (could be a signal filtered in the gamma frequency band).
    • Gain (V/V): this parameter will simply multiply the source's data by a factor that you provide. Theoretically, a signal that you have might wash out the rest of the signals because the amplitude is too high, you could theoretically halve the signal's range by using a gain of 0.5. I am realizing that I do have (V/V) in parentheses, which is technically true. However, this does work for source's that are not in the unit of Volts (such as speed). In fact, speed might be a signal that you wish to increase the gain of as it typically has a much smaller range than the .eeg/.egf data.
    • Arena: at the current iteration of hfoGUI there is an arena drop-down menu. The purpose of this is if you wanted to plot the speed. The data is saved in the units of pixels. Each arena has a varying pixel-per-meter value that is used to convert the data from pixels to centimeters. I realize that this is inconvenient for those outside of our lab as you could have wildly varying pixel-per-meter values for your behavior rooms. In the future I will replace this field with a pixel-per-meter field. The current options are the following:
      • DarkRoom: 711.3701 pixels-per-meter
      • BehaviorRoom: 495.5234  pixels-per-meter
      • Room4: 313  pixels-per-meter
    • Hilbert: when checked, this parameter will apply the Hilbert Transform to the selected source (after all the filtering and data processing has been performed). The Hilbert transform will produce the Analytic Signal (a signal containing complex-values without the negative frequency components). Our use for the Hilbert transform is to allow us to visualize the envelope of the signal. The Analytic Signal is often used in the automatic detection of High Frequency Oscillations. An example of what this output looks like is pictured below (source is in blue, and the envelope is in red).
  4. Once all your parameters have been set, you can press the "Add Graph Source" button. At this point a progress dialogue should appear, after which your source should now be visible in the Main Window.
    1. Each time you add a source it will plot the latest sources added from top to bottom. (Thus the 3rd added source will be on top of the 2nd added source, which is on top of the 1st added source).

Saving Source Profile

After using hfoGUI for a certain amount of time you will likely come across a set of graph sources that you are adding repeatedly upon loading the session. To avoid having to add these sources manually, you can simply save the Graph Settings by pressing the "Save Profile" button. A pop-up window will ask you to then determine the name of the profile, choose one then press the "Ok" button. After confirming the profile name, you will now see your profile in the Load Data Profile drop-down menu. If you press this button, it will load those current plots into the scene.

Updating Graph Source

If you want to modify one of the plotted sources. You can navigate to the Graph Settings Window, and select the source that you want to modify from the list towards the top of the window. When you selected this source, the parameter values were all changed to the values of this current source. Simply change the parameters as desired and press "Update Selected Graph Source".

Visualizing Data in the Main Window

Once you have added your graph sources you can now visualize them within the Main Window. I first suggest determining which Window Size to use. This value will represent the amount of time (in milliseconds) to plot at once. I set the default to 500 ms, however I sometimes move it up to 1 second of data. Just know that the larger this value is, the more taxing it will be on the PC to plot.

There are a few ways to navigate the data. One is by scrolling with the scroll bar. This is a relatively quick way to manually search through your data to find any interesting signals. Alternatively, if you know there is an event at some time (you've previously determined interesting events in the behavior) and want to jump to those time points. Simply type that number in the Current Time field (again in milliseconds).

The remaining two text fields (Start Time and Stop Time) have to do with scoring the data, see the scoring data section for a more in depth explanation. However as a brief description, the Start Time and Stop Time fields represent the start and stop times of an event that you wish to save.

Plotting Spikes

You will notice that there is now option to plot the spikes from the Graph Settings Window. As of this time we have the ability to plot the spikes in the form of a raster below the sources created in the Graph Settings Window. However, in the current state this process slows down the plotting significantly and I recommend avoiding it. The idea would be so that we can visually determine if the spikes occur at the same phase of certain signals (such as a theta filtered signal). With this you could theoretically visualize theta precession. Currently this option will plot the spikes on a per tetrode basis, the bottom row are the spikes from tetrode 1, the row above that are the spikes for tetrode 2, etc. An example of the plot spikes option is shown below. Note: the spike colors match how they are in Tint.

Visualizing Time-Frequency Representations

Important for determining if the event is an HFO is the time-frequency representation (TFR) of that event. To visualize the TFR of a signal you must first left click on the Main Window at the time point that you'd like to analyze. If you have done so correctly (God I really hope you can left click on the graph), then you should see a vertical black line at the selected location.

To visualize the TFR of this event, you must click the "T-F Plots" button at the bottom of the Main Window. You will see a pop-up window that looks something like the image below.

The top plot will always be the raw trace of the selected source (you can choose the source in the Source drop-down menu at the top, it will only include sources that you have plotted on the Main Window). The middle plot is the filtered signal, this should be filtered within the HFO frequency band (80 Hz to 500 Hz), however feel free to modify it by changing the "Low Freq(Hz)" and "High Freq(Hz)" parameters in the Filtered Signal Parameter section at the top of the T-F Plots Window. The bottom plot is the TFR centered around the time point that was selected on the Main Window. This graph is created with the use of the Stockwell Transformation. The warmer colors (red) represent frequencies at that time point where the power is the highest (thus contributes more to the morphology of the signal). You can see that the window size of this plot is 250 ms (this value can be changed via the "Window Size" parameter), I suggest keeping this value low as the Stockwell Transform takes time and quite a large amount of physical memory from the computer. Keep in mind that the Stockwell Transform does over-represent the higher frequencies, which makes it perfect for this application as the lower frequencies tend to drown out the higher frequencies otherwise (lower frequency components tend to have higher amplitudes).

You might also notice that there's a tab in the T-F Plots Window called the "PSD Tab". This tab will show you the Power Spectral Density (PSD) of the time point that you selected. You can think of the Stockwell Transform almost as an instantaneous Power Spectral Density. The plotted PSD is really just a slice of all the frequencies along that one time point in the Stockwell Transform's output. We can use this to characterize the event as a Ripple (80 Hz - 250 Hz) or a Fast Ripple (250 Hz - 500 Hz). In our current example, the time point appears to be at around 300 Hz, if I didn't just choose a random point to analyze, it would live on as a Fast Ripple.

Scoring the Session

If you find an event of interest (EOI) in your data, you might want to mark the data within the session so that you can either come back and visualize it again (i.e. example for a manuscript), or save these events for another script to analyze. Typically when using this for HFO's, we would take these events, load them into our favorite coding language, extract features from these events and use them to automate the process of identifying HFO's within our data using machine learning. To score the data you must perform the following process:

  1. Open the Score Window by pressing the "Score" button at the bottom of the Main Window. You should see a window similar to the one pictured below.
  2. First you must provide your name in the "Scorer" field. This is useful if you have a few people scoring the data and would like to know who scored the data. It will not allow you to add a score unless you provide a name for this field.
  3. Now you must select the Event of Interest time boundaries. To do this you must proceed with the following protocol:
    1. Go to the Main Window.
    2. Press and hold the left mouse button starting at the beginning of the event.
    3. Drag the mouse to the end of the event, and release the left mouse button.
    4. You should see that the desired data has now been highlighted.
      • You can drag from the ends of this highlighted section to fix the start or stop position. 
      • You can also shift this highlighted section by clicking on the highlighted section, holding, and dragging the mouse.
  4. Now that the temporal boundaries of your event have been selected. You can navigate back to the Score Window.
  5. Select a score from the Score drop-down menu. The following score options are provided: Spike, Theta, Gamma Low, Gamma High, Ripple, Fast Ripple, Sharp Wave Ripple, Artifact, and Other. In the future I should add the ability to add your own custom scores, for now if you want to add scores, feel free to fork the project on GitHub and add your own values to the list.
  6. Finally, you can press the "Add Score" button to confirm the score. You will see this score now placed in the list located in the Score Window. The Score ID will be MAN[X], where MAN stands for Manual (since you manually curated this event). This is to distinguish between the manual and automated methods.
    • You can Update the score by selecting them from the list, providing the correct sore value, and pressing the "Update Selected Score" button at the bottom of the Score Window.
    • If you select a score from this window, it will navigate the Main Window to this event. Therefore you will not have to manually move the scrollbar to this point every time you want to show off your event of interest.
    • If you decide that an event is no longer interesting, feel free to delete the score using a similar method to updating it. Select the desired score from the list, and then press the "Delete Selected Scores" button.
  7. If you have found scores within this session that you want to save. You will need to press the "Save Scores" button towards the top of the Score Window. A pop-up window will have you provide a filename that you wish to save the scores as. 
  8. When you are decide to re-load a session that you have previously analyzed. You can load the scores by opening the Score Window and selecting the "Load Scores" button. A pop-up will occur that will have you navigate to the score filename that you saved. After confirming the score filename you will see the score list populate appropriately.

Automatic HFO Detection

Manually scoring files can be time consuming, luckily there are a few various automatic detection algorithms that people have created specifically for HFO detection, which I call Hilbert Detection. To perform the automatic detection, you must first open the Score window, and navigate to the "Automatic Detection" tab. At the bottom of that window you will see a "Find EOI's" button. Once you click that, a pop-up window will allow you to provide the necessary parameters for automatic detection. Once you have finished changing the parameters you may press the "Analyze" button to proceed with the automatic detection. I should provide a progress dialogue to show you how far the detection has gone, however I have not done so. It does print the percentage in the console though. To learn about each of the detection parameters, feel free to read about the methods below.

Hilbert Detection

There is currently only one detection algorithm that I have coded which is based off of Sergey Burnos'1 work as well as RippleLab2. I have listed the method below:

  1. The data must first be band-pass filtered with the cutoffs at 80 Hz and 500 Hz, this will ensure that we are only including the HFO frequency bands. They use an Infinite Impulse Response (IIR) in the Burnos paper1, but I use a 3rd order Finite Impulse Response (FIR), specifically a butterworth filter. Their preference for an IIR filter over an FIR filter is due to the computational run time. I traditionally prefer FIR filters as to avoid phase delays introduced by IIR filters. If you prefer alternative cutoff frequencies feel free to set the "Min Frequency(HZ)" and "Max Frequency(HZ)" parameters after pressing the "Find EOI's" button.
  2. The Analytic Signal / Envelope of the signal is calculated with the use of the Hilbert Transformation.
  3. The envelope is binned into 5 minute (300 second) epochs. You can change this 5 minute value by modifying the "Epoch(s)" parameter.
  4. The standard deviation of the envelope within the 5 minute bins are then calculated.
  5. To find preliminary EOI's a simple thresholding is applied. They suggest the mean of the envelope plus 3 standard deviations (within the bin). You can modify this threshold parameter by changing the "Threshold(SD)" parameter.
  6. For each signal above threshold, the start/stop time must be determined. The Burnos determines this by when the signal reaches 50% of the max amplitude of the envelope of this event. An example of this is pictured below. I prefer to 30% of the max. However feel free to change this as desired by modifying the "Boundary Threshold(Percent)" parameter.
  7. These events are then discarded if they do not have a minimum duration of 6 ms. EOI's with an inter-event-interval of less than 10 ms are merged together.
  8. It is here where the Burnos group diverts from the RippleLab group. The Burnos group then goes on to visualize the time-frequency representation of each of the events using a Stockwell Transform. This probably does a great job at discarding EOI's that are unlikely to be an HFO, however the Stockwell Transform tends to take a lot of time so I decided to go with more of a RippleLab approach from here. You still have the ability to visualize the Stockwell Transform of the signal, but it is not automated. In the future maybe I'll add the ability to continue with the Burnos method.
  9. The RippleLab group adds secondary threshold and peak requirement. They require that at least 6 peaks exceed a threshold of mean + 3 SD's (they have their initial threshold set to 5 SD'S)2. You can set the required peaks and the corresponding threshold by modifying the "Required Peaks" and "Required Peak Threshold(SD)" parameters respectively. I have 6 peaks above 2 SD's set as the default currently, but feel free to modify these values.

Resources

  1. Burnos, S., Hilfiker, P., Sürücü, O., Scholkmann, F., Krayenbühl, N., Grundwald, T., et al. (2014). Human intracranial high frequency oscillations (HFOs) detected by automatic time-frequency analysis. PLoS ONE9:e94381. doi: 10.1371/journal.pone.0094381 https://journals.plos.org/plosone/article?id=10.1371/journal.pone.0094381
  2. Navarrete M, Alvarado‐Rojas C, Le Van Quyen M, et al. RIPPLELAB: a comprehensive application for the detection, analysis and classification of high frequency oscillations in electroencephalographic signals. PLoS ONE 2016;11:e0158276. https://journals.plos.org/plosone/article?id=10.1371/journal.pone.0158276

Comments

Post Comment