Skip to content

Conversation

@wmvanvliet
Copy link
Contributor

This adds a base function apply_reference that can apply various
different referencing schemes. Two convenience functions are also
added that provide a convenient interface to the base function:

  • set_eeg_reference: apply a simple reference to all EEG channels
  • set_bipolar_reference: apply a bipolar reference (or more)

A helper function _parse_channel_list is also added to help functions
be more flexible in how they allow channels to be specified.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@wmvanvliet which problem does this solve?

@coveralls
Copy link

Coverage Status

Coverage increased (+31.39%) when pulling df8b9e6 on wmvanvliet:reference into 4abb240 on mne-tools:master.

mne/io/base.py Outdated
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

eeg -> EEG

@agramfort
Copy link
Member

should we have a way to store in info or somewhere what type of referencing was applied?

How about a method to revert a reference. I am thinking about this for inverse modeling as you don't want anything else than average ref for inverse modeling. This undo_reference or revert_reference method should be able to be applied to any data container.

@wmvanvliet
Copy link
Contributor Author

It would be very hard to invert referencing and apply CAR retroactively. For example, channels may be dropped along the way. If the user wants to perform source modelling, they should definitely stick to a CAR reference, which is and should be the default. The user has to explicitly define another reference and presumably the user knows what he/she is doing.

@agramfort
Copy link
Member

The user has to explicitly define another reference and presumably the user knows what he/she is doing.

you're optimistic :)

Then we should have a flag that says if data has been referenced is a
non-compatible way with inverse modeling. Then raise an error.

@dengemann
Copy link
Member

Then we should have a flag that says if data has been referenced is a
non-compatible way with inverse modeling. Then raise an error.

+1

@wmvanvliet
Copy link
Contributor Author

I can add the flag, but the check should be implemented by someone familiar with the source modelling code.

@agramfort
Copy link
Member

sounds like a plan

@dengemann
Copy link
Member

fair enough

@wmvanvliet
Copy link
Contributor Author

Shall I add a constant to io.constants.FIFF for some referencing types (including OTHER)? Then source modelling code can check assert info['reference'] == FIFF.FIFFV_REF_CAR

@agramfort
Copy link
Member

how many of such options would we add? other option is have a boolean flag.

@wmvanvliet
Copy link
Contributor Author

but we must now what kind of reference was applied, CAR or something else…
The flag would become ‘car_reference_applied’ or something similar.

On 26 Nov 2014, at 19:44, Alexandre Gramfort notifications@github.com wrote:

how many of such options would we add? other option is have a boolean flag.

Reply to this email directly or view it on GitHub #1670 (comment).

Marijn van Vliet
w.m.vanvliet@gmail.com

@agramfort
Copy link
Member

but we must now what kind of reference was applied, CAR or something else…
The flag would become ‘car_reference_applied’ or something similar.

the thing is that CAR works with an SSP / proj and it's nice and elegant.

I feel we should stick to it when we apply CAR (ie. create proj and apply it)

For all the other reference options set a flag that says that it will
not be compatible with inverse modeling.

wdyt?

@wmvanvliet
Copy link
Contributor Author

Agreed.

Lets recap the EEG referencing arguments so far:

  1. The default reference should be CAR
  2. It should be straightforward for the user to apply another reference
  3. When another reference is set, source localization will be unreliable/wrong
  4. Computing the CAR on bad channels is bad

1. The default reference should be CAR

Upon loading a raw file, a CAR projector is automatically added for the EEG. Any bad channels already marked in the raw data are excluded.

2. It should be straightforward for the user to apply another reference

The apply_reference function applies a different reference, but not through an SSP projector (this is as far as I know only possible for CAR). The convenience functions set_eeg_reference and set_bipolar_reference wrap this function to provide a nice interface to the user.

If a CAR SSP projection is present in the data, it should be removed by this function. Otherwise things become very confusing for the user. When an instance of Epochs is created, the current behaviour is to add a CAR projection if not present. Instead, the flag should be checked and respected. Also, the user should be able to use the set_eeg_reference to specify the data has already been referenced (some systems, like the Emotiv EPOC, do referencing at the driver level) and prevent any automatic adding of a CAR reference.

3. When another reference is set, source localization will be unreliable/wrong

The user might not be aware of this, so a flag should be set if a non-CAR reference is applied. An error can then be generated during source localization.

