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

Add function to determine pivot energy for any spectral model #4635

Merged
merged 28 commits into from Jul 26, 2023

Conversation

Astro-Kirsty
Copy link
Member

Description
This PR is addressing the feature request from issue #4016.
I have added a pivot_energy function to the SpectralModel class that finds the energy at which the error butterfly is minimum. This function is then 'overridden' in the PowerLawSpectralModel where there is an analytical equation available.

Please note: this must be performed in log space (as I understand) because the butterfly minimum occurs in the log space plot.

Dear reviewer
I am certainly open to suggestions/feedback on this issue.

Signed-off-by: Astro-Kirsty <AstroKirsty@gmail.com>
@Astro-Kirsty Astro-Kirsty added this to the 1.2 milestone Jul 3, 2023
@Astro-Kirsty Astro-Kirsty linked an issue Jul 3, 2023 that may be closed by this pull request
@Astro-Kirsty Astro-Kirsty self-assigned this Jul 3, 2023
@Astro-Kirsty Astro-Kirsty added this to In progress in gammapy.modeling via automation Jul 3, 2023
Copy link
Member

@MRegeard MRegeard left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @Astro-Kirsty,
Really helpful feature ! See inline comments.

gammapy/modeling/models/spectral.py Show resolved Hide resolved
@bkhelifi
Copy link
Member

bkhelifi commented Jul 3, 2023

Thanks a lot @Astro-Kirsty . With this PR, I think that it would be great to have some tutorials with this new feature.... e.g. the spectral analysis or 3D detailed analysis

Signed-off-by: Astro-Kirsty <AstroKirsty@gmail.com>
Copy link
Member

@AtreyeeS AtreyeeS left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @Astro-Kirsty !
Is is sufficient to see the thinnest band among the range of energies supplied by the user? The decorrelation energy may not even lie in the given range.

If the energy array is too coarsely binned, the estimate will be incorrect. Finding the minima of the error might be better, no?

gammapy/modeling/models/spectral.py Outdated Show resolved Hide resolved
gammapy/modeling/models/spectral.py Outdated Show resolved Hide resolved
Signed-off-by: Astro-Kirsty <AstroKirsty@gmail.com>
@codecov
Copy link

codecov bot commented Jul 6, 2023

Codecov Report

Merging #4635 (b9bf6a3) into main (74d0de2) will decrease coverage by 0.04%.
The diff coverage is 100.00%.

❗ Current head b9bf6a3 differs from pull request most recent head 98e9bef. Consider uploading reports for the commit 98e9bef to get more accurate results

@@            Coverage Diff             @@
##             main    #4635      +/-   ##
==========================================
- Coverage   95.09%   95.06%   -0.04%     
==========================================
  Files         222      221       -1     
  Lines       31750    31561     -189     
==========================================
- Hits        30193    30002     -191     
- Misses       1557     1559       +2     
Files Changed Coverage Δ
gammapy/modeling/models/spectral.py 97.29% <100.00%> (+0.01%) ⬆️
gammapy/modeling/models/tests/test_spectral.py 100.00% <100.00%> (ø)

... and 21 files with indirect coverage changes

📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more

Signed-off-by: Astro-Kirsty <AstroKirsty@gmail.com>
Signed-off-by: Astro-Kirsty <AstroKirsty@gmail.com>
@AtreyeeS
Copy link
Member

AtreyeeS commented Jul 6, 2023

Thanks @Astro-Kirsty ! This looks better, but it is still an issue that this does not guarantee you are returning the decorrelation energy. This is just the minimum error point in the given range (without letting users know if the actual pivot lies outside). I tried with fsolve, and the results look stable. Maybe this is not the best optimiser, but something along the lines of

from scipy.optimize import fsolve
from gammapy.modeling.models import *

lp = LogParabolaSpectralModel(
        amplitude="5.82442e-11 cm-2 s-1 GeV-1",
        reference="17.337 GeV",
        alpha="1.9134",
        beta="0.2217",
    )
lp.amplitude.error = "2.8804e-12 cm-2 s-1 GeV-1"
lp.alpha.error = "0.1126"
lp.beta.error = "0.0670"

def f1(x, unit=u.TeV):
    x=np.exp(x)
    dnde, dnde_error = lp.evaluate_error(x*unit)
    ene = dnde_error / dnde
    return ene

print("pivot = ", np.exp(fsolve(f1, x0=0))*u.TeV)

maybe an option? What do you think?

@Astro-Kirsty
Copy link
Member Author

Astro-Kirsty commented Jul 6, 2023

I agree @AtreyeeS. Using fsolve would be a nice way so that the use does not have to define any energy and therefore always gives the decorrelation energy for that SpectralModel

Signed-off-by: Astro-Kirsty <AstroKirsty@gmail.com>
@Astro-Kirsty
Copy link
Member Author

