-
Notifications
You must be signed in to change notification settings - Fork 1.4k
add_channels() documentation is difficult to understand #11106
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Indeed. Can you send a PR to improve?
|
Oh wow only after actually looking at the code I realize I totally misunderstood what this method is even supposed to do, based on what I expected from the method name and its docstring. The docstring says,
So what I thought I could do is, just pass an array of data for additional channels (and channel names), and they will be appended to the existing instance. But actually what this method is supposed to do is in fact a concatenation of multiple objects of the same type, right? But we already have I guess I'm thinking sort of like in terms of Any thoughts here? |
it's adding channels so pd.concat(..., axis=channels)
it needs to be more than channel name and array as a channel info["chs"] is
a lot more than this.
… Message ID: ***@***.***>
|
Exactly! That's why naming the method Look just how much code I had to produce to add two channels to an existing raw: # Add GSR and temperature channels
gsr_data = np.array([2.1e-6] * len(raw.times))
temperature_data = np.array([36.5] * len(raw.times))
gsr_and_temp_data = np.concatenate([
np.atleast_2d(gsr_data),
np.atleast_2d(temperature_data),
])
gsr_and_temp_info = mne.create_info(
ch_names=["GSR", "Temperature"],
sfreq=raw.info["sfreq"],
ch_types=["gsr", "temperature"],
)
gsr_and_temp_info["line_freq"] = raw.info["line_freq"]
gsr_and_temp_info["subject_info"] = raw.info["subject_info"]
with gsr_and_temp_info._unlock():
gsr_and_temp_info["lowpass"] = raw.info["lowpass"]
gsr_and_temp_info["highpass"] = raw.info["highpass"]
gsr_and_temp_raw = mne.io.RawArray(
data=gsr_and_temp_data,
info=gsr_and_temp_info,
first_samp=raw.first_samp,
)
raw.add_channels([gsr_and_temp_raw])
del gsr_and |
I am not sure what you suggest here.
Message ID: ***@***.***>
… |
+1 to improve the docs based on the 4 points in the OP once that is clarified, I think it's easier to live with the fact that
not sure either, but perhaps that |
Agree that this is way too difficult. Comments below: # Add GSR and temperature channels
gsr_data = np.array([2.1e-6] * len(raw.times))
temperature_data = np.array([36.5] * len(raw.times))
gsr_and_temp_data = np.concatenate([
np.atleast_2d(gsr_data),
np.atleast_2d(temperature_data),
]) The above could be simplified a bit; still 3 expressions but much shorter: gsr = np.full((1, len(raw.times)), 2.1e-6)
temp = np.full((1, len(raw.times)), 36.5)
gsr_and_temp_data = np.vstack([gsr, temp]) This next bit seems unaviodable but not so bad: gsr_and_temp_info = mne.create_info(
ch_names=["GSR", "Temperature"],
sfreq=raw.info["sfreq"],
ch_types=["gsr", "temperature"],
) Are the below lines necessary when creating RawArray, or only when adding the channels to the existing Raw? (I suspect the latter, but haven't checked). Regardless, we should make it possible to skip line_freq, lowpass, highpass, and subject_info for cases like this --- perhaps by having "wildcard" defaults that will automatically take on the values of the Raw they are concatenated with? This is (I think) what gsr_and_temp_info["line_freq"] = raw.info["line_freq"]
gsr_and_temp_info["subject_info"] = raw.info["subject_info"]
with gsr_and_temp_info._unlock():
gsr_and_temp_info["lowpass"] = raw.info["lowpass"]
gsr_and_temp_info["highpass"] = raw.info["highpass"] The rest seems unavoidable, but if the two simplifications above were made, I think we're down to something reasonable/acceptable. gsr_and_temp_raw = mne.io.RawArray(
data=gsr_and_temp_data,
info=gsr_and_temp_info,
first_samp=raw.first_samp,
)
raw.add_channels([gsr_and_temp_raw]) As for the intuitiveness of the API name... I think I would agree that something like |
I am not sure myself either 😆 But I suppose my feeling was that:
Thanks @drammock for the simplifications, that's helpful! |
I would suggest to follow what @drammock <https://github.com/drammock>
suggests.
the rest well, if someone has time to iterate but for me it's a lot of work
for a small
return.
this operation was necessary to hack a test in mne-bids not to actually
process data
so I don't expect people to do these operations all the time.
Message ID: ***@***.***>
… |
I would rather not add this. To me it's replicating RawArray without much gain. I don't think this extra line is worth the API duplication. Can we just live with a documentation improvement for now? |
Yep, let's do that! |
Hey! who said I'd be volunteering? 😅😅😅😅 |
I believe @agramfort calls this being "volun-told" :) More seriously if you won't have time in the next few days @drammock or I could give it a shot. But I think you're the best equipped having most recently suffered through the doc badness :) |
Milestone on this has been bumped six times, removing milestone until someone champions this issue. But also marking as "easy" so it hopefully gets visibility / higher likelihood of being tackled |
I have added some documentation in #13051, however, having this as a convenience function without having to worry about potentially overwriting things in the Having a simple function |
I just wanted to use
Raw.add_channels()
, so I looked at the API docs and even though I'm a developer, it actually took me a couple of seconds to even understand what could probably be meant, and still I think I'll have to take a look at the code to get a better understanding:self
I believe we're making bad use of the docdict here, avoiding redundancy but making the docs effectively useless because they're too weird and hard to understand.
Didn't we recently have a somewhat similar case where we ended up with a way to improve things?
The text was updated successfully, but these errors were encountered: