Scaling of auxiliary channels

  • MNE version: e.g. 0.24.0
  • operating system: Windows 10

Hello everyone,

I am working with a brainvision system and one of the issues I have had is that when I plot the recording, the auxiliary channels (i.e. eog and ecg) are way out of scale even after setting the channel types: raw.set_channel_types({‘ECG’:‘ecg’,‘VEOG’:‘eog’,‘HEOG’:‘eog’})
I end up not being able to even make out the shapes till I decrease the scaling to around 300,000,000microvolts on the plot. I was just ignoring this as a minor inconvenience, but I just tried running an ICA and these channels end up showing up after epoching on the ICs plot as well (another question for another time of why they are there), and they take over the whole plot since they are so out of scale. Is there a fix for this issue? For more info, my vhdr file does have the eeg channels recorded in microvolts and the aux channels in millivolts:

Ch61=62,,0.0488281,µV
Ch62=63,,0.0488281,µV
Ch63=64,,0.0488281,µV
Ch64=ecg,,1,mv
Ch65=veog,,1,mv
Ch66=heog,,1,mv

I am not sure if this is an issue on the MNE side or the brainvision side

I appreciate any and all advice.

hi,

to check if it’s an MNE problem, can you look the file using another reader and see if it works?

Alex

Hi Alex,

Thank you for getting back to me so quickly. I just checked out my data in EEGLab and also Brainstorm. Both do not seem to run into the same issue of scaling before or after declaring those channel types as ECG and EOG channels. In MNE, before I use the raw.set_channel_types() function, the scaling looks good on the plot, but are in AU instead of microvolts or millivolts. The issue happens upon using that function to set the channel types. Is this a problem others have seen, and is there a fix?

Best,
Matt

can you share your file with a tiny script to replicate the pb? with code I will understand faster the problem

Alex

Of course. Here is a link to my google drive folder with the data and a short script to read it in and set the channel types. I will note that I am using MNE version 0.23. you will see at first everything looks okay, but then once I set the channel types the scaling on the 3 auxiliary channels goes out of bounds.

https://drive.google.com/drive/folders/14X6iImD_MfbEoNwbwe_Pl92Fby6QFqOF?usp=sharing

I believe this is affecting other things further on in my full pipeline as well, such as when running an ICA.

Best,

Matt

1 Like

the unit if the EOG channels is not correct in the raw data. See:

raw[-1, :30][0]

array([[158.41308594, 158.75292969, 149.55322266, 146.72070312,
156.34472656, 161.00488281, 146.59619141, 127.57470703,
121.31005859, 126.24755859, 132.13916016, 131.96240234,
136.08007812, 149.08154297, 153.19238281, 147.78369141,
145.99023438, 144.67138672, 146.81982422, 156.24316406,
155.20458984, 143.40869141, 137.97753906, 137.30224609,
139.90966797, 146.26611328, 147.50585938, 143.31201172,
137.03662109, 135.54394531]])

it’s the HEOG values that are read as been 158V

you need to fix your header file

Alex

Thank you so much for taking a look. What in the vhdr file needs to be changed exactly? I did have the system set up to record the ECG and EOG channels in millivolts while the eeg channels were set to microvolts, so I am not sure what should be changed. This setup was suggested by BrainVision, but they do assume you are using their analysis software so this recommendation might not be optimal for other programs.

Best,

Matt

Hello @Matt, I’m actually surprised you’re seeing this scaling issue and I’m wondering if it’s a bug in our reader. What did catch my attention, though, is that the “v” in “mv” is in lower case. Maybe that’s what is causing the hiccup? Can you change it to “mV” and see if this changes anything?

1 Like

Hi @richard , I just tried your suggestion, and it does help, but does not fix the problem completely. when loading in the data with it set as ‘mv’ it is first scaled to around 42au. After declaring the channels as ecg, it goes to around 100,000,000microvolts. Changing the header file so the ecg channel is in mV, loads the ecg data scaled to around 0.04au and declaring that as an ecg channel changes it to around 2,000microvolts. Much better but not a total fix. But I think I know why now, I set the scaling for the ecg and eog channels in the recording to 0.01milivolts during collection. As suggested by the brainvision team. Though the header file has it at 1mv. Changing the header file to scale the ecg to 0.01mV seems to make everything look good.

I went back and did a bunch of short ecg recordings (see ecg folder in google drive link above) to find optimal settings that are not misread into the header. There are two places in BV to adjust scaling, during the initial setup and in preferences. Preferences should not actually change the way the data is saved, and I found it didn’t seem to. I played with different combinations of these with whole numbers since it seemed to save my 0.01mv as 1mv, but unfortuanly got results that didn’t make a ton of sense. However, I just noticed that the ecg and eog channels sometimes use a v and other times use a V. My guess is that you are correct, the v vs V can mess things up, but also BV only likes whole numbers when individually setting channels. That is my guess, please feel free to play around with the data I uploaded in the ecg folder to further vet this out. I used the full array, but only the ecg was hooked up. I will later on feed a known signal thought the system so I can be confident in the output file.

