Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Activity
    Dirk Gütlin
    @DiGyt
    Yeah, that would be a quite good alternative since it wouldn't even require to pass on the ouput type to SourceTFR
    Dirk Gütlin
    @DiGyt
    But then again, this would imply additional struggle for users, since the handling of SourceEstimate functions would diverge quite a lot from the handling of usual data. So power as well as possibly other params like return_itc would be needed to be False for SourceEstimates and the users need to manually create the power field. And this additional expense for the user would be only implemented because of a "marginal" case, since for fully (non-kernelized) SourceEstimates (which i'd say are the only ones really used atm) all this wouldn't even pose a problem...
    Would it be more ethically acceptable to create the SourceTFR data field from SourceTFR.get_data() instead of SourceTFR.data and then do the implementation i described above?
    Eric Larson
    @larsoner
    sure
    get_data should work
    Dirk Gütlin
    @DiGyt
    ok, great!
    Thanks for the help!
    Dirk Gütlin
    @DiGyt

    Hey again.

    I'm at a point now where most stuff works fine for single stcs and morlet, multitaper & stockwell.
    However, there's one bigger step left in the data processing, which is the introduction of 'epoched' SourceTFR.
    If we want to be able to return the Inter-Trial-Coherence, we need to be able to feed multiple SourceEstimates, in the form of lists, to tfr_functions.

    Dirk Gütlin
    @DiGyt

    my vision of doing this would be taking lists of equal data types into the tfr_function, and concatenating their contents to a single data array at a very early stage, so that the data is treated like an epochs field. For stcs with a data field of (kernel, sens_data) this process would lead to a data array similar to a usual epochs data array. However, for stcs with fully represented data, this can lead to quite huge data arrays. Of course, we warn the user of this, and advise him to use kernelized data in order to save memory.
    Still, i wanted to hear your opinion on this.

    Another thing that has me hesitating is that @agramfort mentioned to take into mind the implications that the processing of lists might have. I think 'epoching up' the data at an early stage and from then on treating the data like epochs should be quite safe for stcs as well as standard epochs/average data. Still, i could of course be missing some important implications (e.g. implications this might have for epochs and average data). That's why i wanted to ask you: Is there something i should take care of when allowing tfr_functions to take lists as input?
    Of course i can rely on the tests telling me if anything went wrong, but i still thought it's better to ask.

    So, in short: What's your opinion on making tfr_functions take list as input?
    and: Are there some special implications we should be aware of?

    Dirk Gütlin
    @DiGyt
    For example, one tricky thing i'm thinking of would to to keep in mind the number of nave when feeding lists of Evoked objects to tfr_functions.
    If there are multiple Evokeds with different nave numbers, we should keep track of this, especially of they're averaged again in the tfr_function,
    in which case they should be averaged with a weighted mean. Theoretically this should also hold for SourceEstimates, even though i think they don't even carry that information themselves.
    Eric Larson
    @larsoner

    and: Are there some special implications we should be aware of?

    Memory consumption can be a limiting factor as you say. Is there some way we could avoid creating a gigantic array? Can ITC be computed efficiently while only processing one epoch at a time?

    Alexandre Gramfort
    @agramfort

    I imagine that if you do:

    stcs = apply_inverse_epochs(..., return_generator=True)
    itc = tfr_morlet(stcs, ...)

    it should be able to work.

    Dirk Gütlin
    @DiGyt
    OK, i'll try that, thanks for your suggestions!
    Dirk Gütlin
    @DiGyt

    Hey, just for your information:

    Yesterday, I created 2 very brute attempts to feed lists and generators into tfr functions.

    https://github.com/DiGyt/mne-python/blob/37a0e7e169b56f24711c0ab8164c4f18fd4aef6c/mne/time_frequency/tfr.py#L597

    In this first approach, i tried to process each list element subsequently in order to save memory, as @larsoner suggested. This 'fast and dirty' hack worked for tfr_morlet, but didn't for multitapers. The problem is, that if we want to do this properly, we need to pass the lists/gens waaaay down through _tfr_aux and _compute_tfr into _time_frequency_loop, or alternatively pull the loop that iterates over the different taper functions way up from _time_frequency_loop into _tfr_aux. Since there is a lot of data handling that would e.g. require to get the length of the generator object before starting to loop through it, this task simply looks to my like entirely restructuring those three functions.
    Of course this can be done, but it will require some time. Because i would really try to make things work for Source Space first as the primary objective, i then implemented the second approach:

    https://github.com/DiGyt/mne-python/blob/98596051dc6e74b773f66939c7d33c65ebe2ea8e/mne/time_frequency/tfr.py#L596

    This is the simple approach I named before. It just takes the list at the beginning of _tfr_aux and concatenates it to one big data field. From then on, it works exactly the same as usual data. (I.e. works fine for epochs/average lists/generators of morlet/multitaper). Of course, this kind of misses the memory saving point of having a list at all, but it serves well enough to start working with SourceEstimates.

    So for now, i'd carry on with the second approach, and when we got the rest of the SourceTFR stuff working, i'd say we can approach the first problem.
    Please note that until then, we still would have the kernel trick to work for us in order to save memory, so that effectively, memory used for transforming stcs would not exceed the memory used for an epochs object.

    Alexandre Gramfort
    @agramfort
    Can you attempt to make a pr to main repo with a minimal first contribution eg restricted to tfr_morlet?
    Dirk Gütlin
    @DiGyt
    For the SourceSpace TFR? I was planning to start a more or less complete PR after finishing the lists for SourceEstimates, somewhen next week.
    But if you like i can do a PR on the second list thing right away ( https://github.com/DiGyt/mne-python/tree/feed_lists_to_tfr_ii ).
    So if everything there works fine (and after some smaller fixes), the only thing left to think about would be plotting...
    Alexandre Gramfort
    @agramfort
    Keep in mind that we will have to review the diff. And fed with small pieces it is easier to digest for reviewers
    Dirk Gütlin
    @DiGyt
    That's true! but at least the morlet/multitaper stuff is very hard to separate...
    But I'll try to push a few separable things beforehand!
    Dirk Gütlin
    @DiGyt

    Hey everyone,

    Sorry for not yet pushing the time_frequency with SourceTFR commits. I had quite some trouble with the combination of multiple tapers and lists/gens, especially the subsequent processing of the generator objects and calculating the inter-trial-coherence correctly. I kind of needed to change everything and introduced a separate function tfr_loop_list in order to make this work.
    But it's running all smooth now, which means that morlet, multitaper and stockwell work correctly with single stcs/lists/generators, normal/vector ori, return_itc (as well as average for morlet & multitapers).

    Other good news are that - at least for multitapers and morlet- the single list elements are now computed subsequently, which means we can actually save memory when using generators, and won't need to create huge data fields first.

    Bad news are that enabling all this to work for lists/generators AND kernelized data fields will still involve a lot of additional work, especially since i got the impression that most of the computation needs to be transferred from the tfr_functions to the SourceTFR objects, when stfr.data is called. I'll show you the problems later, and hope that there's an efficient solution for this.

    So for now, i'll just clean up the list stuff a little bit and make it ready for a PR, and then focus on the Kernel stuff later.

    Alexandre Gramfort
    @agramfort
    Maybe there is a simple design we can come up with
    Pass callables as params or use private functions etc
    Dirk Gütlin
    @DiGyt
    Yes, i hope so! I'll give it a new try tomorrow and then will point out to you all the things that cause problems.
    Joan Massich
    @massich
    hei
    @DiGyt was it intendeed to touch the doc/ in https://github.com/mne-tools/mne-python/pull/6629/files ?
    30+ commits, and 25 files are complicated to review.
    before pushing you should check with git diff master..MY_BRANCH to check what's in the diff.
    Joan Massich
    @massich
    git diff master.. --names-only shows this changes:
    doc/_static/institution_logos/Aalto.svg doc/_static/institution_logos/BU.svg doc/_static/institution_logos/Inserm.svg doc/_static/institution_logos/Julich.svg doc/_static/institution_logos/MGH.svg doc/_static/institution_logos/MIT.svg doc/_templates/layout.html doc/data_formats.rst doc/precision.rst doc/units.rst mne/minimum_norm/inverse.py mne/minimum_norm/tests/test_inverse.py mne/source_estimate.py mne/source_tfr.py mne/tests/test_source_tfr.py mne/time_frequency/_stockwell.py mne/time_frequency/tests/test_stockwell.py mne/time_frequency/tests/test_tfr.py mne/time_frequency/tfr.py mne/viz/_brain/_brain.py mne/viz/_brain/view.py mne/viz/epochs.py mne/viz/raw.py mne/viz/utils.py tutorials/raw/plot_10_raw_overview.py
    I don't think you wanted to change all these files. I'll push a commit to clean up the diff
    Dirk Gütlin
    @DiGyt

    Hey Everyone.

    I now got the first simple implementation for plotting SourceTFR. When @agramfort and I discussed the project, he said that the minimum would be to be able to convert the SourceTFR into stcs, and then plot these. Based on this, I implemented stfr.plot(fmin=0, fmax=None, epoch=0, **plot_params).

        def plot(self,fmin=0, fmax=None, epoch=0, **plot_params):
    
            freq_idx = _freq_mask(self.freqs, self.sfreq, fmin, fmax)
            #FIXME: sum over average? sum is easier to interprete, but will result in bad color scalings
            data_cropped = np.mean(self.data[..., freq_idx, :], axis=-2)
    
            if "epochs" in self.dims:
                data_cropped = data_cropped[..., epoch, :, :]
    
            if self._src_type == "volume":
                # use the magnitude only if it's a VolVectorSourceEstimate (see _BaseVectorSourceEstimate.plot)
                if "orientations" in self.dims:
                    data_cropped = np.linalg.norm(data_cropped, axis=1)
                brain = plot_volume_source_estimates(
                    VolSourceEstimate(data_cropped, self.vertices, self.tmin, self.tstep, self.subject), **plot_params)
    
            elif "orientations" in self.dims:
                brain = plot_vector_source_estimates(
                    VectorSourceEstimate(data_cropped, self.vertices, self.tmin, self.tstep, self.subject), **plot_params)
    
            else:
                brain = plot_source_estimates(
                SourceEstimate(data_cropped, self.vertices, self.tmin, self.tstep, self.subject), **plot_params)
    
            return brain

    With this plot method, you can choose the frequencies you want to include. These frequencies are then selected by utils._freq_mask and averaged. If the SourceTRF has an "epochs" dimension, the epoch param is used as index on which frequency to plot. Then this data plotted, using the according [Vol/Vector]SourceEstimate plot function. The plot params here are the respective params of plot[_volume/vector]_source_estimate, and therefore will differ, depending on the plotting function used.
    Of course, this is just some kind of hack, but It works fine and looks pretty clean to me.

    As a further goal, I wanted to do a proper SourceTFR plotting function, that includes stuff like a "Time-Frequency Viewer" (as compared to the "Time Viewer" Plot), where you can skim through the time axis as well as the frequency axis in the plotting GUI. However, i realize, that building a function that unites the plotting functionality of all source types (Note that this also should be done for two types of plots: The normal surface/vector plots, and the volume plots) will require a good amount of work again.

    That's why i wanted to ask you for advice, if you have some ideas how (or maybe even if) we should implemented this. Maybe there is some point where we could tweak the existing plotting structures, and integrate the functionality they provide with the new SourceTFR-specific tasks?

    Alexandre Gramfort
    @agramfort
    I am too disconnected to come up with options. What options would you consider?
    Sorry for not being too reactive but I am on holidays. I will be back to the lab next week
    Dirk Gütlin
    @DiGyt
    No worries, enjoy your holidays (and sorry for mentioning you in my message)!
    i'll just play around a little bit and see if I find a convenient way.
    Dirk Gütlin
    @DiGyt

    Hey all,

    concerning the plotting:
    I checked a little deeper into the plotting stuff last week, and I think that if we want to build a more elaborate plotting function for SourceTFRs, we will probably need some time after the GSoC to do so. I think that if we wanted to create a GUI, where users can not only switch along the time axis, but also along the freq axis, the best thing would be to copy FreeSurfer's TimeViewer, and generalize it to an AxisViewer, where one ore more axes can be manipulated in the same way as the time axis now. Likewise, for the Volume Plots, we could add a second window to the SourceTFR plotting function, which allows frequency indexing, just as the time window currently does. But as said, this will be a lot of work and I'd say that we should add this separately after GSoC (since I would rather spend the last week giving a final polish to what we've accomplished so far).

    I also wanted to talk to you about the final project page for GSoC:
    Last week, I started a GitHub gist that contains information, links and a summary of the project. I thought that this would be a simple, but good looking way of presenting the results of this GSoC. I tried to write it in a way that satisfies Google's requirements, but at the same is readable for the general public (so I could for example publish it on social media).

    I already wrote down most of the stuff, so you can get an idea on how it would look like if it's done.
    Here it is:
    https://gist.github.com/DiGyt/717393296a49e77a769c8fe182d3ffff

    Please have a look at it and tell me if it looks okay to you and if you're missing anything!

    Alexandre Gramfort
    @agramfort
    gist looks good
    as you must realize there is still some work to do to manage to merge this code in master.
    don't worry it's quite common for GSOC that the code take soem extra months to land in master
    but your help after the gsoc final date will be extremely appreciated
    Dirk Gütlin
    @DiGyt
    Yes, sure! There are still a lot of possibilites to make everything more compact.
    And more readable
    Dirk Gütlin
    @DiGyt
    Hey everyone. I want to include one of my examples in my github project gist, in a HTML representation like the one created from Sphinx-Gallery for the "https://martinos.org/mne/stable/auto_examples/..." examples. Is there a script somewhere in the MNE folders that tells Sphinx how to do it (e.g. plotting)? Or should I rather integrate it manually into the markdown script?
    Alexandre Gramfort
    @agramfort
    you ahve the rendered doc link by circle ci. Is it enough?
    Dirk Gütlin
    @DiGyt
    Wow, neat! Yes, that will absolutely do :)
    Thanks!
    Joan Massich
    @massich
    Are there any Polhemus users in the ROOM ????
    which file formats do you get your data? .txt .mat .hsp .elp ??
    is there any Polhemus official doc?
    Joan Massich
    @massich
    ups wrong room !!
    Dirk Gütlin
    @DiGyt
    no problem. But thanks for the cool guitar finger tracking vid ;)