Lets keep the code simple and make apply_reference always set this flag to True. This means that even if the user applies CAR using this function, it would be flagged as a non-CAR reference. Otherwise the function would have to do some trickery to determine whether the reference is CAR equivalent or require the user to specify this. Both methods are prone to error. Always setting the flag to True is another reason for removing the default behaviour of set_eeg_reference.

4. Computing the CAR on bad channels is bad

There should be a way to conveniently update the CAR projection after modifying the info['bads'] structure.

@dengemann @agramfort @t3on Do you agree on all points?

@dengemann
Copy link
Member

regarding #1 the only thing is that you often do not know about bad channels before loading data, often you only tknow that at the epochs stage.

apart from that sounds good

On 28 Nov 2014, at 09:05, Marijn van Vliet notifications@github.com wrote:

Agreed.

Lets recap the EEG referencing arguments so far:

The default reference should be CAR
It should be straightforward for the user to apply another reference
When another reference is set, source localization will be unreliable/wrong
Computing the CAR on bad channels is bad

  1. The default reference should be CAR

Upon loading a raw file, a CAR projector is automatically added for the EEG. Any bad channels already marked in the raw data are excluded.

  1. It should be straightforward for the user to apply another reference

The apply_reference function applies a different reference, but not through an SSP projector (this is as far as I know only possible for CAR). The convenience functions set_eeg_reference and set_bipolar_reference wrap this function to provide a nice interface to the user.

  1. When another reference is set, source localization will be unreliable/wrong

The user might not be aware of this, so a flag should be set if a non-CAR reference is applied. An error can then be generated during source localization.

Lets keep the code simple and make apply_reference always set this flag to True. This means that even if the user applies CAR using this function, it would be flagged as a non-CAR reference. Otherwise the function would have to do some trickery to determine whether the reference is CAR equivalent or require the user to specify this. Both methods are prone to error. Always setting the flag to True is another reason for removing the default behaviour of set_eeg_reference.

Lastly, if a CAR SSP projection is present in the data, it should be removed by this function. Otherwise things become very confusing for the user. When an instance of Epochs is created, the current behaviour is to add a CAR projection if not present. Instead, the flag should be checked and respected. The user should be able to use the set_eeg_reference to specify the data has already been referenced (some systems, like the Emotiv EPOC, do referencing at the driver level) and prevent any automatic adding of a CAR reference.

  1. Computing the CAR on bad channels is bad

There should be a way to conveniently update the CAR projection after modifying the info['bads'] structure.

@dengemann @agramfort @t3on Do you agree on all points?


Reply to this email directly or view it on GitHub.

@dengemann
Copy link
Member

yess, 4. is exactly it

On 28 Nov 2014, at 09:05, Marijn van Vliet notifications@github.com wrote:

Agreed.

Lets recap the EEG referencing arguments so far:

The default reference should be CAR
It should be straightforward for the user to apply another reference
When another reference is set, source localization will be unreliable/wrong
Computing the CAR on bad channels is bad

  1. The default reference should be CAR

Upon loading a raw file, a CAR projector is automatically added for the EEG. Any bad channels already marked in the raw data are excluded.

  1. It should be straightforward for the user to apply another reference

The apply_reference function applies a different reference, but not through an SSP projector (this is as far as I know only possible for CAR). The convenience functions set_eeg_reference and set_bipolar_reference wrap this function to provide a nice interface to the user.

  1. When another reference is set, source localization will be unreliable/wrong

The user might not be aware of this, so a flag should be set if a non-CAR reference is applied. An error can then be generated during source localization.

Lets keep the code simple and make apply_reference always set this flag to True. This means that even if the user applies CAR using this function, it would be flagged as a non-CAR reference. Otherwise the function would have to do some trickery to determine whether the reference is CAR equivalent or require the user to specify this. Both methods are prone to error. Always setting the flag to True is another reason for removing the default behaviour of set_eeg_reference.

Lastly, if a CAR SSP projection is present in the data, it should be removed by this function. Otherwise things become very confusing for the user. When an instance of Epochs is created, the current behaviour is to add a CAR projection if not present. Instead, the flag should be checked and respected. The user should be able to use the set_eeg_reference to specify the data has already been referenced (some systems, like the Emotiv EPOC, do referencing at the driver level) and prevent any automatic adding of a CAR reference.

  1. Computing the CAR on bad channels is bad

There should be a way to conveniently update the CAR projection after modifying the info['bads'] structure.

@dengemann @agramfort @t3on Do you agree on all points?


Reply to this email directly or view it on GitHub.

