Closed ChrisBeaumont closed 7 years ago
This is relatively straightforward, I agree, but still quite a bit of overhead. Long-term, it would be nice if a user could simply define a model function and you'd have a wrapper class to perform introspection on the function to extract parameter names.
The most important options I think you're presently missing are limits on the individual parameters. My preference is to have each parameter have at least 4 user-settable properties: value, upper and lower limit, and "fixed".
I really like having "sliders" to control the various parameters too. That may not be what you're asking though.
I want to have access to the parameters, error on parameters (both to put in tables, in principle) and the full array.
Minor comment on spectrum display: could you make the plot type 'step-filled'? I feel pretty strongly that, because the data points are discrete, it is more honest to show them without interpolation. Also, it makes it easier to display a 'filled' style error bar.
step-filled profiles and option sliders are both good ideas. (What do you mean by filled style error bar?)
Regarding your first point: you could imagine an even simpler interface, like this:
@fit_plugin
def fitter (x, y, dy, n_components=3, baseline_fixed=False):
pass
That introspects the signature to build a UI. Some drawbacks:
1) I've found I usually want my UI labels to be different (more human/descriptive) than the variable name they correspond to. E.g., how do you specify that baseline_fixed
should be presented as Use a fixed baseline
?
2) You have to make more guesses about what kind of UI to build. Should n_components be a slider or dropdown? Does it have an upper/lower bound? is it constrained to be one of a few values? What are those values, and what is the default? etc.
One solution is to use the class-based approach above, but make the Option
attributes optional and auto-generate them from the fit signature if they aren't present. I prefer that over adding lots of optional kwargs to a @fit_plugin
decorator (although you could still have the bare decorator interface to support the example above).
Regarding the comment about constraining the model parameters themselves: I just want to confirm that tweaking this information is something you would want to do interactively, and it is worth spending screen real-estate on? Another approach is to write multiple plugins with different hard-coded sets of constraints. It isn't as flexible, but would be easier to fit onto a widget. But maybe that's too hacky/restrictive.
Filled style error bars like:
That introspects the signature to build a UI. Some drawbacks:
1) I've found I usually want my UI labels to be different (more human/descriptive) than the variable name they correspond to. E.g., how do you specify that baseline_fixed should be presented as Use a fixed baseline?
Good point - this would be great to parse from the docstring! That may well be extremely difficult, though.
2) You have to make more guesses about what kind of UI to build. Should n_components be a slider or dropdown? Does it have an upper/lower bound? is it constrained to be one of a few values? What are those values, and what is the default? etc.
Yes, that's also a real difficulty, and counts as a vote in favor of preferring class-based plugins.
So, I agree with your approach: have the decorator that defaults everything to the least restrictive setting (for example), but have the class interface as a preferred / more flexible one.
Regarding the comment about constraining the model parameters themselves: I just want to confirm that tweaking this information is something you would want to do interactively, and it is worth spending screen real-estate on? Another approach is to write multiple plugins with different hard-coded sets of constraints. It isn't as flexible, but would be easier to fit onto a widget. But maybe that's too hacky/restrictive.
Yes. And this brings up a new use-case: Say I want to fit a model, subtract it from the data, then fit another model to the residual. That's a perfect case where I'd want to change the restrictions on-the-fly.
The other common use case for restricting fits is if you have, say, a CO spectrum through the Galactic midplane and want to fit 6 gaussians, each restricted to be narrow and limited to a particular velocity range.
Finally, the most important: if you fit one parameter and you like that fit, it's really helpful to fix that parameter but free the others on the fly. This feature is implemented nicely in xspec
and was my favorite (and I believe a favorite of many X-ray astronomers).
Just as an update on this, @keflavich and I have been working on a more sophisticated spectral viewer in Glue based on pysepeckit: https://github.com/glue-viz/glue-pyspeckit-plugin
I think the original intent was this issue was actually implemented as fitter plugins in glue by @ChrisBeaumont - http://glueviz.org/en/stable/gui_guide/spectrum.html#custom-fitting-plugins
I'm interested in @keflavich and @astrofrog's thoughts here
I'm working on a spectrum/profile extraction utility in Glue that, among other things, allows users to fit models to profiles. It looks like this currently:
I'd like to make it easy for users to plug in their own model fitting code (maybe from astropy, or something homegrown). Here's a possible interface:
Given a class like this, Glue would:
I think such a class is simple enough that any python coder could roll their own basic fitting plugin based on an example tutorial. My main questions are:
fit
, or do some models need more?Options
are needed when building the form UI?