class TestGuinierHayterM(unittest.TestCase):
    """ 
        Unit tests for GuinierModel(Q) * HayterMSAStructure(Q)
    """
    def setUp(self):
        from sas.models.GuinierModel import GuinierModel
        from sas.models.HayterMSAStructure import HayterMSAStructure
        from sas.models.MultiplicationModel import MultiplicationModel

        self.model = GuinierModel()
        self.model2 = HayterMSAStructure()
        self.model3 = MultiplicationModel(self.model, self.model2)  

    #Radius of model1.calculate_ER should be equal to the output/2 of DiamFunctions
    def test_multplication_radius(self):
        """
            test multiplication model (check the effective radius & the output
             of the multiplication)
        """
        self.model.setParam("rg", 60)
        self.model.setParam("scale", 1)
        #Compare new method with old method         
        self.assertEqual(self.model3.run(0.1), self.model.run(0.1)*self.model2.run(0.1))
        
        #effective radius calculation is not implemented for this model. 
        self.assertEqual(self.model3.calculate_ER(), NotImplemented)       
class TestGuinierHayterM(unittest.TestCase):
    """ 
        Unit tests for GuinierModel(Q) * HayterMSAStructure(Q)
    """
    def setUp(self):
        from sas.models.GuinierModel import GuinierModel
        from sas.models.HayterMSAStructure import HayterMSAStructure
        from sas.models.MultiplicationModel import MultiplicationModel

        self.model = GuinierModel()
        self.model2 = HayterMSAStructure()
        self.model3 = MultiplicationModel(self.model, self.model2)  

    #Radius of model1.calculate_ER should be equal to the output/2 of DiamFunctions
    def test_multplication_radius(self):
        """
            test multiplication model (check the effective radius & the output
             of the multiplication)
        """
        self.model.setParam("rg", 60)
        self.model.setParam("scale", 1)
        #Compare new method with old method         
        self.assertEqual(self.model3.run(0.1), self.model.run(0.1)*self.model2.run(0.1))
        
        #effective radius calculation is not implemented for this model. 
        self.assertEqual(self.model3.calculate_ER(), NotImplemented)       
    def setUp(self):
        from sas.models.LamellarModel import LamellarModel
        from sas.models.HayterMSAStructure import HayterMSAStructure
        from sas.models.MultiplicationModel import MultiplicationModel

        self.model = LamellarModel()
        self.model2 = HayterMSAStructure()
        self.model3 = MultiplicationModel(self.model, self.model2)  
    def setUp(self):
        from sas.models.SphereModel import SphereModel
        from sas.models.HardsphereStructure import HardsphereStructure
        from sas.models.DiamCylFunc import DiamCylFunc
        from sas.models.MultiplicationModel import MultiplicationModel

        self.model = SphereModel()
        self.model2 = HardsphereStructure()
        self.model3 = MultiplicationModel(self.model, self.model2)  
        self.modelD = DiamCylFunc() 
    def setUp(self):
        from sas.models.CylinderModel import CylinderModel
        from sas.models.HayterMSAStructure import HayterMSAStructure
        from sas.models.DiamCylFunc import DiamCylFunc
        from sas.models.MultiplicationModel import MultiplicationModel

        self.model = CylinderModel()
        self.model2 = HayterMSAStructure()
        self.model3 = MultiplicationModel(self.model, self.model2)  
        self.modelD = DiamCylFunc()
    def setUp(self):
        from sas.models.LamellarModel import LamellarModel
        from sas.models.HayterMSAStructure import HayterMSAStructure
        from sas.models.MultiplicationModel import MultiplicationModel

        self.model = LamellarModel()
        self.model2 = HayterMSAStructure()
        self.model3 = MultiplicationModel(self.model, self.model2)  
    def setUp(self):
        from sas.models.SphereModel import SphereModel
        from sas.models.HardsphereStructure import HardsphereStructure
        from sas.models.DiamCylFunc import DiamCylFunc
        from sas.models.MultiplicationModel import MultiplicationModel

        self.model = SphereModel()
        self.model2 = HardsphereStructure()
        self.model3 = MultiplicationModel(self.model, self.model2)  
        self.modelD = DiamCylFunc() 
    def setUp(self):
        from sas.models.CylinderModel import CylinderModel
        from sas.models.HayterMSAStructure import HayterMSAStructure
        from sas.models.DiamCylFunc import DiamCylFunc
        from sas.models.MultiplicationModel import MultiplicationModel

        self.model = CylinderModel()
        self.model2 = HayterMSAStructure()
        self.model3 = MultiplicationModel(self.model, self.model2)  
        self.modelD = DiamCylFunc()
