Skip to content

Conversation

@klytje
Copy link
Contributor

@klytje klytje commented Jan 26, 2025

Description
I have implemented support for performing SAXS fits through the AUSAXS library. Note that this requires a newer version of AUSAXS which must manually be moved to the src/sas/sascalc/calculator/ausaxs/lib directory, available from here: https://github.com/SasView/AUSAXS/releases/tag/v4

I have refactored how SasView hooks into my library. I think this new approach is far superior, and is also easier to extend in the future. Due to this change, we will need extensive testing to ensure the existing SANS hook is still working as expected.

I also made some changes to the GenericScatteringCalculator GUI manager since my SAXS calculation need some additional data which was not previously available:

  • I've added a new self.type enum variable to the GenSAS object, with four possible values corresponding to the currently selected calculation model:
    image
    I use this variable to check what calculations are supposed to be run, instead of relying on various combinations of existing variables, as was previously done.
  • The PDB reader now also parses and saves the atomic name, residue name, and atomic element strings for every atom. I've added this extra data to the MagSLD object, which is perhaps not ideal.

Comments and suggestions
As part of this PR, I had to dig quite deep into the internals of this part of SasView. I have a few comments and suggestions for future improvements:

  • The GenericScatteringCalculator class is extremely bloated. In my opinion the GUI manager should be completely separated from the data structure, and only communicate with it through event notifications. I think this would simplify things quite a bit.
  • The data structure is a nightmare. There's multiple instances of the same SLD data being passed back and forth between the GUI manager and the GenSAS object, and it is incredibly difficult to predict what data is currently stored where, especially considering how it is being overwritten in unexpected places.
  • Another example of the bloated data structure is how the GenericScatteringCalculator contains instances of every possible data reader (PDB, OMF, ...). I'd suggest constructing them on the fly when needed instead of storing them as member variables. There's probably other member variables which can also be optimized away like this.
  • With the introduction of SAXS calculations, it is now possible for the user to perform invalid actions, such as trying to run a SAXS calculation with an SLD file. While this can be caught and send errors to the logger, I think it'd be better to create an actual popup in the main SasView window when an invalid action is performed, to give more direct feedback to the user. This would also allow the code to gracefully return from calculations instead of relying on propagating exceptions, which may leave the GenericScatteringCalculator GUI in an ill-formed state unable to perform further calculations.
  • My SAXS calculator needs access to the scattering data, but this is not (I think) currently available in the GenericScatteringCalculator class. I thought about adding a new option to the "Send to" button in the main window to solve this, but it seems to me as if this functionality is intrinsically tied to perspectives. I couldn't see an easy way to refactor this, so I'll just leave it as a suggestion to decouple these two to allow loaded data to be sent to any GUI window. This could then also be used to load and send magnetic data to the GenericScatteringCalculator instead of loading them separately within the GenericScatteringCalculator GUI.

Todo

  • Figure out how to make scattering data available to the SAXS fitter.
  • Add unit tests
  • Test existing SANS hook
  • Test the rest of the GenericScatteringCalculator interface is still working as expected.
  • (AUSAXS) Add offline-support for determining the atomic form factors. Currently, residue definition files are automatically being downloaded from the internet to do this.
  • (AUSAXS) Add offline-only toggle.
  • (Flatpak) libausaxs must now be included since there is no fallback for SAXS calculations.
  • Possible issues with other distributions not including libausaxs?

Future additions
This is a list of additional features which could be useful to do in a future PR:

  • Add a CIF reader to SasView.
  • (requires CIF reader) Determine the atomic form factors within SasView itself.
  • Perform the fitting with SasView, using AUSAXS only to calculate the scattering profile for each iteration?

Documentation
Significant documentation of this new feature is required. I will add this later.

Installers
This could potentially affect the installers since I'll have to change which version of AUSAXS is being shipped with SasView. Testing should be performed for each platform.

  • Windows installer (GH artifact) has been tested (installed and worked)
  • MacOSX installer (GH artifact) has been tested (installed and worked)
  • Linux installer (GH artifact) has been tested (installed and worked)

Note: All GH artifacts are currently broken due to using an older version of AUSAXS!

@klytje klytje marked this pull request as draft January 26, 2025 12:15
@pkienzle
Copy link
Contributor

Does periodictable have the formfactors needed by auSAXS? Could we add them if it doesn't?

@klytje
Copy link
Contributor Author

klytje commented Jan 27, 2025

Does periodictable have the formfactors needed by auSAXS? Could we add them if it doesn't?

AUSAXS uses residue information to determine the number of hydrogens bound to every atom in the structure. With this, compound form factors (CH, CH2, NH, ...) can be used instead of the pure atomic ones (C, N, O, ..) for better accuracy. This can actually have a significant impact on the quality of the fit.

I imagine such aggregated form factor tables are outside the scope of periodictable, which seems more focused towards individual atoms?

@pkienzle
Copy link
Contributor

Yeah, it is currently out of scope.

@jamescrake-merani
Copy link
Contributor

In regards to your 'Comments and suggestions' header, I'd like to note that the issues around data structures are currently being addressed in the refactoring project, although its going to take some time before that project is ready.

Specifically, each reader at the moment just has a load_data function, taking in any parameters it needs. While this might change, at the moment I don't think there's a compelling reason for the reader to be a class that needs to be instantiated.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants