SasView / sasview

Code for the SasView application.
BSD 3-Clause "New" or "Revised" License
51 stars 41 forks source link

Theoretical data become NaN for one plugin model generated from a PDB file when the resolution function is used. #2671

Open yunliu01 opened 1 year ago

yunliu01 commented 1 year ago

For the custom model using the Generic Scattering Calculator with a PDB file, it generates a data set with limited Q ranges. This data sets can be written in a plug in model that can be later used to fit experimental data.

I calculated the form factor of apoferritin protein based on a PDB file. The Q range was from 0.001 A^-1 to 0.3 A^-2. About 30 data points were generated and written in a plug in model. From the SasView, I loaded the experimental data (1D data for apoferritin included in the SasView), whose Q range is from 0.0055 A^-1 to 0.3995 A^-1. I tried to use the plug in model of the apoferritin PDB file to fit the experimental data. The theoretical curve disappeared from the fitting window. By right clicking the figure window to show the content of the theoretical data, the results are all "NaN".

I tried to change the fitting Q range from about 0.08 to 0.15 A^-1. The values of the theoretical data were still NaN. However, if I removed the resolution function, the theoretical curve can be shown, and the data are not NaN. So clearly, it is related with the resolution function. However, it is not clear to me how the resolution function is used in the SasView when calculating the theoretical curves.

Note that for the plugin model, if a Q value is outside the range of the theoretical calculation from the Generic Scattering Calculator (in this case, it was from 0.001 A^-1 to 0.3 A^-1), the returned I(Q) is NaN. This makes sense as the plugin model should only interpolate data not extrapolate the data.

As a side note, when I changed the Q range to 0.0005 A^-1 - 1 A^-1 (much larger than the experimental apoferritin data), it has no problem to use the plug in model to fit the experimental apoferritin data with the resolution function.

Steps to reproduce the behavior:

  1. load a PDB apoferritin file
  2. Choose the Q range from 0.001 A^-1 to 0.3 A^-1
  3. choose Debye full w/ beta(Q), and choose a name for the plug in model, such as custom_apoferritin
  4. Click compute
  5. In the SasView, load 1D data (apoferritin.txt) and send it to fitting.
  6. Chose plugin model with custom_apoferritin and Q range you would like to fit the data, and click on compute/plot
  7. The figure window only shows the experimental data. There is no theoretical data.

Expected behavior At the step 7, if a fitting Q range is chosen to be significantly smaller than the Q range of the plugin model, the theoretical data should not be NaN.

SasView version (please complete the following information):

Operating system (please complete the following information):

wpotrzebowski commented 11 months ago

I am also able to reproduce the error and to fill in with additional information, this is an error message I get:

15:22:16 - sas.qtgui.Perspectives.Fitting.FitThread - ERROR - Fitting failed: Traceback (most recent call last):
  File "/Users/wojciechpotrzebowski/SASVIEW_WORKSPACE/sasview/src/sas/qtgui/Perspectives/Fitting/FitThread.py", line 79, in compute
    result = list(map(map_apply, inputs))
  File "/Users/wojciechpotrzebowski/SASVIEW_WORKSPACE/sasview/src/sas/qtgui/Perspectives/Fitting/FitThread.py", line 19, in map_apply
    return arguments[0](*arguments[1:])
  File "/Users/wojciechpotrzebowski/SASVIEW_WORKSPACE/sasview/src/sas/qtgui/Perspectives/Fitting/FitThread.py", line 16, in map_getattr
    return  getattr(classInstance, classFunc)(*args)
  File "/Users/wojciechpotrzebowski/SASVIEW_WORKSPACE/sasview/src/sas/sascalc/fit/BumpsFitting.py", line 284, in fit
    assert values is not None and errs is not None
AssertionError

15:22:16 - root - ERROR -  
 === Steps: 1 of 200  chisq: nan ETA: 2023-11-20 15:22 (0s from now)
M1.scale            :         1 |  

15:22:16 - sas.qtgui.Perspectives.Fitting.FittingWidget - ERROR - Traceback (most recent call last):
  File "/Users/wojciechpotrzebowski/SASVIEW_WORKSPACE/sasview/src/sas/qtgui/Perspectives/Fitting/FittingWidget.py", line 2051, in fitComplete
    res_list = result[0][0]
IndexError: string index out of range
wpotrzebowski commented 11 months ago

As @yunliu01 already recognized the problem is related to the following condition:

const double logq = log(q*swelling);
    if (logq < LOGQ[0] || logq > LOGQ[NQ-1]) {
        *f1 = *f2 = NAN;
        return;
    }

Returning value (e.g. 0) instead of NAN makes the model running but I am not sure if that's what we want?

yunliu01 commented 11 months ago

As @yunliu01 already recognized the problem is related to the following condition:

const double logq = log(q*swelling);
    if (logq < LOGQ[0] || logq > LOGQ[NQ-1]) {
        *f1 = *f2 = NAN;
        return;
    }

Returning value (e.g. 0) instead of NAN makes the model running but I am not sure if that's what we want?

@wpotrzebowski Thanks for testing it. Glad to know that you are able to reproduce the problem.

I am a little bit concerned to return value 0. Using this way, the program will generate some data that are not theoretically correct. Users may not realize this and could accidentally use the incorrect data to fit the experimental data. Personally, I still prefer to return NaN when the code does not have enough information to give correct calculation.

wpotrzebowski commented 11 months ago

@yunliu01 I don't think using zeros is the correct approach. We probably need to think about more proper error handling in case this if clause is met.

butlerpd commented 3 months ago

I'm wondering if the nan is not the correct answer (nan not NAN given the changes in numpy). The fix should be in sasmodels which could raise the error "value out of range" or some such? this could then also be used for form factors which are not defined at zero for example? and the GUI could check for the exception raised and report something sensible to the user like "The requested Q range (including as extended by the resolution smearing calculation) is beyond the validity of the model."

Not sure this can make it into 6.0 though?