Exemplo n.º 9
0
    def _on_model(self, evt):
        """
        React to a model menu event

        :param event: wx menu event

        """
        if int(evt.GetId()) in self.form_factor_dict.keys():
            from sas.models.MultiplicationModel import MultiplicationModel
            self.model_dictionary[MultiplicationModel.__name__] = MultiplicationModel
            model1, model2 = self.form_factor_dict[int(evt.GetId())]
            model = MultiplicationModel(model1, model2)
        else:
            model = self.struct_factor_dict[str(evt.GetId())]()
class TestLamellarHayterM(unittest.TestCase):
    """ 
        Unit tests for LamellarModel(Q) * HayterMSAStructure(Q)
    """
    def setUp(self):
        from sas.models.LamellarModel import LamellarModel
        from sas.models.HayterMSAStructure import HayterMSAStructure
        from sas.models.MultiplicationModel import MultiplicationModel

        self.model = LamellarModel()
        self.model2 = HayterMSAStructure()
        self.model3 = MultiplicationModel(self.model, self.model2)  

    #Radius of model1.calculate_ER should Not be finite.
    def test_multplication_radius(self):
        """
            test multiplication model (check the effective radius & the output
             of the multiplication)
        """
        #Check run       
        self.assertFalse(numpy.isfinite(self.model3.run(0.1)))
        #check effective radius . 
        self.assertTrue(numpy.isfinite(self.model.calculate_ER()))      
class TestLamellarHayterM(unittest.TestCase):
    """ 
        Unit tests for LamellarModel(Q) * HayterMSAStructure(Q)
    """
    def setUp(self):
        from sas.models.LamellarModel import LamellarModel
        from sas.models.HayterMSAStructure import HayterMSAStructure
        from sas.models.MultiplicationModel import MultiplicationModel

        self.model = LamellarModel()
        self.model2 = HayterMSAStructure()
        self.model3 = MultiplicationModel(self.model, self.model2)  

    #Radius of model1.calculate_ER should Not be finite.
    def test_multplication_radius(self):
        """
            test multiplication model (check the effective radius & the output
             of the multiplication)
        """
        #Check run       
        self.assertFalse(numpy.isfinite(self.model3.run(0.1)))
        #check effective radius . 
        self.assertTrue(numpy.isfinite(self.model.calculate_ER()))      
