Skip to content

Ticket 1006#53

Merged
butlerpd merged 3 commits intomasterfrom
ticket1006
Oct 28, 2017
Merged

Ticket 1006#53
butlerpd merged 3 commits intomasterfrom
ticket1006

Conversation

@gonzalezma
Copy link
Copy Markdown
Contributor

The problem in the interface when combining a form factor that has multiplicity with a structure factor was due to the fact that the MultiplicationModel function did not propagate to the new model the information about the multiplicity and the non_fittable (n) parameters. With these changes, my test with the core_multi_shell model x the hard sphere S(Q) works well. But probably Paul K should check if there are some other attributes that need to be passed or if this should be done in a different way.

@gonzalezma
Copy link
Copy Markdown
Contributor Author

I also noticed that when selecting an S(Q), there is the following RuntimeError message in my terminal:
File "C:\Users\gonzalezm\AppData\Local\Continuum\Anaconda\lib\site-packages\wx-3.0-msw\wx_core.py", line 16767, in lambda event: event.callable(*event.args, **event.kw) )
File "C:\Users\gonzalezm\Git\sasview\src\sas\sasgui\guiframe\data_panel.py", line 789, in append_theory_helper for theory_id, item in theory_list.iteritems():
RuntimeError: dictionary changed size during iteration

This appears only the first time, also for standard models (e.g. sphere + hardsphere), and it does not seem to have consequences, but I suppose it would be good to get rid of it if possible.

Copy link
Copy Markdown
Member

@butlerpd butlerpd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unless I am missing something I think new lines 212 and 213 seem redundant with 214? In fact currently line 214 can never be reached can it? Not sure which is more pythonic: remove 212 and 213 or remove 214? Maybe Paul K. knows?

Once this is sorted I think this should be pullable though I should check the functionality first I guess

@gonzalezma
Copy link
Copy Markdown
Contributor Author

You're right Paul. I forgot to remove the initial return. I did it now, removing line 214 because I liked it more this way, but I don't know either which is the prefered way in python. I let Paul K to decide on this, and in particular to check if other attributes need to be added to the ConstructedModel or if my changes may have unexpected consequences in some cases (everything seems to work, but I just made a few standard tests combining form factors and structure models and without fitting).

@pkienzle
Copy link
Copy Markdown
Contributor

You should be able to do just the following:

def MultiplicationModel(form_factor, structure_factor):
    # type: ("SasviewModel", "SasviewModel") -> "SasviewModel"
    model_info = product.make_product_info(form_factor._model_info,
                                           structure_factor._model_info)
    ConstructedModel = make_model_from_info(model_info)
    return ConstructedModel(form_factor.multiplicity)

If not, then make_product_info isn't describing the multiplicity variables correctly, or make_model_from_info isn't processing them correctly.

@butlerpd
Copy link
Copy Markdown
Member

It clearly has not bee working! Are you saying the error was ONLY on line 207 which should ALWAYS return ConstructedModel(form_factor.multiplicity) regardless if the form factor has multiplicity or not? if so why doesn't the API just do that without needing to pass (form_factor.multiplicity)? Seems very odd.

@pkienzle
Copy link
Copy Markdown
Contributor

The multiplicity attribute is always set in the model, even if it happens to be None. You can see this from the definition of SasviewModel in sasview_model.py:

def __init__(self, multiplicity=None):
    ...
    self.multiplicity = multiplicity
    ...

Within the GUI, the multiplicity models have a drop-down box at the top of the form in which to select the multiplicity value. Since this is only for multiplicity models, it is put in a separate branch, passing the multiplicity to the form_factor constructor, then updating the form with any fields that may have appeared as a result of the multiplicity. The other branch could call the constructor with multiplicity=None, but that is the default so it doesn't bother.

The point is that when adding a structure factor, the multiplication model shouldn't care whether or not there is multiplicity on the form factor, it should just pass whatever multiplicity P has along to the S*P product model so that it is set correctly during model evaluation (the _get_weights function attaches the value of multiplicity to the parameter set).

Furthermore, at this point only the multiplicity value is needed; the additional fields would only be needed by the GUI, but it is using the multiplicity info from the underlying form_factor model.

@gonzalezma
Copy link
Copy Markdown
Contributor Author

Using 'return ConstructedModel(form_factor.multiplicity)' improves things, but it is not enough as the parameter 'n' continues to appear in the list of model parameters. The reason is that ConstructedModel.non_fittable is not getting the info from the form_factor and remains empty. Similarly ConstructedModel.is_multiplicity_model returns False and the multiplicity_info is empty (number=0, control='', etc.), but I guess this does not matter much if they are not used. I will try to check make_product_info and make_model_from_info to set properly the non_fittable attribute.

@gonzalezma
Copy link
Copy Markdown
Contributor Author

Hopefully, this is the right solution. I added model_info.control into make_product_info in order to pass the information about the controlling and non_fittable parameters (e.g. n in the core_multi_shell model). Note that I assumed that only the form factor has control parameters.

@pkienzle
Copy link
Copy Markdown
Contributor

pkienzle commented Oct 27, 2017

Looking at sasview_models._generate_model_attributes and product.make_product_info, I suspect the problem is that model_info.control is not being set. hidden should also be copied from the form factor (though there are no form factor models which provide a hidden function at the moment, just rpa).

This will also be a problem in mixture.py, if you are combining two models, one of which is a multiplicity model (combining two multiplicity models should raise an error). In that case, the control parameter will need to be tagged with the appropriate 'A_', 'B_', ... prefix before assigning, and the hidden() function, if present, will need to be wrapped so that the parameter names in the returned set are also prefixed.

Other parameters in model_info.ModelInfo should not be a problem. profile, profile_axes (for spherical shell models) are probably going to be drawn from the form_factor, and so don't need to be included. single and opencl are used internally to select a calculator, and can be undefined for this model (this model should present as a python model).

Copy link
Copy Markdown
Contributor

@pkienzle pkienzle left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code looks fine. Haven't tested. I'll turn my comment re: mixture models into a ticket.

@butlerpd
Copy link
Copy Markdown
Member

will test functionality this morning and merge if passes

Copy link
Copy Markdown
Member

@butlerpd butlerpd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have tested on windows and now works so am calling functionality fixed

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.

3 participants