Best,
Matt

2 Likes

Thanks for the extensive testing, @Matt!

@sappelhoff @cbrnr it appears that BV recorder behaves a bit inconsistently; but at least the misrepresentation of Volts as “v” instead of “V” should be easy to work around at our end. Care to look into this?

Fixing the lowercase issue is easy, but the real problem seems to be that the true scaling is 0.01mV (or 0.1mV) and not 1mV. I believe that we already take care of the resolution here, but of course there could be something wrong with our code.

However, I do not want to just accept a lowercase v because of the following lines in the header file:

64    ecg         65                 1 mv             DC              280              Off         0.1[mV/mv]       0[mV] = 0[mv]
65    veog        66                 1 mv             DC              280              Off         0.1[mV/mv]       0[mV] = 0[mv]
66    heog        67                 1 mv             DC              280              Off         0.1[mV/mv]       0[mV] = 0[mv]

The two rightmost columns contain some conversion rule, which I have no idea what it is. We do not currently parse this information.

2 Likes

Hey @Matt – could you write the Brain Products support team about this issue? It might be a bug that they need to fix in BrainVision Recorder. You can write them an email: techsup@brainproducts.com

That could be as easy as editing the dict here: https://github.com/mne-tools/mne-python/blob/820bd7a90f7babe7104efdc722c840d0137919a7/mne/io/brainvision/brainvision.py#L338-L348

agreed, this is weird … probably warrants an email to the Brain Products team as well. @Matt if you are going to write an email, could you please include that question? Also, feel free to link to this exact forum post so that the Brain Products team can also go through our problems here (if they feel like it). I’ve made good experiences with their support earlier, so I think that’d be the best way forward.

3 Likes

Thank you so much for looking into this for me, I really appreciate it. I did plan on emailing them, so yes, I will link them to this forum post and see if they have anything to add. I will keep you all apprised of any developments.

2 Likes

Hi all,

Sorry for the long delay, it took quite along back and forth between BV and myself while I was traveling to get close to a usable answer. So, here is the essence of what is happening. in the setup of BV recorder to start an experiment you are asked to set the units and gradient for all AUX channels that are not typical EEG channels. The gradient is used to calculate the resolution seen in the vhdr file (under both “[Channel Infos]” and “Channels”) which is always offset to 1, no matter what is put in the gradient field during setup. the right most equations (under Channels) that @cbrnr points out, are the equations that says how the gradient was offset to 1 for the resolution in the above Channel Infos. Thus, BV is automatically applying a correction offset for all aux channels if the gradient is anything but 1. if you do not fill in this field during setup it automatically sets the gradient to something like 0.475, so a correction offset for those channels is still applied. This becomes an issue when bringing the data into MNE and then using the set_channle_type() as this function has a built in offset correction too it seems. Thus, the offset gets set twice. That was essentially most of what they were willing to tell me.

Additionally, the units that are set in the setup screen with the gradient are essentially meant to be a place holder, not read as an actual unit. This means that no matter what you put in for units, that far right equation @cbrnr brings up essentially means: “0.1[mV/X] 0[mV] = 0”. The unit “X” you set is just telling BV software how to convert the aux channel to a mV measurement from an arbitrary unit. This becomes a problem when transferring data into MNE because MNE registers any unit with a capital V at the end as an actual unit and thus a scaling factor. The BV software does not do this and reads all units as arbitrary until converted. They additionally pointed out that the BV analyzer ends up not having this problem because they read from the “Channels” section of the vhdr file, not the “[Channel Infos]” section. That is in essence my takeaway from many back and forths with them. If you need more detail I can supply the email chains. There may have been some important details in them that were over my head.

Below is a picture of the setup screen before starting an experiment, with only aux channels selected. This is what is set prior to recording and is used to calculate the resolution of the aux channels to 1 in the vhdr file after recording. the only things you can change here (besides the name and channel number) are the unit, the number under gradient, and the offset (which is stating where to expect baseline to start. almost always 0).

For my particular experiment the fix is quite simple, change the resolution units in the vhdr file from “mv” to “µV” and if necessary the resolution from 1 to 0.1 if I need the output smaller still. I have found that because BV analyzer reads from the “Channels” section I only need to change it there, but I also need to change the far right hand equation units to match as well. On the other hand, in MNE, I only need to change the resolution number and units under the “[Channels Infos]” section due to the “Channel” section not being used by MNE, at least not the “Resolution” part or the far right hand equation in that section of the vhdr file.

Hope that helps shine some light,
Matt

2 Likes