Exemplo n.º 12
0
def eval_sasview(model_info, data):
    # type: (Modelinfo, Data) -> Calculator
    """
    Return a model calculator using the pre-4.0 SasView models.
    """
    # importing sas here so that the error message will be that sas failed to
    # import rather than the more obscure smear_selection not imported error
    import sas
    import sas.models
    from sas.models.qsmearing import smear_selection
    from sas.models.MultiplicationModel import MultiplicationModel
    from sas.models.dispersion_models import models as dispersers

    def get_model_class(name):
        # type: (str) -> "sas.models.BaseComponent"
        #print("new",sorted(_pars.items()))
        __import__('sas.models.' + name)
        ModelClass = getattr(getattr(sas.models, name, None), name, None)
        if ModelClass is None:
            raise ValueError("could not find model %r in sas.models" % name)
        return ModelClass

    # WARNING: ugly hack when handling model!
    # Sasview models with multiplicity need to be created with the target
    # multiplicity, so we cannot create the target model ahead of time for
    # for multiplicity models.  Instead we store the model in a list and
    # update the first element of that list with the new multiplicity model
    # every time we evaluate.

    # grab the sasview model, or create it if it is a product model
    if model_info.composition:
        composition_type, parts = model_info.composition
        if composition_type == 'product':
            P, S = [get_model_class(revert_name(p))() for p in parts]
            model = [MultiplicationModel(P, S)]
        else:
            raise ValueError("sasview mixture models not supported by compare")
    else:
        old_name = revert_name(model_info)
        if old_name is None:
            raise ValueError("model %r does not exist in old sasview" %
                             model_info.id)
        ModelClass = get_model_class(old_name)
        model = [ModelClass()]
    model[0].disperser_handles = {}

    # build a smearer with which to call the model, if necessary
    smearer = smear_selection(data, model=model)
    if hasattr(data, 'qx_data'):
        q = np.sqrt(data.qx_data**2 + data.qy_data**2)
        index = ((~data.mask) & (~np.isnan(data.data))
                 & (q >= data.qmin) & (q <= data.qmax))
        if smearer is not None:
            smearer.model = model  # because smear_selection has a bug
            smearer.accuracy = data.accuracy
            smearer.set_index(index)

            def _call_smearer():
                smearer.model = model[0]
                return smearer.get_value()

            theory = _call_smearer
        else:
            theory = lambda: model[0].evalDistribution(
                [data.qx_data[index], data.qy_data[index]])
    elif smearer is not None:
        theory = lambda: smearer(model[0].evalDistribution(data.x))
    else:
        theory = lambda: model[0].evalDistribution(data.x)

    def calculator(**pars):
        # type: (float, ...) -> np.ndarray
        """
        Sasview calculator for model.
        """
        oldpars = revert_pars(model_info, pars)
        # For multiplicity models, create a model with the correct multiplicity
        control = oldpars.pop("CONTROL", None)
        if control is not None:
            # sphericalSLD has one fewer multiplicity.  This update should
            # happen in revert_pars, but it hasn't been called yet.
            model[0] = ModelClass(control)
        # paying for parameter conversion each time to keep life simple, if not fast
        for k, v in oldpars.items():
            if k.endswith('.type'):
                par = k[:-5]
                if v == 'gaussian': continue
                cls = dispersers[v if v != 'rectangle' else 'rectangula']
                handle = cls()
                model[0].disperser_handles[par] = handle
                try:
                    model[0].set_dispersion(par, handle)
                except Exception:
                    exception.annotate_exception("while setting %s to %r" %
                                                 (par, v))
                    raise

        #print("sasview pars",oldpars)
        for k, v in oldpars.items():
            name_attr = k.split('.')  # polydispersity components
            if len(name_attr) == 2:
                par, disp_par = name_attr
                model[0].dispersion[par][disp_par] = v
            else:
                model[0].setParam(k, v)
        return theory()

    calculator.engine = "sasview"
    return calculator
Exemplo n.º 13
0
    def test_cyl_times_square(self):
        """ Simple cylinder model fit  """
        
        out=Loader().load("cyl_400_20.txt")
        data = Data1D(x=out.x, y=out.y, dx=out.dx, dy=out.dy)
        # Receives the type of model for the fitting
        model1  =  MultiplicationModel(CylinderModel(),SquareWellStructure())
        model1.setParam('background', 0.0)
        model1.setParam('sldCyl', 3e-006)
        model1.setParam('sldSolv', 0.0)
        model1.setParam('length', 420)
        model1.setParam('radius', 40)
        model1.setParam('scale_factor', 2)
        model1.setParam('volfraction', 0.04)
        model1.setParam('welldepth', 1.5)
        model1.setParam('wellwidth', 1.2)
      
        model = Model(model1)
    
        pars1 =['length','radius','scale_factor']
        fitter = Fit()
        fitter.set_data(data,1)
        fitter.set_model(model,1,pars1)
        fitter.select_problem_for_fit(id=1,value=1)
        result1, = fitter.fit()

        self.assert_(result1)
        self.assertTrue(len(result1.pvec)>=0 )
        self.assertTrue(len(result1.stderr)>= 0)

        #print "results",list(zip(result1.pvec, result1.stderr))
        self.assertTrue( math.fabs(result1.pvec[0]-612)/3.0 <= result1.stderr[0] )
        self.assertTrue( math.fabs(result1.pvec[1]-20.3)/3.0  <= result1.stderr[1] )
        self.assertTrue( math.fabs(result1.pvec[2]-25)/3.0 <= result1.stderr[2] )
        
        self.assertTrue( result1.fitness/len(data.x) < 1.0 )