@agramfort
Copy link
Member

  1. The default reference should be CAR

Upon loading a raw file, a CAR projector is automatically added for the EEG. Any bad channels already marked in the raw data are excluded.

should we deprecate this default behavior?

  1. It should be straightforward for the user to apply another reference

The apply_reference function applies a different reference, but not through an SSP projector (this is as far as I know only possible for CAR). The convenience functions set_eeg_reference and set_bipolar_reference wrap this function to provide a nice interface to the user.

I feel when CAR is asked the proj should be added and applied. It is
wrong to have 2 ways to do the same thing internally. But we can have
a common API to set the different references.

  1. When another reference is set, source localization will be unreliable/wrong

The user might not be aware of this, so a flag should be set if a non-CAR reference is applied. An error can then be generated during source localization.

+1

Lets keep the code simple and make apply_reference always set this flag to True.

I would set it to True only if non CAR.

This means that even if the user applies CAR using this function, it would be flagged as a non-CAR reference.

I am -1 on this.

Lastly, if a CAR SSP projection is present in the data, it should be removed by this function. Otherwise things become very confusing for the user.

hide the complexity from the user.

does it seem doable?

  1. Computing the CAR on bad channels is bad

There should be a way to conveniently update the CAR projection after modifying the info['bads'] structure.

+1. Any suggestion of how to do this?

@wmvanvliet
Copy link
Contributor Author

should we deprecate this default behavior?

Probably not. It would open up the possibility for the user to forget to apply a reference. If we can make it easy for the user to set another reference, this default should not inconvenience the user.

I feel when CAR is asked the proj should be added and applied

But how should the user ask for CAR? Of course, the best method for the user would be to simply keep the default. But if the user really wants to explicitly ask for it, I was thinking of making him call the make_eeg_ref_proj function. Maybe it is a better idea to allow the user to specify CAR through the set_eeg_reference function as well. I will play with the API and get back to you.

hide the complexity from the user.
does it seem doable?

yes.

+1. Any suggestion of how to do this?

I was thinking about putting a system in place that checks the info dictionary. When it is changed (for example, channel names are updates, channels are added or removed) the dictionary is updated (nchans, ch_names, etc.) Such a system could also keep track of changes to the bad channels. Definitely not something for this PR, but something to think about.

@wmvanvliet
Copy link
Contributor Author

what does the active flag of a projection actually do?

@wmvanvliet
Copy link
Contributor Author

@agramfort how about this for an API to set_eeg_reference? Now it's backwards compatible, and used the correct method for applying CAR.

@agramfort
Copy link
Member

what does the active flag of a projection actually do?

when a proj is active it means it has been applied to the data.

@agramfort
Copy link
Member

besides LGTM

you'll need to update python_reference.rst + what's new

someone please have a look too.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So this field always exists when reading info now...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, otherwise you'll have to check if 'custom_ref_applied' in info and info['custom_ref_applied'] every time you want to do something with the flag.

@larsoner
Copy link
Member

Other than my minor concerns, LGTM.

mne/io/base.py Outdated
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pep257

One headline after """
then empty line and a full sentence / paragraph describing the function.

@agramfort
Copy link
Member

also:

  • we should have an example that demonstrates the use of the function
  • you'll need to update what's new and python_reference.rst

that's it for me now.

@wmvanvliet
Copy link
Contributor Author

Rebased.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use the mean of channels EEG 001 and EEG 002 as a reference

This adds a base function 'apply_reference' that can apply various
different referencing schemes. Two convenience functions are also
added that provide a convenient interface to the base function:

 - set_eeg_reference: apply a simple reference to all EEG channels
 - set_bipolar_reference: apply a bipolar reference (or more)
Raw and Epoch classes will no longer add an average reference if the
`custom_ref_applied` flag was set. SSP projections will still attempt
this, but a new assertion in `make_eeg_average_ref_proj` will raise an
error if the flag was set.

Before a CAR projection is added, the `info['custom_ref_applied']` flag
is checked.
- Also check for duplicate channel names
- Bilpolar channels can be named after the anode/cathode
- Inform user of the chosen bipolar channel name
@wmvanvliet
Copy link
Contributor Author

rebased (again), and tweaked the example a little to reduce memory consumption.

@agramfort
Copy link
Member

closing in favor of #1713

@wmvanvliet see my last 4 commits.

@agramfort agramfort closed this Dec 23, 2014
@wmvanvliet wmvanvliet deleted the reference branch January 5, 2015 09:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants