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 Reparameterization Editor #3099

Closed
wants to merge 41 commits into from
Closed

Conversation

tsole0
Copy link
Contributor

@tsole0 tsole0 commented Aug 28, 2024

Description

Based off 6.0.0 release but not intended to be included in 6.0.0 release
Create a user interface for creating custom reparameterized models. The new window lives in Fitting > Reparameterize Model, and provides a more graphical experience for reparameterizing a model. For more about reparameterization, refer to the SasView documentation on reparameterization. Feature list:

  • Fields for specifying model name and redefinition (= mapping the old parameters to the new parameters)
  • An intuitive user interface for selecting a model to be reparameterized
  • Dropdown menus for easily navigating parameters and parameter attributes
  • A specialized popup allowing the user to customize all aspects of a new parameter (could even be incorporated into the model editor in the future)
  • Detailed parameter checking/warning system that autodetects parameter-based errors before model compilation
  • Model error checking on 'Apply'--syntax errors appear in log explorer

Known limitations

Cannot use arbitrary numpy function imports--imports to the reparameterization file are not seen by sasmodels, and sasmodels will not accept anything in the "translation" string besides var = expr type syntax, precluding import statements.

How Has This Been Tested?

Community feedback and testing encouraged!

Review Checklist:

[if using the editor, use [x] in place of [ ] to check a box]

Documentation (check at least one)

  • There is nothing that needs documenting (although the reparameterization docs are a bit old)
  • Documentation changes are in this PR
  • There is an issue open for the documentation (link?)

Installers

  • There is a chance this will affect the installers, if so
    • Windows installer (GH artifact) has been tested (installed and worked)
    • MacOSX installer (GH artifact) has been tested (installed and worked)

Licencing (untick if necessary)

  • The introduced changes comply with SasView license (BSD 3-Clause)

tsole0 added 30 commits July 2, 2024 11:26
…makes GUI window displayable via the Fitting dropdown menu
…and set default number of columns to 2 in both qtreewidgets
get dictionary of all models and their categories, and load into the modelTree of `ModelSelector`. Allow user to select model and return model parameters table to `ReparameterizationEditor`. Iterate through param table and display all parameters and values in oldParamTree.
…meterEditDialog`. additionally fixes bug that would cause error if user left boxes empty when creating/editing parameters
refactor code to get parameter name from any selected item to separate function so both edit and delete functions can access it
…sed.

Notify user via logger and report errors. Also slight linting by separating `@classmethod`, `@staticmethod`, and overriding functions into their own groupings
Store output parameters in `self.new_params_dict` and process into parameters output. Insert raw `redefinition` text into `translation` variable.
…ay `*` in window title if model is edited, remove if changes are applied
…sabled widgets. Disable trees when no parameters are displayed and update enabled status dynamically.
…c items.

previous methods for finding specific parameters relied on the parameter's name; this caused errors making it impossible to specify a specific parameter if multiple had the same name. Now refactored to use the unique QTableWidgetItem object, which allows for unambiguous variable specification. Therefore, self.new_param_list dict was removed. Also includes some type checking to make it clear some variables mean certain things.
…d back into original state

(no model name, overwrite not checked, warnings present, save before leaving)
@wpotrzebowski wpotrzebowski added the SasView 6.0.0 Required for 6.0.0 release label Sep 2, 2024
@tsole0 tsole0 removed the SasView 6.0.0 Required for 6.0.0 release label Sep 3, 2024
@tsole0
Copy link
Contributor Author

tsole0 commented Sep 3, 2024

This PR is based on the 6.0.0 branch but is not intended for the 6.0.0 release.

@pkienzle
Copy link
Contributor

pkienzle commented Sep 4, 2024

The execution context is C code in the polydispersity loop. You have access to any functions defined for the base kernel.

I thought I had provisions for putting in arbitrary C functions using reparameterize(..., source=source), but that was only for adding additional libraries from sasmodels/models/lib. I don't think you can add C files relative to the reparameterization definition file since it is not on the source search path but I haven't tested.

You can put in arbitrary C code, but you have to do so by hacking the returned model_info object [untested]:

parameters = [
    # name, units, default, [min, max], type, description
    ["volume", "Ang^3", 1e5, [0, inf], "volume", "ellipsoid volume"],
    ["eccentricity", "", 1, [0, inf], "volume", "polar:equatorial radius"],
]

source = [] # list of additional libraries needed for the code

translation = """
radius_polar = eccentricity*Re(volume, eccentricity)
radius_equatorial = Re(volume, eccentricity)
"""

c_code = """
static double Re(double volume, double eccentricity) {
    return cbrt(volume/eccentricity/M_4PI_3);
}
"""

model_info = reparameterize("ellipsoid", parameters, translations, __file__, source=source)
# Tell the compiler what source filename to use when reporting error messages.
c_code = f'#line 1 "{__file__}"\n{c_code}'
model_info.c_code = f"{model_info.c_code}\n{c_code}" if model_info.c_code else c_code

Meanwhile, add a ticket to sasmodels asking for reparameterize(..., c_code="..."), and another to check if helper code can be saved as model_reparam.c in the same directory as the model_reparam.py file.


[Updated to make it clear that the user is not responsible for putting in the #line 1 "{__file__}" preprocessor pragma.]

@pkienzle
Copy link
Contributor

pkienzle commented Sep 4, 2024

Rather than reparameterization we could build the variants into the model.

For example, for ellipsoid provide all four parameters (volume, eccentricity, Re, Rp) but require that the user choose two.

This could be done with an enumeration (6 variants: V-ε, V-Re, V-Rp, ε-Re, ε-Rp, Re-Rp), or by setting the unused parameters to NaN.

If we are likely to go this route, then it would be better to skip the reparameterization infrastructure that we will need to support indefinitely for backward compatibility.

@pkienzle
Copy link
Contributor

pkienzle commented Sep 4, 2024

Regardless of whether we use reparameterize() or model variants, it would be nice to show derived internal parameter values to the user.

This is challenging because the derived parameter will have a number density distribution arising from the polydispersity.

Even more challenging, there will be uncertainty in that distribution through the interaction with uncertainty on the fitted parameter values and polydispersities.

Maybe put this as a ticket on the sasmodels wish list.

CustomGUI for custom or modified qtgui elements like CodeEditor.
ModelEditors and its subpackages for model editors
ModelEditors.Dialogs for dialogs called by model editors
@krzywon
Copy link
Contributor

krzywon commented Oct 25, 2024

This should be superseded by #3136. Keeping it open for now, but likely will be closed next week.

@lucas-wilkins
Copy link
Contributor

Close as rebase PR exists (#3136)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants