Skip to content

Doubts on linear and log scale #402

@LeonardoMelloni

Description

@LeonardoMelloni

Hello!
in these days I am working with specparam (latest version).

I am getting a bit confused with the conversion between log10 and linear scales, in particular when using SpectralModel.get_data()

My goal is to obtain the flattened spectrum in linear scale, in order to compare it with the raw PSD, in linear scale, computed with mne.minimum_norm.compute_source_psd(…, dB=False). Right now I am going for
flat_psd = model.get_data('peak', space='linear')

Inspecting the function, I was a bit confused by the subtraction at this line 202 in the space=='linear' branch of

elif component == 'peak':
            output = self._model.results.model._spectrum_flat if space == 'log' else \
                unlog(self.power_spectrum) - unlog(self._model.results.model._ap_fit)

To be more precise, I would have expected a division, so that the result would basically be 10^_spectrum_flat.

But then I understood the decision after reading

Notes
        -----
        The 'space' parameter doesn't just define the spacing of the data component
        values, but rather defines the space of the additive data definition such that
        `power_spectrum = aperiodic_component + peak_component`.
        With space set as 'log', this combination holds in log space.
        With space set as 'linear', this combination holds in linear space.

Given this, I am interpreting that the flattened spectrum is computed as

flat_linear = rawPSD – aperiodic_power = rawPSD – 10^offset * 1 / f^exponent

Question 1: is this interpretation correct?

If so,

Question 2: why would it be desirable to have this sort of computation (which seems to be in conflict with how the algorithm works)?

Question 3: why in this line 199 a division is used? In my view this conflicts with what written in the Notes.

I feel I am missing something and making confusion.
I would appreciate some clarification and suggestion on how to approach this problem without making too much confusion when changing scales.
As far as I understood the algorithm, the best way to go is to consider always the power values in log10, meaning that the recursive fitting is performed on the log10 of power values and the subtractions are always between log10 power values.
Consequently, if I wanted the flattened spectrum in linear scale sticking to what is shown in the tutorials, the best option would be to

flat_log = model.get_data('peak', space='log')
flat_linear = np.power(10, flat_log)

Which would be different from what I currently obtain with model.get_data('peak', space='linear').....Right?

Thanks in advance!!!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions