Opened 7 years ago

Closed 5 years ago

Last modified 5 years ago

#829 closed enhancement (fixed)

allow models to define ModelInfo directly

Reported by: pkienzle Owned by:
Priority: minor Milestone: SasView 4.2.0
Component: SasView Keywords:
Cc: Work Package: SasView Bug Fixing

Description

(1) Allow models to be defined directly as a ModelInfo object.

For example:

   from sasmodels.modelinfo import ModelInfo, Parameter, ParameterTable

   info = ModelInfo()
   info.id = 'model_id'
   info.name = 'Model Name'
   info.filename = abspath(__file__)
   info.docs = __doc__
   ...

   parameters = [
       Parameter(name='radius', units='Ang', default=50, limits=[0,inf], ptype='volume', description='Sphere radius'),
       ...
   ]
   info.parameters = ParameterTable(parameters)

This approach follows parts of the Zen of Python:

Explicit is better than implicit.
Simple is better than complex.

It also means that your IDE will allow tab-completion on the model attributes so you don't have to guess the names. This could be a big benefit.

Implementation is simple. Just put the following at the top of make_model_info():

   predefined_info = getattr(kernel_model, 'info', None)
   if predefined_info is not None:
       return predefined_info

(2) Don't allow attributes to be introduced into the model definition beyond those defined in the ModelInfo? class.

This can be done with the following method in the ModelInfo class:

    def __setattr__(self, key, value):
        # Check for class attr when setting; this is because hasattr on
        # a property will return False if getattr on that property raises
        # an exception.  This means if you really want to sneak an
        # attribute into the group from your data loader, you will have
        # to populate it from the
        if not key.startswith('_') and not hasattr(self.__class__, key):
            raise AttributeError("Cannot add attribute %s to class %s"
                                 % (key, self.__class__.__name__))
        object.__setattr__(self, key, value)

By doing this, users will not be able to introduce typos into the model attribute definitions, or otherwise wish for capabilities that are not already there. For example, the model *multilayer_vescicle* defines the following, which looks like it should make *radius* and *n_pairs* polydisperse, but which in fact is completely ignored by sasmodels:

polydispersity = ["radius", "n_pairs"]

Change History (4)

comment:1 Changed 6 years ago by butler

  • Milestone changed from SasView 4.2.0 to SasView 4.3.0

comment:2 Changed 6 years ago by pkienzle

Part (1) is already supported: if the module contains model_info then it is returned directly without any further processing of the module attributes. This needs to be documented in sasmodels/doc/guide/plugin.rst

comment:3 Changed 5 years ago by pkienzle

  • Resolution set to fixed
  • Status changed from new to closed

Part (1) was fixed 2017-09-01

Part (2) is now in ticket #1216.

Closing this ticket.

comment:4 Changed 5 years ago by butler

  • Milestone changed from SasView 4.3.0 to SasView 4.2.0
Note: See TracTickets for help on using tickets.