Skip to content
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

Problem on retrieving aperiodic and peak data from Group object with get_data #316

Open
maschpall opened this issue Feb 20, 2024 · 1 comment

Comments

@maschpall
Copy link

Hi,

I am using fooof version 1.1 and loaded and fited a FOOOFGroup model to later extract the 'aperiodic' and 'peak' data (not params) and found that they are NonType. This is not the case for the 'full' version, which gives me the spectrum output.

I checked that has_data = True and that when I save the results save_data = True too.

To further check i downloaded the data from the tutorial 04: Exploring the FOOOF Object and here when using fm.get_data worked for all 'full', 'aperiodic' and 'peak'.
Then I downloaded the data and followed the tutorial from 06: FOOOFGroup and when I extracted an individual fit, get_data again did not worked for 'aperiodic' and 'peak'.

Also when trying get_params to the group object that the Tutorial computes also did not give any output for neither the 3 of them.

Am I doing something wrong? Is there a way to extract the aperiodic corrected spectrums? I find myself now substracting the get_model('aperiodic') from the get_data('full') to obtain it

Thanks!

@TomDonoghue
Copy link
Member

Hey @maschpall - as far as I can tell, you are trying to use the get_data and/or get_model methods to return isolated (a)periodic components of the data and/or model, and doing so from a FOOOFGroup object?

I've been checking into this, trying to replicate what you describe, and noticed a few quirks, some that are basically expected, but not super clearly described by the code, and some aspects that don't really work as expected (this functionality is new, and not quite fully functional, it would seem).

The key point I think is that while those methods exist on the FOOOFGroup object, they aren't really designed to work directly from the Group object - since the group object doesn't store all the isolated data & model components. Those methods still exist on that object, because of how it inherits from the FOOOF object, but will return None, as you are seeing (because the attributes with individual data and components are empty). I agree that this is not particularly clear in terms of the code, and should be updated - I'll keep a note and seek to update this in the upcoming new version.

To double check, with fg being a FOOOFGroup with data and fit results, the following will all return None:

fg.get_data('full')
fg.get_data('aperiodic')
fg.get_model('full')
fg.get_model('aperiodic')

So, to actually get these isolated components, the current set up of the code (as is) is that you can extract model objects for individual model fits, and these model objects will recompute the isolated components, and you can access them from there.

For example, doing this to extract and recompute the components for each spectrum from it's own model object:

# Extract isolated model components
for ind in range(len(fg)):
    cfm = fg.get_fooof(ind, regenerate=True)
    print(cfm.get_model('aperiodic'))

The final piece that is more of a bug is that it turns out the above does not work for get_data('aperiodic) (or 'peak'), which I think might be actually what you wanted? The reason is that the isolated data components are created during the fit process, and are not recomputed by regenerating the model components, and so in the above construction, end up as None when extracting from Group objects in this way. This is actually specific to the 'log' space components - extracting in linear space actually does work (since it's recomputed differently anyways). This issue / inconsistency escaped me as I was setting this up.

The simplest / quick fix for this is to extract the models and re-fit, to get the recomputed model components. By looping through the Group object, each model object will get the same data and settings - so should give the exact same answer as the original fits, while providing the isolated components (though the re-fitting is definitely annoying).

For example, this does work:

# Extract isolated data components
for ind in range(len(fg)):
    cfm = fg.get_fooof(ind, regenerate=True)
    cfm.fit()
    print(cfm.get_model('aperiodic'))

In terms of updates to the code - I hope that gets you moving for what you want / need to do. In terms of updates / fixes, I need to look through this a bit more, and figure out what to do with the get_model and get_data methods on the group object (maybe remove them), and also clean up the extraction of data for individual models. This will definitely be updated & fixed for upcoming version 2.0, though I'm not sure yet if it'll make sense / work to do a retroactive patch to 1.1.

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

No branches or pull requests

2 participants