OpenBCI_GUI 3.2.0 and Max 7: Networking

retiututretiutut Louisiana, USA
edited February 2018 in OpenBCI_GUI
Hello All,

The current GUI for Mac is working well via OSC messages, and I'm doing my best to create a template to make the data usable with Max 7 objects. I have a few questions to make this possible. The data looks correct when displayed on multislider objects, but I don't understand how the received OSC values correlate to what I see in the GUI in regards to measurements.

How do I convert the Time Series amplitude to microvolts?
Recorded Data Range on Synthetic Channel 1: -150. to 150. (floating point)

I believe I can plot the data logarithmically as in the GUI in Max, but it doesn't seem to match what the GUI shows with synthetic data. How do I interpret Band Power to (uV)^2 / Hz per channel?
Recorded Data Range on Synthetic: 0. to 5. (floating point)

Can I use the data from the previous question to create a focus algorithm in Max per the description in the GUI?

Comments

  • retiututretiutut Louisiana, USA
    Corrections:

    I re-ran the synthetic data this morning and checked for minimum and maximum for the Time Series on Channel 1 over OSC messaging from a Windows machine to a Mac running Max 7. It showed values of -300. to 300. in Max while CH1 in the GUI fluctuated from 50-80uVrms. 

    The Band Power still shows 0. to 5. across all bands. I had to apply smoothing and easing functions on the Band Power data to remove harsh outliers (caused by packet loss?)
  • retiututretiutut Louisiana, USA
    edited February 2018
    A smoothing function without a range restriction was able to format the numbers into something that resembles the readings in the GUI. Here is the algorithm:

    floats~ SmoothVar[Set to 0.01], SmMultiplier, RightAddend[Initialized to 0.99], LeftAddend, RightAddend, DataPoint1, DataPoint2, etc.

    • 1. - SmoothVar = .99 = SmMultiplier
    • DataPoint1 stored as a floating point variable
    • DataPoint1 * SmoothVar = LeftAddend
    • Left Addend + RightAddend = SmoothSum
    • [SmoothSum] * [SmMultiplier] = RightAddend
    • DataPoint2 stored as a floating point variable
    • DataPoint2 * SmoothVar = LeftAddend
    • LeftAddend + RightAddend = SmoothSum
    • [SmoothSum] * [SmMultiplier] = RightAddend

  • retiututretiutut Louisiana, USA
    image
  • How do I convert the Time Series amplitude to microvolts?

    The data is in microvolts already!

    Can I use the data from the previous question to create a focus algorithm in Max per the description in the GUI?

    Link to previous question please.
  • retiututretiutut Louisiana, USA
    edited March 2018
    I'm not sure the answer is that simple. Please reread the full context of what I have observed by sending OSC data to Max. The values are not the same at all. I've been digging in the GUI source code for answers and I have yet to understand why the data values shown in the GUI do not match what I see in Max both with and without GUI filters.

    How do I convert the Time Series amplitude to microvolts?
    Recorded Data Range on Synthetic Channel 1: -150. to 150. (floating point)
    I re-ran the synthetic data this morning and checked for minimum and maximum for the Time Series on Channel 1 over OSC messaging from a Windows machine to a Mac running Max 7. It showed values of -300. to 300. in Max while CH1 in the GUI fluctuated from 50-80uVrms. 

    I believe I can plot the data logarithmically as in the GUI in Max, but it doesn't seem to match what the GUI shows with synthetic data. How do I interpret Band Power to (uV)^2 / Hz per channel?
    Recorded Data Range on Synthetic: 0. to 5. (floating point)
    The Band Power still shows 0. to 5. across all bands. I had to apply smoothing and easing functions on the Band Power data to remove harsh outliers (caused by packet loss?)

    Can I use the data from the previous question to create a focus algorithm in Max per the description in the GUI?
    (The answer is yes, but I can't program this without explaining why the raw data is a scaled version of what is shown graphically in the GUI.)

    The following screenshots clearly display the discrepancy involved with the Time Series data.





  • retiututretiutut Louisiana, USA
    edited March 2018
    imageimage
    image
    This OSC data is being sent internally on an iMac running both the GUI and Max to rule out packet loss and data outliers. The text file displays data collected from just Channel 1 over the same time period as pictured in the GUI. Note that there are negative values in the text file while the microvolt value in the GUI is always a positive value. This means that the data Max is receiving is not equivalent to the value displayed in the GUI.
  • retiututretiutut Louisiana, USA
    edited March 2018
    When playing back SD card recorded session, I noticed that the Band Power widget values matched the OSC values in max while still using the data smoothing algorithm set to 0.01.

    From what I was able to read here and in my Niedermeyer's EEG textbook, it is not best practice to look at amplitude:

    "Precise determination of the voltage of each wave is unnecessary and should be discouraged as pseudoaccuracy" because there are too many variables involved.

    I was a bit confused about the exact amplitude of waves because it was not mentioned in earlier chapters. Thank you index! It also goes on to mention that EEGers are allowed to comment on a range of amplitudes, example: "alpha rhythm from 20 to 30uV", but to stay away from vague terms such as high, medium, low.

    • So the uVrms value displayed in the GUI is an average reading of the amplitude? How is this value calculated in the source code? 
    • How exactly are the microvolt readings from a text file, or stream, scaled to be graphed in the GUI in the source code? (refer to previous post)
  • retiututretiutut Louisiana, USA
    edited March 2018
    https://www.dataforth.com/measuring-rms-values.aspx

    I believe I've found the lines of code  that explain what I've noticed.

    //here is the processing routine called by the OpenBCI main program...update this with whatever you'd like to do

    public void process(float[][] data_newest_uV, //holds raw bio data that is new since the last call
    float[][] data_long_uV, //holds a longer piece of buffered EEG data, of same length as will be plotted on the screen
    float[][] data_forDisplay_uV, //this data has been filtered and is ready for plotting on the screen
    FFT[] fftData) { //holds the FFT (frequency spectrum) of the latest data
    //apply user processing
    // ...yLittleBuff_uV[Ichan] is the most recent raw data since the last call to this processing routine
    // ...dataBuffY_filtY_uV[Ichan] is the full set of filtered data as shown in the time-domain plot in the GUI
    // ...fftBuff[Ichan] is the FFT data structure holding the frequency spectrum as shown in the freq-domain plot in the GUI
    // w_emg.process(yLittleBuff_uV, dataBuffY_uV, dataBuffY_filtY_uV, fftBuff); //%%%
    // w_openbionics.process();

    Exact lines of code in the networking widget that send unfiltered time series data:

    // TIME SERIES UNFILTERED
    if(filter==0){
    // OSC
    if(this.protocol.equals("OSC")){
    for(int i=0;i msg.clearArguments();
    for(int j=0;j msg.add(yLittleBuff_uV[j][i]);
    }
    try{
    this.osc.send(msg,this.netaddress);
    }catch (Exception e){
    println(e);
    }
    }



  • wjcroftwjcroft Mount Shasta, CA
    edited March 2018
    I'm not sure I exactly understand what you are after, but here are a couple points.

    The values that the GUI writes to the CSV output file, and the values written to the OSC should be the same. All in microvolts, both plus and minus values will be found here. Also note that you will need to remove the DC offset (which is in the millivolts range) with a high pass filter (at say .5 hz) to match what you are seeing on the screen. This offset removal is true for the CSV file. Not sure about the OSC, that may already have a high pass filter applied. Check the source code.

    The uVrms figures shown on the GUI Time Series tab (per channel) can be considered this way: they just represent RMS amplitude measurement of the maximum swings of the EEG signal. This will always be positive. So if the number on the screen says ~70 uVrms, then the EEG signal is swinging back and forth between approximately -100 and +100 uV (see below). Some of these RMS measurements also apply a running average type operation so the figure changes more slowly than the actual sample to sample variation of the EEG.

    Actually RMS does not reflect the peak values, but rather the root mean square calculation. Sometimes EEG amplitude is stated in RMS terms, especially for averaging purposes. Though graphs of EEG time series are generally in raw scale, where 100uV on the graph would correspond to an actual EEG signal of 100uV.

    Regards,

    William
  • wjcroftwjcroft Mount Shasta, CA
    edited March 2018
    So actually 100 uV peak, would result in 70.7 uVrms.


    Which is only true for sine waves. A true RMS calculation would take into account the waveform shape.

  • retiututretiutut Louisiana, USA
    edited March 2018
    Yes! This is beginning to make sense. I really want to understand these raw values fully before manipulating the data. I'm sure the numbers will line up tomorrow when I apply your recommended settings.

    Thank you for finally explaining this. What you said aligns with what I was able to read today, though not as concise! The notes in the source code were very helpful once I identified the variables. 

    "So actually 100 uV peak, would result in 70.7 uVrms.

    https://www.allaboutcircuits.com/tools/rms-voltage-calculator/

    Which is only true for sine waves. A true RMS calculation would take into account the waveform shape." 

    VP
    : The maximum instantaneous value of a function as measured from the zero-volt level.
    VP−P
    : The full voltage between positive and negative peaks of the waveform; that is, the sum of the magnitude of the positive and negative peaks.
    Vrms
    : The root-mean-square or effective value of a waveform.

    • To confirm, the GUI use the VP value instead of VP-P to calculate Vrms? This is one of the big concepts I was trying to understand.
  • wjcroftwjcroft Mount Shasta, CA
    Yes, the Vrms is calculated from Vp, not Vp-p.

    In actuality for a time series of EEG voltage readings, the RMS calculation would be using the first equation here,


    The square root of the average of the sum of the squared voltage values. This is always a positive number because of the squaring operations.

Sign In or Register to comment.