labstreaminglayer / App-BrainProducts

BrainProducts App
2 stars 3 forks source link

Actichamp lsl units different from pycorder #5

Closed nmc-costa closed 4 years ago

nmc-costa commented 5 years ago

Hello,

This is a follow up of a possible error I reported to Chadwick, some months ago.

Below Is an example of the data saved using pycorder and lsl app without any type of processing:

Pycorder [0.01562246 0.01562241 0.01562026 0.01561719 0.01561621 0.01561421 0.01561523 0.01561685 0.01561904 0.01561929 0.01561475 0.01561016 0.01561255 0.0156165 0.01561782 0.01561909 0.01561836 0.01561694 0.01561982 0.0156252 0.01562598 0.01562915 0.01562603 0.01562422 0.01562187 0.01561753 0.01561704 0.01561855 0.01561953 0.01561831]

LSL APP [220975.921875 219307.203125 216602.15625 214850.75 216484.78125 219165.0625 217279.984375 218020.796875 221028.28125 217249.6875 216987.34375 214310.5625 218962.46875 218149.265625 218684.859375 219599.1875 218390.96875 219006.40625 216916.984375 219051.921875 219706.734375 217162.984375 214919.046875 214086.734375 219044.65625 217850.671875 217084.0625 219812.546875 218377.96875 216271.125 ]

Still haven't found the problem. Units, DC offset or lack of electrode reference ?

Units The units are supposed to be in microvolts in pycorder(the .vhdr states format IEEE_FLOAT_32 and scale 1) and also in the lsl app, correct?

DC offset I used an highpass filter with low cutoff of 1 Hz, but nothing.

Electrode Reference While Pycorder can be saved with electrode reference, lsl app can't (only active shield enabled).

Signals I attach the raw signal from pycorder and lsl app files in .fif format. They have similar number of channels(pycorder: Ch 1 was reference(31) + Auxiliars(6), lsl APP (32 Chs with no ref))

e2_test.zip

cboulay commented 5 years ago

@dmedine

nmc-costa commented 5 years ago

@dmedine

Thanks @cboulay

nmc-costa commented 5 years ago

Update with signal processing(from e2_test.zip files):

Using mne to work with .fif format:

filter=True
rereference=True
ref_channels=['Fp1']

**#pycorder (reference : Fp1)**
filepath=os.path.join(dir_root, "e2_pycorder_test_newbat_1min")
raw_p = mne.io.read_raw_fif(filepath, preload=True)
print(raw_p.ch_names)
if filter:
    l_freq, h_freq=1, None#highpass
    raw_p.filter(l_freq, h_freq)
    l_freq, h_freq=None, 40#lowpass
    raw_p.filter(l_freq, h_freq)

raw_p_data, raw_p_times= raw_p[:] #format: chs X dat

**#lsl app (no reference)**
filepath=os.path.join(dir_root, "EG_S007_REST_ss01_b01_05092019_12h15m_rest_1")
raw_m = mne.io.read_raw_fif(filepath, preload=True)
print(raw_m.ch_names)
if filter:
    l_freq, h_freq=1, None#highpass
    raw_m.filter(l_freq, h_freq)
    l_freq, h_freq=None, 40#lowpass
    raw_m.filter(l_freq, h_freq)
if rereference:
    raw_m.set_eeg_reference(ref_channels=ref_channels, projection=False)

raw_m_data, raw_m_times= raw_m[:] #format: chs X dat

print(raw_p_data[1, 1000:1030])
print(raw_m_data[2, 1000:1030])
**#Output**

_Pycorder_
[-4.00186905e-06 -4.12276401e-06 -4.21407110e-06 -4.27598689e-06
 -4.30884310e-06 -4.31348985e-06 -4.29080132e-06 -4.24122460e-06
 -4.16527532e-06 -4.06363380e-06 -3.93640006e-06 -3.78416174e-06
 -3.60752405e-06 -3.40756334e-06 -3.18603423e-06 -2.94491605e-06
 -2.68692913e-06 -2.41648642e-06 -2.13829846e-06 -1.85733369e-06
 -1.57941973e-06 -1.31074253e-06 -1.05735131e-06 -8.25211431e-07
 -6.19749106e-07 -4.45732364e-07 -3.06979995e-07 -2.05322779e-07
 -1.40908219e-07 -1.13602668e-07]

_lsl_
[ 64.66551625  61.62812632  55.53366646  46.75018938  35.69182797
  23.02263417   9.46377904  -4.14607252 -17.10115282 -28.46455331
 -37.56054529 -43.86562235 -46.93714279 -46.60882999 -42.95490179
 -36.16107335 -26.72251816 -15.27110773  -2.55973655  10.59579539
  23.39286029  35.09712272  45.05783552  52.71528491  57.62727058
  59.7758795   59.20510404  56.20929013  51.2033426   44.70723236]