Implemented the code using fsolve, I tried the function on multiple spectra to find a reasonable initial guess.

Copy link
Contributor

@registerrier registerrier left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @Astro-Kirsty .

fsolve is a root finder, not a minimizer. Is it really adapted here? Shouldn't one use something like minimize_scalar instead?

Those methods require an interval to search for the minimum. We have to see if it is possible to keep pivot_energy a simple property in this context.

One should probably check that a proper minimum is found and yield an error if not.

gammapy/modeling/models/spectral.py Outdated Show resolved Hide resolved
@Astro-Kirsty
Copy link
Member Author

An option would be to implement:
minimizer = scipy.optimize.minimize_scalar(min_energy, bounds=bounds)

where the bounds are predefined by default as the reference value from the SpectralModel plus or minus some small value. But making this an optional argument, so that the user can specific their own bounds?

And as you mention, to add that if the minimizer is not successful, then it should alert the user

Signed-off-by: Astro-Kirsty <AstroKirsty@gmail.com>
Signed-off-by: Astro-Kirsty <AstroKirsty@gmail.com>
@Astro-Kirsty
Copy link
Member Author

Astro-Kirsty commented Jul 17, 2023

Updated to make sure there is no issue with units.

Added an if statement for the std. The scipy minimize functions will always minimize a function, even if there is no minimum (i.e. a constant array of values). Hence providing the user with an incorrect, nonsensical pivot energy. Therefore, adding this if statement takes care of this.

I also adapted the test functions to ensure this was included.

@registerrier
Copy link
Contributor

Thanks @Astro-Kirsty . There is a test failing, could you increase the tolerance? I suppose the method won't be precise below the percent.

Signed-off-by: Astro-Kirsty <AstroKirsty@gmail.com>
@Astro-Kirsty
Copy link
Member Author

Thanks @registerrier. It was not failing on my laptop which is odd. I have increased the tolerance

Copy link
Contributor

@registerrier registerrier left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @Astro-Kirsty . This looks good.

The only missing thing to me is a test with some correlation. e.g. use an exp-cutoff with the same parameters and correlation matrix as the PWL test and check you get the same result.

gammapy/modeling/models/spectral.py Show resolved Hide resolved
Copy link
Contributor

@QRemy QRemy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @Astro-Kirsty this is a nice feature, I have just one question :


bounds = [np.log(self.reference.value) - 3, np.log(self.reference.value) + 3]

std = np.std(min_func(x=np.linspace(bounds[0], bounds[1], 100)))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does the choice of the number of steps in linespace can affect the precision ?
If yes it should be configurable.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does not

Signed-off-by: Astro-Kirsty <AstroKirsty@gmail.com>
Signed-off-by: Astro-Kirsty <AstroKirsty@gmail.com>
Signed-off-by: Astro-Kirsty <AstroKirsty@gmail.com>
Signed-off-by: Astro-Kirsty <AstroKirsty@gmail.com>
Signed-off-by: Astro-Kirsty <AstroKirsty@gmail.com>
Signed-off-by: Astro-Kirsty <AstroKirsty@gmail.com>
Signed-off-by: Astro-Kirsty <AstroKirsty@gmail.com>
Signed-off-by: Astro-Kirsty <AstroKirsty@gmail.com>
Signed-off-by: Astro-Kirsty <AstroKirsty@gmail.com>
Signed-off-by: Astro-Kirsty <AstroKirsty@gmail.com>
Signed-off-by: Astro-Kirsty <AstroKirsty@gmail.com>
Signed-off-by: Astro-Kirsty <AstroKirsty@gmail.com>
AtreyeeS
AtreyeeS previously approved these changes Jul 25, 2023
Copy link
Member

@AtreyeeS AtreyeeS left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! no more comments from me

Signed-off-by: Astro-Kirsty <AstroKirsty@gmail.com>
Signed-off-by: Astro-Kirsty <AstroKirsty@gmail.com>
Signed-off-by: Astro-Kirsty <AstroKirsty@gmail.com>
Copy link
Member

@bkhelifi bkhelifi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @Astro-Kirsty, all good for me.
I am still wondering if one could not have an optional argument about the energy range of computation. But this can be added later if needed.

Copy link
Member

@MRegeard MRegeard left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @Astro-Kirsty,
Seems good to me !

@Astro-Kirsty Astro-Kirsty merged commit f6bc795 into gammapy:main Jul 26, 2023
11 of 13 checks passed
gammapy.modeling automation moved this from In progress to Done Jul 26, 2023
@Astro-Kirsty Astro-Kirsty deleted the pivotenergy branch October 31, 2023 09:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
Development

Successfully merging this pull request may close these issues.

Need for general decorrelation energy for any Spectral Model
6 participants