Changeset 304c775 in sasmodels for sasmodels/model_test.py


Ignore:
Timestamp:
Oct 25, 2018 5:35:06 PM (5 years ago)
Author:
Paul Kienzle <pkienzle@…>
Branches:
master, core_shell_microgels, magnetic_model, ticket-1257-vesicle-product, ticket_1156, ticket_1265_superball, ticket_822_more_unit_tests
Children:
39a06c9
Parents:
6d5601c
Message:

provide method for testing Fq results. Refs #1202.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • sasmodels/model_test.py

    r74e9b5f r304c775  
    5959from . import core 
    6060from .core import list_models, load_model_info, build_model 
    61 from .direct_model import call_kernel, call_ER, call_VR 
     61from .direct_model import call_kernel, call_Fq 
    6262from .exception import annotate_exception 
    6363from .modelinfo import expand_pars 
     
    215215                ({}, [(0.1, 0.1)]*2, [None]*2), 
    216216                # test that ER/VR will run if they exist 
    217                 ({}, 'ER', None), 
    218                 ({}, 'VR', None), 
     217                ({}, 0.1, None, None, None, None, None), 
    219218                ] 
    220219            tests = smoke_tests 
     
    288287            # type: (KernelModel, TestCondition) -> None 
    289288            """Run a single test case.""" 
    290             user_pars, x, y = test 
     289            user_pars, x, y = test[:3] 
    291290            pars = expand_pars(self.info.parameters, user_pars) 
    292291            invalid = invalid_pars(self.info.parameters, pars) 
     
    301300            self.assertEqual(len(y), len(x)) 
    302301 
    303             if x[0] == 'ER': 
    304                 actual = np.array([call_ER(model.info, pars)]) 
    305             elif x[0] == 'VR': 
    306                 actual = np.array([call_VR(model.info, pars)]) 
    307             elif isinstance(x[0], tuple): 
     302            if isinstance(x[0], tuple): 
    308303                qx, qy = zip(*x) 
    309304                q_vectors = [np.array(qx), np.array(qy)] 
    310                 kernel = model.make_kernel(q_vectors) 
    311                 actual = call_kernel(kernel, pars) 
    312305            else: 
    313306                q_vectors = [np.array(x)] 
    314                 kernel = model.make_kernel(q_vectors) 
     307 
     308            kernel = model.make_kernel(q_vectors) 
     309            if len(test) == 3: 
    315310                actual = call_kernel(kernel, pars) 
    316  
    317             self.assertTrue(len(actual) > 0) 
    318             self.assertEqual(len(y), len(actual)) 
    319  
    320             for xi, yi, actual_yi in zip(x, y, actual): 
     311                self._check_vectors(x, y, actual, 'I') 
     312                return actual 
     313            else: 
     314                y1 = y 
     315                y2 = test[3] if not isinstance(test[3], list) else [test[3]] 
     316                F1, F2, R_eff, volume, volume_ratio = call_Fq(kernel, pars) 
     317                if F1 is not None:  # F1 is none for models with Iq instead of Fq 
     318                    self._check_vectors(x, y1, F1, 'F') 
     319                self._check_vectors(x, y2, F2, 'F^2') 
     320                self._check_scalar(test[4], R_eff, 'R_eff') 
     321                self._check_scalar(test[5], volume, 'volume') 
     322                self._check_scalar(test[6], volume_ratio, 'form:shell ratio') 
     323                return F2 
     324 
     325        def _check_scalar(self, target, actual, name): 
     326            if target is None: 
     327                # smoke test --- make sure it runs and produces a value 
     328                self.assertTrue(not np.isnan(actual), 
     329                                'invalid %s: %s' % (name, actual)) 
     330            elif np.isnan(target): 
     331                # make sure nans match 
     332                self.assertTrue(np.isnan(actual), 
     333                                '%s: expected:%s; actual:%s' 
     334                                % (name, target, actual)) 
     335            else: 
     336                # is_near does not work for infinite values, so also test 
     337                # for exact values. 
     338                self.assertTrue(target == actual or is_near(target, actual, 5), 
     339                                '%s: expected:%s; actual:%s' 
     340                                % (name, target, actual)) 
     341 
     342        def _check_vectors(self, x, target, actual, name='I'): 
     343            self.assertTrue(len(actual) > 0, 
     344                            '%s(...) expected return'%name) 
     345            if target is None: 
     346                return 
     347            self.assertEqual(len(target), len(actual), 
     348                             '%s(...) returned wrong length'%name) 
     349            for xi, yi, actual_yi in zip(x, target, actual): 
    321350                if yi is None: 
    322351                    # smoke test --- make sure it runs and produces a value 
    323352                    self.assertTrue(not np.isnan(actual_yi), 
    324                                     'invalid f(%s): %s' % (xi, actual_yi)) 
     353                                    'invalid %s(%s): %s' % (name, xi, actual_yi)) 
    325354                elif np.isnan(yi): 
     355                    # make sure nans match 
    326356                    self.assertTrue(np.isnan(actual_yi), 
    327                                     'f(%s): expected:%s; actual:%s' 
    328                                     % (xi, yi, actual_yi)) 
     357                                    '%s(%s): expected:%s; actual:%s' 
     358                                    % (name, xi, yi, actual_yi)) 
    329359                else: 
    330360                    # is_near does not work for infinite values, so also test 
    331                     # for exact values.  Note that this will not 
     361                    # for exact values. 
    332362                    self.assertTrue(yi == actual_yi or is_near(yi, actual_yi, 5), 
    333                                     'f(%s); expected:%s; actual:%s' 
    334                                     % (xi, yi, actual_yi)) 
    335             return actual 
     363                                    '%s(%s); expected:%s; actual:%s' 
     364                                    % (name, xi, yi, actual_yi)) 
    336365 
    337366    return ModelTestCase 
     
    345374    invalid = [] 
    346375    for par in sorted(pars.keys()): 
     376        # special handling of R_eff mode, which is not a usual parameter 
     377        if par == 'radius_effective_type': 
     378            continue 
    347379        parts = par.split('_pd') 
    348380        if len(parts) > 1 and parts[1] not in ("", "_n", "nsigma", "type"): 
Note: See TracChangeset for help on using the changeset viewer.