Exemplo n.º 14
0
def eval_sasview(model_info, data):
    """
    Return a model calculator using the pre-4.0 SasView models.
    """
    # importing sas here so that the error message will be that sas failed to
    # import rather than the more obscure smear_selection not imported error
    import sas
    from sas.models.qsmearing import smear_selection

    def get_model(name):
        #print("new",sorted(_pars.items()))
        sas = __import__('sas.models.' + name)
        ModelClass = getattr(getattr(sas.models, name, None), name, None)
        if ModelClass is None:
            raise ValueError("could not find model %r in sas.models" % name)
        return ModelClass()

    # grab the sasview model, or create it if it is a product model
    if model_info['composition']:
        composition_type, parts = model_info['composition']
        if composition_type == 'product':
            from sas.models.MultiplicationModel import MultiplicationModel
            P, S = [get_model(revert_name(p)) for p in parts]
            model = MultiplicationModel(P, S)
        else:
            raise ValueError("sasview mixture models not supported by compare")
    else:
        model = get_model(revert_name(model_info))

    # build a smearer with which to call the model, if necessary
    smearer = smear_selection(data, model=model)
    if hasattr(data, 'qx_data'):
        q = np.sqrt(data.qx_data**2 + data.qy_data**2)
        index = ((~data.mask) & (~np.isnan(data.data))
                 & (q >= data.qmin) & (q <= data.qmax))
        if smearer is not None:
            smearer.model = model  # because smear_selection has a bug
            smearer.accuracy = data.accuracy
            smearer.set_index(index)
            theory = lambda: smearer.get_value()
        else:
            theory = lambda: model.evalDistribution(
                [data.qx_data[index], data.qy_data[index]])
    elif smearer is not None:
        theory = lambda: smearer(model.evalDistribution(data.x))
    else:
        theory = lambda: model.evalDistribution(data.x)

    def calculator(**pars):
        """
        Sasview calculator for model.
        """
        # paying for parameter conversion each time to keep life simple, if not fast
        pars = revert_pars(model_info, pars)
        for k, v in pars.items():
            parts = k.split('.')  # polydispersity components
            if len(parts) == 2:
                model.dispersion[parts[0]][parts[1]] = v
            else:
                model.setParam(k, v)
        return theory()

    calculator.engine = "sasview"
    return calculator
class TestsphereHardS(unittest.TestCase):
    """ 
        Unit tests for SphereModel(Q) * HardsphereStructure(Q)
    """
    def setUp(self):
        from sas.models.SphereModel import SphereModel
        from sas.models.HardsphereStructure import HardsphereStructure
        from sas.models.DiamCylFunc import DiamCylFunc
        from sas.models.MultiplicationModel import MultiplicationModel

        self.model = SphereModel()
        self.model2 = HardsphereStructure()
        self.model3 = MultiplicationModel(self.model, self.model2)  
        self.modelD = DiamCylFunc() 

    #Radius of model1.calculate_ER should be equal to the output/2 of DiamFunctions
    def test_multplication_radius(self):
        """
            test multiplication model (check the effective radius & the output
             of the multiplication)
        """
        self.model.setParam("radius", 60)
        modelDrun = 60
        self.model2.setParam("volfraction", 0.2)
        self.model2.setParam("effect_radius", modelDrun )
        
        #Compare new method with old method         
        self.assertEqual(self.model3.run(0.1), self.model.run(0.1)*self.model2.run(0.1))
        
        #Compare radius from two different calculations. Note: modelD.run(0.0) is DIAMETER
        self.assertEqual(self.model.calculate_ER(), modelDrun)
        
        
    def testMultiplicationParam(self):
        """ Test Multiplication  (check the parameters)"""
        ## test details dictionary

        ## test parameters list
        list3= self.model3.getParamList()

        for item in self.model.getParamList():
            if not 'scale' in item: 
                self.assert_(item in list3)
        for item in self.model2.getParamList():
            #model3 parameters should not include effect_radius*
            if not 'effect_radius' in item:  
                self.assert_(item in list3)
            
        ## test set value for parameters and get paramaters
        self.model3.setParam("scale_factor", 15)
        self.assertEqual(self.model3.getParam("scale_factor"), 15)
        self.model3.setParam("radius", 20)
        self.assertEqual(self.model3.getParam("radius"), 20)
        self.model3.setParam("radius.width", 15)
        self.assertEqual(self.model3.getParam("radius.width"), 15)
        self.model3.setParam("scale_factor", 15)
        self.assertEqual(self.model3.getParam("scale_factor"), 15)
        self.assertEqual(self.model3.getParam("volfraction"), self.model.getParam("scale"))
        
        ## Dispersity 
        list3= self.model3.getDispParamList()
        self.assertEqual(list3, ['radius.npts', 'radius.nsigmas', 'radius.width'])
        
        from sas.models.dispersion_models import ArrayDispersion
        disp_th = ArrayDispersion()
        
        values_th = numpy.zeros(100)
        weights   = numpy.zeros(100)
        for i in range(100):
            values_th[i]=(math.pi/99.0*i)
            weights[i]=(1.0)
    
        disp_th.set_weights(values_th, weights)
        
        self.model3.set_dispersion('radius', disp_th)
        
        val_1d = self.model3.run(math.sqrt(0.0002))
        val_2d = self.model3.runXY([0.01,0.01]) 
        
        self.assertTrue(math.fabs(val_1d-val_2d)/val_1d < 0.02)
        model4= self.model3.clone()
        self.assertEqual(model4.getParam("radius"), 20)
