DiGyt's Blog

Week 12: Blog Post (#6)

DiGyt
Published: 08/19/2019

Last week, I worked on several steps to finalize my project.
Some work was put into correcting and improving my pull requests, so they can be merged soon. I created an example file to demonstrate the useability of this project, and opened up a new pull request for it (next to another PR, that introduces the plotting support I implemented the previous week).
As mentioned in my last blog post, I also thought about an alternative solution, i.e. to create a genuine plotting function for SourceTFR. But as I already suspected, this will not work without a lot of additional work. I originally intended to introduce a new type of plot derived from MNE's "TimeViewer", where you can not only skim along the time axis through the plotting GUI, but also along the frequency (and maybe the epochs) axis. After trying out some stuff, my best intuition to reaching this goal would be to simplify the "TimeViewer" class, and make it some kind of a "AxisViewer" class. This class would allow a developer to decide which axis (or even multiple axes) should be manipulable through the GUI. Yet, this would be only a part of the work, as this does not include the actual plotting function used by SourceTFR, and also would only work for the plots made on surface type source level data (since volume type source level data employs an entirely different plotting GUI). In my opinion, this functionality should rather be added later, so I can now concentrate on the finishing touches of the rest of the project.
One such finishing touch is for example time and memory saving computation of tfr_stockwell, which is for now only available for tfr_morlet and tfr_multitaper. I already made attempts to tackle this problem, and currently try to make it pass the equivalence tests. But this will definitely be one of the things to do this week, as it will have big implications on the practical useability of the function.

Another thing I worked on last week (and will continue to work on this week) was the project page where I'll upload my final results next week. I decided to create a GitHub gist for this purpose, since it is simple and good looking at the same time. Most of the gist is already finished, only the links to the PRs and some direct examples will need to be added there. So I hope, everything will work out this week, and I'll be able to show you a nice conclusion on my Google Summer of Code project until next week.

So, for the last time (this summer?!): Stay tuned!

View Blog Post

Week 10: Blog Post (#5)

DiGyt
Published: 08/06/2019

Last week, I finished the main functional goal of this GSoC project, by making tfr_functions compute all the things they should compute correctly. It even was possible to allow tfr_morlet and tfr_multitaper to process lists and generator objects subsequently, which is quite important in order to save memory. However, while doing so, I realized that this will basically scrap all the support I introduced for supporting kernelized data (the other memory saving trick I used, where memory is stored in two small arrays, which can be combined by taking the dot product). So this will be a point to work on again, however, this will probably more look like some dirty fix, as I really don't see any elegant solution to this at the moment.
Another thing I can finally start to work on now will be plotting. To be honest, I'm kind of excited to work on graphical/ user interface stuff, since I often experienced that the implementation of these things is quite fun (i.e. if they work, they work ;) ). But we'll see how that turns out. The other thing to do will be to write some nice tutorial, showing off the newly gained functionality (which I think will also be fun).
So, it's time to start the final sprint of the project, and I think I'm prepared for it. Stay tuned!

View Blog Post

Week 9: Weekly Check-In (#5)

DiGyt
Published: 07/30/2019

1. What did you do this week?

A lot of different stuff:

- Introduced some small tests to make sure the multitaper and stockwell functions do what they should to.
- Made tfr_stockwell catch up with tfr_morlet and tfr_multitaper.
- Pushed a smaller PR that gives the user an option to return SourceEstimates data as kernelized (i.e. memory saving).
- Made tfr_multitaper and tfr_morlet take lists and generators as input, a crucial further step that allows the Inter-Trial-Coherence to be calcualted (how good this works remains to be checked, however).

2. What is coming up next?

We'll need to see how good the IRT stuff works and finish all of it. When everythings done, the core stuff of this GSoC project will be finished. This will involve pushing a quite big chuck of code, reviewing and correcting it. Then I'll make sure the same stuff works for tfr_stockwell as well. Finally I might start this week with the implementation of the last functional aspect, which is plotting the data.

3. Did you get stuck anywhere?

Yes. When introducing lists into tfr functions, the perfect solution would have been to process each "epoch" or element of the list subsequently, in order to save data. After trying to implement this (and getting it to work for tfr_morlet), I found out that if this was to be done cleany and working for all functions, it would require a huge recstructuring of the tfr_functions, that might have grave consequences for other aspects, e.g. parallel computing of the functions. Therefore I had to start of with a bit of a poorer solution, where the data is simply concatenated together at the start of the function, and then treated very much like epochs data. This will increase memory usage. However, I hope that I can implement a memory saving solution at some later point.

View Blog Post

Week 8: Blog Post (#4)

DiGyt
Published: 07/22/2019

Last week, I was working on the parametrizing tests for SourceEstimates with tfr_morlet, and making sure the tests are also passed for all possible different functional arguments. Overall this worked quite smoothly for most parameters. In fact, I was already able to start implementing the same procedure for tfr_multitaper. Anyhow, for tfr_multitaper there is no reference function as for tfr_morlet, so tests for tfr_multitaper are for now basically just running the function and checking that everything is in the right place.

However, some of the parameters still were causing problems. By far the most time this week was spent to work on tfr_morlet processing data from 'vector' representations (i.e. instead of one virtual "sensor" in source space, there are 3 virtual "sensors" created, with each one representating one directional activation axis. Besides adding a further dimension (which was no big problem to adapt to), the data fields consistently showed a slight difference (of about 2-4%).
After noticing that for this case, the results are theoretically not expected to be the same for the two procedures taken in the functions, I'll have to find a case where a comparison is possible between the two.

So this is one thing i'm going to do the following week. But mainly, I'm going to continue covering cases for the tfr_multitaper function, as well as starting with the last function, tfr_stockwell.
Another think to possibly look at now is a further option of the functions, which is to additionally return the inter-trial coherence of the time-frequency transforms.

View Blog Post

Week 7: Weekly Check-In (#4)

DiGyt
Published: 07/15/2019

1. What did you do this week?

This week i finally got my first case of equivalence between the new SourceTFR API and the old source_induced_power function. As it turned out, the unequal results were not actually a problem of the code, but instead resulted from a tiny bug in the source_induced_power function, which i use to test my project. It resulted from a parameter not properly passed, which caused different wavelet functions to return different time_frequency transforms...

2. What is coming up next?

Now, the first thing i'll do is to introduce fully parametrized tests to make sure that the wavelet function works for all cases of SourceEstimates and all cases of parameters. If i get this through fast, i might even start to do the same thing for multitapers.

3. Did you get stuck anywhere?

Yeah, well: If you have to analyze and compare each line between two different (and heavily nested) functions, until you notice that a rather unrelated part is causing the actual problem, i wouldn't exactly call that 'getting stuck'. Anyhow, it results in the same time loss ;)

View Blog Post