These are still strange values to me. What am I missing? Is this correct?

dmedine commented 4 years ago

I am sort of surprised to see this. The actiCHamp lsl connector is quite old and hitherto no one has complained about it. That doesn't mean, of course, that it is not malfunctioning. In any case, I am sorry that this is happening.

I have made a new app which isn't available online yet that connects to both LiveAmp and actiCHamp. In the future, this will be the recommended way to interface these two amplifiers with LSL. We are struggling with some license issues here at Brain Products which is why this software is unreleased (don't worry, it will be opensource!). However, if you need it, I can give you access to a 'beta' release. The only difference between this and the pending official version is the license, so you can rely on it to give correct values. Please contact me at dm[at]brainproducts[dot]com and I will fix you up.

nmc-costa commented 4 years ago

@dmedine Thank you for the response. I've sent you an email. If you can send me the software I will appreciate that.

Thanks

nmc-costa commented 4 years ago

@dmedine @cboulay

Update: I tested Pycorder + Brainvision RDA app. Using pycorder simulation of sinusoidal I can test if the data is ok.

Results:

Pycorder Saved data [ 999860.3125 1000169.375 1000461.875 1000708.984375 1000886.71875 1000977.5 1000972.65625 1000872.5 1000686.953125 1000434.0625 ]

LsL RDA app Saved data [ 99986.03125 100016.9375 100046.1875 100070.8984375 100088.671875 100097.75 100097.265625 100087.25 100068.6953125 100043.40625 ]

So, if pycorder saves in microVolts, and mne transf, must assume a scale factor of 10e1 for the lsl to be in microVolts. Therefore, demonstrating it works with brainvision RDA app.

Problem, the delay is bigger instead of 15ms, it is 50ms.

Hope you can send me the software, meanwhile using RDA app.

Thanks

dmedine commented 4 years ago

I didn't get any email, by the way. Can you confirm that it didn't bounce back to you?

The RDA client simply forwards whatever data is coming into Recorder. I don't know anything about the units in Pycorder. You will have to contact TechSup at Brain Products for questions there. If you are in the USA, you should try Brain Vision LLC first.

On 11.09.2019 15:52, nmc-costa wrote:

@dmedine https://github.com/dmedine @cboulay https://github.com/cboulay

Update: I tested Pycorder + Brainvision RDA app. Using pycorder simulation of sinusoidal I can test if the data is ok.

Results:

/Pycorder Saved data/ [ 0.09995649 0.09998603 0.10001694 0.10004619 0.1000709 0.10008867 0.10009775 0.10009727 0.10008725 0.1000687 0.10004341]

/LsL RDA app Saved data/ [ 99956.4921875 99986.03125 100016.9375 100046.1875 100070.8984375 100088.671875 100097.75 100097.265625 100087.25 100068.6953125 100043.40625 ]

So, if pycorder saves in Volts, must assume a scale factor of 10e-7 for the lsl to be in Volts. Therefore, demonstrating it works with brainvision RDA app.

Problem, the delay is bigger instead of 15ms, it is 50ms.

Hope you can send me the software, meanwhile using RDA app.

Thanks

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/labstreaminglayer/App-BrainProducts/issues/5?email_source=notifications&email_token=AA3SD3WRAJ4XJGD3WSDOAM3QJDZZXA5CNFSM4IU4GBP2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD6OR32A#issuecomment-530390504, or mute the thread https://github.com/notifications/unsubscribe-auth/AA3SD3QHOTOC2JDPWCEOUNTQJDZZXANCNFSM4IU4GBPQ.

nmc-costa commented 4 years ago

Hello @dmedine ,

I´ve sent you a new email to dmedine@ucsd.edu, with the subject: Github follow up - Software for Lsl.

Thanks for your help.

dmedine commented 4 years ago

I am no longer affiliated with UCSD and as far as I know that email address is dead. I have updated my profile and my current private address is in there. You can use that to get in touch with me directly.

nmc-costa commented 4 years ago

Hello @dmedine I've sent you an email, did you received It?

Subject in email: Github follow up - Software for Lsl

Additionally,I don't know your expertise in EEG and Actichamp. However, do you know if in pycorder is better to have a common ref(for example, Fp1) or no-ref with active shield on? Because if I use common ref, this channel is not sent through lsl , and I lose a channel. This, probably will mean I will not be able to rereference with all chs.

For online analysis my basic experience tells me to send through lsl all chs with no-ref and active shield on. Then during online processing use a common average reference and reject epochs using Fp1, Fp2 (EOG) and chs directy related to online feature target.

Thanks for your help, NC