class TestsphereHardS(unittest.TestCase):
    """ 
        Unit tests for SphereModel(Q) * HardsphereStructure(Q)
    """
    def setUp(self):
        from sas.models.SphereModel import SphereModel
        from sas.models.HardsphereStructure import HardsphereStructure
        from sas.models.DiamCylFunc import DiamCylFunc
        from sas.models.MultiplicationModel import MultiplicationModel

        self.model = SphereModel()
        self.model2 = HardsphereStructure()
        self.model3 = MultiplicationModel(self.model, self.model2)  
        self.modelD = DiamCylFunc() 

    #Radius of model1.calculate_ER should be equal to the output/2 of DiamFunctions
    def test_multplication_radius(self):
        """
            test multiplication model (check the effective radius & the output
             of the multiplication)
        """
        self.model.setParam("radius", 60)
        modelDrun = 60
        self.model2.setParam("volfraction", 0.2)
        self.model2.setParam("effect_radius", modelDrun )
        
        #Compare new method with old method         
        self.assertEqual(self.model3.run(0.1), self.model.run(0.1)*self.model2.run(0.1))
        
        #Compare radius from two different calculations. Note: modelD.run(0.0) is DIAMETER
        self.assertEqual(self.model.calculate_ER(), modelDrun)
        
        
    def testMultiplicationParam(self):
        """ Test Multiplication  (check the parameters)"""
        ## test details dictionary

        ## test parameters list
        list3= self.model3.getParamList()

        for item in self.model.getParamList():
            if not 'scale' in item: 
                self.assert_(item in list3)
        for item in self.model2.getParamList():
            #model3 parameters should not include effect_radius*
            if not 'effect_radius' in item:  
                self.assert_(item in list3)
            
        ## test set value for parameters and get paramaters
        self.model3.setParam("scale_factor", 15)
        self.assertEqual(self.model3.getParam("scale_factor"), 15)
        self.model3.setParam("radius", 20)
        self.assertEqual(self.model3.getParam("radius"), 20)
        self.model3.setParam("radius.width", 15)
        self.assertEqual(self.model3.getParam("radius.width"), 15)
        self.model3.setParam("scale_factor", 15)
        self.assertEqual(self.model3.getParam("scale_factor"), 15)
        self.assertEqual(self.model3.getParam("volfraction"), self.model.getParam("scale"))
        
        ## Dispersity 
        list3= self.model3.getDispParamList()
        self.assertEqual(list3, ['radius.npts', 'radius.nsigmas', 'radius.width'])
        
        from sas.models.dispersion_models import ArrayDispersion
        disp_th = ArrayDispersion()
        
        values_th = numpy.zeros(100)
        weights   = numpy.zeros(100)
        for i in range(100):
            values_th[i]=(math.pi/99.0*i)
            weights[i]=(1.0)
    
        disp_th.set_weights(values_th, weights)
        
        self.model3.set_dispersion('radius', disp_th)
        
        val_1d = self.model3.run(math.sqrt(0.0002))
        val_2d = self.model3.runXY([0.01,0.01]) 
        
        self.assertTrue(math.fabs(val_1d-val_2d)/val_1d < 0.02)
        model4= self.model3.clone()
        self.assertEqual(model4.getParam("radius"), 20)