-
Notifications
You must be signed in to change notification settings - Fork 5
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
More generic API for Rainbow variants #324
Conversation
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## master #324 +/- ##
=======================================
Coverage 84.94% 84.94%
=======================================
Files 9 9
Lines 2664 2664
=======================================
Hits 2263 2263
Misses 401 401 ☔ View full report in Codecov by Sentry. |
CodSpeed Performance ReportMerging #324 will not alter performanceComparing Summary
|
Thank you, @karpov-sv, it looks really great. I'll go through it a little later, sorry in advance for the delay |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is a huge and great contribution! Thank you so much for it.
Please find some discussion topics bellow.
Interface of RainbowFit
I believe that bolometric
and temperature
arguments of RainbowFit
should be objects, not classes. I would remove @staticmethod
from abstract methods and allow users to create parametric subclasses of BaseBolometricTerm
and BaseTemperatureTerm
. This interface would make string literals to correspond to the "default" objects of the built-in classes (see the discussion bellow).
bolometric.py
and temperature.py
- I'm not sure how idiomatic the inheritance approach used there: we go from variable length of parameters
*params
to fixed number of params. It should be fine because we are the only users of the child classes, and we hopefully always provide the parameters in a right order. - As I mentioned above, I would appreciate if we make child classes parametric. We can do it with
@dataclass(frozen=True)
. Limits and initial guesses could easily be parameters, having the same default values as you currently use in the code. In this case we can use trivial constructors to create "default" objects forbolometric_terms
andtemperature_terms
.
Scaling literals
I like the idea of specifying scaling rules in bolometric/temperature classes. I would ask to make the way we specify these rules more clear: add all variants to the base classes docs, verify them more strictly on the runtime.
light-curve/light_curve/light_curve_py/features/rainbow/_base.py
Outdated
Show resolved
Hide resolved
light-curve/light_curve/light_curve_py/features/rainbow/_base.py
Outdated
Show resolved
Hide resolved
light-curve/light_curve/light_curve_py/features/rainbow/temperature.py
Outdated
Show resolved
Hide resolved
light-curve/light_curve/light_curve_py/features/rainbow/temperature.py
Outdated
Show resolved
Hide resolved
light-curve/light_curve/light_curve_py/features/rainbow/generic.py
Outdated
Show resolved
Hide resolved
@karpov-sv @erusseil sorry, I've forgotten to write about the amplitude. I see your point about amplitude normalization, but I don't like that the output value doesn't have a clear physical meaning. What about a compromise solution: could we output the final "amplitude" to be a peak flux value in the first passband? We still may have the same "amplitude" definition inside the code, but replace it with some meaningful value in the end. |
So I implemented most of your suggestions. For the rest I suggest to keep it as it is now. Parametric subclasses would not work for the current approach - at least if you wish to pass initial guesses as the parameters to them. These classes operate on scaled variables, and have no way to access the original scalers - thus, their initial parameters are not related to anything the end user may provide, and cannot be converted. (It would also break the concept of "batch processing", no?..). As for the amplitude in the parameters - now it is physically in the same (roughly) scale as original data. It all goes down to the normalization of Planck function, which is still an open question. E.g. one idea is to actually normalize it to the flux at some reference wavelength - it would break the meaning of the first term as bolometric, but would allow better fitting supernovae. However, it cannot be just one more extra parameter for the fit - the fitter is way too unstable as it is now already... |
@karpov-sv sounds great! I agree about the parametric subclasses, but I still want us to find a better solution for the amplitude. |
It still tells me that changes are requested, but I see no more open questions here. What should I do?.. |
@karpov-sv would you like me to merge it now, so we can work on the next PR in Clermont? |
Yes, let's merge it as it is now, and discuss what to do next in Clermont. |
@karpov-sv I'll do it! Sorry for the mis-communication |
…-normalized Planck function
… it works meaningfully with temperature evolution
… to better estimate rise/fall times
for more information, see https://pre-commit.ci
for more information, see https://pre-commit.ci
for more information, see https://pre-commit.ci
267cf92
to
ee90dfb
Compare
* Initial import from Etienne PR, with some adjustments to make it more generic * Make parameter and error unscaling more generic * Implement peak time computation * Use new generic implementation instead of old RainbowFit * (Slightly better) decorrelate temperature and amplitude by using peak-normalized Planck function * Generalize baseline handling w.r.t. bolometric term initial parameters * Cont. of previous commit * Do not crash in baseline fitting when some bands do not have data * Revert the normalization of Planck term back to 'bolometric', so that it works meaningfully with temperature evolution * Decorrelate Bazin amplitude from rise/fall times by normalizing it to 1 * Pass measurement errors to initial parameter estimators, and use them to better estimate rise/fall times * Add tests for generic RainbowFit implementation * Remove now obsolete versions of RainbowFit * Improve docstrings * Do not raise an exception if the fitting fails but `get_initial=True` * Delayed sigmoid temperature term added * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Fix the tests * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Do not use 3.9+ features * Improve docstrings and stricter check for parameter unscaling * Minor fixes requested in the review * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Additional fixes requested in the review * Small docstring for the sigmoid mentioning that it has no peak time properly defined * Fix linting errors --------- Co-authored-by: erusseil <[email protected]> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
After discussion with @erusseil we decided to unify the zoo of Rainbow variants.
So the PR replaces them all with a single
RainbowFit
feature that, on initialization, accepts keywordsbolometric
andtemperature
that may be either strings (for built-in variants) or custom sub-classes of corresponding base classes for bolometric and temperature terms. Default values should match the behaviour of previous version ofRainbowFit
.The built-in variants for bolometric term are:
Temperature options are:
The PR also slightly improves initial guesses for Bazin parameters, and fixes minor bugs from previous code versions.
Also, it changes the normalization of the underlying Planck term to be more straightforward - it both de-clutters the code a bit (basically, by moving the normalization directy to the term from extra scaling/unscaling methods), and returns the
amplitude
parameter in (approximately) the same units as input data, which should be more understandable by the end user.